Skip to main content

Mesh data processing

Project description

https://img.shields.io/conda/vn/conda-forge/mdal-python.svg https://badge.fury.io/py/mdal.svg

Basics

MDAL Python integration allows you to access and manipulation geospatial mesh data sets using MDAL in Python.

Currently, this integration can:

  • read and write all MDAL compatible file formats

  • access vertex, face, edge and volume data as numpy arrays

  • write vertex, face, edge and volume data from numpy arrays

  • access and write scalar and vector datasets

  • beta level read and write integration with meshio

  • beta level read integration with Open3D

Drivers

[‘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’]

Installation

Conda

MDAL Python support is installable via Conda:

conda install -c conda-forge mdal-python

PyPI

MDAL Python support can be installed using pip

pip install mdal

This will ONLY work if there is a valid and working installation of MDAL on the device and accessible through the device library search path.

GitHub

The repository for MDAL’s Python extension is available at https://github.com/ViRGIS-Team/mdal-python

Usage

The basic usage can be seen in this code snippet:

from mdal import Datasource, Info, last_status, PyMesh, drivers, MDAL_DataLocation

print(f"MDAL Version:  {Info.version}")
print(f"MDAL Driver Count :{Info.driver_count}")
print(last_status().name)

for driver in Info.drivers:
    print(driver)


ds = Datasource("data/ply/test_mesh.ply")
print(ds.meshes)

