21 #include <QDomDocument> 22 #include <QJsonObject> 31 #include "qgis_core.h" 40 #include <json_fwd.hpp> 125 Q_PROPERTY(
bool isNull READ isNull )
137 NothingHappened = 1000,
274 static QgsGeometry collectGeometry(
const QVector<QgsGeometry> &geometries );
291 static QgsGeometry createWedgeBuffer(
const QgsPoint ¢er,
double azimuth,
double angularWidth,
292 double outerRadius,
double innerRadius = 0 );
299 void fromWkb(
unsigned char *wkb,
int length )
SIP_SKIP;
305 void fromWkb(
const QByteArray &wkb );
325 bool isEmpty()
const;
328 bool isMultipart()
const;
367 FlagAllowSelfTouchingHoles = 1 << 0,
378 bool isGeosValid( QgsGeometry::ValidityFlags flags =
nullptr )
const;
388 bool isSimple()
const;
416 double length()
const;
600 double hausdorffDistance(
const QgsGeometry &geom )
const;
620 double hausdorffDistanceDensify(
const QgsGeometry &geom,
double densifyFraction )
const;
636 QgsPointXY closestVertex(
const QgsPointXY &point,
int &atVertex
SIP_OUT,
int &beforeVertex SIP_OUT,
int &afterVertex SIP_OUT,
double &sqrDist SIP_OUT )
const;
646 double distanceToVertex(
int vertex )
const;
655 double angleAtVertex(
int vertex )
const;
669 void adjacentVertices(
int atVertex,
int &beforeVertex
SIP_OUT,
int &afterVertex SIP_OUT )
const;
683 bool insertVertex(
double x,
double y,
int beforeVertex );
697 bool insertVertex(
const QgsPoint &point,
int beforeVertex );
706 bool moveVertex(
double x,
double y,
int atVertex );
715 bool moveVertex(
const QgsPoint &p,
int atVertex );
728 bool deleteVertex(
int atVertex );
735 QgsPoint vertexAt(
int atVertex )
const;
769 double closestVertexWithContext(
const QgsPointXY &point,
int &atVertex
SIP_OUT )
const;
835 QgsGeometry removeInteriorRings(
double minimumAllowedArea = -1 )
const;
841 OperationResult translate(
double dx,
double dy,
double dz = 0.0,
double dm = 0.0 );
867 OperationResult transform( const QTransform &t,
double zTranslate = 0.0,
double zScale = 1.0,
double mTranslate = 0.0,
double mScale = 1.0 );
909 int makeDifferenceInPlace( const
QgsGeometry &other ) SIP_SKIP;
933 QgsGeometry orientedMinimumBoundingBox(
double &area SIP_OUT,
double &
angle SIP_OUT,
double &width SIP_OUT,
double &height SIP_OUT ) const;
940 QgsGeometry orientedMinimumBoundingBox() const SIP_SKIP;
950 QgsGeometry minimalEnclosingCircle(
QgsPointXY ¢er SIP_OUT,
double &radius SIP_OUT,
unsigned int segments = 36 ) const;
957 QgsGeometry minimalEnclosingCircle(
unsigned int segments = 36 ) const SIP_SKIP;
967 QgsGeometry orthogonalize(
double tolerance = 1.0E-8,
int maxIterations = 1000,
double angleThreshold = 15.0 ) const;
981 QgsGeometry snappedToGrid(
double hSpacing,
double vSpacing,
double dSpacing = 0,
double mSpacing = 0 ) const;
1003 bool removeDuplicateNodes(
double epsilon = 4 * std::numeric_limits<
double>::epsilon(),
bool useZValues = false );
1014 bool intersects( const
QgsRectangle &rectangle ) const;
1025 bool intersects( const
QgsGeometry &geometry ) const;
1036 bool boundingBoxIntersects( const
QgsRectangle &rectangle ) const;
1047 bool boundingBoxIntersects( const
QgsGeometry &geometry ) const;
1058 bool contains( const
QgsGeometry &geometry ) const;
1064 bool disjoint( const
QgsGeometry &geometry ) const;
1070 bool touches( const
QgsGeometry &geometry ) const;
1076 bool overlaps( const
QgsGeometry &geometry ) const;
1089 bool crosses( const
QgsGeometry &geometry ) const;
1124 QgsGeometry buffer(
double distance,
int segments )
const;
1148 QgsGeometry offsetCurve(
double distance,
int segments,
JoinStyle joinStyle,
double miterLimit )
const;
1167 double miterLimit = 2.0 )
const;
1186 QgsGeometry taperedBuffer(
double startWidth,
double endWidth,
int segments )
const;
1202 QgsGeometry variableWidthBufferByM(
int segments )
const;
1210 QgsGeometry extendLine(
double startDistance,
double endDistance )
const;
1224 QgsGeometry densifyByCount(
int extraNodesPerSegment )
const;
1240 QgsGeometry densifyByDistance(
double distance )
const;
1322 QgsGeometry delaunayTriangulation(
double tolerance = 0.0,
bool edgesOnly =
false )
const;
1343 QgsGeometry subdivide(
int maxNodes = 256 )
const;
1373 double lineLocatePoint(
const QgsGeometry &point )
const;
1384 double interpolateAngle(
double distance )
const;
1469 QVector< QgsPointXY > randomPointsInPolygon(
int count,
const std::function<
bool(
const QgsPointXY & ) > &acceptPoint,
unsigned long seed = 0,
QgsFeedback *feedback =
nullptr );
1484 QVector< QgsPointXY > randomPointsInPolygon(
int count,
unsigned long seed = 0,
QgsFeedback *feedback =
nullptr );
1502 const
QgsWkbTypes::GeometryType type = sipCpp->type();
1503 if ( sipCpp->isNull() )
1505 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Cannot generate points inside a null geometry." ).toUtf8().constData() );
1510 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"Cannot generate points inside a %1 geometry. Only Polygon types are permitted." ).arg(
QgsWkbTypes::displayString( sipCpp->wkbType() ) ).toUtf8().constData() );
1515 const sipMappedType *qvector_type = sipFindMappedType(
"QVector<QgsPointXY>" );
1516 sipRes = sipConvertFromNewType(
new QVector< QgsPointXY >( sipCpp->randomPointsInPolygon( a0, a1 ) ), qvector_type, Py_None );
1528 QByteArray asWkb()
const;
1535 QString asWkt(
int precision = 17 )
const;
1538 SIP_PYOBJECT __repr__();
1541 if ( sipCpp->isNull() )
1542 str = QStringLiteral(
"<QgsGeometry: null>" );
1545 QString wkt = sipCpp->asWkt();
1546 if ( wkt.length() > 1000 )
1547 wkt = wkt.left( 1000 ) + QStringLiteral(
"..." );
1548 str = QStringLiteral(
"<QgsGeometry: %1>" ).arg( wkt );
1550 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
1557 QString asJson(
int precision = 17 )
const;
1564 virtual json asJsonObject(
int precision = 17 ) const SIP_SKIP;
1601 if ( sipCpp->isNull() )
1603 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a point." ).toUtf8().constData() );
1608 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"%1 geometry cannot be converted to a point. Only Point types are permitted." ).arg(
QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1613 sipRes = sipConvertFromNewType(
new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
1628 QgsPolylineXY asPolyline()
const;
1641 SIP_PYOBJECT asPolyline() const
SIP_TYPEHINT( QgsPolylineXY );
1644 if ( sipCpp->isNull() )
1646 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a polyline." ).toUtf8().constData() );
1651 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() );
1656 const sipMappedType *qvector_type = sipFindMappedType(
"QVector< QgsPointXY >" );
1657 sipRes = sipConvertFromNewType(
new QgsPolylineXY( sipCpp->asPolyline() ), qvector_type, Py_None );
1688 if ( sipCpp->isNull() )
1690 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a polygon." ).toUtf8().constData() );
1695 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() );
1700 const sipMappedType *qvector_type = sipFindMappedType(
"QVector<QVector<QgsPointXY>>" );
1701 sipRes = sipConvertFromNewType(
new QgsPolygonXY( sipCpp->asPolygon() ), qvector_type, Py_None );
1730 if ( sipCpp->isNull() )
1732 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a multipoint." ).toUtf8().constData() );
1737 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"%1 geometry cannot be converted to a multipoint. Only multipoint types are permitted." ).arg(
QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1742 const sipMappedType *qvector_type = sipFindMappedType(
"QVector< QgsPointXY >" );
1743 sipRes = sipConvertFromNewType(
new QgsPolylineXY( sipCpp->asMultiPoint() ), qvector_type, Py_None );
1774 if ( sipCpp->isNull() )
1776 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a multilinestring." ).toUtf8().constData() );
1781 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() );
1786 const sipMappedType *qvector_type = sipFindMappedType(
"QVector<QVector<QgsPointXY>>" );
1787 sipRes = sipConvertFromNewType(
new QgsMultiPolylineXY( sipCpp->asMultiPolyline() ), qvector_type, Py_None );
1818 if ( sipCpp->isNull() )
1820 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a multipolygon." ).toUtf8().constData() );
1825 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() );
1830 const sipMappedType *qvector_type = sipFindMappedType(
"QVector<QVector<QVector<QgsPointXY>>>" );
1831 sipRes = sipConvertFromNewType(
new QgsMultiPolygonXY( sipCpp->asMultiPolygon() ), qvector_type, Py_None );
1840 QVector<QgsGeometry> asGeometryCollection()
const;
1847 QPointF asQPointF()
const;
1855 QPolygonF asQPolygonF()
const;
1863 bool deleteRing(
int ringNum,
int partNum = 0 );
1870 bool deletePart(
int partNum );
1880 bool convertToMultiType();
1891 bool convertToSingleType();
1914 int avoidIntersections(
const QList<QgsVectorLayer *> &avoidIntersectionsLayers,
1953 : mMessage( QStringLiteral(
"none" ) )
1960 Error(
const QString &m,
const QgsPointXY &p )
1963 , mHasLocation( true ) {}
1968 QString what()
const;
1973 QgsPointXY where()
const;
1978 bool hasWhere()
const;
1981 SIP_PYOBJECT __repr__();
1983 QString str = QStringLiteral(
"<QgsGeometry.Error: %1>" ).arg( sipCpp->what() );
1984 sipRes = PyUnicode_FromString( str.toUtf8().data() );
1990 return other.mMessage == mMessage && other.mHasLocation == mHasLocation && other.mLocation == mLocation;
1995 QgsPointXY mLocation;
1996 bool mHasLocation =
false;
2017 void validateGeometry( QVector<QgsGeometry::Error> &errors
SIP_OUT,
ValidationMethod method = ValidatorQgisInternal, QgsGeometry::ValidityFlags flags =
nullptr )
const;
2024 static QgsGeometry unaryUnion(
const QVector<QgsGeometry> &geometries );
2034 static QgsGeometry polygonize(
const QVector<QgsGeometry> &geometries );
2051 bool requiresConversionToStraightSegments()
const;
2065 void draw( QPainter &p )
const;
2099 QString lastError()
const;
2110 void filterVertices(
const std::function<
bool(
const QgsPoint & ) > &filter )
SIP_SKIP;
2142 static QgsGeometry fromQPolygonF(
const QPolygonF &polygon );
2151 Q_DECL_DEPRECATED
static QgsPolylineXY createPolylineFromQPolygonF(
const QPolygonF &polygon )
SIP_DEPRECATED;
2160 Q_DECL_DEPRECATED
static QgsPolygonXY createPolygonFromQPolygonF(
const QPolygonF &polygon )
SIP_DEPRECATED;
2173 static bool compare(
const QgsPolylineXY &p1,
const QgsPolylineXY &p2,
2174 double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2185 static bool compare(
const QgsPolygonXY &p1,
const QgsPolygonXY &p2,
2186 double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2198 static bool compare(
const QgsMultiPolygonXY &p1,
const QgsMultiPolygonXY &p2,
2199 double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2220 static bool compare( PyObject *obj1, PyObject *obj2,
double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2228 if ( PyList_Check( a0 ) && PyList_Check( a1 ) &&
2229 PyList_GET_SIZE( a0 ) && PyList_GET_SIZE( a1 ) )
2231 PyObject *o0 = PyList_GetItem( a0, 0 );
2232 PyObject *o1 = PyList_GetItem( a1, 0 );
2236 if ( sipCanConvertToType( o0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2237 sipCanConvertToType( o1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2238 sipCanConvertToType( a0, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2239 sipCanConvertToType( a1, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2243 p0 =
reinterpret_cast<QgsPolylineXY *
>( sipConvertToType( a0, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2244 p1 =
reinterpret_cast<QgsPolylineXY *
>( sipConvertToType( a1, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2247 sipReleaseType( p0, sipType_QVector_0100QgsPointXY, state0 );
2248 sipReleaseType( p1, sipType_QVector_0100QgsPointXY, state1 );
2255 else if ( PyList_Check( o0 ) && PyList_Check( o1 ) &&
2256 PyList_GET_SIZE( o0 ) && PyList_GET_SIZE( o1 ) )
2258 PyObject *oo0 = PyList_GetItem( o0, 0 );
2259 PyObject *oo1 = PyList_GetItem( o1, 0 );
2263 if ( sipCanConvertToType( oo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2264 sipCanConvertToType( oo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2265 sipCanConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2266 sipCanConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2270 p0 =
reinterpret_cast<QgsPolygonXY *
>( sipConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2271 p1 =
reinterpret_cast<QgsPolygonXY *
>( sipConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2274 sipReleaseType( p0, sipType_QVector_0600QVector_0100QgsPointXY, state0 );
2275 sipReleaseType( p1, sipType_QVector_0600QVector_0100QgsPointXY, state1 );
2282 else if ( PyList_Check( oo0 ) && PyList_Check( oo1 ) &&
2283 PyList_GET_SIZE( oo0 ) && PyList_GET_SIZE( oo1 ) )
2285 PyObject *ooo0 = PyList_GetItem( oo0, 0 );
2286 PyObject *ooo1 = PyList_GetItem( oo1, 0 );
2290 if ( sipCanConvertToType( ooo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2291 sipCanConvertToType( ooo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2292 sipCanConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2293 sipCanConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2295 QgsMultiPolygonXY *p0;
2296 QgsMultiPolygonXY *p1;
2297 p0 =
reinterpret_cast<QgsMultiPolygonXY *
>( sipConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2298 p1 =
reinterpret_cast<QgsMultiPolygonXY *
>( sipConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2301 sipReleaseType( p0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state0 );
2302 sipReleaseType( p1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state1 );
2335 QgsGeometry smooth(
unsigned int iterations = 1,
double offset = 0.25,
2336 double minimumDistance = -1.0,
double maxAngle = 180.0 )
const;
2348 static void convertPointList(
const QVector<QgsPointXY> &input,
QgsPointSequence &output );
2355 static void convertPointList(
const QgsPointSequence &input, QVector<QgsPointXY> &output );
2358 operator QVariant()
const 2360 return QVariant::fromValue( *
this );
2368 mutable QString mLastError;
2380 void reset( std::unique_ptr< QgsAbstractGeometry > newGeometry );
2382 static void convertToPolyline(
const QgsPointSequence &input, QgsPolylineXY &output );
2383 static void convertPolygon(
const QgsPolygon &input, QgsPolygonXY &output );
2386 QgsGeometry convertToPoint(
bool destMultipart )
const;
2388 QgsGeometry convertToLine(
bool destMultipart )
const;
2390 QgsGeometry convertToPolygon(
bool destMultipart )
const;
2403 std::unique_ptr< QgsLineString > smoothLine(
const QgsLineString &line,
unsigned int iterations = 1,
double offset = 0.25,
2404 double minimumDistance = -1,
double maxAngle = 180.0 )
const;
2417 std::unique_ptr< QgsPolygon > smoothPolygon(
const QgsPolygon &polygon,
unsigned int iterations = 1,
double offset = 0.25,
2418 double minimumDistance = -1,
double maxAngle = 180.0 )
const;
2426 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsGeometry::ValidityFlags )
Geometry engine misses a method implemented or an error occurred in the geometry engine.
QgsPointSequence QgsPolyline
Polyline as represented as a vector of points.
A rectangle specified with double values.
Java-style iterator for traversal of parts of a geometry.
The input ring doesn't have any existing ring to fit into.
Java-style iterator for traversal of vertices of a geometry.
static bool isMultiType(Type type)
Returns true if the WKB type is a multi type.
The source geometry is not multi.
Maximum angle between generating radii (lines from arc center to output vertices) ...
Use GEOS validation methods.
bool operator==(const QgsGeometry::Error &other) const
Java-style iterator for const traversal of parts of a geometry.
Handles storage of information regarding WKB types and their properties.
A class to represent a 2D point.
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item...
A geometry is the spatial representation of a feature.
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
The part_iterator class provides STL-style iterator for const references to geometry parts...
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle...
EndCapStyle
End cap styles for buffers.
#define SIP_TYPEHINT(type)
OperationResult
Success or failure of a geometry operation.
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)
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
Error(const QString &m, const QgsPointXY &p)
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
Base class for feedback objects to be used for cancellation of something running in a worker thread...
CORE_EXPORT QDataStream & operator<<(QDataStream &out, const QgsGeometry &geometry)
Writes the geometry to stream out. QGIS version compatibility is not guaranteed.
Perform transforms between map coordinates and device coordinates.
The selected geometry cannot be found.
No features were selected.
More than one features were selected.
Type
The WKB type describes the number of dimensions a geometry has.
Utility class for identifying a unique vertex within a geometry.
const double DEFAULT_SEGMENT_EPSILON
Default snapping tolerance for segments.
The input ring crosses existing rings (it is not disjoint)
The part_iterator class provides STL-style iterator for geometry parts.
static GeometryType geometryType(Type type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Use internal QgsGeometryValidator method.
Q_DECLARE_METATYPE(QgsMeshTimeSettings)
The input ring is not closed.
Square cap (extends past start/end of line by buffer distance)
Abstract base class for curved geometry type.
Abstract base class for all geometries.
The vertex_iterator class provides STL-style iterator for vertices.
Point geometry type, with support for z-dimension and m-values.
This class offers geometry processing methods.
CORE_EXPORT QDataStream & operator>>(QDataStream &in, QgsGeometry &geometry)
Reads a geometry from stream in into geometry. QGIS version compatibility is not guaranteed.
BufferSide
Side of line to buffer.
QVector< QgsPoint > QgsPointSequence
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
The base geometry on which the operation is done is invalid or empty.
The input geometry (ring, part, split line, etc.) has not the correct geometry type.
Line string geometry type, with support for z-dimension and m-values.
ValidationMethod
Available methods for validating geometries.
ValidityFlag
Validity check flags.
static QString displayString(Type type)
Returns a display string type for a WKB type, e.g., the geometry name used in WKT geometry representa...
The input ring is not valid.
Contains geometry relation and modification algorithms.
Custom exception class for Coordinate Reference System related exceptions.
JoinStyle
Join styles for buffers.
Flat cap (in line with start/end of line)
Represents a vector layer which manages a vector based data sets.
static Type flatType(Type type)
Returns the flat type for a WKB type.
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...
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.