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;
433 double length() const;
620 double hausdorffDistance(
const QgsGeometry &geom )
const;
640 double hausdorffDistanceDensify(
const QgsGeometry &geom,
double densifyFraction )
const;
704 double distanceToVertex(
int vertex )
const;
713 double angleAtVertex(
int vertex )
const;
727 void adjacentVertices(
int atVertex,
int &beforeVertex
SIP_OUT,
int &afterVertex
SIP_OUT )
const;
741 bool insertVertex(
double x,
double y,
int beforeVertex );
755 bool insertVertex(
const QgsPoint &point,
int beforeVertex );
764 bool moveVertex(
double x,
double y,
int atVertex );
773 bool moveVertex(
const QgsPoint &p,
int atVertex );
786 bool deleteVertex(
int atVertex );
795 bool toggleCircularAtVertex(
int atVertex );
802 QgsPoint vertexAt(
int atVertex )
const;
836 double closestVertexWithContext(
const QgsPointXY &point,
int &atVertex
SIP_OUT )
const;
902 QgsGeometry removeInteriorRings(
double minimumAllowedArea = -1 )
const;
934 Qgis::GeometryOperationResult transform( const QTransform &t,
double zTranslate = 0.0,
double zScale = 1.0,
double mTranslate = 0.0,
double mScale = 1.0 );
942 Qgis::GeometryOperationResult rotate(
double rotation, const
QgsPointXY ¢er );
997 Qgis::GeometryOperationResult reshapeGeometry( const
QgsLineString &reshapeLineString );
1070 QgsGeometry orthogonalize(
double tolerance = 1.0E-8,
int maxIterations = 1000,
double angleThreshold = 15.0 ) const;
1084 QgsGeometry triangularWaves(
double wavelength,
double amplitude,
bool strictWavelength = false ) const;
1104 QgsGeometry triangularWavesRandomized(
double minimumWavelength,
double maximumWavelength,
double minimumAmplitude,
double maximumAmplitude,
unsigned long seed = 0 ) const;
1118 QgsGeometry squareWaves(
double wavelength,
double amplitude,
bool strictWavelength = false ) const;
1138 QgsGeometry squareWavesRandomized(
double minimumWavelength,
double maximumWavelength,
double minimumAmplitude,
double maximumAmplitude,
unsigned long seed = 0 ) const;
1152 QgsGeometry roundWaves(
double wavelength,
double amplitude,
bool strictWavelength = false ) const;
1172 QgsGeometry roundWavesRandomized(
double minimumWavelength,
double maximumWavelength,
double minimumAmplitude,
double maximumAmplitude,
unsigned long seed = 0 ) const;
1187 QgsGeometry applyDashPattern( const QVector<
double > &pattern,
1188 Qgis::DashPatternLineEndingRule startRule =
Qgis::DashPatternLineEndingRule::NoRule,
1189 Qgis::DashPatternLineEndingRule endRule =
Qgis::DashPatternLineEndingRule::NoRule,
1190 Qgis::DashPatternSizeAdjustment adjustment =
Qgis::DashPatternSizeAdjustment::ScaleBothDashAndGap,
1191 double patternOffset = 0 ) const;
1205 QgsGeometry snappedToGrid(
double hSpacing,
double vSpacing,
double dSpacing = 0,
double mSpacing = 0 ) const;
1227 bool removeDuplicateNodes(
double epsilon = 4 * std::numeric_limits<
double>::epsilon(),
bool useZValues = false );
1238 bool intersects( const
QgsRectangle &rectangle ) const;
1254 bool intersects( const
QgsGeometry &geometry ) const;
1265 bool boundingBoxIntersects( const
QgsRectangle &rectangle ) const;
1276 bool boundingBoxIntersects( const
QgsGeometry &geometry ) const;
1293 bool contains( const
QgsGeometry &geometry ) const;
1305 bool disjoint( const
QgsGeometry &geometry ) const;
1317 bool touches( const
QgsGeometry &geometry ) const;
1329 bool overlaps( const
QgsGeometry &geometry ) const;
1353 bool crosses( const
QgsGeometry &geometry ) const;
1362 QgsGeometry buffer(
double distance,
int segments ) const;
1376 QgsGeometry buffer(
double distance,
int segments,
Qgis::EndCapStyle endCapStyle,
Qgis::JoinStyle joinStyle,
double miterLimit ) const;
1386 QgsGeometry offsetCurve(
double distance,
int segments,
Qgis::JoinStyle joinStyle,
double miterLimit ) const;
1403 QgsGeometry singleSidedBuffer(
double distance,
int segments,
Qgis::BufferSide side,
1404 Qgis::JoinStyle joinStyle =
Qgis::JoinStyle::Round,
1405 double miterLimit = 2.0 ) const;
1424 QgsGeometry taperedBuffer(
double startWidth,
double endWidth,
int segments ) const;
1440 QgsGeometry variableWidthBufferByM(
int segments ) const;
1448 QgsGeometry extendLine(
double startDistance,
double endDistance ) const;
1462 QgsGeometry densifyByCount(
int extraNodesPerSegment ) const;
1478 QgsGeometry densifyByDistance(
double distance ) const;
1495 QgsGeometry convertToCurves(
double distanceTolerance = 1e-8,
double angleTolerance = 1e-8 ) const;
1654 QgsGeometry delaunayTriangulation(
double tolerance = 0.0,
bool edgesOnly = false ) const;
1703 QgsGeometry subdivide(
int maxNodes = 256 ) const;
1733 double lineLocatePoint( const
QgsGeometry &point ) const;
1744 double interpolateAngle(
double distance ) const;
1834 QVector< QgsPointXY > randomPointsInPolygon(
int count,
const std::function<
bool(
const QgsPointXY & ) > &acceptPoint,
unsigned long seed = 0,
QgsFeedback *feedback =
nullptr,
int maxTriesPerPoint = 0 )
const;
1849 QVector< QgsPointXY > randomPointsInPolygon(
int count,
unsigned long seed = 0,
QgsFeedback *feedback =
nullptr )
const;
1868 const
QgsWkbTypes::GeometryType type = sipCpp->type();
1869 if ( sipCpp->isNull() )
1871 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Cannot generate points inside a null geometry." ).toUtf8().constData() );
1876 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"Cannot generate points inside a %1 geometry. Only Polygon types are permitted." ).arg(
QgsWkbTypes::displayString( sipCpp->wkbType() ) ).toUtf8().constData() );
1881 const sipTypeDef *qvector_type = sipFindType(
"QVector<QgsPointXY>" );
1882 sipRes = sipConvertFromNewType(
new QVector< QgsPointXY >( sipCpp->randomPointsInPolygon( a0, a1 ) ), qvector_type, Py_None );
1897 int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() )
const;
1906 QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() )
const;
1913 QString asWkt(
int precision = 17 )
const;
1916 SIP_PYOBJECT __repr__();
1919 if ( sipCpp->isNull() )
1920 str = QStringLiteral(
"<QgsGeometry: null>" );
1923 QString wkt = sipCpp->asWkt();
1924 if ( wkt.length() > 1000 )
1925 wkt = wkt.left( 1000 ) + QStringLiteral(
"..." );
1926 str = QStringLiteral(
"<QgsGeometry: %1>" ).arg( wkt );
1928 sipRes = PyUnicode_FromString(
str.toUtf8().constData() );
1935 QString asJson(
int precision = 17 )
const;
1970 QVector<
QgsGeometry > coerceToType(
QgsWkbTypes::Type type,
double defaultZ = 0,
double defaultM = 0 ) const;
2013 if ( sipCpp->isNull() )
2015 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a point." ).toUtf8().constData() );
2023 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() );
2028 sipRes = sipConvertFromNewType(
new QgsPointXY( sipCpp->asPoint() ), sipType_QgsPointXY, Py_None );
2061 if ( sipCpp->isNull() )
2063 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a polyline." ).toUtf8().constData() );
2068 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() );
2073 const sipTypeDef *qvector_type = sipFindType(
"QVector< QgsPointXY >" );
2074 sipRes = sipConvertFromNewType(
new QgsPolylineXY( sipCpp->asPolyline() ), qvector_type, Py_None );
2106 if ( sipCpp->isNull() )
2108 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a polygon." ).toUtf8().constData() );
2113 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() );
2118 const sipTypeDef *qvector_type = sipFindType(
"QVector<QVector<QgsPointXY>>" );
2119 sipRes = sipConvertFromNewType(
new QgsPolygonXY( sipCpp->asPolygon() ), qvector_type, Py_None );
2149 if ( sipCpp->isNull() )
2151 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a multipoint." ).toUtf8().constData() );
2156 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"%1 geometry cannot be converted to a multipoint. Only multipoint types are permitted." ).arg(
QgsWkbTypes::displayString( type ) ).toUtf8().constData() );
2161 const sipTypeDef *qvector_type = sipFindType(
"QVector< QgsPointXY >" );
2162 sipRes = sipConvertFromNewType(
new QgsPolylineXY( sipCpp->asMultiPoint() ), qvector_type, Py_None );
2194 if ( sipCpp->isNull() )
2196 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a multilinestring." ).toUtf8().constData() );
2201 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() );
2206 const sipTypeDef *qvector_type = sipFindType(
"QVector<QVector<QgsPointXY>>" );
2207 sipRes = sipConvertFromNewType(
new QgsMultiPolylineXY( sipCpp->asMultiPolyline() ), qvector_type, Py_None );
2239 if ( sipCpp->isNull() )
2241 PyErr_SetString( PyExc_ValueError, QStringLiteral(
"Null geometry cannot be converted to a multipolygon." ).toUtf8().constData() );
2246 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() );
2251 const sipTypeDef *qvector_type = sipFindType(
"QVector<QVector<QVector<QgsPointXY>>>" );
2252 sipRes = sipConvertFromNewType(
new QgsMultiPolygonXY( sipCpp->asMultiPolygon() ), qvector_type, Py_None );
2261 QVector<QgsGeometry> asGeometryCollection()
const;
2290 bool deleteRing(
int ringNum,
int partNum = 0 );
2297 bool deletePart(
int partNum );
2307 bool convertToMultiType();
2318 bool convertToSingleType();
2329 bool convertGeometryCollectionToSubclass(
QgsWkbTypes::GeometryType geomType );
2341 int avoidIntersections( const QList<
QgsVectorLayer *> &avoidIntersectionsLayers,
2408 : mMessage( QStringLiteral(
"none" ) )
2418 , mHasLocation( true ) {}
2423 QString what()
const;
2433 bool hasWhere()
const;
2436 SIP_PYOBJECT __repr__();
2438 QString
str = QStringLiteral(
"<QgsGeometry.Error: %1>" ).arg( sipCpp->what() );
2439 sipRes = PyUnicode_FromString(
str.toUtf8().data() );
2446 return other.mMessage == mMessage && other.mHasLocation == mHasLocation && other.mLocation == mLocation;
2452 bool mHasLocation =
false;
2463 void validateGeometry( QVector<QgsGeometry::Error> &errors
SIP_OUT,
Qgis::GeometryValidationEngine method = Qgis::GeometryValidationEngine::QgisInternal, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() )
const;
2481 static QgsGeometry unaryUnion(
const QVector<QgsGeometry> &geometries );
2491 static QgsGeometry polygonize(
const QVector<QgsGeometry> &geometries );
2508 bool requiresConversionToStraightSegments()
const;
2522 void draw( QPainter &p )
const;
2567 void filterVertices( const std::function<
bool( const
QgsPoint & ) > &filter )
SIP_SKIP;
2599 static
QgsGeometry fromQPolygonF( const QPolygonF &polygon );
2631 double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2643 double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2656 double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2678 static bool compare( PyObject *obj1, PyObject *obj2,
double epsilon = 4 * std::numeric_limits<double>::epsilon() );
2686 if ( PyList_Check( a0 ) && PyList_Check( a1 ) &&
2687 PyList_GET_SIZE( a0 ) && PyList_GET_SIZE( a1 ) )
2689 PyObject *o0 = PyList_GetItem( a0, 0 );
2690 PyObject *o1 = PyList_GetItem( a1, 0 );
2694 if ( sipCanConvertToType( o0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2695 sipCanConvertToType( o1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2696 sipCanConvertToType( a0, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2697 sipCanConvertToType( a1, sipType_QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2701 p0 =
reinterpret_cast<QgsPolylineXY *
>( sipConvertToType( a0, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2702 p1 =
reinterpret_cast<QgsPolylineXY *
>( sipConvertToType( a1, sipType_QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2705 sipReleaseType( p0, sipType_QVector_0100QgsPointXY, state0 );
2706 sipReleaseType( p1, sipType_QVector_0100QgsPointXY, state1 );
2713 else if ( PyList_Check( o0 ) && PyList_Check( o1 ) &&
2714 PyList_GET_SIZE( o0 ) && PyList_GET_SIZE( o1 ) )
2716 PyObject *oo0 = PyList_GetItem( o0, 0 );
2717 PyObject *oo1 = PyList_GetItem( o1, 0 );
2721 if ( sipCanConvertToType( oo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2722 sipCanConvertToType( oo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2723 sipCanConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2724 sipCanConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2728 p0 =
reinterpret_cast<QgsPolygonXY *
>( sipConvertToType( a0, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2729 p1 =
reinterpret_cast<QgsPolygonXY *
>( sipConvertToType( a1, sipType_QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2732 sipReleaseType( p0, sipType_QVector_0600QVector_0100QgsPointXY, state0 );
2733 sipReleaseType( p1, sipType_QVector_0600QVector_0100QgsPointXY, state1 );
2740 else if ( PyList_Check( oo0 ) && PyList_Check( oo1 ) &&
2741 PyList_GET_SIZE( oo0 ) && PyList_GET_SIZE( oo1 ) )
2743 PyObject *ooo0 = PyList_GetItem( oo0, 0 );
2744 PyObject *ooo1 = PyList_GetItem( oo1, 0 );
2748 if ( sipCanConvertToType( ooo0, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2749 sipCanConvertToType( ooo1, sipType_QgsPointXY, SIP_NOT_NONE ) &&
2750 sipCanConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) &&
2751 sipCanConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, SIP_NOT_NONE ) )
2755 p0 =
reinterpret_cast<QgsMultiPolygonXY *
>( sipConvertToType( a0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state0, &sipIsErr ) );
2756 p1 =
reinterpret_cast<QgsMultiPolygonXY *
>( sipConvertToType( a1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, 0, SIP_NOT_NONE, &state1, &sipIsErr ) );
2759 sipReleaseType( p0, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state0 );
2760 sipReleaseType( p1, sipType_QVector_0600QVector_0600QVector_0100QgsPointXY, state1 );
2793 QgsGeometry smooth(
unsigned int iterations = 1,
double offset = 0.25,
2794 double minimumDistance = -1.0,
double maxAngle = 180.0 )
const;
2840 static void convertPointList(
const QVector<QgsPointXY> &input,
QgsPointSequence &output );
2847 static void convertPointList(
const QgsPointSequence &input, QVector<QgsPointXY> &output );
2850 operator QVariant()
const
2852 return QVariant::fromValue( *
this );
2860 mutable QString mLastError;
2872 void reset( std::unique_ptr< QgsAbstractGeometry > newGeometry );
2877 QgsGeometry convertToPoint(
bool destMultipart )
const;
2879 QgsGeometry convertToLine(
bool destMultipart )
const;
2881 QgsGeometry convertToPolygon(
bool destMultipart )
const;
2894 std::unique_ptr< QgsLineString > smoothLine(
const QgsLineString &line,
unsigned int iterations = 1,
double offset = 0.25,
2895 double minimumDistance = -1,
double maxAngle = 180.0 )
const;
2908 std::unique_ptr< QgsPolygon > smoothPolygon(
const QgsPolygon &polygon,
unsigned int iterations = 1,
double offset = 0.25,
2909 double minimumDistance = -1,
double maxAngle = 180.0 )
const;