with ds.load(0) as mesh:
    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.vertices
    print(f"Vertex Array Shape : {vertex.shape}")

    faces = mesh.faces
    print(f"Face Array Shape : {faces.shape}")

    edges = mesh.edges
    print(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("")
    for i in range(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.vertices
    test.faces = mesh.faces
    test.edges = mesh.edges
    print(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")

with Datasource("data/ply/all_features.ply").load(0) as mesh:
    mesh.save("save_test_2.ply")

    with Datasource("save_test_2.ply").load(0) as mesh2:
        print(f"Save equality 2 : {mesh == mesh2}")

with Datasource("data/tuflowfv/withMaxes/trap_steady_05_3D.nc").load() as mesh:
    group = mesh.groups[1]
    a, b, c = group.volumetric(0)

    ds2 = Datasource("test_vol.ply")
    with ds2.add_mesh() as mesh2:
        mesh2.vertices = mesh.vertices
        mesh2.faces = mesh.faces

        print(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()
        with ds2.load() as mesh3:
            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"""

with Datasource("data/ply/all_features.ply").load() as mesh:
    with ds.add_mesh("test") as mesh2:
        mesh2.deep_copy(mesh)
        mesh2.data_copy(mesh)
        print(f"{mesh2.info()}")


print("all finished !")

Integration with meshio

There 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, and

  • MDAL_transform.from_meshio only converts cells of types [“line”, “triangle”, “quad”].

from mdal import Datasource,MDAL_transform

"""meshio tests"""
with Datasource("data/ply/all_features.ply").load() as mesh:

    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}")

with Datasource("test_vol.ply").load() as mesh:
    group = mesh.group(1)
    mio2 = MDAL_transform.to_meshio(group)
    print(f"{mio2}")


print("all finished !")

Integration with Open3D

There 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.

This integration is beta at the moment.

from mdal import Datasource, MDAL_transform

import numpy as np
import open3d as o3d

"""
Open3d Tests
"""
with Datasource("data/ply/test_mesh.ply").load() as mesh:
    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)
    for i in range(len(tmc)):
        value = tmc[i] - tmc2[i]
        if not (value == [0, 0, 0]).all():
            print(value)
            break

with Datasource("test_vol.ply").load() as mesh:
    pc = MDAL_transform.to_point_cloud(mesh.group(1))
    print(pc)


print("all finished !")

Documentation

The documentation is currently WIP and can be found at https://virgis-team.github.io/mdal-python/html/index.html

Requirements

  • MDAL 0.9.0 +

  • Python >=3.8

  • Cython (eg pip install cython)

  • Numpy (eg pip install numpy)

  • Packaging (eg pip install packaging)

  • scikit-build (eg pip install scikit-build)

Credit

This package borrowed heavily from the PDAL-Python package.

Changes

1.1.0

  • Updates the NUMPy ABI to 2.0

  • Fix the CI deprecation (#20)

1.0.3

  • fix debug message error (#15)

  • Deprecate mdal-python (#16)

1.0.2

  • fix memory leaks and inconsistencies around the Datagroup object (#11)

1.0.1

  • Add the PyPI package

1.0.0

First Read / Write Release

  • read and write all MDAL compatible file formats

  • access vertex, face, edge and volume data as numpy arrays

  • write vertex, face, edge and volume data from numpy arrays

  • access and write scalar and vector datasets

  • beta level read and write integration with meshio

  • beta level read integration with Open3D

0.9.0

First 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, and

  • convert the MDAL source mesh into a meshio mesh object (with some restrictions currently).

This version does not currently allow the MDAL source mesh to be written or ammended.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mdal-1.1.0.tar.gz (56.1 MB view details)

Uploaded Source

Built Distributions

mdal-1.1.0-cp312-cp312-win_amd64.whl (123.7 kB view details)

Uploaded CPython 3.12 Windows x86-64

mdal-1.1.0-cp312-cp312-macosx_12_0_x86_64.whl (144.0 kB view details)

Uploaded CPython 3.12 macOS 12.0+ x86-64

mdal-1.1.0-cp311-cp311-win_amd64.whl (126.3 kB view details)

Uploaded CPython 3.11 Windows x86-64

mdal-1.1.0-cp311-cp311-macosx_12_0_x86_64.whl (146.4 kB view details)

Uploaded CPython 3.11 macOS 12.0+ x86-64

mdal-1.1.0-cp310-cp310-win_amd64.whl (125.8 kB view details)

Uploaded CPython 3.10 Windows x86-64

mdal-1.1.0-cp310-cp310-macosx_12_0_x86_64.whl (144.5 kB view details)

Uploaded CPython 3.10 macOS 12.0+ x86-64

mdal-1.1.0-cp39-cp39-win_amd64.whl (126.1 kB view details)

Uploaded CPython 3.9 Windows x86-64

mdal-1.1.0-cp39-cp39-macosx_12_0_x86_64.whl (145.1 kB view details)

Uploaded CPython 3.9 macOS 12.0+ x86-64

File details

Details for the file mdal-1.1.0.tar.gz.

File metadata

  • Download URL: mdal-1.1.0.tar.gz
  • Upload date:
  • Size: 56.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.12.3

File hashes

Hashes for mdal-1.1.0.tar.gz
Algorithm Hash digest
SHA256 a7b33e06c2177198a36eb12b3d70e36548054f0228dd3e840f8598e6e33b9a11
MD5 65cb6df7f646b7d4e09505d8b76e1d26
BLAKE2b-256 0a7b7cf66cd545c76db7a14ec41bf6d029da708232fe85cb48cae45322cd6ce1

See more details on using hashes here.

File details

Details for the file mdal-1.1.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: mdal-1.1.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 123.7 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.12.3

File hashes

Hashes for mdal-1.1.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 75ecd6015cb6a5409bf72eaded224bdb9053a663c7721d88aa3fd8ca4fe6b1f8
MD5 6f735c74e9049bbf9ef76ff1ea1725c6
BLAKE2b-256 95a413709598c2aedcae9a8ea679b87de2f019abc02dc082149ab5b31907956d

See more details on using hashes here.

File details

Details for the file mdal-1.1.0-cp312-cp312-macosx_12_0_x86_64.whl.

File metadata

File hashes

Hashes for mdal-1.1.0-cp312-cp312-macosx_12_0_x86_64.whl
Algorithm Hash digest
SHA256 be57faf86c5a1cab0442a698d59675e99737363328dc109abc14f8753ad70be1
MD5 a903c16c66fa2f1895bafa84dd2b4d72
BLAKE2b-256 e80eea34126f1568b718ce0d9ce24a40f1c3a6a7e437f6767099fb611e59c90e

See more details on using hashes here.

File details

Details for the file mdal-1.1.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: mdal-1.1.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 126.3 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.12.3

File hashes

Hashes for mdal-1.1.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 3857c05fe5331d49dd02595a6c1abacc49c89d42b10feb1d405664e49b222bfb
MD5 8feeb4f3fdf0c647104ce58d63a5ac12
BLAKE2b-256 8d5399751067a8814acbf7012c6c800b72056f8d941aa86abbb1e6bc39e21b17

See more details on using hashes here.

File details

Details for the file mdal-1.1.0-cp311-cp311-macosx_12_0_x86_64.whl.

File metadata

File hashes

Hashes for mdal-1.1.0-cp311-cp311-macosx_12_0_x86_64.whl
Algorithm Hash digest
SHA256 706361d5c1032a33eec6b5a68db675fdb96291cdd09cb4471037cf949d0fbac0
MD5 5789ab85a26cbfe64ced1f3950d78c12
BLAKE2b-256 9220f490d622bd0c0b5577e80be1ed4f6cdc3d43fe3ecbe9ab8f4cb6a3d71b9e

See more details on using hashes here.

File details

Details for the file mdal-1.1.0-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: mdal-1.1.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 125.8 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.12.3

File hashes

Hashes for mdal-1.1.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 3071f921ca732453058e714396de96b8643518b8169a223a64e3e133ba81b49a
MD5 ea93550e28bf3abe691207baaa7aca8e
BLAKE2b-256 82c732bc016a659b5c00f230d36265f98f44998e31d1dad589d00dec7be379a5

See more details on using hashes here.

File details

Details for the file mdal-1.1.0-cp310-cp310-macosx_12_0_x86_64.whl.

File metadata

File hashes

Hashes for mdal-1.1.0-cp310-cp310-macosx_12_0_x86_64.whl
Algorithm Hash digest
SHA256 f98b6dca3504a209de953f5584c060f6bee4ff7821fe8d405df504faa6f2a54e
MD5 5ced3b517038a3e88513cf526e8d4fc5
BLAKE2b-256 773500d48689635e93ffbe5391cb01e6ff1ffb2efe7e161dc7ebd07aa38edf6c

See more details on using hashes here.

File details

Details for the file mdal-1.1.0-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: mdal-1.1.0-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 126.1 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.12.3

File hashes

Hashes for mdal-1.1.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 048268c2e4539b5e0bb4f310e539d2e46c0c166a273092a9d9c857c259a293e7
MD5 33abb9c4bcf3b1a57a68906d93f5e3e1
BLAKE2b-256 aac14551319a66f11cd0e48bd79996e43eb9e288b5b6aef7b2385ba5059ce7a2

See more details on using hashes here.

File details

Details for the file mdal-1.1.0-cp39-cp39-macosx_12_0_x86_64.whl.

File metadata

File hashes

Hashes for mdal-1.1.0-cp39-cp39-macosx_12_0_x86_64.whl
Algorithm Hash digest
SHA256 af0cbbd434e7516be86bcb924c738dafebf94bc6944394aa5d05520b0df992c0
MD5 8f67c5dc20fce67199097a53a11c555a
BLAKE2b-256 f24bebdd14e8b82657832cf742b1c2ed4c48a4cb8f56c30ef53b33f9b0510307

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page