21 #include <QDomDocument>
22 #include <QJsonObject>
31 #include "qgis_core.h"
40 #include "json_fwd.hpp"
41 using namespace nlohmann;
125 Q_PROPERTY(
bool isNull READ isNull )
137 NothingHappened = 1000,
155 Q_ENUM( OperationResult )
275 static QgsGeometry collectGeometry(
const QVector<QgsGeometry> &geometries );
292 static QgsGeometry createWedgeBuffer(
const QgsPoint ¢er,
double azimuth,
double angularWidth,
293 double outerRadius,
double innerRadius = 0 );
300 void fromWkb(
unsigned char *wkb,
int length )
SIP_SKIP;
306 void fromWkb(
const QByteArray &wkb );
326 bool isEmpty()
const;
329 bool isMultipart()
const;
368 FlagAllowSelfTouchingHoles = 1 << 0,
370 Q_DECLARE_FLAGS( ValidityFlags, ValidityFlag )
379 bool isGeosValid( QgsGeometry::ValidityFlags flags = QgsGeometry::ValidityFlags() )
const;
389 bool isSimple()
const;
417 double length()
const;
604 double hausdorffDistance(
const QgsGeometry &geom )
const;
624 double hausdorffDistanceDensify(
const QgsGeometry &geom,
double densifyFraction )
const;
650 double distanceToVertex(
int vertex )
const;
659 double angleAtVertex(
int vertex )
const;
673 void adjacentVertices(
int atVertex,
int &beforeVertex
SIP_OUT,
int &afterVertex
SIP_OUT )
const;
687 bool insertVertex(
double x,
double y,
int beforeVertex );
701 bool insertVertex(
const QgsPoint &point,
int beforeVertex );
710 bool moveVertex(
double x,
double y,
int atVertex );
719 bool moveVertex(
const QgsPoint &p,
int atVertex );
732 bool deleteVertex(
int atVertex );
739 QgsPoint vertexAt(
int atVertex )
const;
773 double closestVertexWithContext(
const QgsPointXY &point,
int &atVertex
SIP_OUT )
const;
793 OperationResult addRing(
const QVector<QgsPointXY> &ring );
839 QgsGeometry removeInteriorRings(
double minimumAllowedArea = -1 )
const;
845 OperationResult translate(
double dx,
double dy,
double dz = 0.0,
double dm = 0.0 );
871 OperationResult transform( const QTransform &t,
double zTranslate = 0.0,
double zScale = 1.0,
double mTranslate = 0.0,
double mScale = 1.0 );
879 OperationResult rotate(
double rotation, const
QgsPointXY ¢er );
918 OperationResult reshapeGeometry( const
QgsLineString &reshapeLineString );
983 QgsGeometry orthogonalize(
double tolerance = 1.0E-8,
int maxIterations = 1000,
double angleThreshold = 15.0 ) const;
997 QgsGeometry snappedToGrid(
double hSpacing,
double vSpacing,
double dSpacing = 0,
double mSpacing = 0 ) const;
1019 bool removeDuplicateNodes(
double epsilon = 4 * std::numeric_limits<
double>::epsilon(),
bool useZValues = false );
1030 bool intersects( const
QgsRectangle &rectangle ) const;
1041 bool intersects( const
QgsGeometry &geometry ) const;
1052 bool boundingBoxIntersects( const
QgsRectangle &rectangle ) const;
1063 bool boundingBoxIntersects( const
QgsGeometry &geometry ) const;
1074 bool contains( const
QgsGeometry &geometry ) const;
1080 bool disjoint( const
QgsGeometry &geometry ) const;
1086 bool touches( const
QgsGeometry &geometry ) const;
1092 bool overlaps( const
QgsGeometry &geometry ) const;
1105 bool crosses( const
QgsGeometry &geometry ) const;
1113 Q_ENUM( BufferSide )
1122 Q_ENUM( EndCapStyle )
1140 QgsGeometry buffer(
double distance,
int segments )
const;
1154 QgsGeometry buffer(
double distance,
int segments, EndCapStyle endCapStyle, JoinStyle joinStyle,
double miterLimit )
const;
1164 QgsGeometry offsetCurve(
double distance,
int segments, JoinStyle joinStyle,
double miterLimit )
const;
1181 QgsGeometry singleSidedBuffer(
double distance,
int segments, BufferSide side,
1182 JoinStyle joinStyle = JoinStyleRound,
1183 double miterLimit = 2.0 )
const;
1202 QgsGeometry taperedBuffer(
double startWidth,
double endWidth,
int segments )
const;
1218 QgsGeometry variableWidthBufferByM(
int segments )
const;
1226 QgsGeometry extendLine(
double startDistance,
double endDistance )
const;
1240 QgsGeometry densifyByCount(
int extraNodesPerSegment )
const;
1256 QgsGeometry densifyByDistance(
double distance )
const;
1273 QgsGeometry convertToCurves(
double distanceTolerance = 1e-8,
double angleTolerance = 1e-8 )
const;
1355 QgsGeometry delaunayTriangulation(
double tolerance = 0.0,
bool edgesOnly =
false )
const;
1376 QgsGeometry subdivide(
int maxNodes = 256 )
const;
1406 double lineLocatePoint(
const QgsGeometry &point )
const;
1417 double interpolateAngle(
double distance )
const;
1502 QVector< QgsPointXY > randomPointsInPolygon(
int count,
const std::function<
bool(
const QgsPointXY & ) > &acceptPoint,
unsigned long seed = 0,
QgsFeedback *feedback =
nullptr )
const;
1517 QVector< QgsPointXY > randomPointsInPolygon(
int count,
unsigned long seed = 0,
QgsFeedback *feedback =
nullptr )
const;
1535 const
QgsWkbTypes::GeometryType type = sipCpp->type();
1536 if ( sipCpp->isNull() )
1538 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Cannot generate points inside a null geometry." ).toUtf8().constData() );
1543 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"Cannot generate points inside a %1 geometry. Only Polygon types are permitted." ).arg(
QgsWkbTypes::displayString( sipCpp->wkbType() ) ).toUtf8().constData() );
1548 const sipMappedType *qvector_type = sipFindMappedType(
"QVector<QgsPointXY>" );
1549 sipRes = sipConvertFromNewType(
new QVector< QgsPointXY >( sipCpp->randomPointsInPolygon( a0, a1 ) ), qvector_type, Py_None );
1564 QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() )
const;
1571 QString asWkt(
int precision = 17 )
const;
1574 SIP_PYOBJECT __repr__();
1577 if ( sipCpp->isNull() )
1578 str = QStringLiteral(
"<QgsGeometry: null>" );
1581 QString wkt = sipCpp->asWkt();
1582 if ( wkt.length() > 1000 )
1583 wkt = wkt.left( 1000 ) + QStringLiteral(
"..." );
1584 str = QStringLiteral(
"<QgsGeometry: %1>" ).arg( wkt );
1586 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
1593 QString asJson(
int precision = 17 )
const;
1666 if ( sipCpp->isNull() )
1668 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a point." ).toUtf8().constData() );
1673 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"%1 geometry cannot be converted to a point. Only Point types are permitted." ).arg(
QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1678 sipRes = sipConvertFromNewType(
new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
1709 if ( sipCpp->isNull() )
1711 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a polyline." ).toUtf8().constData() );
1716 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() );
1721 const sipMappedType *qvector_type = sipFindMappedType(
"QVector< QgsPointXY >" );
1722 sipRes = sipConvertFromNewType(
new QgsPolylineXY( sipCpp->asPolyline() ), qvector_type, Py_None );
1753 if ( sipCpp->isNull() )
1755 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a polygon." ).toUtf8().constData() );
1760 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() );
1765 const sipMappedType *qvector_type = sipFindMappedType(
"QVector<QVector<QgsPointXY>>" );
1766 sipRes = sipConvertFromNewType(
new QgsPolygonXY( sipCpp->asPolygon() ), qvector_type, Py_None );
1795 if ( sipCpp->isNull() )
1797 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a multipoint." ).toUtf8().constData() );
1802 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"%1 geometry cannot be converted to a multipoint. Only multipoint types are permitted." ).arg(
QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
1807 const sipMappedType *qvector_type = sipFindMappedType(
"QVector< QgsPointXY >" );
1808 sipRes = sipConvertFromNewType(
new QgsPolylineXY( sipCpp->asMultiPoint() ), qvector_type, Py_None );
1839 if ( sipCpp->isNull() )
1841 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a multilinestring." ).toUtf8().constData() );
1846 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() );
1851 const sipMappedType *qvector_type = sipFindMappedType(
"QVector<QVector<QgsPointXY>>" );
1852 sipRes = sipConvertFromNewType(
new QgsMultiPolylineXY( sipCpp->asMultiPolyline() ), qvector_type, Py_None );
1883 if ( sipCpp->isNull() )
1885 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a multipolygon." ).toUtf8().constData() );
1890 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() );
1895 const sipMappedType *qvector_type = sipFindMappedType(
"QVector<QVector<QVector<QgsPointXY>>>" );
1896 sipRes = sipConvertFromNewType(
new QgsMultiPolygonXY( sipCpp->asMultiPolygon() ), qvector_type, Py_None );
1905 QVector<QgsGeometry> asGeometryCollection()
const;
1912 QPointF asQPointF()
const;
1920 QPolygonF asQPolygonF()
const;
1928 bool deleteRing(
int ringNum,
int partNum = 0 );
1935 bool deletePart(
int partNum );
1945 bool convertToMultiType();
1956 bool convertToSingleType();
1979 int avoidIntersections(
const QList<QgsVectorLayer *> &avoidIntersectionsLayers,
2018 : mMessage( QStringLiteral(
"none" ) )
2028 , mHasLocation( true ) {}
2033 QString what()
const;
2043 bool hasWhere()
const;
2046 SIP_PYOBJECT __repr__();
2048 QString str = QStringLiteral(
"<QgsGeometry.Error: %1>" ).arg( sipCpp->what() );
2049 sipRes = PyUnicode_FromString( str.toUtf8().data() );
2055 return other.mMessage == mMessage && other.mHasLocation == mHasLocation && other.mLocation == mLocation;
2061 bool mHasLocation =
false;
2082 void validateGeometry( QVector<QgsGeometry::Error> &errors
SIP_OUT, ValidationMethod method = ValidatorQgisInternal, QgsGeometry::ValidityFlags flags = QgsGeometry::ValidityFlags() )
const;
2089 static QgsGeometry unaryUnion(
const QVector<QgsGeometry> &geometries );
2099 static QgsGeometry polygonize(
const QVector<QgsGeometry> &geometries );
2116 bool requiresConversionToStraightSegments()
const;
2130 void draw( QPainter &p )
const;
2164 QString lastError()
const;
2175 void filterVertices(
const std::function<
bool(
const QgsPoint & ) > &filter )
SIP_SKIP;
2207 static QgsGeometry fromQPolygonF(
const QPolygonF &polygon );
2239 double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2251 double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2264 double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2286 static bool compare( PyObject *obj1, PyObject *obj2,
double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2294 if ( PyList_Check( a0 ) && PyList_Check( a1 ) &&
2295 PyList_GET_SIZE( a0 ) && PyList_GET_SIZE( a1 ) )
2297 PyObject *o0 = PyList_GetItem( a0, 0 );
2298 PyObject *o1 = PyList_GetItem( a1, 0 );
2302 if ( sipCanConvertToType( o0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2303 sipCanConvertToType( o1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2304 sipCanConvertToType( a0, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2305 sipCanConvertToType( a1, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2309 p0 =
reinterpret_cast<QgsPolylineXY *
>( sipConvertToType( a0, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2310 p1 =
reinterpret_cast<QgsPolylineXY *
>( sipConvertToType( a1, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2313 sipReleaseType( p0, sipType_QVector_0100QgsPointXY, state0 );
2314 sipReleaseType( p1, sipType_QVector_0100QgsPointXY, state1 );
2321 else if ( PyList_Check( o0 ) && PyList_Check( o1 ) &&
2322 PyList_GET_SIZE( o0 ) && PyList_GET_SIZE( o1 ) )
2324 PyObject *oo0 = PyList_GetItem( o0, 0 );
2325 PyObject *oo1 = PyList_GetItem( o1, 0 );
2329 if ( sipCanConvertToType( oo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2330 sipCanConvertToType( oo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2331 sipCanConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2332 sipCanConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2336 p0 =
reinterpret_cast<QgsPolygonXY *
>( sipConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2337 p1 =
reinterpret_cast<QgsPolygonXY *
>( sipConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2340 sipReleaseType( p0, sipType_QVector_0600QVector_0100QgsPointXY, state0 );
2341 sipReleaseType( p1, sipType_QVector_0600QVector_0100QgsPointXY, state1 );
2348 else if ( PyList_Check( oo0 ) && PyList_Check( oo1 ) &&
2349 PyList_GET_SIZE( oo0 ) && PyList_GET_SIZE( oo1 ) )
2351 PyObject *ooo0 = PyList_GetItem( oo0, 0 );
2352 PyObject *ooo1 = PyList_GetItem( oo1, 0 );
2356 if ( sipCanConvertToType( ooo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2357 sipCanConvertToType( ooo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2358 sipCanConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2359 sipCanConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2363 p0 =
reinterpret_cast<QgsMultiPolygonXY *
>( sipConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2364 p1 =
reinterpret_cast<QgsMultiPolygonXY *
>( sipConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2367 sipReleaseType( p0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state0 );
2368 sipReleaseType( p1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state1 );
2401 QgsGeometry smooth(
unsigned int iterations = 1,
double offset = 0.25,
2402 double minimumDistance = -1.0,
double maxAngle = 180.0 )
const;
2414 static void convertPointList(
const QVector<QgsPointXY> &input,
QgsPointSequence &output );
2421 static void convertPointList(
const QgsPointSequence &input, QVector<QgsPointXY> &output );
2424 operator QVariant()
const
2426 return QVariant::fromValue( *
this );
2434 mutable QString mLastError;
2446 void reset( std::unique_ptr< QgsAbstractGeometry > newGeometry );
2452 QgsGeometry convertToPoint(
bool destMultipart )
const;
2454 QgsGeometry convertToLine(
bool destMultipart )
const;
2456 QgsGeometry convertToPolygon(
bool destMultipart )
const;
2469 std::unique_ptr< QgsLineString > smoothLine(
const QgsLineString &line,
unsigned int iterations = 1,
double offset = 0.25,
2470 double minimumDistance = -1,
double maxAngle = 180.0 )
const;
2483 std::unique_ptr< QgsPolygon > smoothPolygon(
const QgsPolygon &polygon,
unsigned int iterations = 1,
double offset = 0.25,
2484 double minimumDistance = -1,
double maxAngle = 180.0 )
const;
2492 Q_DECLARE_OPERATORS_FOR_FLAGS( QgsGeometry::ValidityFlags )