Package: mdal
BasicsMDAL Python integration allows you to access and manipulation geospatial mesh data sets usingMDALin Python.Currently, this integration can:read and write all MDAL compatible file formatsaccess vertex, face, edge and volume data as numpy arrayswrite vertex, face, edge and volume data from numpy arraysaccess and write scalar and vector datasetsbeta level read and write integration withmeshiobeta level read integration withOpen3DDrivers[‘2DM Mesh File’, ‘XMS Tin Mesh File’, ‘Selafin File’, ‘Esri TIN’, ‘Stanford PLY Ascii Mesh File’, ‘Flo2D’, ‘HEC-RAS 2D’, ‘TUFLOW FV’, ‘AnuGA’, ‘UGRID Results’, ‘GDAL NetCDF’, ‘GDAL Grib’, ‘DAT’, ‘Binary DAT’, ‘TUFLOW XMDF’, ‘XDMF’]InstallationCondaMDAL Python support is installable via Conda:conda install -c conda-forge mdal-pythonPyPIMDAL Python support can be installed usingpipNoteThe previous mdal-python package is deprecated and will not updated beyond 1.0.3. Use the mdal package instead.pip install mdalThis will ONLY work if there is a valid and working installation of MDAL on the device and accessible through the device library search path.GitHubThe repository for MDAL’s Python extension is available athttps://github.com/ViRGIS-Team/mdal-pythonUsageThe basic usage can be seen in this code snippet:frommdalimportDatasource,Info,last_status,PyMesh,drivers,MDAL_DataLocationprint(f"MDAL Version:{Info.version}")print(f"MDAL Driver Count :{Info.driver_count}")print(last_status().name)fordriverinInfo.drivers:print(driver)ds=Datasource("data/ply/test_mesh.ply")print(ds.meshes)withds.load(0)asmesh:print(f"Driver :{mesh.driver_name}")print(f"Format :{mesh.get_metadata('format')}")print(f"Vertex Count :{mesh.vertex_count}")print(f"Face Count :{mesh.face_count}")print(f"Largest Face:{mesh.largest_face}")print(f"Edge Count :{mesh.edge_count}")print(f"CRS :{mesh.projection}")print(f"Mesh extent :{mesh.extent}")print(f"Metadata :{mesh.metadata}")print(f"CRS Metadata :{mesh.get_metadata('crs')}")mesh.add_metadata("test","value")print(f"Metadate set eqiuality :{mesh.get_metadata('test')=='value'}")vertex=mesh.verticesprint(f"Vertex Array Shape :{vertex.shape}")faces=mesh.facesprint(f"Face Array Shape :{faces.shape}")edges=mesh.edgesprint(f"Edges Array Shape :{edges.shape}")print("")group=mesh.group(0)print(f"DatasetGroup Name :{group.name}")print(f"DatasetGroup Location :{group.location.name}")print(f"Dataset Count :{group.dataset_count}")print(f"Group has scalar values :{group.has_scalar}")print(f"Group has temporal values :{group.is_temporal}")print(f"Reference Time :{group.reference_time}")print(f"Maximum Vertical Level Count :{group.level_count}")print(f"Minimum / Maximum ;{group.minmax}")print(f"Metadata :{group.metadata}")print(f"Name Metadata :{group.get_metadata('name')}")group.add_metadata("test","value")print(f"Metadate set eqiuality :{group.get_metadata('test')=='value'}")print("")foriinrange(0,group.dataset_count):data=group.data(i)time=group.dataset_time(i)print(f"Dataset Shape for time{time}:{data.shape}")print("")test=PyMesh()test.vertices=mesh.verticestest.faces=mesh.facestest.edges=mesh.edgesprint(f"Mesh Copy Equality :{test==mesh}")print(f"Mesh Vertex Size equality:{test.vertex_count==mesh.vertex_count}")print(f"Mesh Face Size equality:{test.face_count==mesh.face_count}")test.save("data/save_test.nc")test2=PyMesh(drivers()[0])print(f"Mesh created by Driver :{test2.driver_name}")ds2=Datasource("data/save_test.nc")test4=ds2.load(0)print(f"Save equality :{test4==test}")del(test)del(test4)mesh.save("save_test.ply")withDatasource("data/ply/all_features.ply").load(0)asmesh:mesh.save("save_test_2.ply")withDatasource("save_test_2.ply").load(0)asmesh2:print(f"Save equality 2 :{mesh==mesh2}")withDatasource("data/tuflowfv/withMaxes/trap_steady_05_3D.nc").load()asmesh:group=mesh.groups[1]a,b,c=group.volumetric(0)ds2=Datasource("test_vol.ply")withds2.add_mesh()asmesh2:mesh2.vertices=mesh.verticesmesh2.faces=mesh.facesprint(f"Vertex Count :{mesh.vertex_count}")print(f"Face Count :{mesh.face_count}")group2=mesh2.add_group("test",location=MDAL_DataLocation.DataOnVolumes)group2.add_volumetric(group.data(),a,b)print(f"Level Count:{group2.level_count}")print(f"Location:{group2.location}")print(f"MinMax:{group2.minmax}")print(f"Dataset Count:{group2.dataset_count}")data=group2.data(0)print(f"Data Value Count:{len(data)}")print(f"{data}")print(f"{group2.volumetric(0)}")a,b,c=group2.volumetric(0)print(f"Number of Extrusion values :{len(b)}")mesh2.save()withds2.load()asmesh3:mesh3.info()group3=mesh3.groups[1]print(f"{group3.location}")d,e,f=group3.volumetric(0)print(f"{group3.volumetric(0)}")print(f"{group3.data(0)}")print("Mesh Equality : {mesh2 == mesh3}")"""deep copy test"""withDatasource("data/ply/all_features.ply").load()asmesh:withds.add_mesh("test")asmesh2:mesh2.deep_copy(mesh)mesh2.data_copy(mesh)print(f"{mesh2.info()}")print("all finished !")Integration with meshioThere is read and write integration with the meshio package. Any MDAL mesh
can be converted to a meshio object and vice versa.This integration is beta at the moment.There are the following constraints:MDAL_transform.to_meshio can take as an argument either a Mesh or a Dataset Group,Only scalar MDAL datasets can be converted to meshio,Volumetric data must be passed as a Dataset Group,Volumetric meshio meshes and data are not currently converted, andMDAL_transform.from_meshio only converts cells of types [“line”, “triangle”, “quad”].frommdalimportDatasource,MDAL_transform"""meshio tests"""withDatasource("data/ply/all_features.ply").load()asmesh:mio=MDAL_transform.to_meshio(mesh)print(f"{mio}")mio.write("test.vtk")group=mesh.group(1)mio2=MDAL_transform.to_meshio(group)print(f"{mio2}")mesh2=MDAL_transform.from_meshio(mio)print(f"{mesh2.info()}")print(f"{mesh2.group(0).data()}")print(f"{mesh2.vertex_count}")print(f"{mesh2.face_count}")withDatasource("test_vol.ply").load()asmesh:group=mesh.group(1)mio2=MDAL_transform.to_meshio(group)print(f"{mio2}")print("all finished !")Integration with Open3DThere is read-only integration with Open3D.The MDAL_transform.to_triangle_mesh function converts any MDAL mesh to an Open3D TriangleMesh. The function
can take as an argument an MDAL mesh or Dataset Group. In the former case
if there are colour Datasets then these are converted to the TraingleMesh colours.
In the later case, the data is converted to a false colur using a simple process -
scalar data is loaded into the red values and vector data to
the red and blue values.The MDAL_transform.to_point_cloud converts a MDAL
volumetric DatasetGroup to an Open3D PointCloud with the data values
converted to color as above.NoteOpen3D is NOT loaded as dependency. If these commands are used in an environment without Open3D, they will fail with a user friendly message.This integration is beta at the moment.frommdalimportDatasource,MDAL_transformimportnumpyasnpimportopen3daso3d"""
Open3d Tests
"""withDatasource("data/ply/test_mesh.ply").load()asmesh:tm=MDAL_transform.to_triangle_mesh(mesh)print(tm)tm2=o3d.io.read_triangle_mesh("data/ply/test_mesh.ply")tmc=np.asarray(tm.vertex_colors)tmc2=np.asarray(tm2.vertex_colors)foriinrange(len(tmc)):value=tmc[i]-tmc2[i]ifnot(value==[0,0,0]).all():print(value)breakwithDatasource("test_vol.ply").load()asmesh:pc=MDAL_transform.to_point_cloud(mesh.group(1))print(pc)print("all finished !")NoteAbout Python Versions. MDAL supports 3.8, 3.9 and 3.10. Open3D supports 3.6, 3.7 and 3.8. Therefore,
if you want to use Open3D, the Python version should be pinned to 3.8 before you start.DocumentationThe documentation is currently WIP and can be found athttps://virgis-team.github.io/mdal-python/html/index.htmlRequirementsMDAL 0.9.0 +Python >=3.8Cython (egpip install cython)Numpy (egpip install numpy)Packaging (egpip install packaging)scikit-build (egpip install scikit-build)CreditThis package borrowed heavily from thePDAL-Pythonpackage.Changes1.0.3fix debug message error (#15)Deprecate mdal-python (#16)1.0.2fix memory leaks and inconsistencies around the Datagroup object (#11)1.0.1Add the PyPI package1.0.0First Read / Write Releaseread and write all MDAL compatible file formatsaccess vertex, face, edge and volume data as numpy arrayswrite vertex, face, edge and volume data from numpy arraysaccess and write scalar and vector datasetsbeta level read and write integration with meshiobeta level read integration with Open3D0.9.0First release. This is beta software and has not been completely tested yet:Currently, this integration can:read all MDAL compatible file formats,access the metadata for the source,access the vertex, face and edge data as numpy arrays,access ‘double’ datasets (both scalar and vector) as numpy arrays, andconvert the MDAL source mesh into ameshiomesh object (with some restrictions currently).This version does not currently allow the MDAL source mesh to be written or ammended.