27using namespace Qt::StringLiterals;
88 if ( geometryType !=
Qgis::GeometryType::Point || !( flags & QgsOverlayUtils::SanitizeFlag::DontPromotePointGeometryToMultiPoint ) )
99static QString writeFeatureError()
101 return QObject::tr(
"Could not write feature" );
104void QgsOverlayUtils::difference(
108 const QString &sinkName,
113 QgsOverlayUtils::DifferenceOutput outputAttrs,
121 if ( outputAttrs != OutputBA )
134 feedback->
setProgress(
static_cast<double>( i ) * step );
145 attrs.resize( outputAttrs == OutputA ? fieldsCountA : ( fieldsCountA + fieldsCountB ) );
147 if ( totalCount == 0 )
155 if ( outputAttrs == OutputBA )
171 if ( outputAttrs != OutputBA )
174 std::unique_ptr<QgsGeometryEngine> engine;
176 QVector<QgsGeometry> geometriesB;
188 engine->prepareGeometry();
194 if ( !geometriesB.isEmpty() )
206 geom = geom.
difference( geomB, parameters, feedback );
209 if ( !geom.
isNull() && !sanitizeDifferenceResult( geom, geometryType, flags ) )
213 switch ( outputAttrs )
219 for (
int i = 0; i < fieldsCountA; ++i )
220 attrs[i] = attrsA[i];
223 for (
int i = 0; i < fieldsCountA; ++i )
224 attrs[i + fieldsCountB] = attrsA[i];
233 else if ( !sinkName.isEmpty() )
241 else if ( !sinkName.isEmpty() )
246 feedback->
setProgress( count /
static_cast<double>( totalCount ) * 100. );
251void QgsOverlayUtils::intersection(
255 const QString &sinkName,
260 const QList<int> &fieldIndicesA,
261 const QList<int> &fieldIndicesB,
266 const int attrCount = fieldIndicesA.count() + fieldIndicesB.count();
283 feedback->
setProgress(
static_cast<double>( i ) * step );
291 if ( totalCount == 0 )
294 feedback->
setProgressText( QObject::tr(
"Calculating intersection" ) );
314 std::unique_ptr<QgsGeometryEngine> engine;
315 if ( !intersects.isEmpty() )
319 engine->prepareGeometry();
324 for (
int i = 0; i < fieldIndicesA.count(); ++i )
325 outAttributes[i] = attrsA[fieldIndicesA[i]];
335 if ( !engine->intersects( tmpGeom.constGet() ) )
339 if ( !sanitizeIntersectionResult( intGeom, geometryType ) )
343 for (
int i = 0; i < fieldIndicesB.count(); ++i )
344 outAttributes[fieldIndicesA.count() + i] = attrsB[fieldIndicesB[i]];
350 else if ( !sinkName.isEmpty() )
355 feedback->
setProgress( count /
static_cast<double>( totalCount ) * 100. );
359void QgsOverlayUtils::resolveOverlaps(
365 if ( totalCount == 0 )
384 QSet<QgsFeatureId> fids;
391 fids.insert( f.
id() );
394 QHash<QgsFeatureId, QgsGeometry> geometries;
396 QHash<QgsFeatureId, QList<QgsFeatureId>> intersectingIds;
408 std::unique_ptr<QgsGeometryEngine> g1engine;
410 geometries.insert( fid1, g1 );
414 const QList<QgsFeatureId> ids = index.
intersects( bbox );
424 g1engine->prepareGeometry();
428 if ( !g1engine->intersects( g2.
constGet() ) )
432 if ( !sanitizeIntersectionResult( geomIntersection, geometryType ) )
440 while ( fids.contains( newFid ) )
442 fids.insert( newFid );
444 geometries.insert( newFid, geomIntersection );
446 fx.setGeometry( geomIntersection );
452 QList<QgsFeatureId> lst;
453 if ( intersectingIds.contains( fid1 ) )
454 lst << intersectingIds.value( fid1 );
457 if ( intersectingIds.contains( fid2 ) )
458 lst << intersectingIds.value( fid2 );
461 intersectingIds.insert( newFid, lst );
470 geometries.remove( fid1 );
472 if ( sanitizeDifferenceResult( g12, geometryType, flags ) )
474 geometries.insert( fid1, g12 );
477 f1x.setGeometry( g12 );
488 f2old.setGeometry( g2 );
491 geometries.remove( fid2 );
493 if ( sanitizeDifferenceResult( g21, geometryType, flags ) )
495 geometries.insert( fid2, g21 );
498 f2x.setGeometry( g21 );
508 feedback->
setProgress( count /
static_cast<double>( totalCount ) * 100. );
520 QHash<QgsFeatureId, QgsAttributes> attributesHash;
532 for (
auto i = geometries.constBegin(); i != geometries.constEnd(); ++i )
538 outFeature.setGeometry( i.value() );
540 if ( intersectingIds.contains( i.key() ) )
542 const QList<QgsFeatureId> ids = intersectingIds.value( i.key() );
545 outFeature.setAttributes( attributesHash.value(
id ) );
548 else if ( !sinkName.isEmpty() )
554 outFeature.setAttributes( attributesHash.value( i.key() ) );
557 else if ( !sinkName.isEmpty() )
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
@ GeometryCollection
GeometryCollection.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsFeatureRequest & setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the destination crs for feature's geometries.
QgsFeatureRequest & setInvalidGeometryCheck(Qgis::InvalidGeometryCheck check)
Sets invalid geometry checking behavior.
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
An interface for objects which accept features via addFeature(s) methods.
virtual bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags())
Adds a single feature to the sink.
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
An interface for objects which provide features via a getFeatures method.
virtual QgsFields fields() const =0
Returns the fields associated with features in the source.
virtual QgsCoordinateReferenceSystem sourceCrs() const =0
Returns the coordinate reference system for features in the source.
virtual Qgis::WkbType wkbType() const =0
Returns the geometry type for features returned by this source.
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const =0
Returns an iterator for the features in the source.
virtual long long featureCount() const =0
Returns the number of features contained in the source, or -1 if the feature count is unknown.
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.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
bool isCanceled() const
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
Encapsulates parameters under which a geometry operation is performed.
A geometry is the spatial representation of a feature.
QgsGeometry intersection(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr) const
Returns a geometry representing the points shared by this geometry and other.
QString lastError() const
Returns an error string referring to the last error encountered either when this geometry was created...
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries, const QgsGeometryParameters ¶meters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr)
Compute the unary union on a list of geometries.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
bool convertGeometryCollectionToSubclass(Qgis::GeometryType geomType)
Converts geometry collection to a the desired geometry type subclass (multi-point,...
bool convertToMultiType()
Converts single type geometry into multitype geometry e.g.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Qgis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.).
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...
QgsGeometry difference(const QgsGeometry &geometry, const QgsGeometryParameters ¶meters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr) const
Returns a geometry representing the points making up this geometry that do not make up other.
Contains information about the context in which a processing algorithm is executed.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Qgis::InvalidGeometryCheck invalidGeometryCheck() const
Returns the behavior used for checking invalid geometries in input layers.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
void featureAddedToSink(const QString &output)
Reports that a feature was added to the the sink associated with the specified algorithm output.
virtual void setProgressText(const QString &text)
Sets a progress report text string.
A rectangle specified with double values.
A spatial index for QgsFeature objects.
QList< QgsFeatureId > intersects(const QgsRectangle &rectangle) const
Returns a list of features with a bounding box which intersects the specified rectangle.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a feature to the index.
bool deleteFeature(const QgsFeature &feature)
Removes a feature from the index.
static Qgis::GeometryType geometryType(Qgis::WkbType type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
static Qgis::WkbType multiType(Qgis::WkbType type)
Returns the multi type for a WKB type.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
QSet< QgsFeatureId > QgsFeatureIds
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features