QGIS API Documentation  3.4.15-Madeira (e83d02e274)
qgsalgorithmfixgeometries.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmfixgeometries.cpp
3  -----------------------------
4  begin : April 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 #include "qgsvectorlayer.h"
20 
22 
23 QString QgsFixGeometriesAlgorithm::name() const
24 {
25  return QStringLiteral( "fixgeometries" );
26 }
27 
28 QString QgsFixGeometriesAlgorithm::displayName() const
29 {
30  return QObject::tr( "Fix geometries" );
31 }
32 
33 QStringList QgsFixGeometriesAlgorithm::tags() const
34 {
35  return QObject::tr( "repair,invalid,geometry,make,valid" ).split( ',' );
36 }
37 
38 QString QgsFixGeometriesAlgorithm::group() const
39 {
40  return QObject::tr( "Vector geometry" );
41 }
42 
43 QString QgsFixGeometriesAlgorithm::groupId() const
44 {
45  return QStringLiteral( "vectorgeometry" );
46 }
47 
48 QgsProcessingFeatureSource::Flag QgsFixGeometriesAlgorithm::sourceFlags() const
49 {
51 }
52 
53 QString QgsFixGeometriesAlgorithm::outputName() const
54 {
55  return QObject::tr( "Fixed geometries" );
56 }
57 
58 QgsWkbTypes::Type QgsFixGeometriesAlgorithm::outputWkbType( QgsWkbTypes::Type type ) const
59 {
60  return QgsWkbTypes::multiType( type );
61 }
62 
63 QString QgsFixGeometriesAlgorithm::shortHelpString() const
64 {
65  return QObject::tr( "This algorithm attempts to create a valid representation of a given invalid geometry without "
66  "losing any of the input vertices. Already-valid geometries are returned without further intervention. "
67  "Always outputs multi-geometry layer.\n\n"
68  "NOTE: M values will be dropped from the output." );
69 }
70 
71 QgsFixGeometriesAlgorithm *QgsFixGeometriesAlgorithm::createInstance() const
72 {
73  return new QgsFixGeometriesAlgorithm();
74 }
75 
76 bool QgsFixGeometriesAlgorithm::supportInPlaceEdit( const QgsMapLayer *l ) const
77 {
78  const QgsVectorLayer *layer = qobject_cast< const QgsVectorLayer * >( l );
79  if ( !layer )
80  return false;
81 
83  return false;
84  // The algorithm would drop M, so disable it if the layer has M
85  return ! QgsWkbTypes::hasM( layer->wkbType() );
86 }
87 
88 QgsFeatureList QgsFixGeometriesAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback *feedback )
89 {
90  if ( !feature.hasGeometry() )
91  return QgsFeatureList() << feature;
92 
93  QgsFeature outputFeature = feature;
94 
95  QgsGeometry outputGeometry = outputFeature.geometry().makeValid();
96  if ( outputGeometry.isNull() )
97  {
98  feedback->pushInfo( QObject::tr( "makeValid failed for feature %1 " ).arg( feature.id() ) );
99  outputFeature.clearGeometry();
100  return QgsFeatureList() << outputFeature;
101  }
102 
103  if ( outputGeometry.wkbType() == QgsWkbTypes::Unknown ||
105  {
106  // keep only the parts of the geometry collection with correct type
107  const QVector< QgsGeometry > tmpGeometries = outputGeometry.asGeometryCollection();
108  QVector< QgsGeometry > matchingParts;
109  for ( const QgsGeometry &g : tmpGeometries )
110  {
111  if ( g.type() == feature.geometry().type() )
112  matchingParts << g;
113  }
114  if ( !matchingParts.empty() )
115  outputGeometry = QgsGeometry::collectGeometry( matchingParts );
116  else
117  outputGeometry = QgsGeometry();
118  }
119 
120  outputGeometry.convertToMultiType();
121  if ( QgsWkbTypes::geometryType( outputGeometry.wkbType() ) != QgsWkbTypes::geometryType( feature.geometry().wkbType() ) )
122  {
123  // don't keep geometries which have different types - e.g. lines converted to points
124  feedback->pushInfo( QObject::tr( "Fixing geometry for feature %1 resulted in %2, geometry has been dropped." ).arg( feature.id() ).arg( QgsWkbTypes::displayString( outputGeometry.wkbType() ) ) );
125  outputFeature.clearGeometry();
126  }
127  else
128  {
129  outputFeature.setGeometry( outputGeometry );
130  }
131  return QgsFeatureList() << outputFeature;
132 }
133 
QgsFeatureId id
Definition: qgsfeature.h:64
Base class for all map layer types.
Definition: qgsmaplayer.h:63
static Type multiType(Type type)
Returns the multi type for a WKB type.
Definition: qgswkbtypes.h:298
Base class for providing feedback from a processing algorithm.
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
bool isNull() const
Returns true if the geometry is null (ie, contains no underlying geometry accessible via geometry() )...
QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:571
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:106
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
QgsGeometry makeValid() const
Attempts to make an invalid geometry valid without losing vertices.
static GeometryType geometryType(Type type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:801
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
Flag
Flags controlling how QgsProcessingFeatureSource fetches features.
void clearGeometry()
Removes any geometry associated with the feature.
Definition: qgsfeature.cpp:151
bool convertToMultiType()
Converts single type geometry into multitype geometry e.g.
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:137
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
static QString displayString(Type type)
Returns a display string type for a WKB type, e.g., the geometry name used in WKT geometry representa...
bool supportInPlaceEdit(const QgsMapLayer *layer) const override
Checks whether this algorithm supports in-place editing on the given layer Default implementation for...
static bool hasM(Type type)
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:956
QgsGeometry geometry
Definition: qgsfeature.h:67
Represents a vector layer which manages a vector based data sets.
static Type flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:565
Contains information about the context in which a processing algorithm is executed.
QgsWkbTypes::GeometryType type() const
Returns type of the geometry as a QgsWkbTypes::GeometryType.
static QgsGeometry collectGeometry(const QVector< QgsGeometry > &geometries)
Creates a new multipart geometry from a list of QgsGeometry objects.
QgsWkbTypes::Type wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.