QGIS API Documentation 3.99.0-Master (357b655ed83)
Loading...
Searching...
No Matches
qgsalgorithmtessellate.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmtessellate.cpp
3 ---------------------
4 begin : November 2017
5 copyright : (C) 2017 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19
20#include <geos_c.h>
21
22#include "qgsmultipolygon.h"
23#include "qgspolygon.h"
24#include "qgstessellator.h"
25
26#include <QString>
27
28using namespace Qt::StringLiterals;
29
31
32QString QgsTessellateAlgorithm::name() const
33{
34 return u"tessellate"_s;
35}
36
37QString QgsTessellateAlgorithm::displayName() const
38{
39 return QObject::tr( "Tessellate" );
40}
41
42QStringList QgsTessellateAlgorithm::tags() const
43{
44 return QObject::tr( "3d,triangle" ).split( ',' );
45}
46
47QString QgsTessellateAlgorithm::group() const
48{
49 return QObject::tr( "Vector geometry" );
50}
51
52QString QgsTessellateAlgorithm::groupId() const
53{
54 return u"vectorgeometry"_s;
55}
56
57QString QgsTessellateAlgorithm::outputName() const
58{
59 return QObject::tr( "Tessellated" );
60}
61
62Qgis::ProcessingSourceType QgsTessellateAlgorithm::outputLayerType() const
63{
65}
66
67Qgis::WkbType QgsTessellateAlgorithm::outputWkbType( Qgis::WkbType inputWkbType ) const
68{
70}
71
72QString QgsTessellateAlgorithm::shortHelpString() const
73{
74 return QObject::tr( "This algorithm tessellates a polygon geometry layer, dividing the geometries into triangular components." )
75 + u"\n\n"_s
76 + QObject::tr( "The output layer consists of multipolygon geometries for each input feature, with each multipolygon consisting of multiple triangle component polygons." );
77}
78
79QString QgsTessellateAlgorithm::shortDescription() const
80{
81 return QObject::tr( "Tessellates a polygon geometry layer, dividing the geometries into triangular components." );
82}
83
84QList<int> QgsTessellateAlgorithm::inputLayerTypes() const
85{
86 return QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::VectorPolygon );
87}
88
89QgsTessellateAlgorithm *QgsTessellateAlgorithm::createInstance() const
90{
91 return new QgsTessellateAlgorithm();
92}
93
94QgsFeatureList QgsTessellateAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback *feedback )
95{
96 QgsFeature f = feature;
97 if ( f.hasGeometry() )
98 {
100 f.clearGeometry();
101 else
102 {
103 const QgsGeometry inputGeometry = f.geometry();
104 bool tessellationComplete = false;
105#if ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR >= 11 ) || GEOS_VERSION_MAJOR > 3
106 if ( !inputGeometry.constGet()->is3D() )
107 {
108 // on supported GEOS versions we prefer to use GEOS GEOSConstrainedDelaunayTriangulation
109 // for 2D triangulation, as it's more stable and tolerant to situations like polygon
110 // holes touching an exterior ring vs the poly2tri based tessellation
111 const QgsGeometry triangulation = inputGeometry.constrainedDelaunayTriangulation();
112 if ( triangulation.isEmpty() && !inputGeometry.isEmpty() )
113 {
114 if ( !triangulation.lastError().isEmpty() )
115 {
116 feedback->reportError( QObject::tr( "Feature ID %1 could not be tessellated: %2" ).arg( f.id() ).arg( triangulation.lastError() ) );
117 }
118 else
119 {
120 feedback->reportError( QObject::tr( "Feature ID %1 could not be tessellated" ).arg( f.id() ) );
121 }
122 }
123 else
124 {
125 f.setGeometry( triangulation );
126 }
127 tessellationComplete = true;
128 }
129#endif
130
131 if ( !tessellationComplete )
132 {
133 // 3D case, or 2D case with unsupported GEOS version -- use less stable poly2tri backend
134 const QgsRectangle bounds = f.geometry().boundingBox();
136 t.setBounds( bounds );
137 t.setOutputZUp( true );
138
139 if ( f.geometry().isMultipart() )
140 {
142 for ( int i = 0; i < ms->numGeometries(); ++i )
143 {
144 const std::unique_ptr<QgsPolygon> p( qgsgeometry_cast<QgsPolygon *>( ms->geometryN( i )->segmentize() ) );
145 t.addPolygon( *p, 0 );
146 }
147 }
148 else
149 {
150 const std::unique_ptr<QgsPolygon> p( qgsgeometry_cast<QgsPolygon *>( f.geometry().constGet()->segmentize() ) );
151 t.addPolygon( *p, 0 );
152 }
154 if ( !g.isEmpty() )
155 {
156 if ( !t.error().isEmpty() )
157 {
158 feedback->reportError( QObject::tr( "Feature ID %1 was only partially tessellated: %2" ).arg( f.id() ).arg( t.error() ) );
159 }
160
161 g.translate( bounds.xMinimum(), bounds.yMinimum() );
162 }
163 else
164 {
165 if ( !t.error().isEmpty() )
166 feedback->reportError( QObject::tr( "Feature ID %1 could not be tessellated: %2" ).arg( f.id() ).arg( t.error() ) );
167 else
168 feedback->reportError( QObject::tr( "Feature ID %1 could not be divided into triangular components." ).arg( f.id() ) );
169 }
170 if ( !inputGeometry.constGet()->is3D() )
171 g.get()->dropZValue();
172
173 f.setGeometry( g );
174 }
175 }
176 }
177 return QgsFeatureList() << f;
178}
179
ProcessingSourceType
Processing data source types.
Definition qgis.h:3602
@ VectorPolygon
Vector polygon layers.
Definition qgis.h:3607
@ Polygon
Polygons.
Definition qgis.h:368
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:280
@ MultiPolygon
MultiPolygon.
Definition qgis.h:288
@ MultiPolygonZ
MultiPolygonZ.
Definition qgis.h:305
virtual QgsAbstractGeometry * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:60
QgsFeatureId id
Definition qgsfeature.h:68
QgsGeometry geometry
Definition qgsfeature.h:71
void clearGeometry()
Removes any geometry associated with the feature.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
int numGeometries() const
Returns the number of geometries within the collection.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
A geometry is the spatial representation of a feature.
QString lastError() const
Returns an error string referring to the last error encountered either when this geometry was created...
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Qgis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.).
QgsGeometry constrainedDelaunayTriangulation() const
Returns a constrained Delaunay triangulation for the vertices of the geometry.
Multi surface geometry collection.
Contains information about the context in which a processing algorithm is executed.
Base class for providing feedback from a processing algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
A rectangle specified with double values.
double xMinimum
double yMinimum
Tessellates polygons into triangles.
std::unique_ptr< QgsMultiPolygon > asMultiPolygon() const
Returns the triangulation as a multipolygon geometry.
void setBounds(const QgsRectangle &bounds)
Sets scaling and the bounds of the input geometry coordinates.
void addPolygon(const QgsPolygon &polygon, float extrusionHeight)
Tessellates a triangle and adds its vertex entries to the output data array.
QString error() const
Returns a descriptive error string if the tessellation failed.
void setOutputZUp(bool zUp)
Sets whether the "up" direction should be the Z axis on output (true), otherwise the "up" direction w...
static Qgis::GeometryType geometryType(Qgis::WkbType type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QList< QgsFeature > QgsFeatureList