QGIS API Documentation 3.99.0-Master (8e76e220402)
Loading...
Searching...
No Matches
qgsgeometrytypecheck.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsgeometrytypecheck.cpp
3 ---------------------
4 begin : September 2015
5 copyright : (C) 2014 by Sandro Mani / Sourcepole AG
6 email : smani at sourcepole dot ch
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgsfeaturepool.h"
20#include "qgsmulticurve.h"
21#include "qgsmultilinestring.h"
22#include "qgsmultipoint.h"
23#include "qgsmultipolygon.h"
24
25#include <QString>
26
27using namespace Qt::StringLiterals;
28
29QList<QgsSingleGeometryCheckError *> QgsGeometryTypeCheck::processGeometry( const QgsGeometry &geometry ) const
30{
31 QList<QgsSingleGeometryCheckError *> errors;
32 const QgsAbstractGeometry *geom = geometry.constGet();
33 const Qgis::WkbType type = QgsWkbTypes::flatType( geom->wkbType() );
34 if ( ( mAllowedTypes & ( 1 << static_cast<quint32>( type ) ) ) == 0 )
35 {
36 errors.append( new QgsGeometryTypeCheckError( this, geometry, geometry, type ) );
37 }
38 return errors;
39}
40
41void QgsGeometryTypeCheck::fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const
42{
43 QgsFeaturePool *featurePool = featurePools[error->layerId()];
44 QgsFeature feature;
45 if ( !featurePool->getFeature( error->featureId(), feature ) )
46 {
47 error->setObsolete();
48 return;
49 }
50 const QgsGeometry featureGeom = feature.geometry();
51 const QgsAbstractGeometry *geom = featureGeom.constGet();
52
53 // Check if error still applies
54 const Qgis::WkbType type = QgsWkbTypes::flatType( geom->wkbType() );
55 if ( ( mAllowedTypes & ( 1 << static_cast<quint32>( type ) ) ) != 0 )
56 {
57 error->setObsolete();
58 return;
59 }
60
61 // Fix with selected method
62 if ( method == NoChange )
63 {
64 error->setFixed( method );
65 }
66 else if ( method == Convert )
67 {
68 // Check if corresponding single type is allowed
69 if ( QgsWkbTypes::isMultiType( type ) && ( ( 1 << static_cast<quint32>( QgsWkbTypes::singleType( type ) ) ) & mAllowedTypes ) != 0 )
70 {
71 // Explode multi-type feature into single-type features
72 for ( int iPart = 1, nParts = geom->partCount(); iPart < nParts; ++iPart )
73 {
74 QgsFeature newFeature;
75 newFeature.setAttributes( feature.attributes() );
76 newFeature.setGeometry( QgsGeometry( QgsGeometryCheckerUtils::getGeomPart( geom, iPart )->clone() ) );
77 featurePool->addFeature( newFeature );
78 changes[error->layerId()][newFeature.id()].append( Change( ChangeFeature, ChangeAdded ) );
79 }
80 // Recycle feature for part 0
81 feature.setGeometry( QgsGeometry( QgsGeometryCheckerUtils::getGeomPart( geom, 0 )->clone() ) );
82 featurePool->updateFeature( feature );
83 changes[error->layerId()][feature.id()].append( Change( ChangeFeature, ChangeChanged ) );
84 }
85 // Check if corresponding multi type is allowed
86 else if ( QgsWkbTypes::isSingleType( type ) && ( ( 1 << static_cast<quint32>( QgsWkbTypes::multiType( type ) ) ) & mAllowedTypes ) != 0 )
87 {
88 QgsGeometryCollection *geomCollection = nullptr;
89 switch ( QgsWkbTypes::multiType( type ) )
90 {
92 {
93 geomCollection = new QgsMultiPoint();
94 break;
95 }
97 {
98 geomCollection = new QgsMultiLineString();
99 break;
100 }
102 {
103 geomCollection = new QgsMultiPolygon();
104 break;
105 }
107 {
108 geomCollection = new QgsMultiCurve();
109 break;
110 }
112 {
113 geomCollection = new QgsMultiSurface();
114 break;
115 }
116 default:
117 break;
118 }
119 if ( !geomCollection )
120 {
121 error->setFixFailed( tr( "Unknown geometry type" ) );
122 }
123 else
124 {
125 geomCollection->addGeometry( geom->clone() );
126
127 feature.setGeometry( QgsGeometry( geomCollection ) );
128 featurePool->updateFeature( feature );
129 changes[error->layerId()][feature.id()].append( Change( ChangeFeature, ChangeChanged ) );
130 }
131 }
132 // Delete feature
133 else
134 {
135 featurePool->deleteFeature( feature.id() );
136 changes[error->layerId()][error->featureId()].append( Change( ChangeFeature, ChangeRemoved ) );
137 }
138 error->setFixed( method );
139 }
140 else if ( method == Delete )
141 {
142 featurePool->deleteFeature( feature.id() );
143 error->setFixed( method );
144 changes[error->layerId()][error->featureId()].append( Change( ChangeFeature, ChangeRemoved ) );
145 }
146 else
147 {
148 error->setFixFailed( tr( "Unknown method" ) );
149 }
150}
151
153{
154 static const QStringList methods = QStringList()
155 << tr( "Convert to corresponding multi or single type if possible, otherwise delete feature" )
156 << tr( "Delete feature" )
157 << tr( "No action" );
158 return methods;
159}
160
162{
163 return tr( "Geometry type" );
164}
165
167{
168 return factoryDescription();
169}
170
172{
173 return u"QgsGeometryTypeCheck"_s;
174}
175
180
182{
183 return factoryId();
184}
185
190
192{
193 return QgsSingleGeometryCheckError::isEqual( other ) && mFlatType == static_cast<const QgsGeometryTypeCheckError *>( other )->mFlatType;
194}
195
197{
198 return u"%1 (%2)"_s.arg( mCheck->description(), QgsWkbTypes::displayString( mFlatType ) );
199}
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:280
@ MultiPoint
MultiPoint.
Definition qgis.h:286
@ MultiPolygon
MultiPolygon.
Definition qgis.h:288
@ MultiLineString
MultiLineString.
Definition qgis.h:287
@ MultiCurve
MultiCurve.
Definition qgis.h:293
@ MultiSurface
MultiSurface.
Definition qgis.h:294
Abstract base class for all geometries.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
virtual int partCount() const =0
Returns count of parts contained in the geometry.
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
A feature pool is based on a vector layer and caches features.
virtual void updateFeature(QgsFeature &feature)=0
Updates a feature in this pool.
virtual void deleteFeature(QgsFeatureId fid)=0
Removes a feature from this pool.
bool getFeature(QgsFeatureId id, QgsFeature &feature)
Retrieves the feature with the specified id into feature.
virtual bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags())
Adds a single feature to the sink.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:60
QgsAttributes attributes
Definition qgsfeature.h:69
QgsFeatureId id
Definition qgsfeature.h:68
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
QgsGeometry geometry
Definition qgsfeature.h:71
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
This represents an error reported by a geometry check.
QgsFeatureId featureId() const
The id of the feature on which this error has been detected.
void setFixed(int method)
Set the status to fixed and specify the method that has been used to fix the error.
void setFixFailed(const QString &reason)
Set the error status to failed and specify the reason for failure.
void setObsolete()
Set the error status to obsolete.
const QString & layerId() const
The id of the layer on which this error has been detected.
QMap< QString, QMap< QgsFeatureId, QList< QgsGeometryCheck::Change > > > Changes
A collection of changes.
@ ChangeFeature
This change happens on feature level.
CheckType
The type of a check.
@ FeatureCheck
The check controls geometries as a whole.
@ ChangeChanged
Something has been updated.
@ ChangeAdded
Something has been added.
@ ChangeRemoved
Something has been removed.
static QgsAbstractGeometry * getGeomPart(QgsAbstractGeometry *geom, int partIdx)
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
A geometry type check error.
bool isEqual(const QgsSingleGeometryCheckError *other) const override
Check if this error is equal to other.
QString description() const override
A human readable description of this error.
QgsGeometryTypeCheckError(const QgsSingleGeometryCheck *check, const QgsGeometry &geometry, const QgsGeometry &errorLocation, Qgis::WkbType flatType)
Constructor for QgsGeometryTypeCheckError.
Q_DECL_DEPRECATED QStringList resolutionMethods() const override
Returns a list of descriptions for available resolutions for errors.
QgsGeometryCheck::CheckType checkType() const override
Returns the check type.
QString id() const override
Returns an id for this check.
void fixError(const QMap< QString, QgsFeaturePool * > &featurePools, QgsGeometryCheckError *error, int method, const QMap< QString, int > &mergeAttributeIndices, Changes &changes) const override
Fixes the error error with the specified method.
QList< QgsSingleGeometryCheckError * > processGeometry(const QgsGeometry &geometry) const override
Check the geometry for errors.
static QgsGeometryCheck::CheckType factoryCheckType()
QString description() const override
Returns a human readable description for this check.
static QString factoryDescription()
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Multi curve geometry collection.
Multi line string geometry collection.
Multi point geometry collection.
Multi polygon geometry collection.
Multi surface geometry collection.
const QgsSingleGeometryCheck * mCheck
virtual bool isEqual(const QgsSingleGeometryCheckError *other) const
Check if this error is equal to other.
QgsSingleGeometryCheckError(const QgsSingleGeometryCheck *check, const QgsGeometry &geometry, const QgsGeometry &errorLocation, const QgsVertexId &vertexId=QgsVertexId())
Creates a new single geometry check error.
static Q_INVOKABLE QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
static Q_INVOKABLE bool isSingleType(Qgis::WkbType type)
Returns true if the WKB type is a single type.
static Qgis::WkbType singleType(Qgis::WkbType type)
Returns the single type for a WKB type.
Definition qgswkbtypes.h:52
static Qgis::WkbType multiType(Qgis::WkbType type)
Returns the multi type for a WKB type.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
static Q_INVOKABLE bool isMultiType(Qgis::WkbType type)
Returns true if the WKB type is a multi type.
Descripts a change to fix a geometry.