Skip to content
Permalink
Browse files

TIN Mesh creation

  • Loading branch information
vcloarec committed Sep 10, 2020
1 parent fa18514 commit d2f4c40f8ae6ea2702fb1e2d61a97c8c437ca387
@@ -279,7 +279,6 @@ namespace MDAL

private:
const std::string mDriverName;
size_t mFaceVerticesMaximumCount = 0; //typically 3 or 4, sometimes up to 9
const std::string mUri; // file/uri from where it came
std::string mCrs;
};
@@ -5,6 +5,7 @@
%Include auto_generated/interpolation/qgsinterpolator.sip
%Include auto_generated/interpolation/qgstininterpolator.sip
%Include auto_generated/mesh/qgsmeshcontours.sip
%Include auto_generated/mesh/qgsmeshtriangulation.sip
%Include auto_generated/network/qgsgraph.sip
%Include auto_generated/network/qgsgraphanalyzer.sip
%Include auto_generated/network/qgsgraphbuilder.sip
@@ -0,0 +1,114 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/analysis/mesh/qgsmeshtriangulation.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsMeshTriangulation : QObject
{
%Docstring

Class that handles mesh creation with Delaunay constrained triangulation

.. versionadded:: 3.16
%End

%TypeHeaderCode
#include "qgsmeshtriangulation.h"
%End
public:

QgsMeshTriangulation();
%Docstring
Contructor
%End

~QgsMeshTriangulation();

bool addVertices( QgsVectorLayer *vectorLayer, int valueAttribute, const QgsCoordinateTransformContext &transformContext, QgsFeedback *feedback = 0 );
%Docstring
Adds vertices to the triangulation from a vector layer, return true if success.

:param vectorLayer: the vector layer with vertices to insert
:param valueAttribute: the index of the attribute that represents the value of vertices, if -1 uses Z coordinate of vertices
:param transformContext: the transform context used to transform coordinates
%End

bool addBreakLines( QgsVectorLayer *linesSource, int valueAttribute, const QgsCoordinateTransformContext &transformContext, QgsFeedback *feedback = 0 );
%Docstring
Adds break lines from a vector layer, return true if success

:param vectorLayer: the vector layer with break lines to insert
:param valueAttribute: the index of the attribute that represents the value of vertices, if -1 uses Z coordinate of vertices
:param transformContext: the transform context used to transform coordinates

.. note::

if the vector layer contain point, only vertices will be added without breaklines
%End

QgsMesh triangulatedMesh() const;
%Docstring
Returns the triangulated mesh
%End

void setCrs( const QgsCoordinateReferenceSystem &crs );
%Docstring
Sets the coordinate reference system used for the triangulation
%End

private:
QgsMeshTriangulation( const QgsMeshTriangulation &rhs );
};


class QgsMeshZValueDatasetGroup: QgsMeshDatasetGroup
{
%Docstring

Convenient class that can be used to obtain a datasetgroup on vertices that represents the Z value of the mesh vertices

.. versionadded:: 3.16
%End

%TypeHeaderCode
#include "qgsmeshtriangulation.h"
%End
public:
QgsMeshZValueDatasetGroup( const QString &datasetGroupName, const QgsMesh &mesh );
%Docstring
Constructor

:param datasetGroupName: the name of the dataset group
:param mesh: the mesh used to create the Z value dataset
%End

virtual void initialize();

virtual QgsMeshDatasetMetadata datasetMetadata( int datasetIndex ) const;

virtual int datasetCount() const;

virtual QgsMeshDataset *dataset( int index ) const;

virtual QgsMeshDatasetGroup::Type type() const;
virtual QDomElement writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const;


private:
QgsMeshZValueDatasetGroup( const QgsMeshZValueDatasetGroup &rhs );
};

