21 #include <QDomDocument>
22 #include <QJsonObject>
31 #include "qgis_core.h"
41 #include "json_fwd.hpp"
42 using namespace nlohmann;
127 Q_PROPERTY(
bool isNull READ isNull )
281 static QgsGeometry collectGeometry(
const QVector<QgsGeometry> &geometries );
298 static QgsGeometry createWedgeBuffer(
const QgsPoint ¢er,
double azimuth,
double angularWidth,
299 double outerRadius,
double innerRadius = 0 );
306 void fromWkb(
unsigned char *wkb,
int length )
SIP_SKIP;
312 void fromWkb(
const QByteArray &wkb );
332 bool isEmpty() const;
378 bool isGeosValid(
Qgis::GeometryValidityFlags flags =
Qgis::GeometryValidityFlags() ) const;
388 bool isSimple() const;
403 bool isAxisParallelRectangle(
double maximumDeviation,
bool simpleRectanglesOnly = false ) const;
431 double length() const;
618 double hausdorffDistance(
const QgsGeometry &geom )
const;
638 double hausdorffDistanceDensify(
const QgsGeometry &geom,
double densifyFraction )
const;
702 double distanceToVertex(
int vertex )
const;
711 double angleAtVertex(
int vertex )
const;
725 void adjacentVertices(
int atVertex,
int &beforeVertex
SIP_OUT,
int &afterVertex
SIP_OUT )
const;
739 bool insertVertex(
double x,
double y,
int beforeVertex );
753 bool insertVertex(
const QgsPoint &point,
int beforeVertex );
762 bool moveVertex(
double x,
double y,
int atVertex );
771 bool moveVertex(
const QgsPoint &p,
int atVertex );
784 bool deleteVertex(
int atVertex );
793 bool toggleCircularAtVertex(
int atVertex );
800 QgsPoint vertexAt(
int atVertex )
const;
834 double closestVertexWithContext(
const QgsPointXY &point,
int &atVertex
SIP_OUT )
const;
900 QgsGeometry removeInteriorRings(
double minimumAllowedArea = -1 )
const;
932 Qgis::GeometryOperationResult transform( const QTransform &t,
double zTranslate = 0.0,
double zScale = 1.0,
double mTranslate = 0.0,
double mScale = 1.0 );
940 Qgis::GeometryOperationResult rotate(
double rotation, const
QgsPointXY ¢er );
995 Qgis::GeometryOperationResult reshapeGeometry( const
QgsLineString &reshapeLineString );
1068 QgsGeometry orthogonalize(
double tolerance = 1.0E-8,
int maxIterations = 1000,
double angleThreshold = 15.0 ) const;
1082 QgsGeometry snappedToGrid(
double hSpacing,
double vSpacing,
double dSpacing = 0,
double mSpacing = 0 ) const;
1104 bool removeDuplicateNodes(
double epsilon = 4 * std::numeric_limits<
double>::epsilon(),
bool useZValues = false );
1115 bool intersects( const
QgsRectangle &rectangle ) const;
1131 bool intersects( const
QgsGeometry &geometry ) const;
1142 bool boundingBoxIntersects( const
QgsRectangle &rectangle ) const;
1153 bool boundingBoxIntersects( const
QgsGeometry &geometry ) const;
1170 bool contains( const
QgsGeometry &geometry ) const;
1182 bool disjoint( const
QgsGeometry &geometry ) const;
1194 bool touches( const
QgsGeometry &geometry ) const;
1206 bool overlaps( const
QgsGeometry &geometry ) const;
1230 bool crosses( const
QgsGeometry &geometry ) const;
1239 QgsGeometry buffer(
double distance,
int segments ) const;
1253 QgsGeometry buffer(
double distance,
int segments,
Qgis::EndCapStyle endCapStyle,
Qgis::JoinStyle joinStyle,
double miterLimit ) const;
1263 QgsGeometry offsetCurve(
double distance,
int segments,
Qgis::JoinStyle joinStyle,
double miterLimit ) const;
1280 QgsGeometry singleSidedBuffer(
double distance,
int segments,
Qgis::BufferSide side,
1281 Qgis::JoinStyle joinStyle =
Qgis::JoinStyle::Round,
1282 double miterLimit = 2.0 ) const;
1301 QgsGeometry taperedBuffer(
double startWidth,
double endWidth,
int segments ) const;
1317 QgsGeometry variableWidthBufferByM(
int segments ) const;
1325 QgsGeometry extendLine(
double startDistance,
double endDistance ) const;
1339 QgsGeometry densifyByCount(
int extraNodesPerSegment ) const;
1355 QgsGeometry densifyByDistance(
double distance ) const;
1372 QgsGeometry convertToCurves(
double distanceTolerance = 1e-8,
double angleTolerance = 1e-8 ) const;
1531 QgsGeometry delaunayTriangulation(
double tolerance = 0.0,
bool edgesOnly = false ) const;
1580 QgsGeometry subdivide(
int maxNodes = 256 ) const;
1610 double lineLocatePoint( const
QgsGeometry &point ) const;
1621 double interpolateAngle(
double distance ) const;
1745 const
QgsWkbTypes::GeometryType type = sipCpp->type();
1746 if ( sipCpp->isNull() )
1748 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Cannot generate points inside a null geometry." ).toUtf8().constData() );
1753 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"Cannot generate points inside a %1 geometry. Only Polygon types are permitted." ).arg(
QgsWkbTypes::displayString( sipCpp->wkbType() ) ).toUtf8().constData() );
1758 const sipTypeDef *qvector_type = sipFindType(
"QVector<QgsPointXY>" );
1759 sipRes = sipConvertFromNewType(
new QVector< QgsPointXY >( sipCpp->randomPointsInPolygon( a0, a1 ) ), qvector_type, Py_None );
1774 int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() )
const;
1783 QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() )
const;
1790 QString asWkt(
int precision = 17 )
const;
1793 SIP_PYOBJECT __repr__();
1796 if ( sipCpp->isNull() )
1797 str = QStringLiteral(
"<QgsGeometry: null>" );
1800 QString wkt = sipCpp->asWkt();
1801 if ( wkt.length() > 1000 )
1802 wkt = wkt.left( 1000 ) + QStringLiteral(
"..." );
1803 str = QStringLiteral(
"<QgsGeometry: %1>" ).arg( wkt );
1805 sipRes = PyUnicode_FromString(
str.toUtf8().constData() );
1812 QString asJson(
int precision = 17 )
const;
1886 if ( sipCpp->isNull() )
1888 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a point." ).toUtf8().constData() );
1893 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"%1 geometry cannot be converted to a point. Only Point types are permitted." ).arg(
QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1898 sipRes = sipConvertFromNewType(
new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
1930 if ( sipCpp->isNull() )
1932 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a polyline." ).toUtf8().constData() );
1937 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"%1 geometry cannot be converted to a polyline. Only single line or curve types are permitted." ).arg(
QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1942 const sipTypeDef *qvector_type = sipFindType(
"QVector< QgsPointXY >" );
1943 sipRes = sipConvertFromNewType(
new QgsPolylineXY( sipCpp->asPolyline() ), qvector_type, Py_None );
1975 if ( sipCpp->isNull() )
1977 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a polygon." ).toUtf8().constData() );
1982 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"%1 geometry cannot be converted to a polygon. Only single polygon or curve polygon types are permitted." ).arg(
QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1987 const sipTypeDef *qvector_type = sipFindType(
"QVector<QVector<QgsPointXY>>" );
1988 sipRes = sipConvertFromNewType(
new QgsPolygonXY( sipCpp->asPolygon() ), qvector_type, Py_None );
2018 if ( sipCpp->isNull() )
2020 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a multipoint." ).toUtf8().constData() );
2025 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"%1 geometry cannot be converted to a multipoint. Only multipoint types are permitted." ).arg(
QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
2030 const sipTypeDef *qvector_type = sipFindType(
"QVector< QgsPointXY >" );
2031 sipRes = sipConvertFromNewType(
new QgsPolylineXY( sipCpp->asMultiPoint() ), qvector_type, Py_None );
2063 if ( sipCpp->isNull() )
2065 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a multilinestring." ).toUtf8().constData() );
2070 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"%1 geometry cannot be converted to a multilinestring. Only multi linestring or curves are permitted." ).arg(
QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
2075 const sipTypeDef *qvector_type = sipFindType(
"QVector<QVector<QgsPointXY>>" );
2076 sipRes = sipConvertFromNewType(
new QgsMultiPolylineXY( sipCpp->asMultiPolyline() ), qvector_type, Py_None );
2108 if ( sipCpp->isNull() )
2110 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a multipolygon." ).toUtf8().constData() );
2115 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"%1 geometry cannot be converted to a multipolygon. Only multi polygon or curves are permitted." ).arg(
QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
2120 const sipTypeDef *qvector_type = sipFindType(
"QVector<QVector<QVector<QgsPointXY>>>" );
2121 sipRes = sipConvertFromNewType(
new QgsMultiPolygonXY( sipCpp->asMultiPolygon() ), qvector_type, Py_None );
2130 QVector<QgsGeometry> asGeometryCollection()
const;
2159 bool deleteRing(
int ringNum,
int partNum = 0 );
2166 bool deletePart(
int partNum );
2176 bool convertToMultiType();
2187 bool convertToSingleType();
2198 bool convertGeometryCollectionToSubclass(
QgsWkbTypes::GeometryType geomType );
2210 int avoidIntersections( const QList<
QgsVectorLayer *> &avoidIntersectionsLayers,
2252 : mMessage( QStringLiteral(
"none" ) )
2262 , mHasLocation( true ) {}
2267 QString what()
const;
2277 bool hasWhere()
const;
2280 SIP_PYOBJECT __repr__();
2282 QString
str = QStringLiteral(
"<QgsGeometry.Error: %1>" ).arg( sipCpp->what() );
2283 sipRes = PyUnicode_FromString(
str.toUtf8().data() );
2290 return other.mMessage == mMessage && other.mHasLocation == mHasLocation && other.mLocation == mLocation;
2296 bool mHasLocation =
false;
2307 void validateGeometry( QVector<QgsGeometry::Error> &errors
SIP_OUT,
Qgis::GeometryValidationEngine method = Qgis::GeometryValidationEngine::QgisInternal, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() )
const;
2325 static QgsGeometry unaryUnion(
const QVector<QgsGeometry> &geometries );
2335 static QgsGeometry polygonize(
const QVector<QgsGeometry> &geometries );
2352 bool requiresConversionToStraightSegments()
const;
2366 void draw( QPainter &p )
const;
2411 void filterVertices( const std::function<
bool( const
QgsPoint & ) > &filter )
SIP_SKIP;
2443 static
QgsGeometry fromQPolygonF( const QPolygonF &polygon );
2475 double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2487 double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2500 double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2522 static bool compare( PyObject *obj1, PyObject *obj2,
double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2530 if ( PyList_Check( a0 ) && PyList_Check( a1 ) &&
2531 PyList_GET_SIZE( a0 ) && PyList_GET_SIZE( a1 ) )
2533 PyObject *o0 = PyList_GetItem( a0, 0 );
2534 PyObject *o1 = PyList_GetItem( a1, 0 );
2538 if ( sipCanConvertToType( o0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2539 sipCanConvertToType( o1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2540 sipCanConvertToType( a0, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2541 sipCanConvertToType( a1, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2545 p0 =
reinterpret_cast<QgsPolylineXY *
>( sipConvertToType( a0, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2546 p1 =
reinterpret_cast<QgsPolylineXY *
>( sipConvertToType( a1, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2549 sipReleaseType( p0, sipType_QVector_0100QgsPointXY, state0 );
2550 sipReleaseType( p1, sipType_QVector_0100QgsPointXY, state1 );
2557 else if ( PyList_Check( o0 ) && PyList_Check( o1 ) &&
2558 PyList_GET_SIZE( o0 ) && PyList_GET_SIZE( o1 ) )
2560 PyObject *oo0 = PyList_GetItem( o0, 0 );
2561 PyObject *oo1 = PyList_GetItem( o1, 0 );
2565 if ( sipCanConvertToType( oo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2566 sipCanConvertToType( oo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2567 sipCanConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2568 sipCanConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2572 p0 =
reinterpret_cast<QgsPolygonXY *
>( sipConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2573 p1 =
reinterpret_cast<QgsPolygonXY *
>( sipConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2576 sipReleaseType( p0, sipType_QVector_0600QVector_0100QgsPointXY, state0 );
2577 sipReleaseType( p1, sipType_QVector_0600QVector_0100QgsPointXY, state1 );
2584 else if ( PyList_Check( oo0 ) && PyList_Check( oo1 ) &&
2585 PyList_GET_SIZE( oo0 ) && PyList_GET_SIZE( oo1 ) )
2587 PyObject *ooo0 = PyList_GetItem( oo0, 0 );
2588 PyObject *ooo1 = PyList_GetItem( oo1, 0 );
2592 if ( sipCanConvertToType( ooo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2593 sipCanConvertToType( ooo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2594 sipCanConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2595 sipCanConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2599 p0 =
reinterpret_cast<QgsMultiPolygonXY *
>( sipConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2600 p1 =
reinterpret_cast<QgsMultiPolygonXY *
>( sipConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2603 sipReleaseType( p0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state0 );
2604 sipReleaseType( p1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state1 );
2637 QgsGeometry smooth(
unsigned int iterations = 1,
double offset = 0.25,
2638 double minimumDistance = -1.0,
double maxAngle = 180.0 )
const;
2684 static void convertPointList(
const QVector<QgsPointXY> &input,
QgsPointSequence &output );
2691 static void convertPointList(
const QgsPointSequence &input, QVector<QgsPointXY> &output );
2694 operator QVariant()
const
2696 return QVariant::fromValue( *
this );
2704 mutable QString mLastError;
2716 void reset( std::unique_ptr< QgsAbstractGeometry > newGeometry );
2721 QgsGeometry convertToPoint(
bool destMultipart )
const;
2723 QgsGeometry convertToLine(
bool destMultipart )
const;
2725 QgsGeometry convertToPolygon(
bool destMultipart )
const;
2738 std::unique_ptr< QgsLineString > smoothLine(
const QgsLineString &line,
unsigned int iterations = 1,
double offset = 0.25,
2739 double minimumDistance = -1,
double maxAngle = 180.0 )
const;
2752 std::unique_ptr< QgsPolygon > smoothPolygon(
const QgsPolygon &polygon,
unsigned int iterations = 1,
double offset = 0.25,
2753 double minimumDistance = -1,
double maxAngle = 180.0 )
const;
The Qgis class provides global constants for use throughout the application.
GeometryOperationResult
Success or failure of a geometry operation.
GeometryValidationEngine
Available engines for validating geometries.
TransformDirection
Indicates the direction (forward or inverse) of a transform.
The part_iterator class provides STL-style iterator for const references to geometry parts.
The part_iterator class provides STL-style iterator for geometry parts.
The vertex_iterator class provides STL-style iterator for vertices.
Abstract base class for all geometries.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
@ MaximumAngle
Maximum angle between generating radii (lines from arc center to output vertices)
Custom exception class for Coordinate Reference System related exceptions.
Abstract base class for curved geometry type.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Java-style iterator for const traversal of parts of a geometry.
A geometry engine is a low-level representation of a QgsAbstractGeometry object, optimised for use wi...
Java-style iterator for traversal of parts of a geometry.
Error(const QString &m, const QgsPointXY &p)
bool operator==(const QgsGeometry::Error &other) const
A geometry is the spatial representation of a feature.
QVector< QgsPointXY > randomPointsInPolygon(int count, const std::function< bool(const QgsPointXY &) > &acceptPoint, unsigned long seed=0, QgsFeedback *feedback=nullptr, int maxTriesPerPoint=0) const
Returns a list of count random points generated inside a (multi)polygon geometry (if acceptPoint is s...
QVector< QgsPointXY > randomPointsInPolygon(int count, unsigned long seed=0, QgsFeedback *feedback=nullptr) const
Returns a list of count random points generated inside a (multi)polygon geometry.
static bool compare(const QgsPolylineXY &p1, const QgsPolylineXY &p2, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compares two polylines for equality within a specified tolerance.
This class offers geometry processing methods.
Line string geometry type, with support for z-dimension and m-values.
Perform transforms between map coordinates and device coordinates.
Custom exception class which is raised when an operation is not supported.
A class to represent a 2D point.
Point geometry type, with support for z-dimension and m-values.
A rectangle specified with double values.
Represents a vector layer which manages a vector based data sets.
Java-style iterator for traversal of vertices of a geometry.
Handles storage of information regarding WKB types and their properties.
static GeometryType geometryType(Type type) SIP_HOLDGIL
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
static bool isMultiType(Type type) SIP_HOLDGIL
Returns true if the WKB type is a multi type.
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Type
The WKB type describes the number of dimensions a geometry has.
static QString displayString(Type type) SIP_HOLDGIL
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
CORE_EXPORT QgsMeshVertex centroid(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns the centroid of the face.
std::unique_ptr< GEOSGeometry, GeosDeleter > unique_ptr
Scoped GEOS pointer.
const double DEFAULT_SEGMENT_EPSILON
Default snapping tolerance for segments.
#define SIP_TYPEHINT(type)
QVector< QgsPoint > QgsPointSequence
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item.
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
CORE_EXPORT QDataStream & operator>>(QDataStream &in, QgsGeometry &geometry)
Reads a geometry from stream in into geometry. QGIS version compatibility is not guaranteed.
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
CORE_EXPORT QDataStream & operator<<(QDataStream &out, const QgsGeometry &geometry)
Writes the geometry to stream out. QGIS version compatibility is not guaranteed.
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
QgsPointSequence QgsPolyline
Polyline as represented as a vector of points.
Q_DECLARE_METATYPE(QgsMeshTimeSettings)
Utility class for identifying a unique vertex within a geometry.