38    if ( change.vidx.vertex == mIntersection.
segment1 || change.vidx.vertex == mIntersection.
segment1 + 1 || change.vidx.vertex == mIntersection.
segment2 || change.vidx.vertex == mIntersection.
segment2 + 1 )
 
   42    else if ( change.vidx.vertex >= 0 )
 
   44      if ( change.vidx.vertex < mIntersection.
segment1 )
 
   48      if ( change.vidx.vertex < mIntersection.
segment2 )
 
 
   62  mIntersection.
point = err->mIntersection.
point;
 
 
   90  bool ringIsClosed = 
false;
 
  102  bool intersection = 
false;
 
  118    bool ring1EndsWithS = 
false;
 
  119    bool ring2EndsWithS = 
false;
 
  120    for ( 
int i = 0; i < nVerts; ++i )
 
  122      if ( i <= inter.segment1 || i >= inter.
segment2 + 1 )
 
  125        ring1EndsWithS = 
false;
 
  129          ring2EndsWithS = 
true;
 
  135        ring2EndsWithS = 
true;
 
  139          ring1EndsWithS = 
false;
 
  146      ring2EndsWithS = 
true;
 
  148    if ( ringIsClosed || ring1EndsWithS )
 
  149      ring1.append( ring1.front() ); 
 
  150    if ( ringIsClosed || ring2EndsWithS )
 
  151      ring2.append( ring2.front() ); 
 
  153    if ( ring1.size() < 3 + ( ringIsClosed || ring1EndsWithS ) || ring2.size() < 3 + ( ringIsClosed || ring2EndsWithS ) )
 
  155      error->
setFixFailed( tr( 
"Resulting geometry is degenerate" ) );
 
  158    auto ringGeom1 = std::make_unique<QgsLineString>();
 
  159    ringGeom1->setPoints( ring1 );
 
  160    auto ringGeom2 = std::make_unique<QgsLineString>();
 
  161    ringGeom2->setPoints( ring2 );
 
  165    if ( 
QgsCurvePolygon *poly = qgsgeometry_cast<QgsCurvePolygon *>( part ) )
 
  170        poly->removeInteriorRing( vidx.
ring );
 
  171        poly->addInteriorRing( ringGeom1.release() );
 
  172        poly->addInteriorRing( ringGeom2.release() );
 
  182        poly->setExteriorRing( ringGeom1.release() );
 
  185        std::unique_ptr<QgsCurvePolygon> poly2 = qgsgeometry_cast<QgsPolygon *>( part ) ? std::make_unique<QgsPolygon>() : std::make_unique<QgsCurvePolygon>();
 
  186        poly2->setExteriorRing( ringGeom2.release() );
 
  191        for ( 
int n = poly->numInteriorRings(), i = n - 1; i >= 0; --i )
 
  193          if ( !geomEnginePoly1->contains( poly->interiorRing( i ) ) )
 
  195            if ( geomEnginePoly2->contains( poly->interiorRing( i ) ) )
 
  197              poly2->addInteriorRing( qgsgeometry_cast<QgsCurve *>( poly->interiorRing( i )->clone() ) );
 
  200            poly->removeInteriorRing( i );
 
  210            collection->addGeometry( poly2.release() );
 
  219            auto multiPoly = std::make_unique<QgsMultiPolygon>();
 
  220            multiPoly->addGeometry( poly->clone() );
 
  221            multiPoly->addGeometry( poly2.release() );
 
  240    else if ( qgsgeometry_cast<QgsCurve *>( part ) )
 
  246          geomCollection->removeGeometry( vidx.
part );
 
  247          geomCollection->addGeometry( ringGeom1.release() );
 
  248          geomCollection->addGeometry( ringGeom2.release() );
 
  257          std::unique_ptr<QgsMultiCurve> multiCurve = std::make_unique<QgsMultiLineString>();
 
  258          multiCurve->addGeometry( ringGeom1.release() );
 
  259          multiCurve->addGeometry( ringGeom2.release() );
 
  269          geomCollection->removeGeometry( vidx.
part );
 
  270          geomCollection->addGeometry( ringGeom1.release() );
 
 
  299  static const QStringList methods = QStringList()
 
  300                                     << tr( 
"Split feature into a multi-object feature" )
 
  301                                     << tr( 
"Split feature into multiple single-object features" )
 
  302                                     << tr( 
"No action" );
 
 
  308  QList<QgsSingleGeometryCheckError *> errors;
 
  310  for ( 
int iPart = 0, nParts = geom->
partCount(); iPart < nParts; ++iPart )
 
  312    for ( 
int iRing = 0, nRings = geom->
ringCount( iPart ); iRing < nRings; ++iRing )
 
 
  324QList<Qgis::GeometryType> QgsGeometrySelfIntersectionCheck::factoryCompatibleGeometryTypes()
 
  329bool QgsGeometrySelfIntersectionCheck::factoryIsCompatible( 
QgsVectorLayer *layer )
 
  331  return factoryCompatibleGeometryTypes().contains( layer->
geometryType() );
 
  334QString QgsGeometrySelfIntersectionCheck::factoryDescription()
 
  336  return tr( 
"Self intersection" );
 
  344QString QgsGeometrySelfIntersectionCheck::factoryId()
 
  346  return QStringLiteral( 
"QgsGeometrySelfIntersectionCheck" );
 
