181 Q_PROPERTY(
bool isNull READ isNull )
182 Q_PROPERTY(
Qgis::GeometryType type READ type )
260 Q_INVOKABLE static
QgsGeometry fromWkt( const QString &wkt );
347 static QgsGeometry collectGeometry(
const QVector<QgsGeometry> &geometries );
364 static QgsGeometry createWedgeBuffer(
const QgsPoint ¢er,
double azimuth,
double angularWidth,
365 double outerRadius,
double innerRadius = 0 );
380 static QgsGeometry createWedgeBufferFromAngles(
const QgsPoint ¢er,
double startAngle,
double endAngle,
381 double outerRadius,
double innerRadius = 0 );
388 void fromWkb(
unsigned char *wkb,
int length )
SIP_SKIP;
393 void fromWkb(
const QByteArray &wkb );
456 bool isGeosValid(
Qgis::GeometryValidityFlags flags =
Qgis::GeometryValidityFlags() ) const;
465 bool isSimple() const;
480 bool isAxisParallelRectangle(
double maximumDeviation,
bool simpleRectanglesOnly = false ) const;
508 double length() const;
691 double hausdorffDistance(
const QgsGeometry &geom )
const;
710 double hausdorffDistanceDensify(
const QgsGeometry &geom,
double densifyFraction )
const;
773 double distanceToVertex(
int vertex )
const;
781 double angleAtVertex(
int vertex )
const;
795 void adjacentVertices(
int atVertex,
int &beforeVertex
SIP_OUT,
int &afterVertex
SIP_OUT )
const;
809 bool insertVertex(
double x,
double y,
int beforeVertex );
823 bool insertVertex(
const QgsPoint &point,
int beforeVertex );
832 bool addTopologicalPoint(
const QgsPoint &point,
double snappingTolerance = 1e-8,
double segmentSearchEpsilon = 1e-12 );
841 bool moveVertex(
double x,
double y,
int atVertex );
850 bool moveVertex(
const QgsPoint &p,
int atVertex );
863 bool deleteVertex(
int atVertex );
872 bool toggleCircularAtVertex(
int atVertex );
879 QgsPoint vertexAt(
int atVertex )
const;
911 double closestVertexWithContext(
const QgsPointXY &point,
int &atVertex
SIP_OUT )
const;
1006 QgsGeometry removeInteriorRings(
double minimumAllowedArea = -1 )
const;
1038 Qgis::GeometryOperationResult transform( const QTransform &t,
double zTranslate = 0.0,
double zScale = 1.0,
double mTranslate = 0.0,
double mScale = 1.0 );
1046 Qgis::GeometryOperationResult rotate(
double rotation, const
QgsPointXY ¢er );
1058 Q_DECL_DEPRECATED
Qgis::GeometryOperationResult splitGeometry( const QVector<
QgsPointXY> &splitLine, QVector<
QgsGeometry> &newGeometries,
bool topological, QVector<
QgsPointXY> &topologyTestPoints,
bool splitFeature = true )
SIP_SKIP;
1115 if ( PyList_Check( a0 ) && PyList_GET_SIZE( a0 ) )
1117 PyObject *p0 = PyList_GetItem( a0, 0 );
1118 if ( sipCanConvertToType( p0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
1119 sipCanConvertToType( a0, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) )
1121 QVector<QgsGeometry> newGeometries;
1122 QVector<QgsPointXY> topologyTestPoints;
1124 QVector<QgsPointXY> *splitLine =
reinterpret_cast<QVector<QgsPointXY> *
>( sipConvertToType( a0, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
1129 PyObject *o0 = sipConvertFromEnum(
static_cast<int>( result ), sipType_Qgis_GeometryOperationResult );
1130 PyObject *o1 = sipConvertFromType( &newGeometries, sipType_QVector_0100QgsGeometry, Py_None );
1131 PyObject *o2 = sipConvertFromType( &topologyTestPoints, sipType_QVector_0100QgsPointXY, Py_None );
1133 sipRes = PyTuple_New( 3 );
1134 PyTuple_SET_ITEM( sipRes, 0, o0 );
1135 PyTuple_SET_ITEM( sipRes, 1, o1 );
1136 PyTuple_SET_ITEM( sipRes, 2, o2 );
1138 sipReleaseType( splitLine, sipType_QVector_0100QgsPointXY, state );
1141 else if ( sipCanConvertToType( p0, sipType_QgsPoint, SIP_NOT_NONE ) &&
1142 sipCanConvertToType( a0, sipType_QVector_0100QgsPoint, SIP_NOT_NONE ) )
1144 QVector<QgsGeometry> newGeometries;
1145 QVector<QgsPoint> topologyTestPoints;
1147 QVector<QgsPoint> *splitLine =
reinterpret_cast<QVector<QgsPoint> *
>( sipConvertToType( a0, sipType_QVector_0100QgsPoint, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
1152 PyObject *o0 = sipConvertFromEnum(
static_cast<int>( result ), sipType_Qgis_GeometryOperationResult );
1153 PyObject *o1 = sipConvertFromType( &newGeometries, sipType_QVector_0100QgsGeometry, Py_None );
1154 PyObject *o2 = sipConvertFromType( &topologyTestPoints, sipType_QVector_0100QgsPoint, Py_None );
1156 sipRes = PyTuple_New( 3 );
1157 PyTuple_SET_ITEM( sipRes, 0, o0 );
1158 PyTuple_SET_ITEM( sipRes, 1, o1 );
1159 PyTuple_SET_ITEM( sipRes, 2, o2 );
1161 sipReleaseType( splitLine, sipType_QVector_0100QgsPoint, state );
1166 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"Could not convert first argument to a list of QgsPoint or QgsPointXY." ).toUtf8().constData() );
1172 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"First argument is not a list of points or is empty." ).toUtf8().constData() );
1272 QgsGeometry orthogonalize(
double tolerance = 1.0E-8,
int maxIterations = 1000,
double angleThreshold = 15.0 ) const;
1286 QgsGeometry triangularWaves(
double wavelength,
double amplitude,
bool strictWavelength = false ) const;
1306 QgsGeometry triangularWavesRandomized(
double minimumWavelength,
double maximumWavelength,
double minimumAmplitude,
double maximumAmplitude,
unsigned long seed = 0 ) const;
1320 QgsGeometry squareWaves(
double wavelength,
double amplitude,
bool strictWavelength = false ) const;
1340 QgsGeometry squareWavesRandomized(
double minimumWavelength,
double maximumWavelength,
double minimumAmplitude,
double maximumAmplitude,
unsigned long seed = 0 ) const;
1354 QgsGeometry roundWaves(
double wavelength,
double amplitude,
bool strictWavelength = false ) const;
1374 QgsGeometry roundWavesRandomized(
double minimumWavelength,
double maximumWavelength,
double minimumAmplitude,
double maximumAmplitude,
unsigned long seed = 0 ) const;
1389 QgsGeometry applyDashPattern( const QVector<
double > &pattern,
1390 Qgis::DashPatternLineEndingRule startRule =
Qgis::DashPatternLineEndingRule::NoRule,
1391 Qgis::DashPatternLineEndingRule endRule =
Qgis::DashPatternLineEndingRule::NoRule,
1392 Qgis::DashPatternSizeAdjustment adjustment =
Qgis::DashPatternSizeAdjustment::ScaleBothDashAndGap,
1393 double patternOffset = 0 ) const;
1406 QgsGeometry snappedToGrid(
double hSpacing,
double vSpacing,
double dSpacing = 0,
double mSpacing = 0 ) const;
1427 bool removeDuplicateNodes(
double epsilon = 4 * std::numeric_limits<
double>::epsilon(),
bool useZValues = false );
1438 bool intersects( const
QgsRectangle &rectangle ) const;
1454 bool intersects( const
QgsGeometry &geometry ) const;
1464 bool boundingBoxIntersects( const
QgsRectangle &rectangle ) const;
1474 bool boundingBoxIntersects( const
QgsGeometry &geometry ) const;
1486 bool contains(
double x,
double y ) const;
1497 bool contains( const
QgsGeometry &geometry ) const;
1508 bool disjoint( const
QgsGeometry &geometry ) const;
1519 bool touches( const
QgsGeometry &geometry ) const;
1530 bool overlaps( const
QgsGeometry &geometry ) const;
1552 bool crosses( const
QgsGeometry &geometry ) const;
1561 QgsGeometry buffer(
double distance,
int segments ) const;
1574 QgsGeometry buffer(
double distance,
int segments,
Qgis::EndCapStyle endCapStyle,
Qgis::JoinStyle joinStyle,
double miterLimit ) const;
1583 QgsGeometry offsetCurve(
double distance,
int segments,
Qgis::JoinStyle joinStyle,
double miterLimit ) const;
1599 QgsGeometry singleSidedBuffer(
double distance,
int segments,
Qgis::BufferSide side,
1600 Qgis::JoinStyle joinStyle =
Qgis::JoinStyle::Round,
1601 double miterLimit = 2.0 ) const;
1620 QgsGeometry taperedBuffer(
double startWidth,
double endWidth,
int segments ) const;
1636 QgsGeometry variableWidthBufferByM(
int segments ) const;
1643 QgsGeometry extendLine(
double startDistance,
double endDistance ) const;
1656 QgsGeometry densifyByCount(
int extraNodesPerSegment ) const;
1671 QgsGeometry densifyByDistance(
double distance ) const;
1688 QgsGeometry convertToCurves(
double distanceTolerance = 1e-8,
double angleTolerance = 1e-8 ) const;
1861 QgsGeometry delaunayTriangulation(
double tolerance = 0.0,
bool edgesOnly = false ) const;
2008 double lineLocatePoint( const
QgsGeometry &point ) const;
2018 double interpolateAngle(
double distance ) const;
2155 const
Qgis::GeometryType type = sipCpp->type();
2156 if ( sipCpp->isNull() )
2158 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Cannot generate points inside a null geometry." ).toUtf8().constData() );
2163 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"Cannot generate points inside a %1 geometry. Only Polygon types are permitted." ).arg(
QgsWkbTypes::displayString( sipCpp->wkbType() ) ).toUtf8().constData() );
2168 const sipTypeDef *qvector_type = sipFindType(
"QVector<QgsPointXY>" );
2169 sipRes = sipConvertFromNewType(
new QVector< QgsPointXY >( sipCpp->randomPointsInPolygon( a0, a1 ) ), qvector_type, Py_None );
2199 Q_INVOKABLE QString asWkt(
int precision = 17 )
const;
2202 SIP_PYOBJECT __repr__();
2205 if ( sipCpp->isNull() )
2206 str = QStringLiteral(
"<QgsGeometry: null>" );
2209 QString wkt = sipCpp->asWkt();
2210 if ( wkt.length() > 1000 )
2211 wkt = wkt.left( 1000 ) + QStringLiteral(
"..." );
2212 str = QStringLiteral(
"<QgsGeometry: %1>" ).arg( wkt );
2214 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
2221 QString asJson(
int precision = 17 )
const;
2260 QVector<
QgsGeometry > coerceToType(
Qgis::WkbType type,
double defaultZ = 0,
double defaultM = 0,
bool avoidDuplicates = true ) const;
2273 QgsGeometry convertToType(
Qgis::GeometryType destType,
bool destMultipart = false ) const;
2302 if ( sipCpp->isNull() )
2304 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a point." ).toUtf8().constData() );
2312 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"%1 geometry cannot be converted to a point. Only Point types are permitted." ).arg(
QgsWkbTypes::displayString( geom->
wkbType() ) ).toUtf8().constData() );
2317 sipRes = sipConvertFromNewType(
new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
2349 const
Qgis::WkbType type = sipCpp->wkbType();
2350 if ( sipCpp->isNull() )
2352 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a polyline." ).toUtf8().constData() );
2357 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() );
2362 const sipTypeDef *qvector_type = sipFindType(
"QVector< QgsPointXY >" );
2363 sipRes = sipConvertFromNewType(
new QgsPolylineXY( sipCpp->asPolyline() ), qvector_type, Py_None );
2394 const
Qgis::WkbType type = sipCpp->wkbType();
2395 if ( sipCpp->isNull() )
2397 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a polygon." ).toUtf8().constData() );
2402 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() );
2407 const sipTypeDef *qvector_type = sipFindType(
"QVector<QVector<QgsPointXY>>" );
2408 sipRes = sipConvertFromNewType(
new QgsPolygonXY( sipCpp->asPolygon() ), qvector_type, Py_None );
2437 const
Qgis::WkbType type = sipCpp->wkbType();
2438 if ( sipCpp->isNull() )
2440 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a multipoint." ).toUtf8().constData() );
2445 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"%1 geometry cannot be converted to a multipoint. Only multipoint types are permitted." ).arg(
QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
2450 const sipTypeDef *qvector_type = sipFindType(
"QVector< QgsPointXY >" );
2451 sipRes = sipConvertFromNewType(
new QgsPolylineXY( sipCpp->asMultiPoint() ), qvector_type, Py_None );
2482 const
Qgis::WkbType type = sipCpp->wkbType();
2483 if ( sipCpp->isNull() )
2485 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a multilinestring." ).toUtf8().constData() );
2490 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() );
2495 const sipTypeDef *qvector_type = sipFindType(
"QVector<QVector<QgsPointXY>>" );
2496 sipRes = sipConvertFromNewType(
new QgsMultiPolylineXY( sipCpp->asMultiPolyline() ), qvector_type, Py_None );
2527 const
Qgis::WkbType type = sipCpp->wkbType();
2528 if ( sipCpp->isNull() )
2530 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a multipolygon." ).toUtf8().constData() );
2535 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() );
2540 const sipTypeDef *qvector_type = sipFindType(
"QVector<QVector<QVector<QgsPointXY>>>" );
2541 sipRes = sipConvertFromNewType(
new QgsMultiPolygonXY( sipCpp->asMultiPolygon() ), qvector_type, Py_None );
2549 QVector<QgsGeometry> asGeometryCollection()
const;
2575 bool deleteRing(
int ringNum,
int partNum = 0 );
2581 bool deletePart(
int partNum );
2591 bool convertToMultiType();
2608 bool convertToCurvedMultiType();
2619 bool convertToSingleType();
2630 bool convertGeometryCollectionToSubclass(
Qgis::GeometryType geomType );
2643 Q_DECL_DEPRECATED
int avoidIntersections( const QList<
QgsVectorLayer *> &avoidIntersectionsLayers,
2657 Qgis::GeometryOperationResult avoidIntersectionsV2( const QList<
QgsVectorLayer *> &avoidIntersectionsLayers,
2691 Qgis::AngularDirection polygonOrientation() const;
2772 : mMessage( QStringLiteral(
"none" ) )
2782 , mHasLocation( true ) {}
2787 QString what()
const;
2797 bool hasWhere()
const;
2800 SIP_PYOBJECT __repr__();
2802 QString str = QStringLiteral(
"<QgsGeometry.Error: %1>" ).arg( sipCpp->what() );
2803 sipRes = PyUnicode_FromString( str.toUtf8().data() );
2810 return other.mMessage == mMessage && other.mHasLocation == mHasLocation && other.mLocation == mLocation;
2816 bool mHasLocation =
false;
2856 static QgsGeometry polygonize(
const QVector<QgsGeometry> &geometries );
2871 bool requiresConversionToStraightSegments()
const;
2883 void draw( QPainter &p )
const;
2925 void filterVertices( const std::function<
bool( const
QgsPoint & ) > &filter )
SIP_SKIP;
2955 static
QgsGeometry fromQPolygonF( const QPolygonF &polygon );
2986 double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2997 double epsilon = 4 * std::numeric_limits<double>::epsilon() );
3009 double epsilon = 4 * std::numeric_limits<double>::epsilon() );
3030 static bool compare( PyObject *obj1, PyObject *obj2,
double epsilon = 4 * std::numeric_limits<double>::epsilon() );
3038 if ( PyList_Check( a0 ) && PyList_Check( a1 ) &&
3039 PyList_GET_SIZE( a0 ) && PyList_GET_SIZE( a1 ) )
3041 PyObject *o0 = PyList_GetItem( a0, 0 );
3042 PyObject *o1 = PyList_GetItem( a1, 0 );
3046 if ( sipCanConvertToType( o0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
3047 sipCanConvertToType( o1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
3048 sipCanConvertToType( a0, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
3049 sipCanConvertToType( a1, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) )
3053 p0 =
reinterpret_cast<QgsPolylineXY *
>( sipConvertToType( a0, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
3054 p1 =
reinterpret_cast<QgsPolylineXY *
>( sipConvertToType( a1, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
3059 sipReleaseType( p0, sipType_QVector_0100QgsPointXY, state0 );
3060 sipReleaseType( p1, sipType_QVector_0100QgsPointXY, state1 );
3062 else if ( PyList_Check( o0 ) && PyList_Check( o1 ) &&
3063 PyList_GET_SIZE( o0 ) && PyList_GET_SIZE( o1 ) )
3065 PyObject *oo0 = PyList_GetItem( o0, 0 );
3066 PyObject *oo1 = PyList_GetItem( o1, 0 );
3070 if ( sipCanConvertToType( oo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
3071 sipCanConvertToType( oo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
3072 sipCanConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
3073 sipCanConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
3077 p0 =
reinterpret_cast<QgsPolygonXY *
>( sipConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
3078 p1 =
reinterpret_cast<QgsPolygonXY *
>( sipConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
3083 sipReleaseType( p0, sipType_QVector_0600QVector_0100QgsPointXY, state0 );
3084 sipReleaseType( p1, sipType_QVector_0600QVector_0100QgsPointXY, state1 );
3086 else if ( PyList_Check( oo0 ) && PyList_Check( oo1 ) &&
3087 PyList_GET_SIZE( oo0 ) && PyList_GET_SIZE( oo1 ) )
3089 PyObject *ooo0 = PyList_GetItem( oo0, 0 );
3090 PyObject *ooo1 = PyList_GetItem( oo1, 0 );
3094 if ( sipCanConvertToType( ooo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
3095 sipCanConvertToType( ooo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
3096 sipCanConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
3097 sipCanConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
3101 p0 =
reinterpret_cast<QgsMultiPolygonXY *
>( sipConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
3102 p1 =
reinterpret_cast<QgsMultiPolygonXY *
>( sipConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
3107 sipReleaseType( p0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state0 );
3108 sipReleaseType( p1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state1 );
3135 QgsGeometry smooth(
unsigned int iterations = 1,
double offset = 0.25,
3136 double minimumDistance = -1.0,
double maxAngle = 180.0 )
const;
3184 static void convertPointList(
const QVector<QgsPointXY> &input,
QgsPointSequence &output );
3191 static void convertPointList(
const QgsPointSequence &input, QVector<QgsPointXY> &output );
3194 operator QVariant()
const
3196 return QVariant::fromValue( *
this );
3194 operator QVariant()
const {
…}
3204 mutable QString mLastError;
3216 void reset( std::unique_ptr< QgsAbstractGeometry > newGeometry );
3221 QgsGeometry convertToPoint(
bool destMultipart )
const;
3223 QgsGeometry convertToLine(
bool destMultipart )
const;
3225 QgsGeometry convertToPolygon(
bool destMultipart )
const;
3238 std::unique_ptr< QgsLineString > smoothLine(
const QgsLineString &line,
unsigned int iterations = 1,
double offset = 0.25,
3239 double minimumDistance = -1,
double maxAngle = 180.0 )
const;
3252 std::unique_ptr< QgsPolygon > smoothPolygon(
const QgsPolygon &polygon,
unsigned int iterations = 1,
double offset = 0.25,
3253 double minimumDistance = -1,
double maxAngle = 180.0 )
const;