/************************************************************************
* This file has been generated automatically from *
* *
* src/analysis/mesh/qgsmeshtriangulation.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -164,6 +164,16 @@ Adds datasets to the mesh from file with ``path``. Use the the time ``defaultRef
.. versionadded:: 3.14
%End

bool addDatasets( QgsMeshDatasetGroup *datasetGroup /Transfer/ );
%Docstring
Adds extra datasets to the mesh. Take ownership.

:param datasetGroup: the extra dataset group

:return: whether the dataset is effectively added

.. versionadded:: 3.16
%End

bool saveDataset( const QString &path, int datasetGroupIndex, QString driver );
%Docstring
@@ -34,6 +34,7 @@ Holds metadata about mesh driver
CanWriteFaceDatasets,
CanWriteVertexDatasets,
CanWriteEdgeDatasets,
CanWriteMeshData,
};

typedef QFlags<QgsMeshDriverMetadata::MeshDriverCapability> MeshDriverCapabilities;
@@ -219,6 +220,17 @@ eg. "yes" value will be returned as true, 0 will be returned as false
Creates a new instance of the raster data provider.

.. versionadded:: 3.10
%End

virtual bool createMeshData(
const QgsMesh &mesh,
const QString uri,
const QString &driverName,
const QgsCoordinateReferenceSystem &crs ) const;
%Docstring
Creates mesh data source (depending of the provider)

.. versionadded:: 3.16
%End

virtual QList<QPair<QString, QString> > pyramidResamplingMethods();
@@ -83,6 +83,7 @@
from .TextToFloat import TextToFloat
from .TilesXYZ import TilesXYZAlgorithmDirectory, TilesXYZAlgorithmMBTiles
from .TinInterpolation import TinInterpolation
from .TinMeshCreation import TinMeshCreation
from .TopoColors import TopoColor
from .UniqueValues import UniqueValues
from .VariableDistanceBuffer import VariableDistanceBuffer
@@ -155,6 +156,7 @@ def getAlgs(self):
TilesXYZAlgorithmDirectory(),
TilesXYZAlgorithmMBTiles(),
TinInterpolation(),
TinMeshCreation(),
TopoColor(),
UniqueValues(),
VariableDistanceBuffer(),
@@ -0,0 +1,142 @@
# -*- coding: utf-8 -*-

"""
***************************************************************************
TinInterpolation.py
---------------------
Date : August 2020
Copyright : (C) 2020 by Vincent Cloarec
Email : vcloarec at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""

__author__ = 'Vincent Cloarec'
__date__ = 'August 2020'
__copyright__ = '(C) 2020, Vincent Cloarec'

import os

from qgis.PyQt.QtGui import QIcon
from qgis.utils import iface

from qgis.core import (QgsProcessingUtils,
QgsProcessingContext,
QgsProcessingParameterCrs,
QgsProcessingParameterEnum,
QgsProcessingParameterFileDestination,
QgsProcessingException,
QgsProviderRegistry,
QgsMeshDriverMetadata,
QgsMeshLayer)
from qgis.analysis import (QgsMeshTriangulation,
QgsMeshZValueDatasetGroup)

from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.algs.qgis.ui.TinMeshWidgets import ParameterTinMeshData

pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]


class TinMeshCreation(QgisAlgorithm):
SOURCE_DATA = 'SOURCE_DATA'
EXTENT = 'EXTENT'
MESH_FORMAT = 'MESH_FORMAT'
CRS = 'CRS_OUTPUT'
OUTPUT_MESH = 'OUTPUT_MESH'

def group(self):
return self.tr('Mesh')

def groupId(self):
return 'mesh'

def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.addParameter(ParameterTinMeshData(self.SOURCE_DATA, self.tr('Input layer(s)')))

self.FORMATS = []
self.providerMetaData = QgsProviderRegistry.instance().providerMetadata("mdal")
meshDriverMetaList = self.providerMetaData.meshDriversMetadata()
meshDriverAvailable = []
for driver in meshDriverMetaList:
if bool(driver.capabilities() & QgsMeshDriverMetadata.CanWriteMeshData):
meshDriverAvailable.append(driver)
self.FORMATS.append(driver.name())

self.addParameter(QgsProcessingParameterEnum(self.MESH_FORMAT,
self.tr('Output format'),
options=self.FORMATS,
defaultValue=0))

self.addParameter(QgsProcessingParameterCrs(self.CRS,
self.tr('Output coordinate system'),
optional=True))

self.addParameter(QgsProcessingParameterFileDestination(self.OUTPUT_MESH,
self.tr('Output file'),
optional=False))

def name(self):
return 'tinmeshcreation'

def displayName(self):
return self.tr('TIN mesh creation')

def processAlgorithm(self, parameters, context, feedback):
sourceData = ParameterTinMeshData.parseValue(parameters[self.SOURCE_DATA])

if sourceData is None:
raise QgsProcessingException(
self.tr('You need to specify at least one input layer.'))

crs = self.parameterAsCrs(parameters, self.CRS, context)
if not crs.isValid():
crs = iface.mapCanvas().mapSettings().destinationCrs()

meshTriangulation = QgsMeshTriangulation()

for i, row in enumerate(sourceData.split('::|::')):
v = row.split('::~::')
layer = QgsProcessingUtils.mapLayerFromString(v[0], context)
if not crs.isValid():
crs = layer.sourceCrs()

valueAttribute = int(v[1])

if v[2] == '0': # points
meshTriangulation.addVertices(layer, valueAttribute, context.transformContext(), feedback)
else: # lines
meshTriangulation.addBreakLines(layer, valueAttribute, context.transformContext(), feedback)

fileName = self.parameterAsFile(parameters, self.OUTPUT_MESH, context)
driverIndex = self.parameterAsEnum(parameters, self.MESH_FORMAT, context)
mesh = meshTriangulation.triangulatedMesh()
self.providerMetaData.createMeshData(mesh, fileName, self.FORMATS[driverIndex], crs)

#SELAFIN format doesn't support saving Z value on mesh vertices, so create a specific dataset group
if self.FORMATS[driverIndex] == "SELAFIN":
self.addZValueDataset(fileName, mesh)

context.addLayerToLoadOnCompletion(fileName, QgsProcessingContext.LayerDetails('TIN Mesh',
context.project(),
'TIN', QgsProcessingUtils.LayerHint.Mesh))

return {self.OUTPUT_MESH: fileName}

def addZValueDataset(self, fileName, mesh):

tempLayer = QgsMeshLayer(fileName, "temp", "mdal")

zValueDatasetGroup = QgsMeshZValueDatasetGroup(self.tr("Terrain Elevation"), mesh)
tempLayer.addDatasets(zValueDatasetGroup)
datasetGroupIndex = tempLayer.datasetGroupCount() - 1
tempLayer.saveDataset(fileName, datasetGroupIndex, "SELAFIN")

0 comments on commit d2f4c40

Please sign in to comment.
You can’t perform that action at this time.