QGIS API Documentation  3.6.0-Noosa (5873452)
qgsgeometrycheckerror.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgeometrycheckerror.cpp
3  --------
4  begin : September 2018
5  copyright : (C) 2018 by Denis Rouzaud
6  email : [email protected]
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 
18 #include "qgsgeometrycheckerror.h"
19 
21  const QString &layerId,
22  QgsFeatureId featureId,
23  const QgsGeometry &geometry,
24  const QgsPointXY &errorLocation,
25  QgsVertexId vidx,
26  const QVariant &value, ValueType valueType )
27  : mCheck( check )
28  , mLayerId( layerId )
29  , mFeatureId( featureId )
30  , mGeometry( geometry )
31  , mErrorLocation( errorLocation )
32  , mVidx( vidx )
33  , mValue( value )
34  , mValueType( valueType )
35  , mStatus( StatusPending )
36 {
37 }
38 
40  const QgsGeometryCheckerUtils::LayerFeature &layerFeature,
41  const QgsPointXY &errorLocation,
43  const QVariant &value,
45  : mCheck( check )
46  , mLayerId( layerFeature.layerId() )
47  , mFeatureId( layerFeature.feature().id() )
48  , mErrorLocation( errorLocation )
49  , mVidx( vidx )
50  , mValue( value )
51  , mValueType( valueType )
53 {
54  if ( vidx.part != -1 )
55  {
56  mGeometry = QgsGeometry( QgsGeometryCheckerUtils::getGeomPart( layerFeature.geometry().constGet(), vidx.part )->clone() );
57  }
58  else
59  {
60  mGeometry = layerFeature.geometry();
61  }
62  if ( !layerFeature.useMapCrs() )
63  {
64  QgsVectorLayer *vl = layerFeature.layer().data();
65  if ( vl )
66  {
67  QgsCoordinateTransform ct( vl->crs(), check->context()->mapCrs, check->context()->transformContext );
68  try
69  {
70  mGeometry.transform( ct );
71  mErrorLocation = ct.transform( mErrorLocation );
72  }
73  catch ( const QgsCsException & )
74  {
75  QgsDebugMsg( QStringLiteral( "Can not show error in current map coordinate reference system" ) );
76  }
77  }
78  }
79 }
80 
82 {
83  return mGeometry;
84 }
85 
87 {
88  return mGeometry.boundingBox();
89 }
90 
92 {
94  const QStringList methods = mCheck->resolutionMethods();
95  mResolutionMessage = methods[method];
96 }
97 
98 void QgsGeometryCheckError::setFixFailed( const QString &reason )
99 {
101  mResolutionMessage = reason;
102 }
103 
105 {
106  return other->check() == check() &&
107  other->layerId() == layerId() &&
108  other->featureId() == featureId() &&
109  other->vidx() == vidx();
110 }
111 
113 {
114  return false;
115 }
116 
118 {
119  if ( status() == StatusObsolete )
120  {
121  return false;
122  }
123 
124  for ( const QgsGeometryCheck::Change &change : changes.value( layerId() ).value( featureId() ) )
125  {
126  if ( change.what == QgsGeometryCheck::ChangeFeature )
127  {
128  if ( change.type == QgsGeometryCheck::ChangeRemoved )
129  {
130  return false;
131  }
132  else if ( change.type == QgsGeometryCheck::ChangeChanged )
133  {
134  // If the check is checking the feature at geometry nodes level, the
135  // error almost certainly invalid after a geometry change. In the other
136  // cases, it might likely still be valid.
138  }
139  }
140  else if ( change.what == QgsGeometryCheck::ChangePart )
141  {
142  if ( mVidx.part == change.vidx.part )
143  {
144  return false;
145  }
146  else if ( mVidx.part > change.vidx.part )
147  {
148  mVidx.part += change.type == QgsGeometryCheck::ChangeAdded ? 1 : -1;
149  }
150  }
151  else if ( change.what == QgsGeometryCheck::ChangeRing )
152  {
153  if ( mVidx.partEqual( change.vidx ) )
154  {
155  if ( mVidx.ring == change.vidx.ring )
156  {
157  return false;
158  }
159  else if ( mVidx.ring > change.vidx.ring )
160  {
161  mVidx.ring += change.type == QgsGeometryCheck::ChangeAdded ? 1 : -1;
162  }
163  }
164  }
165  else if ( change.what == QgsGeometryCheck::ChangeNode )
166  {
167  if ( mVidx.ringEqual( change.vidx ) )
168  {
169  if ( mVidx.vertex == change.vidx.vertex )
170  {
171  return false;
172  }
173  else if ( mVidx.vertex > change.vidx.vertex )
174  {
175  mVidx.vertex += change.type == QgsGeometryCheck::ChangeAdded ? 1 : -1;
176  }
177  }
178  }
179  }
180  return true;
181 }
182 
184 {
185  Q_ASSERT( mCheck == other->mCheck );
186  Q_ASSERT( mLayerId == other->mLayerId );
187  Q_ASSERT( mFeatureId == other->mFeatureId );
189  mVidx = other->mVidx;
190  mValue = other->mValue;
191  mGeometry = other->mGeometry;
192 }
193 
194 QgsGeometryCheck::LayerFeatureIds::LayerFeatureIds( const QMap<QString, QgsFeatureIds> &ids )
195  : ids( ids )
196 {
197 }
The error is obsolete because of other modifications.
This change happens on part level.
A rectangle specified with double values.
Definition: qgsrectangle.h:41
The error is detected and pending to be handled.
virtual void update(const QgsGeometryCheckError *other)
Update this error with the information from other.
OperationResult transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection direction=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
static QgsAbstractGeometry * getGeomPart(QgsAbstractGeometry *geom, int partIdx)
Something has been added.
const QgsCoordinateReferenceSystem mapCrs
The coordinate system in which calculations should be done.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
A class to represent a 2D point.
Definition: qgspointxy.h:43
virtual bool closeMatch(QgsGeometryCheckError *) const
Check if this error is almost equal to other.
qint64 QgsFeatureId
Definition: qgsfeatureid.h:25
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:106
ValueType
Describes the type of an error value.
void setFixFailed(const QString &reason)
Set the error status to failed and specify the reason for failure.
Something has been removed.
const QgsGeometryCheck * check() const
The geometry check that created this error.
This change happens on ring level.
QPointer< QgsVectorLayer > layer() const
The layer.
Utility class for identifying a unique vertex within a geometry.
virtual CheckType checkType() const =0
Returns the check type.
A layer feature combination to uniquely identify and access a feature in a set of layers...
const QgsGeometryCheck * mCheck
This class implements a geometry check.
const QString & layerId() const
The id of the layer on which this error has been detected.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
QgsGeometry geometry() const
The geometry of the error in map units.
Status status() const
The status of the error.
bool partEqual(QgsVertexId o) const
bool ringEqual(QgsVertexId o) const
bool useMapCrs() const
Returns if the geometry is reprojected to the map CRS or not.
QMap< QString, QMap< QgsFeatureId, QList< QgsGeometryCheck::Change > > > Changes
A collection of changes.
virtual QgsRectangle affectedAreaBBox() const
The bounding box of the affected area of the error.
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.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
virtual bool handleChanges(const QgsGeometryCheck::Changes &changes)
Apply a list of changes.
A fix has been tried on the error but failed.
Class for doing transforms between two map coordinate systems.
virtual QStringList resolutionMethods() const =0
Returns a list of descriptions for available resolutions for errors.
const QgsCoordinateTransformContext transformContext
The coordinate transform context with which transformations will be done.
QgsFeatureId featureId() const
The id of the feature on which this error has been detected.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
const QgsGeometryCheckContext * context() const
Returns the context.
This represents an error reported by a geometry check.
This change happens on node level.
QVariant value() const
An additional value for the error.
ValueType valueType() const
The type of the value.
Represents a vector layer which manages a vector based data sets.
Something has been updated.
const QgsVertexId & vidx() const
The id of the affected vertex.
QgsGeometryCheckError(const QgsGeometryCheck *check, const QgsGeometryCheckerUtils::LayerFeature &layerFeature, const QgsPointXY &errorLocation, QgsVertexId vidx=QgsVertexId(), const QVariant &value=QVariant(), ValueType valueType=ValueOther)
Create a new geometry check error with the parent check and for the layerFeature pair at the errorLoc...
This change happens on feature level.
virtual bool isEqual(QgsGeometryCheckError *other) const
Check if this error is equal to other.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:71
The check controls individual nodes.
const QgsGeometry & geometry() const
Returns the geometry of this feature.