QGIS API Documentation  3.25.0-Master (6b426f5f8a)
qgsgeometryutils.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgeometryutils.h
3  -------------------------------------------------------------------
4 Date : 21 Nov 2014
5 Copyright : (C) 2014 by Marco Hugentobler
6 email : marco.hugentobler at sourcepole dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #ifndef QGSGEOMETRYUTILS_H
17 #define QGSGEOMETRYUTILS_H
18 
19 #include <limits>
20 
21 #include "qgis_core.h"
22 #include "qgis_sip.h"
23 #include "qgspoint.h"
24 #include "qgsvertexid.h"
25 #include "qgsgeometry.h"
26 #include "qgsvector3d.h"
27 
28 #include <QJsonArray>
29 
30 class QgsLineString;
31 
38 class CORE_EXPORT QgsGeometryUtils
39 {
40  public:
41 
46  static QVector<QgsLineString *> extractLineStrings( const QgsAbstractGeometry *geom ) SIP_FACTORY;
47 
52  static QgsPoint closestVertex( const QgsAbstractGeometry &geom, const QgsPoint &pt, QgsVertexId &id SIP_OUT );
53 
59  static QgsPoint closestPoint( const QgsAbstractGeometry &geometry, const QgsPoint &point );
60 
68  static double distanceToVertex( const QgsAbstractGeometry &geom, QgsVertexId id );
69 
81  static bool verticesAtDistance( const QgsAbstractGeometry &geometry,
82  double distance,
83  QgsVertexId &previousVertex SIP_OUT,
84  QgsVertexId &nextVertex SIP_OUT );
85 
89  static double sqrDistance2D( const QgsPoint &pt1, const QgsPoint &pt2 ) SIP_HOLDGIL;
90 
94  static double sqrDistToLine( double ptX, double ptY, double x1, double y1, double x2, double y2, double &minDistX SIP_OUT, double &minDistY SIP_OUT, double epsilon ) SIP_HOLDGIL;
95 
104  static double distToInfiniteLine( const QgsPoint &point, const QgsPoint &linePoint1, const QgsPoint &linePoint2, double epsilon = 1e-7 );
105 
117  static bool lineIntersection( const QgsPoint &p1, QgsVector v1, const QgsPoint &p2, QgsVector v2, QgsPoint &intersection SIP_OUT ) SIP_HOLDGIL;
118 
155  static bool segmentIntersection( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &q1, const QgsPoint &q2, QgsPoint &intersectionPoint SIP_OUT, bool &isIntersection SIP_OUT, double tolerance = 1e-8, bool acceptImproperIntersection = false ) SIP_HOLDGIL;
156 
168  static bool lineCircleIntersection( const QgsPointXY &center, double radius,
169  const QgsPointXY &linePoint1, const QgsPointXY &linePoint2,
170  QgsPointXY &intersection SIP_INOUT ) SIP_HOLDGIL;
171 
182  static int circleCircleIntersections( const QgsPointXY &center1, double radius1,
183  const QgsPointXY &center2, double radius2,
184  QgsPointXY &intersection1 SIP_OUT, QgsPointXY &intersection2 SIP_OUT ) SIP_HOLDGIL;
185 
194  static bool tangentPointAndCircle( const QgsPointXY &center, double radius,
196 
214  static int circleCircleOuterTangents(
215  const QgsPointXY &center1, double radius1, const QgsPointXY &center2, double radius2,
216  QgsPointXY &line1P1 SIP_OUT, QgsPointXY &line1P2 SIP_OUT,
217  QgsPointXY &line2P1 SIP_OUT, QgsPointXY &line2P2 SIP_OUT ) SIP_HOLDGIL;
218 
237  static int circleCircleInnerTangents(
238  const QgsPointXY &center1, double radius1, const QgsPointXY &center2, double radius2,
239  QgsPointXY &line1P1 SIP_OUT, QgsPointXY &line1P2 SIP_OUT,
240  QgsPointXY &line2P1 SIP_OUT, QgsPointXY &line2P2 SIP_OUT ) SIP_HOLDGIL;
241 
249  static QgsPoint projectPointOnSegment( const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2 ) SIP_HOLDGIL
250  {
251  const double nx = s2.y() - s1.y();
252  const double ny = -( s2.x() - s1.x() );
253  const double t = ( p.x() * ny - p.y() * nx - s1.x() * ny + s1.y() * nx ) / ( ( s2.x() - s1.x() ) * ny - ( s2.y() - s1.y() ) * nx );
254  return t < 0. ? s1 : t > 1. ? s2 : QgsPoint( s1.x() + ( s2.x() - s1.x() ) * t, s1.y() + ( s2.y() - s1.y() ) * t );
255  }
256 
259  {
260  int segment1;
261  int segment2;
263  };
264 
275  static QVector<SelfIntersection> selfIntersections( const QgsAbstractGeometry *geom, int part, int ring, double tolerance ) SIP_SKIP;
276 
284  static int leftOfLine( const double x, const double y, const double x1, const double y1, const double x2, const double y2 ) SIP_HOLDGIL;
285 
295  static int leftOfLine( const QgsPoint &point, const QgsPoint &p1, const QgsPoint &p2 ) SIP_HOLDGIL;
296 
300  static QgsPoint pointOnLineWithDistance( const QgsPoint &startPoint, const QgsPoint &directionPoint, double distance ) SIP_HOLDGIL;
301 
311  static void pointOnLineWithDistance( double x1, double y1, double x2, double y2, double distance, double &x, double &y,
312  double *z1 = nullptr, double *z2 = nullptr, double *z = nullptr,
313  double *m1 = nullptr, double *m2 = nullptr, double *m = nullptr ) SIP_SKIP;
314 
342  static void perpendicularOffsetPointAlongSegment( double x1, double y1, double x2, double y2, double proportion, double offset, double *x SIP_OUT, double *y SIP_OUT );
343 
352  static QgsPoint interpolatePointOnArc( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double distance ) SIP_HOLDGIL;
353 
355  static double ccwAngle( double dy, double dx ) SIP_HOLDGIL;
356 
358  static void circleCenterRadius( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double &radius SIP_OUT,
359  double &centerX SIP_OUT, double &centerY SIP_OUT ) SIP_HOLDGIL;
360 
367  static bool circleClockwise( double angle1, double angle2, double angle3 ) SIP_HOLDGIL;
368 
370  static bool circleAngleBetween( double angle, double angle1, double angle2, bool clockwise ) SIP_HOLDGIL;
371 
376  static bool angleOnCircle( double angle, double angle1, double angle2, double angle3 ) SIP_HOLDGIL;
377 
379  static double circleLength( double x1, double y1, double x2, double y2, double x3, double y3 ) SIP_HOLDGIL;
380 
382  static double sweepAngle( double centerX, double centerY, double x1, double y1, double x2, double y2, double x3, double y3 ) SIP_HOLDGIL;
383 
390  static bool segmentMidPoint( const QgsPoint &p1, const QgsPoint &p2, QgsPoint &result SIP_OUT, double radius, const QgsPoint &mousePos ) SIP_HOLDGIL;
391 
403  static QgsPoint segmentMidPointFromCenter( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &center, bool useShortestArc = true ) SIP_HOLDGIL;
404 
406  static double circleTangentDirection( const QgsPoint &tangentPoint, const QgsPoint &cp1, const QgsPoint &cp2, const QgsPoint &cp3 ) SIP_HOLDGIL;
407 
412  static void segmentizeArc( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &p3,
413  QgsPointSequence SIP_PYALTERNATIVETYPE( QVector<QgsPoint> ) &points SIP_OUT, double tolerance = M_PI_2 / 90,
414  QgsAbstractGeometry::SegmentationToleranceType toleranceType = QgsAbstractGeometry::MaximumAngle,
415  bool hasZ = false, bool hasM = false );
416 
432  static bool pointContinuesArc( const QgsPoint &a1, const QgsPoint &a2, const QgsPoint &a3, const QgsPoint &b, double distanceTolerance,
433  double pointSpacingAngleTolerance ) SIP_HOLDGIL;
434 
440  static int segmentSide( const QgsPoint &pt1, const QgsPoint &pt3, const QgsPoint &pt2 ) SIP_HOLDGIL;
441 
446  static double interpolateArcValue( double angle, double a1, double a2, double a3, double zm1, double zm2, double zm3 ) SIP_HOLDGIL;
447 
452  static QgsPointSequence pointsFromWKT( const QString &wktCoordinateList, bool is3D, bool isMeasure ) SIP_SKIP;
453 
458  static void pointsToWKB( QgsWkbPtr &wkb, const QgsPointSequence &points, bool is3D, bool isMeasure ) SIP_SKIP;
459 
464  static QString pointsToWKT( const QgsPointSequence &points, int precision, bool is3D, bool isMeasure ) SIP_SKIP;
465 
470  static QDomElement pointsToGML2( const QgsPointSequence &points, QDomDocument &doc, int precision, const QString &ns, QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) SIP_SKIP;
471 
476  static QDomElement pointsToGML3( const QgsPointSequence &points, QDomDocument &doc, int precision, const QString &ns, bool is3D, QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) SIP_SKIP;
477 
482  static QString pointsToJSON( const QgsPointSequence &points, int precision ) SIP_SKIP;
483 
488  static json pointsToJson( const QgsPointSequence &points, int precision ) SIP_SKIP;
489 
495  static double normalizedAngle( double angle ) SIP_HOLDGIL;
496 
505  static double lineAngle( double x1, double y1, double x2, double y2 ) SIP_HOLDGIL;
506 
518  static double angleBetweenThreePoints( double x1, double y1, double x2, double y2,
519  double x3, double y3 ) SIP_HOLDGIL;
520 
530  static double linePerpendicularAngle( double x1, double y1, double x2, double y2 ) SIP_HOLDGIL;
531 
536  static double averageAngle( double x1, double y1, double x2, double y2, double x3, double y3 ) SIP_HOLDGIL;
537 
544  static double averageAngle( double a1, double a2 ) SIP_HOLDGIL;
545 
550  static QPair<QgsWkbTypes::Type, QString> wktReadBlock( const QString &wkt ) SIP_SKIP;
551 
559  static QStringList wktGetChildBlocks( const QString &wkt, const QString &defaultType = QString() ) SIP_SKIP;
560 
583  static int closestSideOfRectangle( double right, double bottom, double left, double top, double x, double y );
584 
608  static QgsPoint midpoint( const QgsPoint &pt1, const QgsPoint &pt2 ) SIP_HOLDGIL;
609 
623  static QgsPointXY interpolatePointOnLine( double x1, double y1, double x2, double y2, double fraction ) SIP_HOLDGIL;
624 
641  static QgsPoint interpolatePointOnLine( const QgsPoint &p1, const QgsPoint &p2, double fraction ) SIP_HOLDGIL;
642 
655  static QgsPointXY interpolatePointOnLineByValue( double x1, double y1, double v1, double x2, double y2, double v2, double value ) SIP_HOLDGIL;
656 
664  static double gradient( const QgsPoint &pt1, const QgsPoint &pt2 ) SIP_HOLDGIL;
665 
675  static void coefficients( const QgsPoint &pt1, const QgsPoint &pt2,
676  double &a SIP_OUT, double &b SIP_OUT, double &c SIP_OUT ) SIP_HOLDGIL;
677 
685  static QgsLineString perpendicularSegment( const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2 ) SIP_HOLDGIL;
686 
710  static void perpendicularCenterSegment( double centerPointX, double centerPointY,
711  double segmentPoint1x, double segmentPoint1y,
712  double segmentPoint2x, double segmentPoint2y,
713  double &perpendicularSegmentPoint1x SIP_OUT, double &perpendicularSegmentPoint1y SIP_OUT,
714  double &perpendicularSegmentPoint2x SIP_OUT, double &perpendicularSegmentPoint2y SIP_OUT,
715  double segmentLength = 0
716  ) SIP_HOLDGIL;
717 
726  static double skewLinesDistance( const QgsVector3D &P1, const QgsVector3D &P12,
727  const QgsVector3D &P2, const QgsVector3D &P22 ) SIP_HOLDGIL;
728 
739  static bool skewLinesProjection( const QgsVector3D &P1, const QgsVector3D &P12,
740  const QgsVector3D &P2, const QgsVector3D &P22,
741  QgsVector3D &X1 SIP_OUT,
742  double epsilon = 0.0001 ) SIP_HOLDGIL;
743 
780  static bool linesIntersection3D( const QgsVector3D &La1, const QgsVector3D &La2,
781  const QgsVector3D &Lb1, const QgsVector3D &Lb2,
782  QgsVector3D &intersection SIP_OUT ) SIP_HOLDGIL;
783 
790  static double triangleArea( double aX, double aY, double bX, double bY, double cX, double cY ) SIP_HOLDGIL;
791 
809  static void weightedPointInTriangle( double aX, double aY, double bX, double bY, double cX, double cY,
810  double weightB, double weightC, double &pointX SIP_OUT, double &pointY SIP_OUT ) SIP_HOLDGIL;
811 
828  Q_DECL_DEPRECATED static bool setZValueFromPoints( const QgsPointSequence &points, QgsPoint &point ) SIP_DEPRECATED
829  {
830  return transferFirstZValueToPoint( points, point );
831  }
832 
848  static bool transferFirstZValueToPoint( const QgsPointSequence &points, QgsPoint &point );
849 
865  static bool transferFirstMValueToPoint( const QgsPointSequence &points, QgsPoint &point );
866 
885  template <class Iterator> static bool transferFirstZOrMValueToPoint( Iterator verticesBegin, Iterator verticesEnd, QgsPoint &point ) SIP_SKIP
886  {
887  bool zFound = false;
888  bool mFound = false;
889 
890  for ( auto it = verticesBegin ; it != verticesEnd ; ++it )
891  {
892  if ( !mFound && ( *it ).isMeasure() )
893  {
894  point.convertTo( QgsWkbTypes::addM( point.wkbType() ) );
895  point.setM( ( *it ).m() );
896  mFound = true;
897  }
898  if ( !zFound && ( *it ).is3D() )
899  {
900  point.convertTo( QgsWkbTypes::addZ( point.wkbType() ) );
901  point.setZ( ( *it ).z() );
902  zFound = true;
903  }
904  if ( zFound && mFound )
905  break;
906  }
907 
908  return zFound || mFound;
909  }
910 
927  static bool transferFirstZOrMValueToPoint( const QgsPointSequence &points, QgsPoint &point )
928  {
929  return QgsGeometryUtils::transferFirstZOrMValueToPoint( points.constBegin(), points.constEnd(), point );
930  }
931 
948  static bool transferFirstZOrMValueToPoint( const QgsGeometry &geom, QgsPoint &point )
949  {
951  }
952 
974  static bool angleBisector( double aX, double aY, double bX, double bY, double cX, double cY, double dX, double dY,
975  double &pointX SIP_OUT, double &pointY SIP_OUT, double &angle SIP_OUT ) SIP_HOLDGIL;
976 
993  static bool bisector( double aX, double aY, double bX, double bY, double cX, double cY,
994  double &pointX SIP_OUT, double &pointY SIP_OUT ) SIP_HOLDGIL;
995 
998  {
1001  Part
1002  };
1003 
1005  template<class T> static double closestSegmentFromComponents( T &container, ComponentType ctype, const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf, double epsilon ) SIP_SKIP
1006  {
1007  double minDist = std::numeric_limits<double>::max();
1008  double minDistSegmentX = 0.0, minDistSegmentY = 0.0;
1009  QgsVertexId minDistVertexAfter;
1010  int minDistLeftOf = 0;
1011  double sqrDist = 0.0;
1012  int vertexOffset = 0;
1013  int ringOffset = 0;
1014  int partOffset = 0;
1015 
1016  for ( int i = 0; i < container.size(); ++i )
1017  {
1018  sqrDist = container.at( i )->closestSegment( pt, segmentPt, vertexAfter, leftOf, epsilon );
1019  if ( sqrDist >= 0 && sqrDist < minDist )
1020  {
1021  minDist = sqrDist;
1022  minDistSegmentX = segmentPt.x();
1023  minDistSegmentY = segmentPt.y();
1024  minDistVertexAfter = vertexAfter;
1025  minDistVertexAfter.vertex = vertexAfter.vertex + vertexOffset;
1026  minDistVertexAfter.part = vertexAfter.part + partOffset;
1027  minDistVertexAfter.ring = vertexAfter.ring + ringOffset;
1028  if ( leftOf )
1029  {
1030  minDistLeftOf = *leftOf;
1031  }
1032  }
1033 
1034  if ( ctype == Vertex )
1035  {
1036  //-1 because compoundcurve counts duplicated vertices of neighbour curves as one node
1037  vertexOffset += container.at( i )->nCoordinates() - 1;
1038  }
1039  else if ( ctype == Ring )
1040  {
1041  ringOffset += 1;
1042  }
1043  else if ( ctype == Part )
1044  {
1045  partOffset += 1;
1046  }
1047  }
1048 
1049  if ( minDist == std::numeric_limits<double>::max() )
1050  return -1; // error: no segments
1051 
1052  segmentPt.setX( minDistSegmentX );
1053  segmentPt.setY( minDistSegmentY );
1054  vertexAfter = minDistVertexAfter;
1055  if ( leftOf )
1056  {
1057  *leftOf = minDistLeftOf;
1058  }
1059  return minDist;
1060  }
1061 };
1062 
1063 #endif // QGSGEOMETRYUTILS_H
Abstract base class for all geometries.
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
Contains various geometry utility functions.
static bool transferFirstZOrMValueToPoint(const QgsPointSequence &points, QgsPoint &point)
A Z or M dimension is added to point if one of the points in the list points contains Z or M value.
static QgsPoint projectPointOnSegment(const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2) SIP_HOLDGIL
Project the point on a segment.
static bool transferFirstZOrMValueToPoint(const QgsGeometry &geom, QgsPoint &point)
A Z or M dimension is added to point if one of the points in the list points contains Z or M value.
static double closestSegmentFromComponents(T &container, ComponentType ctype, const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf, double epsilon)
static bool transferFirstZOrMValueToPoint(Iterator verticesBegin, Iterator verticesEnd, QgsPoint &point)
A Z or M dimension is added to point if one of the points in the list points contains Z or M value.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:125
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:44
A class to represent a 2D point.
Definition: qgspointxy.h:59
double y
Definition: qgspointxy.h:63
Q_GADGET double x
Definition: qgspointxy.h:62
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
bool convertTo(QgsWkbTypes::Type type) override
Converts the geometry to a specified type.
Definition: qgspoint.cpp:620
void setZ(double z) SIP_HOLDGIL
Sets the point's z-coordinate.
Definition: qgspoint.h:304
void setM(double m) SIP_HOLDGIL
Sets the point's m-value.
Definition: qgspoint.h:319
A class to represent a vector.
Definition: qgsvector.h:30
WKB pointer handler.
Definition: qgswkbptr.h:44
Handles storage of information regarding WKB types and their properties.
Definition: qgswkbtypes.h:42
static Type addZ(Type type) SIP_HOLDGIL
Adds the z dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1176
static Type addM(Type type) SIP_HOLDGIL
Adds the m dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1201
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)
Definition: MathUtils.cpp:786
bool ANALYSIS_EXPORT lineIntersection(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Returns true, if line1 (p1 to p2) and line2 (p3 to p4) intersect. If the lines have an endpoint in co...
Definition: MathUtils.cpp:311
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'. Negative values mean left ...
Definition: MathUtils.cpp:292
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
#define SIP_PYALTERNATIVETYPE(type)
Definition: qgis_sip.h:141
#define SIP_DEPRECATED
Definition: qgis_sip.h:106
#define SIP_SKIP
Definition: qgis_sip.h:126
#define SIP_OUT
Definition: qgis_sip.h:58
#define SIP_HOLDGIL
Definition: qgis_sip.h:166
#define SIP_FACTORY
Definition: qgis_sip.h:76
#define SIP_INOUT
Definition: qgis_sip.h:71
QVector< QgsPoint > QgsPointSequence
int precision
Utility class for identifying a unique vertex within a geometry.
Definition: qgsvertexid.h:31
int vertex
Vertex number.
Definition: qgsvertexid.h:95
int part
Part number.
Definition: qgsvertexid.h:89
int ring
Ring number.
Definition: qgsvertexid.h:92