35 , mGapThresholdMapUnits( configuration.value( QStringLiteral(
"gapThreshold" ) ).toDouble() )
41 if ( configuration.value( QStringLiteral(
"allowedGapsEnabled" ) ).toBool() )
46 mAllowedGapsLayer = layer;
47 mAllowedGapsSource = qgis::make_unique<QgsVectorLayerFeatureSource>( layer );
49 mAllowedGapsBuffer = configuration.value( QStringLiteral(
"allowedGapsBuffer" ) ).toDouble();
54 mAllowedGapsSource.reset();
63 std::unique_ptr<QgsAbstractGeometry> allowedGapsGeom;
64 std::unique_ptr<QgsGeometryEngine> allowedGapsGeomEngine;
66 if ( mAllowedGapsSource )
68 QVector<QgsGeometry> allowedGaps;
78 allowedGaps.append( gg );
85 allowedGapsGeom.reset( allowedGapsEngine->combine( allowedGaps, &errMsg ) );
87 allowedGapsGeomEngine->prepareGeometry();
90 QVector<QgsGeometry> geomList;
95 geomList.append( layerFeature.geometry() );
104 if ( geomList.isEmpty() )
113 std::unique_ptr<QgsAbstractGeometry> unionGeom( geomEngine->combine( geomList, &errMsg ) );
116 messages.append( tr(
"Gap check: %1" ).arg( errMsg ) );
122 geomEngine->prepareGeometry();
123 std::unique_ptr<QgsAbstractGeometry> envelope( geomEngine->envelope( &errMsg ) );
126 messages.append( tr(
"Gap check: %1" ).arg( errMsg ) );
132 geomEngine->prepareGeometry();
133 QgsAbstractGeometry *bufEnvelope = geomEngine->buffer( 2, 0, GEOSBUF_CAP_SQUARE, GEOSBUF_JOIN_MITRE, 4. );
134 envelope.reset( bufEnvelope );
138 geomEngine->prepareGeometry();
139 std::unique_ptr<QgsAbstractGeometry> diffGeom( geomEngine->difference( unionGeom.get(), &errMsg ) );
142 messages.append( tr(
"Gap check: %1" ).arg( errMsg ) );
167 QMap<QString, QgsFeatureIds> neighboringIds;
174 neighboringIds[layerFeature.layer()->id()].insert( layerFeature.feature().id() );
179 if ( neighboringIds.isEmpty() )
184 if ( allowedGapsGeomEngine && allowedGapsGeomEngine->contains( gapGeom ) )
190 double area = gapGeom->
area();
198 QMetaEnum metaEnum = QMetaEnum::fromType<QgsGeometryGapCheck::ResolutionMethod>();
199 if ( !metaEnum.isValid() || !metaEnum.valueToKey( method ) )
206 switch ( methodValue )
215 if ( mergeWithNeighbor( featurePools, static_cast<QgsGeometryGapCheckError *>( error ), changes, errMsg, LongestSharedEdge ) )
221 error->
setFixFailed( tr(
"Failed to merge with neighbor: %1" ).arg( errMsg ) );
233 error->
setFixFailed( tr(
"Could not start editing layer %1" ).arg( layer->
name() ) );
241 error->
setFixFailed( tr(
"Could not add feature to layer %1" ).arg( layer->
name() ) );
251 error->
setFixFailed( tr(
"Allowed gaps layer could not be resolved" ) );
277 error->
setFixFailed( tr(
"Could not resolve target layer %1 to add feature" ).arg( error->
layerId() ) );
285 if ( mergeWithNeighbor( featurePools, static_cast<QgsGeometryGapCheckError *>( error ), changes, errMsg, LargestArea ) )
291 error->
setFixFailed( tr(
"Failed to merge with neighbor: %1" ).arg( errMsg ) );
299 bool QgsGeometryGapCheck::mergeWithNeighbor(
const QMap<QString, QgsFeaturePool *> &featurePools,
QgsGeometryGapCheckError *err,
Changes &changes, QString &errMsg, Condition condition )
const 302 QString mergeLayerId;
304 int mergePartIdx = -1;
309 const auto layerIds = err->
neighbors().keys();
310 QList<QgsFeature> neighbours;
313 for (
const QString &layerId : layerIds )
316 std::unique_ptr<QgsAbstractGeometry> errLayerGeom( errGeometry->
clone() );
320 const auto featureIds = err->
neighbors().value( layerId );
325 if ( !featurePool->
getFeature( testId, feature ) )
333 neighbours.append( feature );
336 for (
const QgsFeature &testFeature : neighbours )
338 const QgsGeometry featureGeom = testFeature.geometry();
340 for (
int iPart = 0, nParts = testGeom->
partCount(); iPart < nParts; ++iPart )
345 case LongestSharedEdge:
357 mergeFeature = testFeature;
358 mergePartIdx = iPart;
359 mergeLayerId = layerId;
370 QgsSpatialIndex neighbourIndex( QgsSpatialIndex::Flag::FlagStoreFeatureGeometries );
383 snappedRing.append( closestPoint );
387 std::unique_ptr<QgsPolygon> snappedErrGeom = qgis::make_unique<QgsPolygon>();
388 snappedErrGeom->setExteriorRing(
new QgsLineString( snappedRing ) );
392 std::unique_ptr<QgsAbstractGeometry> errLayerGeom( snappedErrGeom->clone() );
413 QStringList methods = QStringList()
414 << tr(
"Add gap area to neighboring polygon with longest shared edge" )
415 << tr(
"No action" );
416 if ( mAllowedGapsSource )
417 methods << tr(
"Add gap to allowed exceptions" );
424 QList<QgsGeometryCheckResolutionMethod> fixes
431 if ( mAllowedGapsSource )
434 fixes << QgsGeometryCheckResolutionMethod(
NoChange, tr(
"No action" ), tr(
"Do not perform any action and mark this error as fixed." ),
false );
441 return factoryDescription();
451 return factoryFlags();
455 QString QgsGeometryGapCheck::factoryDescription()
460 QString QgsGeometryGapCheck::factoryId()
462 return QStringLiteral(
"QgsGeometryGapCheck" );
465 QgsGeometryCheck::Flags QgsGeometryGapCheck::factoryFlags()
470 QList<QgsWkbTypes::GeometryType> QgsGeometryGapCheck::factoryCompatibleGeometryTypes()
477 return factoryCompatibleGeometryTypes().contains( layer->
geometryType() );
488 return mContextBoundingBox;
500 return err && err->
layerId() == layerId() && err->
neighbors() == neighbors();
508 mNeighbors = err->mNeighbors;
509 mGapAreaBBox = err->mGapAreaBBox;
Wrapper for iterator of features from vector data provider or vector layer.
QgsPointSequence QgsPolyline
Polyline as represented as a vector of points.
A rectangle specified with double values.
Java-style iterator for traversal of parts of a geometry.
static bool pointsFuzzyEqual(const QgsPointXY &p1, const QgsPointXY &p2, double tol)
Determine whether two points are equal up to the specified tolerance.
QList< QgsWkbTypes::GeometryType > compatibleGeometryTypes() const override
A list of geometry types for which this check can be performed.
QgsGeometry geometry(QgsFeatureId id) const
Returns the stored geometry for the indexed feature with matching id.
virtual void update(const QgsGeometryCheckError *other)
Update this error with the information from other.
bool closeMatch(QgsGeometryCheckError *other) const override
Check if this error is almost equal to 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)
double progress() const
Returns the current progress reported by the feedback object.
Java-style iterator for traversal of vertices of a geometry.
QList< QgsFeature > QgsFeatureList
QString description() const override
Returns a human readable description for this check.
A class to represent a 2D point.
const QgsPointXY & location() const
The location of the error in map units.
void setProgress(double progress)
Sets the current progress for the feedback object.
Q_INVOKABLE bool startEditing()
Makes the layer editable.
QMap< QString, QgsFeatureIds > toMap() const
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Base configuration for geometry checks.
Contains a set of layers and feature ids in those layers to pass to a geometry check.
CheckType
The type of a check.
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
A geometry is the spatial representation of a feature.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
Merge with neighbouring polygon with largest area.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
static QgsPoint closestVertex(const QgsAbstractGeometry &geom, const QgsPoint &pt, QgsVertexId &id)
Returns the closest vertex to a geometry for a specified point.
virtual QgsRectangle boundingBox() const =0
Returns the minimal bounding box for the geometry.
QgsRectangle snappedToGrid(double spacing) const
Returns a copy of this rectangle that is snapped to a grid with the specified spacing between the gri...
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
void replaceFeatureGeometryPart(const QMap< QString, QgsFeaturePool *> &featurePools, const QString &layerId, QgsFeature &feature, int partIdx, QgsAbstractGeometry *newPartGeom, Changes &changes) const
Replaces a part in a feature geometry.
void setFixFailed(const QString &reason)
Set the error status to failed and specify the reason for failure.
QIcon icon() const override
Returns an icon that should be shown for this kind of error.
Base class for feedback objects to be used for cancellation of something running in a worker thread...
An error produced by a QgsGeometryGapCheck.
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
void prepare(const QgsGeometryCheckContext *context, const QVariantMap &configuration) override
Will be run in the main thread before collectErrors is called (which may be run from a background thr...
static double sharedEdgeLength(const QgsAbstractGeometry *geom1, const QgsAbstractGeometry *geom2, double tol)
void update(const QgsGeometryCheckError *other) override
Update this error with the information from other.
Utility class for identifying a unique vertex within a geometry.
Add gap geometry to allowed gaps layer.
Q_DECL_DEPRECATED QStringList resolutionMethods() const override
Returns a list of descriptions for available resolutions for errors.
bool getFeature(QgsFeatureId id, QgsFeature &feature)
Retrieves the feature with the specified id into feature.
A layer feature combination to uniquely identify and access a feature in a set of layers...
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static QgsFeature createFeature(const QgsVectorLayer *layer, const QgsGeometry &geometry=QgsGeometry(), const QgsAttributeMap &attributes=QgsAttributeMap(), QgsExpressionContext *context=nullptr)
Creates a new feature ready for insertion into a layer.
QMap< int, QVariant > QgsAttributeMap
QgsRectangle contextBoundingBox() const override
The context of the error.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=nullptr) FINAL
Adds a list of features to the sink.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
Encapsulates a QGIS project, including sets of map layers and their styles, layouts, annotations, canvases, etc.
const double reducedTolerance
The tolerance to allow for in geometry checks.
This class implements a geometry check.
virtual double area() const
Returns the planar, 2-dimensional area of the geometry.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
QgsGeometryCheck::Flags flags() const override
Flags for this geometry check.
Abstract base class for all geometries.
QMap< QString, QgsFeatureIds > allLayerFeatureIds(const QMap< QString, QgsFeaturePool *> &featurePools) const
Returns all layers and feature ids.
const QString & layerId() const
The id of the layer on which this error has been detected.
ResolutionMethod
Resolution methods for geometry gap checks.
const QgsGeometryCheckContext * mContext
const QgsCoordinateReferenceSystem mapCrs
The coordinate system in which calculations should be done.
Point geometry type, with support for z-dimension and m-values.
A list of layers and feature ids for each of these layers.
const QMap< QString, QgsFeatureIds > & neighbors() const
A map of layers and feature ids of the neighbors of the gap.
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.
static bool isSingleType(Type type)
Returns true if the WKB type is a single type.
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle...
QgsGeometryGapCheck(const QgsGeometryCheckContext *context, const QVariantMap &configuration)
The configuration accepts a "gapThreshold" key which specifies the maximum gap size in squared map un...
QMap< QString, QgsFeatureIds > involvedFeatures() const override
Returns a list of involved features.
A spatial index for QgsFeature objects.
QMap< QString, QMap< QgsFeatureId, QList< QgsGeometryCheck::Change > > > Changes
A collection of changes.
bool isCanceled() const
Tells whether the operation has been canceled already.
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.
QgsAbstractGeometry * next()
Returns next part of the geometry (undefined behavior if hasNext() returns false before calling next(...
bool handleChanges(const QgsGeometryCheck::Changes &) override
Apply a list of changes.
const double tolerance
The tolerance to allow for in geometry checks.
A feature pool is based on a vector layer and caches features.
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=nullptr) override
Adds a list of features to the index.
QgsPoint next()
Returns next vertex of the geometry (undefined behavior if hasNext() returns false before calling nex...
Create a new feature with the gap geometry.
Line string geometry type, with support for z-dimension and m-values.
QgsRectangle affectedAreaBBox() const override
The bounding box of the affected area of the error.
static QgsProject * instance()
Returns the QgsProject singleton instance.
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's geometry.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr) FINAL
Adds a single feature to the sink.
const QgsProject * project() const
The project can be used to resolve additional layers.
void collectErrors(const QMap< QString, QgsFeaturePool *> &featurePools, QList< QgsGeometryCheckError *> &errors, QStringList &messages, QgsFeedback *feedback, const LayerFeatureIds &ids=LayerFeatureIds()) const override
The main worker method.
bool isEqual(QgsGeometryCheckError *other) const override
Check if this error is equal to other.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
This class implements a resolution for problems detected in geometry checks.
QgsCoordinateReferenceSystem crs() const
The coordinate reference system of this layer.
const QgsGeometryCheckContext * context() const
Returns the context.
QList< int > QgsAttributeList
This represents an error reported by a geometry check.
static std::unique_ptr< QgsGeometryEngine > createGeomEngine(const QgsAbstractGeometry *geometry, double tolerance)
bool nextFeature(QgsFeature &f)
bool hasNext() const
Find out whether there are more vertices.
static QgsFeatureList makeFeatureCompatible(const QgsFeature &feature, const QgsVectorLayer *layer)
Converts input feature to be compatible with the given layer.
QList< QgsFeatureId > nearestNeighbor(const QgsPointXY &point, int neighbors=1, double maxDistance=0) const
Returns nearest neighbors to a point.
Represents a vector layer which manages a vector based data sets.
QgsVertexIterator vertices() const
Returns a read-only, Java-style iterator for traversal of vertices of all the geometry, including all geometry parts and rings.
QString id() const override
Returns an id for this check.
QList< QgsGeometryCheckResolutionMethod > availableResolutionMethods() const override
Returns a list of available resolution methods.
Merge the gap with the polygon with the longest shared edge.
bool hasNext() const
Find out whether there are more parts.
This geometry check should be available in layer validation on the vector layer peroperties.
virtual int partCount() const =0
Returns count of parts contained in the geometry.
The check controls a whole layer (topology checks)
const QgsCoordinateTransformContext transformContext
The coordinate transform context with which transformations will be done.