28 #include <QPainterPath> 43 auto result = qgis::make_unique< QgsCurvePolygon >();
45 return result.release();
50 return QStringLiteral(
"CurvePolygon" );
167 std::unique_ptr< QgsCurve > currentCurve;
168 for (
int i = 0; i < nRings; ++i )
171 wkbPtr -= 1 +
sizeof( int );
189 currentCurve->fromWkb( wkbPtr );
214 QString defaultChildWkbType = QStringLiteral(
"LineString%1%2" ).arg(
is3D() ? QStringLiteral(
"Z" ) : QString(),
isMeasure() ? QStringLiteral(
"M" ) : QString() );
217 for (
const QString &childWkt : blocks )
259 hasZ = hasZ || curve->is3D();
260 hasM = hasM || curve->isMeasure();
283 int binarySize =
sizeof( char ) +
sizeof( quint32 ) +
sizeof( quint32 );
284 QVector<QByteArray> wkbForRings;
289 binarySize += wkb.length();
294 QByteArray wkb( curve->asWkb() );
295 binarySize += wkb.length();
300 wkbArray.resize( binarySize );
303 wkbPtr << static_cast<quint32>(
wkbType() );
304 wkbPtr << static_cast<quint32>( wkbForRings.count() );
305 for (
const QByteArray &wkb : qgis::as_const( wkbForRings ) )
318 if ( qgsgeometry_cast<QgsLineString *>(
mExteriorRing.get() ) )
321 childWkt = childWkt.mid( childWkt.indexOf(
'(' ) );
323 wkt += childWkt +
',';
327 QString childWkt = curve->asWkt( precision );
328 if ( qgsgeometry_cast<const QgsLineString *>( curve ) )
331 childWkt = childWkt.mid( childWkt.indexOf(
'(' ) );
333 wkt += childWkt +
',';
335 if ( wkt.endsWith(
',' ) )
346 QDomElement elemPolygon = doc.createElementNS( ns, QStringLiteral(
"Polygon" ) );
351 QDomElement elemOuterBoundaryIs = doc.createElementNS( ns, QStringLiteral(
"outerBoundaryIs" ) );
352 std::unique_ptr< QgsLineString > exteriorLineString(
exteriorRing()->curveToLine() );
353 QDomElement outerRing = exteriorLineString->asGml2( doc, precision, ns, axisOrder );
354 outerRing.toElement().setTagName( QStringLiteral(
"LinearRing" ) );
355 elemOuterBoundaryIs.appendChild( outerRing );
356 elemPolygon.appendChild( elemOuterBoundaryIs );
357 std::unique_ptr< QgsLineString > interiorLineString;
360 QDomElement elemInnerBoundaryIs = doc.createElementNS( ns, QStringLiteral(
"innerBoundaryIs" ) );
361 interiorLineString.reset(
interiorRing( i )->curveToLine() );
362 QDomElement innerRing = interiorLineString->asGml2( doc, precision, ns, axisOrder );
363 innerRing.toElement().setTagName( QStringLiteral(
"LinearRing" ) );
364 elemInnerBoundaryIs.appendChild( innerRing );
365 elemPolygon.appendChild( elemInnerBoundaryIs );
372 QDomElement elemCurvePolygon = doc.createElementNS( ns, QStringLiteral(
"Polygon" ) );
375 return elemCurvePolygon;
377 QDomElement elemExterior = doc.createElementNS( ns, QStringLiteral(
"exterior" ) );
379 if ( curveElem.tagName() == QLatin1String(
"LineString" ) )
381 curveElem.setTagName( QStringLiteral(
"LinearRing" ) );
383 elemExterior.appendChild( curveElem );
384 elemCurvePolygon.appendChild( elemExterior );
388 QDomElement elemInterior = doc.createElementNS( ns, QStringLiteral(
"interior" ) );
390 if ( innerRing.tagName() == QLatin1String(
"LineString" ) )
392 innerRing.setTagName( QStringLiteral(
"LinearRing" ) );
394 elemInterior.appendChild( innerRing );
395 elemCurvePolygon.appendChild( elemInterior );
397 return elemCurvePolygon;
403 QString json = QStringLiteral(
"{\"type\": \"Polygon\", \"coordinates\": [" );
407 std::unique_ptr< QgsLineString > exteriorLineString(
exteriorRing()->curveToLine() );
409 exteriorLineString->points( exteriorPts );
412 std::unique_ptr< QgsLineString > interiorLineString;
415 interiorLineString.reset(
interiorRing( i )->curveToLine() );
417 interiorLineString->points( interiorPts );
420 if ( json.endsWith( QLatin1String(
", " ) ) )
425 json += QLatin1String(
"] }" );
436 double totalArea = 0.0;
442 totalArea += std::fabs( area );
448 if ( ring->isRing() )
450 ring->sumUpArea( area );
451 totalArea -= std::fabs( area );
466 perimeter += ring->length();
473 std::unique_ptr< QgsPolygon > polygon(
new QgsPolygon() );
475 return polygon.release();
477 polygon->setExteriorRing(
exteriorRing()->curveToLine() );
478 QVector<QgsCurve *> interiors;
480 interiors.reserve( n );
481 for (
int i = 0; i < n; ++i )
485 polygon->setInteriorRings( interiors );
486 return polygon.release();
503 for (
int i = 0; i < nInteriorRings; ++i )
520 auto exterior = std::unique_ptr<QgsCurve> {
static_cast< QgsCurve *
>(
mExteriorRing->snappedToGrid( hSpacing, vSpacing, dSpacing, mSpacing ) ) };
525 polygon->mExteriorRing = std::move( exterior );
533 QgsCurve *gridifiedInterior =
static_cast< QgsCurve *
>( interior->snappedToGrid( hSpacing, vSpacing, dSpacing, mSpacing ) );
535 if ( !gridifiedInterior )
538 polygon->mInteriorRings.append( gridifiedInterior );
541 return polygon.release();
548 auto cleanRing = [epsilon, useZValues ](
QgsCurve * ring )->
bool 550 if ( ring->numPoints() <= 4 )
553 if ( ring->removeDuplicateNodes( epsilon, useZValues ) )
557 ring->pointAt( 0, startPoint, type );
571 result = result || cleanRing( ring );
578 std::unique_ptr< QgsPolygon > poly(
new QgsPolygon() );
581 return poly.release();
584 poly->setExteriorRing(
mExteriorRing->curveToLine( tolerance, toleranceType ) );
586 QVector<QgsCurve *> rings;
590 rings.push_back( ring->curveToLine( tolerance, toleranceType ) );
592 poly->setInteriorRings( rings );
593 return poly.release();
651 else if ( !ring->
is3D() )
676 for (
int ringIndex =
mInteriorRings.size() - 1; ringIndex >= 0; --ringIndex )
678 if ( minimumAllowedArea < 0 )
684 if ( area < minimumAllowedArea )
694 QVector<QgsCurve *> validRings;
698 if ( !curve->isRing() )
716 std::unique_ptr< QgsCurve > flipped(
mExteriorRing->reversed() );
720 QVector<QgsCurve *> validRings;
727 validRings << flipped;
754 ring->addToPainterPath( path );
769 curve->transform( ct, d, transformZ );
778 mExteriorRing->transform( t, zTranslate, zScale, mTranslate, mScale );
783 curve->transform( t, zTranslate, zScale, mTranslate, mScale );
802 ring->points( sequence.back().back() );
819 count += ring->nCoordinates();
830 if (
id.ring < 0 || id.ring >=
ringCount() )
845 if (
id.ring == i + 1 )
848 if ( partNumber == -1 )
850 return number + partNumber;
874 QVector<QgsCurve *> segmentList;
926 if ( vertex.
vertex == 0 && n < 3 )
930 else if ( vertex.
vertex == 0 )
938 if ( vertex.
vertex == n - 1 && n < 3 )
942 else if ( vertex.
vertex == n - 1 )
961 if ( vertex.
ring == 0 )
989 else if ( vId.
vertex == n )
1006 bool success = ring->
moveVertex( vId, newPos );
1012 else if ( vId.
vertex == n - 1 )
1031 if ( vId.
ring == 0 )
1055 else if ( vId.
vertex == n - 1 )
1071 if ( ring->hasCurvedSegments() )
1081 return toPolygon( tolerance, toleranceType );
1138 curve->addZValue( zValue );
1155 curve->addMValue( mValue );
1171 curve->dropZValue();
1187 curve->dropMValue();
1216 curve->filterVertices( filter );
QByteArray asWkb() const override
Returns a WKB representation of the geometry.
const QgsCurve * exteriorRing() const
Returns the curve polygon's exterior ring.
virtual QgsCurve * reversed() const =0
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
virtual void setExteriorRing(QgsCurve *ring)
Sets the exterior ring of the polygon.
void ringAdjacentVertices(const QgsCurve *curve, QgsVertexId vertex, QgsVertexId &previousVertex, QgsVertexId &nextVertex)
bool dropMValue() override
Drops any measure values which exist in the geometry.
static QString pointsToJSON(const QgsPointSequence &points, int precision)
Returns a geoJSON coordinates string.
void draw(QPainter &p) const override
Draws the geometry using the specified QPainter.
A rectangle specified with double values.
bool operator==(const QgsAbstractGeometry &other) const override
QgsCurvePolygon & operator=(const QgsCurvePolygon &p)
virtual bool deleteVertex(QgsVertexId position)=0
Deletes a vertex within the geometry.
double segmentLength(QgsVertexId startVertex) const override
Returns the length of the segment of the geometry which begins at startVertex.
QgsAbstractGeometry & operator=(const QgsAbstractGeometry &geom)
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
static QPair< QgsWkbTypes::Type, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
virtual bool insertVertex(QgsVertexId position, const QgsPoint &vertex)=0
Inserts a vertex into the geometry.
bool hasCurvedSegments() const override
Returns true if the geometry contains curved segments.
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
virtual void addInteriorRing(QgsCurve *ring)
Adds an interior ring to the geometry (takes ownership)
QVector< QgsRingSequence > QgsCoordinateSequence
void swapXy() override
Swaps the x and y coordinates from the geometry.
bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const override
Returns next vertex id and coordinates.
QgsCurvePolygon * toCurveType() const override
Returns the geometry converted to the more generic curve type.
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the geometry.
virtual double vertexAngle(QgsVertexId vertex) const =0
Returns approximate angle at a vertex.
QgsAbstractGeometry * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
Curve polygon geometry type.
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle...
void clear() override
Clears the geometry, ie reset it to a null geometry.
void forceRHR()
Forces the geometry to respect the Right-Hand-Rule, in which the area that is bounded by the polygon ...
static endian_t endian()
Returns whether this machine uses big or little endian.
double area() const override
Returns the area of the geometry.
void setInteriorRings(const QVector< QgsCurve * > &rings)
Sets all interior rings (takes ownership)
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
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 Type dropM(Type type)
Drops the m dimension (if present) for a WKB type and returns the new type.
QgsWkbTypes::Type mWkbType
int numInteriorRings() const
Returns the number of interior rings contained with the curve polygon.
bool removeInteriorRing(int ringIndex)
Removes an interior ring from the polygon.
QVector< QgsCurve * > mInteriorRings
bool fromWkb(QgsConstWkbPtr &wkb) override
Sets the geometry from a WKB string.
void removeInvalidRings()
Removes any interior rings which are not valid from the polygon.
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) override SIP_THROW(QgsCsException)
Transforms the geometry using a coordinate transform.
~QgsCurvePolygon() override
int vertexNumberFromVertexId(QgsVertexId id) const override
Returns the vertex number corresponding to a vertex id.
Type
The WKB type describes the number of dimensions a geometry has.
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...
int childCount() const override
Returns number of child geometries (for geometries with child geometries) or child points (for geomet...
int nCoordinates() const override
Returns the number of nodes contained in the geometry.
bool isMeasure() const
Returns true if the geometry contains m values.
virtual double segmentLength(QgsVertexId startVertex) const =0
Returns the length of the segment of the geometry which begins at startVertex.
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type.
QString asJson(int precision=17) const override
Returns a GeoJSON representation of the geometry.
QString wktTypeStr() const
Returns the WKT type string of the geometry.
Utility class for identifying a unique vertex within a geometry.
int ringCount(int part=0) const override
Returns the number of rings of which this geometry is built.
int dimension() const override
Returns the inherent dimension of the geometry.
QgsCurvePolygon * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership...
QgsRectangle calculateBoundingBox() const override
Default calculator for the minimal bounding box for the geometry.
bool insertVertex(QgsVertexId position, const QgsPoint &vertex) override
Inserts a vertex into the geometry.
QString geometryType() const override
Returns a unique string representing the geometry type.
QgsCurvePolygon * snappedToGrid(double hSpacing, double vSpacing, double dSpacing=0, double mSpacing=0) const override
Makes a new geometry with all the points or vertices snapped to the closest point of the grid...
QgsPoint vertexAt(QgsVertexId id) const override
Returns the point corresponding to a specified vertex id.
static GeometryType geometryType(Type type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, QgsWkbTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type.
T qgsgeometry_cast(const QgsAbstractGeometry *geom)
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
Multi curve geometry collection.
double perimeter() const override
Returns the perimeter of the geometry.
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
Abstract base class for curved geometry type.
QgsAbstractGeometry * childGeometry(int index) const override
Returns pointer to child geometry (for geometries with child geometries - i.e.
Abstract base class for all geometries.
QgsCoordinateSequence coordinateSequence() const override
Retrieves the sequence of geometries, rings and nodes.
QgsPoint vertexAt(QgsVertexId id) const override
Returns the point corresponding to a specified vertex id.
Counter-clockwise orientation.
QgsWkbTypes::Type readHeader() const
readHeader
Point geometry type, with support for z-dimension and m-values.
AxisOrder
Axis order for GML generation.
bool operator!=(const QgsAbstractGeometry &other) const override
double vertexAngle(QgsVertexId vertex) const override
Returns approximate rotation angle for a vertex.
int partCount() const override
Returns count of parts contained in the geometry.
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
QVector< QgsPoint > QgsPointSequence
void adjacentVertices(QgsVertexId vertex, QgsVertexId &previousVertex, QgsVertexId &nextVertex) const override
Returns the vertices adjacent to a specified vertex within a geometry.
QVector< QgsPointSequence > QgsRingSequence
static Type dropZ(Type type)
Drops the z dimension (if present) for a WKB type and returns the new type.
virtual QgsPolygon * toPolygon(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a new polygon geometry corresponding to a segmentized approximation of the curve...
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
virtual bool moveVertex(QgsVertexId position, const QgsPoint &newPos)=0
Moves a vertex within the geometry.
QgsCurve * clone() const override=0
Clones the geometry by performing a deep copy.
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
Line string geometry type, with support for z-dimension and m-values.
const QgsCurve * interiorRing(int i) const
Retrieves an interior ring from the curve polygon.
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
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...
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const override
Returns next vertex id and coordinates.
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry.
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.
QgsAbstractGeometry * segmentize(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a geometry without curves.
static bool hasM(Type type)
Tests whether a WKB type contains m values.
Compound curve geometry type.
Circular string geometry type.
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 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...
QgsCurvePolygon * clone() const override
Clones the geometry by performing a deep copy.
virtual bool dropMValue()=0
Drops any measure values which exist in the geometry.
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.
int vertexCount(int part=0, int ring=0) const override
Returns the number of vertices of which this geometry is built.
std::unique_ptr< QgsCurve > mExteriorRing
QgsPolygon * surfaceToPolygon() const override
Gets a polygon representation of this surface.
static Type flatType(Type type)
Returns the flat type for a WKB type.
void removeInteriorRings(double minimumAllowedArea=-1)
Removes the interior rings from the polygon.
bool isEmpty() const override
Returns true if the geometry is empty.
virtual int numPoints() const =0
Returns the number of points in the curve.
double ANALYSIS_EXPORT leftOf(const QgsPoint &thepoint, const QgsPoint *p1, const QgsPoint *p2)
Returns whether 'thepoint' is left or right of the line from 'p1' to 'p2'. Negativ values mean left a...
virtual bool dropZValue()=0
Drops any z-dimensions which exist in the geometry.
static double closestSegmentFromComponents(T &container, ComponentType ctype, const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf, double epsilon)
virtual QDomElement asGml3(QDomDocument &doc, int precision=17, const QString &ns="gml", AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const =0
Returns a GML3 representation of the geometry.