Abstract base class for all geometries.
 
virtual int ringCount(int part=0) const =0
Returns the number of rings of which this geometry is built.
 
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
 
virtual int partCount() const =0
Returns count of parts contained in the geometry.
 
Curve polygon geometry type.
 
A feature pool is based on a vector layer and caches features.
 
virtual void updateFeature(QgsFeature &feature)=0
Updates a feature in 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...
 
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
 
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
 
const double tolerance
The tolerance to allow for in geometry checks.
 
Wraps a QgsSingleGeometryError into a standard QgsGeometryCheckError.
 
QgsSingleGeometryCheckError * singleError() const
The underlying single error.
 
This represents an error reported by a geometry check.
 
const QgsVertexId & vidx() const
The id of the affected vertex.
 
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.
 
const QgsGeometryCheckContext * mContext
 
@ ChangeRing
This change happens on ring level.
 
@ ChangeFeature
This change happens on feature level.
 
@ ChangePart
This change happens on part level.
 
CheckType
The type of a check.
 
@ FeatureNodeCheck
The check controls individual nodes.
 
@ ChangeChanged
Something has been updated.
 
@ ChangeAdded
Something has been added.
 
@ ChangeRemoved
Something has been removed.
 
static QgsAbstractGeometry * getGeomPart(QgsAbstractGeometry *geom, int partIdx)
 
static int polyLineSize(const QgsAbstractGeometry *geom, int iPart, int iRing, bool *isClosed=nullptr)
Returns the number of points in a polyline, accounting for duplicate start and end point if the polyl...
 
A self intersection check error.
 
const QgsGeometryUtils::SelfIntersection & intersection() const
 
bool handleChanges(const QList< QgsGeometryCheck::Change > &changes) override
Apply a list of changes.
 
bool isEqual(const QgsSingleGeometryCheckError *other) const override
Check if this error is equal to other.
 
void update(const QgsSingleGeometryCheckError *other) override
Update this error with the information from other.
 
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.
 
Q_DECL_DEPRECATED QStringList resolutionMethods() const override
Returns a list of descriptions for available resolutions for errors.
 
static QVector< SelfIntersection > selfIntersections(const QgsAbstractGeometry *geom, int part, int ring, double tolerance)
Find self intersections in a polyline.
 
static bool segmentIntersection(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &q1, const QgsPoint &q2, QgsPoint &intersectionPoint, bool &isIntersection, double tolerance=1e-8, bool acceptImproperIntersection=false)
Compute the intersection between two segments.
 
A geometry is the spatial representation of a feature.
 
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
 
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
 
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlag::SkipEmptyInteriorRings)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
 
Point geometry type, with support for z-dimension and m-values.
 
An error from a QgsSingleGeometryCheck.
 
virtual bool isEqual(const QgsSingleGeometryCheckError *other) const
Check if this error is equal to other.
 
virtual bool handleChanges(const QList< QgsGeometryCheck::Change > &changes)
Apply a list of changes.
 
virtual void update(const QgsSingleGeometryCheckError *other)
Update this error with the information from other.
 
Represents a vector layer which manages a vector based dataset.
 
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
 
QVector< QgsPoint > QgsPointSequence
 
Descripts a change to fix a geometry.
 
Utility class for identifying a unique vertex within a geometry.
 
bool isValid() const
Returns true if the vertex id is valid.