19#include <nlohmann/json.hpp>
36using namespace Qt::StringLiterals;
45 , mBoundingBox(
c.mBoundingBox )
46 , mHasCachedValidity(
c.mHasCachedValidity )
47 , mValidityFailureReason(
c.mValidityFailureReason )
49 int nGeoms =
c.mGeometries.size();
51 for (
int i = 0; i < nGeoms; ++i )
63 int nGeoms =
c.mGeometries.size();
65 for (
int i = 0; i < nGeoms; ++i )
80 auto result = std::make_unique< QgsGeometryCollection >();
82 return result.release();
99 std::unique_ptr<QgsGeometryCollection> result;
103 std::unique_ptr<QgsAbstractGeometry> gridified { geom->snappedToGrid( hSpacing, vSpacing, dSpacing, mSpacing, removeRedundantPoints ) };
109 result->mGeometries.append( gridified.release() );
113 return result.release();
121 if ( geom->removeDuplicateNodes( epsilon, useZValues ) )
146 if (
id.part < 0 || id.part >=
mGeometries.count() )
153 if ( part ==
id.part )
155 int partNumber = geometry->vertexNumberFromVertexId(
QgsVertexId( 0,
id.ring,
id.vertex ) );
156 if ( partNumber == -1 )
158 return number + partNumber;
162 number += geometry->nCoordinates();
176 if ( !mBoundingBox.isNull() )
178 return mBoundingBox.intersects( box3d );
188 if ( geometry->boundingBoxIntersects( box3d ) )
217 if ( !geometry->isEmpty() )
249 index = std::min(
static_cast<int>(
mGeometries.count() ), index );
270 QVector< QgsAbstractGeometry * > results =
mGeometries;
280 geometry->normalize();
288 QVector< QgsAbstractGeometry * >::const_iterator it =
mGeometries.constBegin();
291 int dim = ( *it )->dimension();
302 return u
"GeometryCollection"_s;
309 g->transform( ct, d, transformZ );
318 g->transform( t, zTranslate, zScale, mTranslate, mScale );
325 QVector< QgsAbstractGeometry * >::const_iterator it =
mGeometries.constBegin();
337 QPainterPath partPath = geom->asQPainterPath();
338 if ( !partPath.isEmpty() )
339 p.addPath( partPath );
358 wkbPtr >> nGeometries;
360 QVector<QgsAbstractGeometry *> geometryListBackup =
mGeometries;
363 for (
int i = 0; i < nGeometries; ++i )
376 qDeleteAll( geometryListBackup );
402 u
"GeometryCollection"_s
408 int binarySize =
sizeof( char ) +
sizeof( quint32 ) +
sizeof( quint32 );
413 binarySize += geom->wkbSize( flags );
422 int countNonNull = 0;
435 wkb << static_cast<quint32>(
wkbType() );
436 wkb << static_cast<quint32>( countNonNull );
441 wkb << geom->asWkb( flags );
458 QString childWkt = geom->asWkt( precision );
461 childWkt = childWkt.mid( childWkt.indexOf(
'(' ) );
463 wkt += childWkt +
',';
465 if ( wkt.endsWith(
',' ) )
476 QDomElement elemMultiGeometry = doc.createElementNS( ns, u
"MultiGeometry"_s );
479 QDomElement elemGeometryMember = doc.createElementNS( ns, u
"geometryMember"_s );
480 elemGeometryMember.appendChild( geom->asGml2( doc, precision, ns, axisOrder ) );
481 elemMultiGeometry.appendChild( elemGeometryMember );
483 return elemMultiGeometry;
488 QDomElement elemMultiGeometry = doc.createElementNS( ns, u
"MultiGeometry"_s );
491 QDomElement elemGeometryMember = doc.createElementNS( ns, u
"geometryMember"_s );
492 elemGeometryMember.appendChild( geom->asGml3( doc, precision, ns, axisOrder ) );
493 elemMultiGeometry.appendChild( elemGeometryMember );
495 return elemMultiGeometry;
500 json coordinates( json::array() );
503 coordinates.push_back( geom->asJsonObject( precision ) );
505 return { {
"type",
"GeometryCollection" }, {
"geometries", coordinates } };
511 kml.append(
"<MultiGeometry>"_L1 );
512 const QVector< QgsAbstractGeometry * > &geometries =
mGeometries;
515 kml.append( geometry->asKml( precision ) );
517 kml.append(
"</MultiGeometry>"_L1 );
523 if ( mBoundingBox.isNull() )
552 mHasCachedValidity =
false;
553 mValidityFailureReason.clear();
560 QVector< QgsAbstractGeometry * >::const_iterator geomIt =
mGeometries.constBegin();
561 for ( ; geomIt !=
mGeometries.constEnd(); ++geomIt )
565 QgsCoordinateSequence::const_iterator cIt = geomCoords.constBegin();
566 for ( ; cIt != geomCoords.constEnd(); ++cIt )
568 sequence.push_back( *cIt );
579 QVector< QgsAbstractGeometry * >::const_iterator geomIt =
mGeometries.constBegin();
580 for ( ; geomIt !=
mGeometries.constEnd(); ++geomIt )
582 count += ( *geomIt )->nCoordinates();
621 return mGeometries.at(
id.part )->nextVertex(
id, vertex );
631 bool success =
mGeometries.at( position.
part )->insertVertex( position, vertex );
646 bool success =
mGeometries.at( position.
part )->moveVertex( position, newPos );
684 QMap<int, QSet<QgsVertexId>> partVertices;
690 partVertices[pos.part].insert(
QgsVertexId( 0, pos.ring, pos.vertex ) );
693 QMapIterator<int, QSet<QgsVertexId>> partVerticesIt( partVertices );
694 partVerticesIt.toBack();
695 while ( partVerticesIt.hasPrevious() )
697 partVerticesIt.previous();
698 int part = partVerticesIt.key();
699 QSet<QgsVertexId> partVertices = partVerticesIt.value();
728 if (
id.part < 0 ||
static_cast<size_t>(
id.part ) >=
parts )
741 QVector< QgsAbstractGeometry * >::const_iterator geomIt =
mGeometries.constBegin();
742 for ( ; geomIt !=
mGeometries.constEnd(); ++geomIt )
744 length += ( *geomIt )->length();
752 QVector< QgsAbstractGeometry * >::const_iterator geomIt =
mGeometries.constBegin();
753 for ( ; geomIt !=
mGeometries.constEnd(); ++geomIt )
755 area += ( *geomIt )->area();
763 QVector< QgsAbstractGeometry * >::const_iterator geomIt =
mGeometries.constBegin();
764 for ( ; geomIt !=
mGeometries.constEnd(); ++geomIt )
766 area3D += ( *geomIt )->area3D();
774 QVector< QgsAbstractGeometry * >::const_iterator geomIt =
mGeometries.constBegin();
775 for ( ; geomIt !=
mGeometries.constEnd(); ++geomIt )
794 QString secondWithoutParentheses =
parts.second;
795 secondWithoutParentheses = secondWithoutParentheses.remove(
'(' ).remove(
')' ).simplified().remove(
' ' );
796 if ( (
parts.second.compare(
"EMPTY"_L1, Qt::CaseInsensitive ) == 0 ) || secondWithoutParentheses.isEmpty() )
801 QString defChildWkbType = u
"%1%2%3 "_s.arg( defaultChildWkbType,
is3D() ? u
"Z"_s : QString(),
isMeasure() ? u
"M"_s : QString() );
804 for (
const QString &childWkt : blocks )
808 bool success =
false;
834 hasZ = hasZ || geom->is3D();
835 hasM = hasM || geom->isMeasure();
849 QVector< QgsAbstractGeometry * >::const_iterator it =
mGeometries.constBegin();
852 if ( ( *it )->hasCurvedSegments() )
864 if ( !geomCollection )
870 QVector< QgsAbstractGeometry * >::const_iterator geomIt =
mGeometries.constBegin();
871 for ( ; geomIt !=
mGeometries.constEnd(); ++geomIt )
873 geomCollection->
addGeometry( ( *geomIt )->segmentize( tolerance, toleranceType ) );
875 return geom.release();
937 if (
id.part < 0 || id.part >=
mGeometries.size() )
953 if ( flags == 0 && mHasCachedValidity )
956 error = mValidityFailureReason;
957 return error.isEmpty();
964 mValidityFailureReason = !res ? error : QString();
965 mHasCachedValidity =
true;
979 geom->addZValue( zValue );
994 geom->addMValue( mValue );
1034 geom->filterVertices( filter );
1054 std::unique_ptr< QgsGeometryCollection > res;
1066 res = std::make_unique< QgsMultiPoint >();
1078 res = std::make_unique< QgsMultiLineString >();
1090 res = std::make_unique< QgsMultiPolygon>();
1110 if ( thisPartType == filterSinglePartType )
1112 res->addGeometry( part->clone() );
1116 return res.release();
1131 auto newCollection = std::make_unique<QgsGeometryCollection>();
1135 newCollection->addGeometry( geom->toCurveType() );
1137 return newCollection.release();
1150 auto res = std::make_unique< QgsGeometryCollection >();
1154 res->addGeometry(
mGeometries.at( i )->simplifyByDistance( tolerance ) );
1156 return res.release();
1168 res = geom->transform( transformer, feedback );
1201 if ( !otherCollection )
1210 const int comparison = aGeom->
compareTo( bGeom );
1211 if ( comparison != 0 )
@ AllowSelfTouchingHoles
Indicates that self-touching holes are permitted. OGC validity states that self-touching holes are NO...
QFlags< GeometryValidityFlag > GeometryValidityFlags
Geometry validity flags.
@ RejectOnInvalidSubGeometry
Don't allow geometries with invalid sub-geometries to be created.
WkbType
The WKB type describes the number of dimensions a geometry has.
@ CompoundCurve
CompoundCurve.
@ MultiPolygon
MultiPolygon.
@ MultiLineString
MultiLineString.
@ CircularString
CircularString.
@ GeometryCollection
GeometryCollection.
@ CurvePolygon
CurvePolygon.
@ PolyhedralSurface
PolyhedralSurface.
@ MultiSurface
MultiSurface.
TransformDirection
Indicates the direction (forward or inverse) of a transform.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
virtual double vertexAngle(QgsVertexId vertex) const =0
Returns approximate angle at a vertex.
bool isMeasure() const
Returns true if the geometry contains m values.
QFlags< WkbFlag > WkbFlags
virtual bool hasVertex(QgsVertexId position) const =0
Returns true if the geometry contains a vertex matching the given position.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
AxisOrder
Axis order for GML generation.
QString wktTypeStr() const
Returns the WKT type string of the geometry.
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
virtual bool deleteVertices(const QSet< QgsVertexId > &positions)=0
Deletes vertices within the geometry.
virtual void clearCache() const
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
QgsAbstractGeometry & operator=(const QgsAbstractGeometry &geom)
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
virtual bool isEmpty() const
Returns true if the geometry is empty.
virtual bool boundingBoxIntersects(const QgsRectangle &rectangle) const
Returns true if the bounding box of this geometry intersects with a rectangle.
virtual bool deleteVertex(QgsVertexId position)=0
Deletes a vertex within the geometry.
virtual double segmentLength(QgsVertexId startVertex) const =0
Returns the length of the segment of the geometry which begins at startVertex.
virtual int compareTo(const QgsAbstractGeometry *other) const
Comparator for sorting of geometry.
QgsAbstractGeometry()=default
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry.
virtual bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const =0
Returns next vertex id and coordinates.
static endian_t endian()
Returns whether this machine uses big or little endian.
A 3-dimensional box composed of x, y, z coordinates.
void combineWith(const QgsBox3D &box)
Expands the bbox so that it covers both the original rectangle and the given rectangle.
Qgis::WkbType readHeader() const
readHeader
Base class for feedback objects to be used for cancellation of something running in a worker thread.
bool isCanceled() const
Tells whether the operation has been canceled already.
QgsGeometryCollection * toCurveType() const override
Returns the geometry converted to the more generic curve type.
bool dropMValue() override
Drops any measure values which exist in the geometry.
QString asKml(int precision=17) const override
Returns a KML representation of the geometry.
double perimeter() const override
Returns the planar, 2-dimensional perimeter of the geometry.
QVector< QgsAbstractGeometry * > mGeometries
void draw(QPainter &p) const override
Draws the geometry using the specified QPainter.
json asJsonObject(int precision=17) const override
Returns a json object representation of the geometry.
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
void transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection d=Qgis::TransformDirection::Forward, bool transformZ=false) override
Transforms the geometry using a coordinate transform.
bool fromCollectionWkt(const QString &wkt, const QVector< Qgis::WkbType > &subtypes, const QString &defaultChildWkbType=QString())
Reads a collection from a WKT string.
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
bool deleteVertices(const QSet< QgsVertexId > &positions) override
Deletes vertices within the geometry.
void clear() override
Clears the geometry, ie reset it to a null geometry.
void reserve(int size)
Attempts to allocate memory for at least size geometries.
QPainterPath asQPainterPath() const override
Returns the geometry represented as a QPainterPath.
QgsAbstractGeometry * segmentize(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a geometry without curves.
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
int vertexCount(int part=0, int ring=0) const override
Returns the number of vertices of which this geometry is built.
QString geometryType() const override
Returns a unique string representing the geometry type.
QgsGeometryCollection & operator=(const QgsGeometryCollection &c)
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
void adjacentVertices(QgsVertexId vertex, QgsVertexId &previousVertex, QgsVertexId &nextVertex) const override
Returns the vertices adjacent to a specified vertex within a geometry.
int wkbSize(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
Returns the length of the QByteArray returned by asWkb().
virtual bool insertGeometry(QgsAbstractGeometry *g, int index)
Inserts a geometry before a specified index and takes ownership.
int vertexNumberFromVertexId(QgsVertexId id) const override
Returns the vertex number corresponding to a vertex id.
QgsGeometryCollection * simplifyByDistance(double tolerance) const override
Simplifies the geometry by applying the Douglas Peucker simplification by distance algorithm.
bool isEmpty() const override
Returns true if the geometry is empty.
QgsGeometryCollection()
Constructor for an empty geometry collection.
bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const override
Returns next vertex id and coordinates.
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
bool fromWkb(QgsConstWkbPtr &wkb) override
Sets the geometry from a WKB string.
QgsAbstractGeometry * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
bool isValid(QString &error, Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const override
Checks validity of the geometry, and returns true if the geometry is valid.
double area() const override
Returns the planar, 2-dimensional area of the geometry.
bool removeDuplicateNodes(double epsilon=4 *std::numeric_limits< double >::epsilon(), bool useZValues=false) override
Removes duplicate nodes from the geometry, wherever removing the nodes does not result in a degenerat...
int ringCount(int part=0) const override
Returns the number of rings of which this geometry is built.
bool hasVertex(QgsVertexId position) const override
Returns true if the geometry contains a vertex matching the given position.
void normalize() final
Reorganizes the geometry into a normalized form (or "canonical" form).
QgsAbstractGeometry * childGeometry(int index) const override
Returns pointer to child geometry (for geometries with child geometries - i.e.
void transformVertices(const std::function< QgsPoint(const QgsPoint &) > &transform) override
Transforms the vertices from the geometry in place, applying the transform function to every vertex.
void filterVertices(const std::function< bool(const QgsPoint &) > &filter) override
Filters the vertices from the geometry in place, removing any which do not return true for the filter...
QDomElement asGml2(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const override
Returns a GML2 representation of the geometry.
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
int nCoordinates() const override
Returns the number of nodes contained in the geometry.
QgsGeometryCollection * extractPartsByType(Qgis::WkbType type, bool useFlatType=true) const
Returns a new QgsGeometryCollection subclass which consists of the parts of this collection which mat...
QgsBox3D boundingBox3D() const override
Returns the 3D bounding box for the geometry.
QVector< QgsAbstractGeometry * > takeGeometries()
Removes all geometries from the collection, returning them and their ownership to the caller.
QgsGeometryCollection * clone() const override
Clones the geometry by performing a deep copy.
virtual bool addGeometries(const QVector< QgsAbstractGeometry * > &geometries)
Adds a list of geometries to the collection, transferring ownership to the collection.
int childCount() const override
Returns number of child geometries (for geometries with child geometries) or child points (for geomet...
bool hasCurvedSegments() const override
Returns true if the geometry contains curved segments.
bool insertVertex(QgsVertexId position, const QgsPoint &vertex) override
Inserts a vertex into the geometry.
double length() const override
Returns the planar, 2-dimensional length of the geometry.
int dimension() const override
Returns the inherent dimension of the geometry.
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
QgsPoint vertexAt(QgsVertexId id) const override
Returns the point corresponding to a specified vertex id.
virtual bool removeGeometry(int nr)
Removes a geometry from the collection.
void swapXy() override
Swaps the x and y coordinates from the geometry.
double area3D() const override
Returns the 3-dimensional surface area of the geometry.
bool boundingBoxIntersects(const QgsBox3D &box3d) const override
Returns true if the bounding box of this geometry intersects with a box3d.
QgsGeometryCollection * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
QgsBox3D calculateBoundingBox3D() const override
Calculates the minimal 3D bounding box for the geometry.
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
QByteArray asWkb(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
Returns a WKB representation of the geometry.
int partCount() const override
Returns count of parts contained in the geometry.
~QgsGeometryCollection() override
virtual bool wktOmitChildType() const
Returns whether child type names are omitted from Wkt representations of the collection.
QgsCoordinateSequence coordinateSequence() const override
Retrieves the sequence of geometries, rings and nodes.
int numGeometries() const
Returns the number of geometries within the collection.
QgsGeometryCollection * snappedToGrid(double hSpacing, double vSpacing, double dSpacing=0, double mSpacing=0, bool removeRedundantPoints=false) const override
Makes a new geometry with all the points or vertices snapped to the closest point of the grid.
double segmentLength(QgsVertexId startVertex) const override
Returns the length of the segment of the geometry which begins at startVertex.
QDomElement asGml3(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const override
Returns a GML3 representation of the geometry.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
double vertexAngle(QgsVertexId vertex) const override
Returns approximate angle at a vertex.
int compareToSameClass(const QgsAbstractGeometry *other) const final
Compares to an other geometry of the same class, and returns a integer for sorting of the two geometr...
double closestSegment(const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf=nullptr, double epsilon=4 *std::numeric_limits< double >::epsilon()) const override
Searches for the closest segment of the geometry to a given point.
const QgsAbstractGeometry * simplifiedTypeRef() const override
Returns a reference to the simplest lossless representation of this geometry, e.g.
static std::unique_ptr< QgsAbstractGeometry > geomFromWkb(QgsConstWkbPtr &wkb)
Construct geometry from a WKB string.
static std::unique_ptr< QgsAbstractGeometry > geomFromWkbType(Qgis::WkbType t)
Returns empty geometry from wkb type.
static QStringList wktGetChildBlocks(const QString &wkt, const QString &defaultType=QString())
Parses a WKT string and returns of list of blocks contained in the WKT.
static QPair< Qgis::WkbType, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
static double closestSegmentFromComponents(T &container, ComponentType ctype, const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf, double epsilon)
Does vector analysis using the GEOS library and handles import, export, and exception handling.
Multi line string geometry collection.
Multi point geometry collection.
Multi polygon geometry collection.
Point geometry type, with support for z-dimension and m-values.
static Qgis::WkbType dropM(Qgis::WkbType type)
Drops the m dimension (if present) for a WKB type and returns the new type.
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 linearType(Qgis::WkbType type)
Returns the linear type for a WKB type.
static Qgis::WkbType dropZ(Qgis::WkbType type)
Drops the z dimension (if present) for a WKB type and returns the new type.
static Qgis::WkbType addM(Qgis::WkbType type)
Adds the m dimension to a WKB type and returns the new type.
static Qgis::WkbType addZ(Qgis::WkbType type)
Adds the z dimension to a WKB type and returns the new type.
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static Qgis::WkbType singleType(Qgis::WkbType type)
Returns the single type for a WKB type.
static Q_INVOKABLE bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
Contains geos related utilities and functions.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsRingSequence > QgsCoordinateSequence
Utility class for identifying a unique vertex within a geometry.