QGIS API Documentation  3.8.0-Zanzibar (11aff65)
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 }
QgsFeatureId id
Definition: qgsfeature.h:64
QString id() const override
Returns an id for this check.
static Type singleType(Type type)
Returns the single type for a WKB type.
Definition: qgswkbtypes.h:155
static Type multiType(Type type)
Returns the multi type for a WKB type.
Definition: qgswkbtypes.h:299
static QgsAbstractGeometry * getGeomPart(QgsAbstractGeometry *geom, int partIdx)
Multi point geometry collection.
Definition: qgsmultipoint.h:29
static bool isMultiType(Type type)
Returns true if the WKB type is a multi type.
Definition: qgswkbtypes.h:560
Something has been added.
virtual bool isEqual(const QgsSingleGeometryCheckError *other) const
Check if this error is equal to other.
Multi line string geometry collection.
CheckType
The type of a check.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:111
void setAttributes(const QgsAttributes &attrs)
Sets the feature&#39;s attributes.
Definition: qgsfeature.cpp:127
void setObsolete()
Set the error status to obsolete.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
Multi surface geometry collection.
QString description() const override
A human readable description of this error.
QString description() const override
Returns a human readable description for this check.
void setFixFailed(const QString &reason)
Set the error status to failed and specify the reason for failure.
virtual void updateFeature(QgsFeature &feature)=0
Updates a feature in this pool.
static QgsGeometryCheck::CheckType factoryCheckType()
The check controls geometries as a whole.
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
Something has been removed.
QgsGeometryCheck::CheckType checkType() const override
Returns the check type.
Geometry collection.
bool getFeature(QgsFeatureId id, QgsFeature &feature)
Retrieves the feature with the specified id into feature.
Multi curve geometry collection.
Definition: qgsmulticurve.h:29
virtual bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr)
Adds a single feature to the sink.
Abstract base class for all geometries.
const QString & layerId() const
The id of the layer on which this error has been detected.
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the geometry.
An error from a QgsSingleGeometryCheck.
static QString factoryDescription()
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static bool isSingleType(Type type)
Returns true if the WKB type is a single type.
Definition: qgswkbtypes.h:550
QList< QgsSingleGeometryCheckError * > processGeometry(const QgsGeometry &geometry) const override
Check the geometry for errors.
QStringList resolutionMethods() const override
Returns a list of descriptions for available resolutions for errors.
QMap< QString, QMap< QgsFeatureId, QList< QgsGeometryCheck::Change > > > Changes
A collection of changes.
Multi polygon geometry collection.
void fixError(const QMap< QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap< QString, int > &mergeAttributeIndices, Changes &changes) const override
Fix the error error with the specified method.
A feature pool is based on a vector layer and caches features.
Descripts a change to fix a geometry.
void setFixed(int method)
Set the status to fixed and specify the method that has been used to fix the error.
void setGeometry(const QgsGeometry &geometry)
Set the feature&#39;s geometry.
Definition: qgsfeature.cpp:137
virtual void deleteFeature(QgsFeatureId fid)=0
Removes a feature from this pool.
static QString displayString(Type type)
Returns a display string type for a WKB type, e.g., the geometry name used in WKT geometry representa...
QgsFeatureId featureId() const
The id of the feature on which this error has been detected.
QgsGeometry geometry
Definition: qgsfeature.h:67
This represents an error reported by a geometry check.
bool isEqual(const QgsSingleGeometryCheckError *other) const override
Check if this error is equal to other.
Something has been updated.
static Type flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:430
This change happens on feature level.
QgsAttributes attributes
Definition: qgsfeature.h:65
virtual int partCount() const =0
Returns count of parts contained in the geometry.
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.