QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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 #include "qgsgeometrytypecheck.h"
18 #include "qgsgeometrycollection.h"
19 #include "qgsmulticurve.h"
20 #include "qgsmultilinestring.h"
21 #include "qgsmultipoint.h"
22 #include "qgsmultipolygon.h"
23 #include "qgsmultirenderchecker.h"
24 #include "qgsfeaturepool.h"
25 
26 
27 
28 QList<QgsSingleGeometryCheckError *> QgsGeometryTypeCheck::processGeometry( const QgsGeometry &geometry ) const
29 {
30  QList<QgsSingleGeometryCheckError *> errors;
31  const QgsAbstractGeometry *geom = geometry.constGet();
33  if ( ( mAllowedTypes & ( 1 << type ) ) == 0 )
34  {
35  errors.append( new QgsGeometryTypeCheckError( this, geometry, geometry, type ) );
36  }
37  return errors;
38 }
39 
40 void QgsGeometryTypeCheck::fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const
41 {
42  QgsFeaturePool *featurePool = featurePools[ error->layerId() ];
43  QgsFeature feature;
44  if ( !featurePool->getFeature( error->featureId(), feature ) )
45  {
46  error->setObsolete();
47  return;
48  }
49  QgsGeometry featureGeom = feature.geometry();
50  const QgsAbstractGeometry *geom = featureGeom.constGet();
51 
52  // Check if error still applies
54  if ( ( mAllowedTypes & ( 1 << type ) ) != 0 )
55  {
56  error->setObsolete();
57  return;
58  }
59 
60  // Fix with selected method
61  if ( method == NoChange )
62  {
63  error->setFixed( method );
64  }
65  else if ( method == Convert )
66  {
67  // Check if corresponding single type is allowed
68  if ( QgsWkbTypes::isMultiType( type ) && ( ( 1 << QgsWkbTypes::singleType( type ) ) & mAllowedTypes ) != 0 )
69  {
70  // Explode multi-type feature into single-type features
71  for ( int iPart = 1, nParts = geom->partCount(); iPart < nParts; ++iPart )
72  {
73  QgsFeature newFeature;
74  newFeature.setAttributes( feature.attributes() );
75  newFeature.setGeometry( QgsGeometry( QgsGeometryCheckerUtils::getGeomPart( geom, iPart )->clone() ) );
76  featurePool->addFeature( newFeature );
77  changes[error->layerId()][newFeature.id()].append( Change( ChangeFeature, ChangeAdded ) );
78  }
79  // Recycle feature for part 0
80  feature.setGeometry( QgsGeometry( QgsGeometryCheckerUtils::getGeomPart( geom, 0 )->clone() ) );
81  featurePool->updateFeature( feature );
82  changes[error->layerId()][feature.id()].append( Change( ChangeFeature, ChangeChanged ) );
83  }
84  // Check if corresponding multi type is allowed
85  else if ( QgsWkbTypes::isSingleType( type ) && ( ( 1 << QgsWkbTypes::multiType( type ) ) & mAllowedTypes ) != 0 )
86  {
87  QgsGeometryCollection *geomCollection = nullptr;
88  switch ( QgsWkbTypes::multiType( type ) )
89  {
91  {
92  geomCollection = new QgsMultiPoint();
93  break;
94  }
96  {
97  geomCollection = new QgsMultiLineString();
98  break;
99  }
101  {
102  geomCollection = new QgsMultiPolygon();
103  break;
104  }
106  {
107  geomCollection = new QgsMultiCurve();
108  break;
109  }
111  {
112  geomCollection = new QgsMultiSurface();
113  break;
114  }
115  default:
116  break;
117  }
118  if ( !geomCollection )
119  {
120  error->setFixFailed( tr( "Unknown geometry type" ) );
121  }
122  else
123  {
124  geomCollection->addGeometry( geom->clone() );
125 
126  feature.setGeometry( QgsGeometry( geomCollection ) );
127  featurePool->updateFeature( feature );
128  changes[error->layerId()][feature.id()].append( Change( ChangeFeature, ChangeChanged ) );
129  }
130  }
131  // Delete feature
132  else
133  {
134  featurePool->deleteFeature( feature.id() );
135  changes[error->layerId()][error->featureId()].append( Change( ChangeFeature, ChangeRemoved ) );
136  }
137  error->setFixed( method );
138  }
139  else if ( method == Delete )
140  {
141  featurePool->deleteFeature( feature.id() );
142  error->setFixed( method );
143  changes[error->layerId()][error->featureId()].append( Change( ChangeFeature, ChangeRemoved ) );
144  }
145  else
146  {
147  error->setFixFailed( tr( "Unknown method" ) );
148  }
149 }
150 
152 {
153  static QStringList methods = QStringList()
154  << tr( "Convert to corresponding multi or single type if possible, otherwise delete feature" )
155  << tr( "Delete feature" )
156  << tr( "No action" );
157  return methods;
158 }
159 
161 {
162  return tr( "Geometry type" );
163 }
164 
166 {
167  return factoryDescription();
168 }
169 
171 {
172  return QStringLiteral( "QgsGeometryTypeCheck" );
173 }
174 
176 {
178 }
179 
181 {
182  return factoryId();
183 }
184 
186 {
187  return factoryCheckType();
188 }
189 
191 {
192  return QgsSingleGeometryCheckError::isEqual( other ) &&
193  mFlatType == static_cast<const QgsGeometryTypeCheckError *>( other )->mFlatType;
194 }
195 
197 {
198  return QStringLiteral( "%1 (%2)" ).arg( mCheck->description(), QgsWkbTypes::displayString( mFlatType ) );
199 }
QgsWkbTypes::multiType
static Type multiType(Type type)
Returns the multi type for a WKB type.
Definition: qgswkbtypes.h:301
QgsGeometryCheckError::setFixFailed
void setFixFailed(const QString &reason)
Set the error status to failed and specify the reason for failure.
Definition: qgsgeometrycheckerror.cpp:109
QgsGeometryCheck::Change
Descripts a change to fix a geometry.
Definition: qgsgeometrycheck.h:177
QgsAbstractGeometry::wkbType
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the geometry.
Definition: qgsabstractgeometry.h:189
QgsGeometryCheckerUtils::getGeomPart
static QgsAbstractGeometry * getGeomPart(QgsAbstractGeometry *geom, int partIdx)
Definition: qgsgeometrycheckerutils.cpp:268
QgsGeometryTypeCheck::factoryCheckType
static QgsGeometryCheck::CheckType factoryCheckType()
Definition: qgsgeometrytypecheck.cpp:175
QgsGeometryCheck::ChangeAdded
@ ChangeAdded
Something has been added.
Definition: qgsgeometrycheck.h:145
QgsGeometryCheck::ChangeFeature
@ ChangeFeature
This change happens on feature level.
Definition: qgsgeometrycheck.h:132
QgsGeometryTypeCheck::checkType
QgsGeometryCheck::CheckType checkType() const override
Returns the check type.
Definition: qgsgeometrytypecheck.cpp:185
QgsWkbTypes::MultiPolygon
@ MultiPolygon
Definition: qgswkbtypes.h:77
QgsWkbTypes::singleType
static Type singleType(Type type)
Returns the single type for a WKB type.
Definition: qgswkbtypes.h:156
QgsGeometryTypeCheck::fixError
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.
Definition: qgsgeometrytypecheck.cpp:40
QgsGeometryTypeCheck::factoryId
static QString factoryId()
Definition: qgsgeometrytypecheck.cpp:170
QgsGeometryCheckError::setObsolete
void setObsolete()
Set the error status to obsolete.
Definition: qgsgeometrycheckerror.h:166
QgsGeometryCheckError::featureId
QgsFeatureId featureId() const
The id of the feature on which this error has been detected.
Definition: qgsgeometrycheckerror.h:90
QgsGeometryCheck::Changes
QMap< QString, QMap< QgsFeatureId, QList< QgsGeometryCheck::Change > > > Changes
A collection of changes.
Definition: qgsgeometrycheck.h:214
QgsFeatureSink::addFeature
virtual bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags())
Adds a single feature to the sink.
Definition: qgsfeaturesink.cpp:20
QgsWkbTypes::isMultiType
static bool isMultiType(Type type)
Returns true if the WKB type is a multi type.
Definition: qgswkbtypes.h:831
QgsGeometryCheck::description
virtual QString description() const =0
Returns a human readable description for this check.
QgsSingleGeometryCheckError::mCheck
const QgsSingleGeometryCheck * mCheck
Definition: qgssinglegeometrycheck.h:100
QgsMultiLineString
Multi line string geometry collection.
Definition: qgsmultilinestring.h:29
qgsmultipoint.h
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
QgsGeometryTypeCheck::processGeometry
QList< QgsSingleGeometryCheckError * > processGeometry(const QgsGeometry &geometry) const override
Check the geometry for errors.
Definition: qgsgeometrytypecheck.cpp:28
QgsGeometryCheck::ChangeChanged
@ ChangeChanged
Something has been updated.
Definition: qgsgeometrycheck.h:147
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
QgsWkbTypes::MultiCurve
@ MultiCurve
Definition: qgswkbtypes.h:82
QgsGeometryTypeCheck::description
QString description() const override
Returns a human readable description for this check.
Definition: qgsgeometrytypecheck.cpp:165
QgsMultiSurface
Multi surface geometry collection.
Definition: qgsmultisurface.h:29
QgsAbstractGeometry::partCount
virtual int partCount() const =0
Returns count of parts contained in the geometry.
QgsSingleGeometryCheckError
Definition: qgssinglegeometrycheck.h:39
QgsFeaturePool::getFeature
bool getFeature(QgsFeatureId id, QgsFeature &feature)
Retrieves the feature with the specified id into feature.
Definition: qgsfeaturepool.cpp:39
qgsgeometrytypecheck.h
qgsfeaturepool.h
QgsGeometryCheck::ChangeRemoved
@ ChangeRemoved
Something has been removed.
Definition: qgsgeometrycheck.h:146
QgsFeature::id
QgsFeatureId id
Definition: qgsfeature.h:68
QgsWkbTypes::MultiLineString
@ MultiLineString
Definition: qgswkbtypes.h:76
QgsGeometryCollection
Geometry collection.
Definition: qgsgeometrycollection.h:35
qgsgeometrycheckcontext.h
qgsmultipolygon.h
QgsFeaturePool::deleteFeature
virtual void deleteFeature(QgsFeatureId fid)=0
Removes a feature from this pool.
QgsFeature::setGeometry
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:137
QgsMultiCurve
Multi curve geometry collection.
Definition: qgsmulticurve.h:29
QgsFeaturePool::updateFeature
virtual void updateFeature(QgsFeature &feature)=0
Updates a feature in this pool.
QgsGeometryCheckError::setFixed
void setFixed(int method)
Set the status to fixed and specify the method that has been used to fix the error.
Definition: qgsgeometrycheckerror.cpp:98
QgsGeometryCollection::addGeometry
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
Definition: qgsgeometrycollection.cpp:226
QgsAbstractGeometry::clone
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
QgsGeometryTypeCheck::factoryDescription
static QString factoryDescription()
Definition: qgsgeometrytypecheck.cpp:160
QgsMultiPolygon
Multi polygon geometry collection.
Definition: qgsmultipolygon.h:29
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsGeometryTypeCheckError::isEqual
bool isEqual(const QgsSingleGeometryCheckError *other) const override
Check if this error is equal to other.
Definition: qgsgeometrytypecheck.cpp:190
QgsWkbTypes::isSingleType
static bool isSingleType(Type type)
Returns true if the WKB type is a single type.
Definition: qgswkbtypes.h:821
QgsMultiPoint
Multi point geometry collection.
Definition: qgsmultipoint.h:29
QgsFeature::attributes
QgsAttributes attributes
Definition: qgsfeature.h:69
QgsAbstractGeometry
Abstract base class for all geometries.
Definition: qgsabstractgeometry.h:71
qgsmultirenderchecker.h
QgsSingleGeometryCheckError::isEqual
virtual bool isEqual(const QgsSingleGeometryCheckError *other) const
Check if this error is equal to other.
Definition: qgssinglegeometrycheck.cpp:50
QgsWkbTypes::MultiSurface
@ MultiSurface
Definition: qgswkbtypes.h:83
QgsGeometry
Definition: qgsgeometry.h:122
QgsGeometryTypeCheckError
Definition: qgsgeometrytypecheck.h:26
QgsWkbTypes::displayString
static QString displayString(Type type)
Returns a display string type for a WKB type, e.g., the geometry name used in WKT geometry representa...
Definition: qgswkbtypes.cpp:145
QgsWkbTypes::MultiPoint
@ MultiPoint
Definition: qgswkbtypes.h:75
QgsGeometryCheck::CheckType
CheckType
The type of a check.
Definition: qgsgeometrycheck.h:155
qgsgeometrycollection.h
qgsmulticurve.h
QgsFeature
Definition: qgsfeature.h:55
QgsGeometryTypeCheck::id
QString id() const override
Returns an id for this check.
Definition: qgsgeometrytypecheck.cpp:180
QgsGeometryCheckError::layerId
const QString & layerId() const
The id of the layer on which this error has been detected.
Definition: qgsgeometrycheckerror.h:85
QgsFeature::setAttributes
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:127
QgsGeometryCheck::FeatureCheck
@ FeatureCheck
The check controls geometries as a whole.
Definition: qgsgeometrycheck.h:158
QgsGeometryCheckError
Definition: qgsgeometrycheckerror.h:35
QgsGeometryTypeCheck::resolutionMethods
Q_DECL_DEPRECATED QStringList resolutionMethods() const override
Returns a list of descriptions for available resolutions for errors.
Definition: qgsgeometrytypecheck.cpp:151
QgsFeaturePool
Definition: qgsfeaturepool.h:37
QgsWkbTypes::flatType
static Type flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:701
qgsmultilinestring.h
QgsGeometryTypeCheckError::description
QString description() const override
A human readable description of this error.
Definition: qgsgeometrytypecheck.cpp:196