0

I'm exploring the use of QGIS QgsMeshLayer to represent temporal datasets via pyqgis.

So far, I've been able to create a mesh and visualise the mesh using its Z values. It looks like these Z values can be manipulated and / or be converted to a QgsMeshDatasetGroup (via createZValueDatasetGroup()) from which a QgsMeshDataset can be extracted and manipulated via QgsMeshDatasetValue. But I don't see a way to persist any manipulations back to the QgsMeshLayer?

QgsMeshLayer has a addDatasets method, but this doesn't seem to work.

I'm wondering if I'm missing something and if anyone has figured out (or understands the intent) of how a QgsMeshDataset (e.g. temporal time steps) can be added to a QgsMeshLayer?

Here is the relevant code:

# Create mesh
mesh = QgsMesh()
# uses MDAL for QgsProviderMetadata
provider_meta = QgsProviderRegistry.instance().providerMetadata("mdal")
mesh_layer_path: str = str(output_path.absolute())
provider_meta.createMeshData(mesh, mesh_layer_path, "Ugrid", crs)  # see C++ docs for createMeshData (not in pyqgis)
# above takes care of creating the layer, below takes care of handling the layer
layer_name = output_path.name.split(".")[0] + " a layer name"
mesh_layer = QgsMeshLayer(mesh_layer_path, layer_name, "mdal")
mesh_layer.setCrs(crs)
# add points to mesh
crs_transform = QgsCoordinateTransform(crs, crs, QgsProject.instance())
mesh_layer.startFrameEditing(crs_transform)
mesh_editor = mesh_layer.meshEditor()  # QgsMeshEditor
mesh_editor.addPointsAsVertices(points, 1)
for vertex_indices in faces.values():
    mesh_editor.addFace(vertex_indices)
mesh_layer.commitFrameEditing(crs_transform, continueEditing=False)
# FYI: Z values can be manipulated: mesh_editor.changeZValues(list(range(100)), [20] * 100)
# FYI: data provider = mesh_layer.dataProvider()
# fetch Z values as DatasetGroup and edit as needed
dsg = mesh_editor.createZValueDatasetGroup()  # QgsMeshDatasetGroup
dsg.setName("First step")
# FYI: dsg.dataset(0).datasetValue(1000).scalar()
# FYI: dsg.dataset(0).datasetValues(True, 0, 2021).value(100).scalar()
# this doesn't work
print(dsg.dataset(0).datasetValues(True, 0, 100).values())  # all values are zero per Z
dsg.dataset(0).datasetValues(True, 0, 100).setValues(list(range(100)))
print(dsg.dataset(0).datasetValues(True, 0, 100).values())  # values are not updated
# this doesn't work either
print(dsg.dataset(0).datasetValue(1).scalar())  # 0
dsg.dataset(0).datasetValue(1).set(10)
print(dsg.dataset(0).datasetValue(1).scalar())  # 0 -> not updated
# add dataset back to mesh layer
mesh_layer.addDatasets(dsg)  # returns True
dsg.setName("Another step")
mesh_layer.addDatasets(dsg)
print(dsg.dataset(0))
print(dsg.dataset(1))
mesh_layer.reload()
# rendering settings
mesh_renderer = mesh_layer.rendererSettings()
mesh_renderer.setActiveScalarDatasetGroup(1)
scalar_settings = mesh_renderer.scalarSettings(1)
scalar_settings.setClassificationMinimumMaximum(1, 2021)
mesh_renderer.setScalarSettings(1, scalar_settings)
mesh_layer.setRendererSettings(mesh_renderer)
1
  • @Peter do you possibly have any examples for how mesh datasets can be created and linked via pyqgis API? Thanks.
    – songololo
    Nov 26, 2022 at 13:40

1 Answer 1

1

createZValueDatasetGroup() returns a "virtual" dataset group that provides Z values of the vertices. You can NOT modify this Z values vertices through this dataset group. Indeed, in that case the dataset group is a virtual one that can access to the value of the vertices of the mesh, but you can't modify these values. This dataset group is mainly used to render the mesh on mesh map during editing, and I don't think you need to use it to your script.

To modify the Z values of vertices, you have to go through the mesh editor (QgsMesheditor.changeZValues(), see the doc). If everything is going well, the corresponding values in the dataset group obtained by createZValueDatasetGroup() will be updated directly. But you don't care about this groups...

4
  • Thanks @vcloarec - Using the method that you suggest, I am able to manipulate the Z values via QgsMeshEditor. Is there a way to add more time steps (Datasets / DatasetGroups) to the mesh in QGIS via pyqgis? Or a way to create the Datasets through another module in Python and then somehow attach the Datasets to the QgsMeshLayer for visualisation?
    – songololo
    Nov 26, 2022 at 18:03
  • 1
    @songololo, you should be able to add new group to the mesh using " mMeshLayer.addDatasets( myDatasetgroup )". myDatasetGroup has to be a instance of class derived from QgsMeshDatasetGroup absrtact class. I do it in C++, but never tested with Python.
    – vcloarec
    Nov 26, 2022 at 18:56
  • Thanks, I missed the overloaded method. I've now tried using the method but it still seems to do nothing. I've updated the code in the question, do you see anything I'm obviously doing wrong? mesh_layer.addDatasets() returns True, but the values all remain as zero in spite of the call to setValues().
    – songololo
    Nov 30, 2022 at 16:19
  • 1
    you CAN NOT modify vertices Z value with the group returned by createZValueDatasetGroup. And to add temporal dataset group, it is quite complicated with Python, as I said you have to play with classes and derived QgsMeshDatasetGroup to another class that could support editing. I have never tested...
    – vcloarec
    Dec 2, 2022 at 1:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.