QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
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 {
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 
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QgsGeometry geometry
Definition: qgsfeature.h:67
void clearGeometry()
Removes any geometry associated with the feature.
Definition: qgsfeature.cpp:177
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:223
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:163
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:125
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
static QgsGeometry collectGeometry(const QVector< QgsGeometry > &geometries)
Creates a new multipart geometry from a list of QgsGeometry objects.
QVector< QgsGeometry > asGeometryCollection() const
Returns contents of the geometry as a list of geometries.
Q_GADGET bool isNull
Definition: qgsgeometry.h:127
QgsWkbTypes::GeometryType type
Definition: qgsgeometry.h:128
QgsGeometry makeValid() const
Attempts to make an invalid geometry valid without losing vertices.
bool convertToMultiType()
Converts single type geometry into multitype geometry e.g.
Base class for all map layer types.
Definition: qgsmaplayer.h:73
Contains information about the context in which a processing algorithm is executed.
bool supportInPlaceEdit(const QgsMapLayer *layer) const override
Checks whether this algorithm supports in-place editing on the given layer Default implementation for...
Flag
Flags controlling how QgsProcessingFeatureSource fetches features.
@ FlagSkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Base class for providing feedback from a processing algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
static GeometryType geometryType(Type type) SIP_HOLDGIL
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:968
static Type promoteNonPointTypesToMulti(Type type) SIP_HOLDGIL
Promotes a WKB geometry type to its multi-type equivalent, with the exception of point geometry types...
Definition: qgswkbtypes.h:451
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:1130
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
@ GeometryCollection
Definition: qgswkbtypes.h:79
static QString displayString(Type type) SIP_HOLDGIL
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:732
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:882