QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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 *
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 "qgsabstractgeometry.h"
25 #include "qgsvector3d.h"
26
27 #include <QJsonArray>
28
29 class QgsLineString;
30
37 class CORE_EXPORT QgsGeometryUtils
38 {
39  public:
40
45  static QVector<QgsLineString *> extractLineStrings( const QgsAbstractGeometry *geom ) SIP_FACTORY;
46
51  static QgsPoint closestVertex( const QgsAbstractGeometry &geom, const QgsPoint &pt, QgsVertexId &id SIP_OUT );
52
58  static QgsPoint closestPoint( const QgsAbstractGeometry &geometry, const QgsPoint &point );
59
67  static double distanceToVertex( const QgsAbstractGeometry &geom, QgsVertexId id );
68
80  static bool verticesAtDistance( const QgsAbstractGeometry &geometry,
81  double distance,
82  QgsVertexId &previousVertex SIP_OUT,
83  QgsVertexId &nextVertex SIP_OUT );
84
88  static double sqrDistance2D( const QgsPoint &pt1, const QgsPoint &pt2 ) SIP_HOLDGIL;
89
93  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;
94
106  static bool lineIntersection( const QgsPoint &p1, QgsVector v1, const QgsPoint &p2, QgsVector v2, QgsPoint &intersection SIP_OUT ) SIP_HOLDGIL;
107
144  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;
145
157  static bool lineCircleIntersection( const QgsPointXY &center, double radius,
158  const QgsPointXY &linePoint1, const QgsPointXY &linePoint2,
159  QgsPointXY &intersection SIP_INOUT ) SIP_HOLDGIL;
160
171  static int circleCircleIntersections( QgsPointXY center1, double radius1,
173  QgsPointXY &intersection1 SIP_OUT, QgsPointXY &intersection2 SIP_OUT ) SIP_HOLDGIL;
174
183  static bool tangentPointAndCircle( const QgsPointXY &center, double radius,
185
203  static int circleCircleOuterTangents(
205  QgsPointXY &line1P1 SIP_OUT, QgsPointXY &line1P2 SIP_OUT,
206  QgsPointXY &line2P1 SIP_OUT, QgsPointXY &line2P2 SIP_OUT ) SIP_HOLDGIL;
207
226  static int circleCircleInnerTangents(
228  QgsPointXY &line1P1 SIP_OUT, QgsPointXY &line1P2 SIP_OUT,
229  QgsPointXY &line2P1 SIP_OUT, QgsPointXY &line2P2 SIP_OUT ) SIP_HOLDGIL;
230
238  static QgsPoint projectPointOnSegment( const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2 ) SIP_HOLDGIL
239  {
240  double nx = s2.y() - s1.y();
241  double ny = -( s2.x() - s1.x() );
242  double t = ( p.x() * ny - p.y() * nx - s1.x() * ny + s1.y() * nx ) / ( ( s2.x() - s1.x() ) * ny - ( s2.y() - s1.y() ) * nx );
243  return t < 0. ? s1 : t > 1. ? s2 : QgsPoint( s1.x() + ( s2.x() - s1.x() ) * t, s1.y() + ( s2.y() - s1.y() ) * t );
244  }
245
248  {
249  int segment1;
250  int segment2;
252  };
253
264  static QVector<SelfIntersection> selfIntersections( const QgsAbstractGeometry *geom, int part, int ring, double tolerance ) SIP_SKIP;
265
273  static int leftOfLine( const double x, const double y, const double x1, const double y1, const double x2, const double y2 ) SIP_HOLDGIL;
274
284  static int leftOfLine( const QgsPoint &point, const QgsPoint &p1, const QgsPoint &p2 ) SIP_HOLDGIL;
285
289  static QgsPoint pointOnLineWithDistance( const QgsPoint &startPoint, const QgsPoint &directionPoint, double distance ) SIP_HOLDGIL;
290
300  static void pointOnLineWithDistance( double x1, double y1, double x2, double y2, double distance, double &x, double &y,
301  double *z1 = nullptr, double *z2 = nullptr, double *z = nullptr,
302  double *m1 = nullptr, double *m2 = nullptr, double *m = nullptr ) SIP_SKIP;
303
312  static QgsPoint interpolatePointOnArc( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double distance ) SIP_HOLDGIL;
313
315  static double ccwAngle( double dy, double dx ) SIP_HOLDGIL;
316
318  static void circleCenterRadius( const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double &radius SIP_OUT,
319  double &centerX SIP_OUT, double &centerY SIP_OUT ) SIP_HOLDGIL;
320
327  static bool circleClockwise( double angle1, double angle2, double angle3 ) SIP_HOLDGIL;
328
330  static bool circleAngleBetween( double angle, double angle1, double angle2, bool clockwise ) SIP_HOLDGIL;
331
336  static bool angleOnCircle( double angle, double angle1, double angle2, double angle3 ) SIP_HOLDGIL;
337
339  static double circleLength( double x1, double y1, double x2, double y2, double x3, double y3 ) SIP_HOLDGIL;
340
342  static double sweepAngle( double centerX, double centerY, double x1, double y1, double x2, double y2, double x3, double y3 ) SIP_HOLDGIL;
343
350  static bool segmentMidPoint( const QgsPoint &p1, const QgsPoint &p2, QgsPoint &result SIP_OUT, double radius, const QgsPoint &mousePos ) SIP_HOLDGIL;
351
363  static QgsPoint segmentMidPointFromCenter( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &center, bool useShortestArc = true ) SIP_HOLDGIL;
364
366  static double circleTangentDirection( const QgsPoint &tangentPoint, const QgsPoint &cp1, const QgsPoint &cp2, const QgsPoint &cp3 ) SIP_HOLDGIL;
367
372  static void segmentizeArc( const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &p3,
373  QgsPointSequence SIP_PYALTERNATIVETYPE( QVector<QgsPoint> ) &points SIP_OUT, double tolerance = M_PI_2 / 90,
374  QgsAbstractGeometry::SegmentationToleranceType toleranceType = QgsAbstractGeometry::MaximumAngle,
375  bool hasZ = false, bool hasM = false );
376
392  static bool pointContinuesArc( const QgsPoint &a1, const QgsPoint &a2, const QgsPoint &a3, const QgsPoint &b, double distanceTolerance,
393  double pointSpacingAngleTolerance ) SIP_HOLDGIL;
394
400  static int segmentSide( const QgsPoint &pt1, const QgsPoint &pt3, const QgsPoint &pt2 ) SIP_HOLDGIL;
401
406  static double interpolateArcValue( double angle, double a1, double a2, double a3, double zm1, double zm2, double zm3 ) SIP_HOLDGIL;
407
412  static QgsPointSequence pointsFromWKT( const QString &wktCoordinateList, bool is3D, bool isMeasure ) SIP_SKIP;
413
418  static void pointsToWKB( QgsWkbPtr &wkb, const QgsPointSequence &points, bool is3D, bool isMeasure ) SIP_SKIP;
419
424  static QString pointsToWKT( const QgsPointSequence &points, int precision, bool is3D, bool isMeasure ) SIP_SKIP;
425
430  static QDomElement pointsToGML2( const QgsPointSequence &points, QDomDocument &doc, int precision, const QString &ns, QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) SIP_SKIP;
431
436  static QDomElement pointsToGML3( const QgsPointSequence &points, QDomDocument &doc, int precision, const QString &ns, bool is3D, QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) SIP_SKIP;
437
442  static QString pointsToJSON( const QgsPointSequence &points, int precision ) SIP_SKIP;
443
448  static json pointsToJson( const QgsPointSequence &points, int precision ) SIP_SKIP;
449
455  static double normalizedAngle( double angle ) SIP_HOLDGIL;
456
465  static double lineAngle( double x1, double y1, double x2, double y2 ) SIP_HOLDGIL;
466
478  static double angleBetweenThreePoints( double x1, double y1, double x2, double y2,
479  double x3, double y3 ) SIP_HOLDGIL;
480
490  static double linePerpendicularAngle( double x1, double y1, double x2, double y2 ) SIP_HOLDGIL;
491
496  static double averageAngle( double x1, double y1, double x2, double y2, double x3, double y3 ) SIP_HOLDGIL;
497
504  static double averageAngle( double a1, double a2 ) SIP_HOLDGIL;
505
510  static QPair<QgsWkbTypes::Type, QString> wktReadBlock( const QString &wkt ) SIP_SKIP;
511
519  static QStringList wktGetChildBlocks( const QString &wkt, const QString &defaultType = QString() ) SIP_SKIP;
520
544  static QgsPoint midpoint( const QgsPoint &pt1, const QgsPoint &pt2 ) SIP_HOLDGIL;
545
559  static QgsPointXY interpolatePointOnLine( double x1, double y1, double x2, double y2, double fraction ) SIP_HOLDGIL;
560
577  static QgsPoint interpolatePointOnLine( const QgsPoint &p1, const QgsPoint &p2, double fraction ) SIP_HOLDGIL;
578
591  static QgsPointXY interpolatePointOnLineByValue( double x1, double y1, double v1, double x2, double y2, double v2, double value ) SIP_HOLDGIL;
592
600  static double gradient( const QgsPoint &pt1, const QgsPoint &pt2 ) SIP_HOLDGIL;
601
611  static void coefficients( const QgsPoint &pt1, const QgsPoint &pt2,
612  double &a SIP_OUT, double &b SIP_OUT, double &c SIP_OUT ) SIP_HOLDGIL;
613
621  static QgsLineString perpendicularSegment( const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2 ) SIP_HOLDGIL;
622
623
632  static double skewLinesDistance( const QgsVector3D &P1, const QgsVector3D &P12,
633  const QgsVector3D &P2, const QgsVector3D &P22 ) SIP_HOLDGIL;
634
645  static bool skewLinesProjection( const QgsVector3D &P1, const QgsVector3D &P12,
646  const QgsVector3D &P2, const QgsVector3D &P22,
647  QgsVector3D &X1 SIP_OUT,
648  double epsilon = 0.0001 ) SIP_HOLDGIL;
649
686  static bool linesIntersection3D( const QgsVector3D &La1, const QgsVector3D &La2,
687  const QgsVector3D &Lb1, const QgsVector3D &Lb2,
688  QgsVector3D &intersection SIP_OUT ) SIP_HOLDGIL;
689
696  static double triangleArea( double aX, double aY, double bX, double bY, double cX, double cY ) SIP_HOLDGIL;
697
715  static void weightedPointInTriangle( double aX, double aY, double bX, double bY, double cX, double cY,
716  double weightB, double weightC, double &pointX SIP_OUT, double &pointY SIP_OUT ) SIP_HOLDGIL;
717
728  static bool setZValueFromPoints( const QgsPointSequence &points, QgsPoint &point );
729
732  {
735  Part
736  };
737
739  template<class T> static double closestSegmentFromComponents( T &container, ComponentType ctype, const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf, double epsilon ) SIP_SKIP
740  {
741  double minDist = std::numeric_limits<double>::max();
742  double minDistSegmentX = 0.0, minDistSegmentY = 0.0;
743  QgsVertexId minDistVertexAfter;
744  int minDistLeftOf = 0;
745  double sqrDist = 0.0;
746  int vertexOffset = 0;
747  int ringOffset = 0;
748  int partOffset = 0;
749
750  for ( int i = 0; i < container.size(); ++i )
751  {
752  sqrDist = container.at( i )->closestSegment( pt, segmentPt, vertexAfter, leftOf, epsilon );
753  if ( sqrDist >= 0 && sqrDist < minDist )
754  {
755  minDist = sqrDist;
756  minDistSegmentX = segmentPt.x();
757  minDistSegmentY = segmentPt.y();
758  minDistVertexAfter = vertexAfter;
759  minDistVertexAfter.vertex = vertexAfter.vertex + vertexOffset;
760  minDistVertexAfter.part = vertexAfter.part + partOffset;
761  minDistVertexAfter.ring = vertexAfter.ring + ringOffset;
762  if ( leftOf )
763  {
764  minDistLeftOf = *leftOf;
765  }
766  }
767
768  if ( ctype == Vertex )
769  {
770  //-1 because compoundcurve counts duplicated vertices of neighbour curves as one node
771  vertexOffset += container.at( i )->nCoordinates() - 1;
772  }
773  else if ( ctype == Ring )
774  {
775  ringOffset += 1;
776  }
777  else if ( ctype == Part )
778  {
779  partOffset += 1;
780  }
781  }
782
783  if ( minDist == std::numeric_limits<double>::max() )
784  return -1; // error: no segments
785
786  segmentPt.setX( minDistSegmentX );
787  segmentPt.setY( minDistSegmentY );
788  vertexAfter = minDistVertexAfter;
789  if ( leftOf )
790  {
791  *leftOf = minDistLeftOf;
792  }
793  return minDist;
794  }
795 };
796
797 #endif // QGSGEOMETRYUTILS_H
QgsVertexId::part
int part
Part number.
Definition: qgsabstractgeometry.h:1131
QgsVertexId::vertex
int vertex
Vertex number.
Definition: qgsabstractgeometry.h:1137
QgsPointXY::y
double y
Definition: qgspointxy.h:48
QgsGeometryUtils::Vertex
@ Vertex
Definition: qgsgeometryutils.h:733
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:38
QgsVector3D
3 Class for storage of 3D vectors similar to QVector3D, with the difference that it uses double preci...
Definition: qgsvector3d.h:32
SIP_OUT
#define SIP_OUT
Definition: qgis_sip.h:58
QgsPointXY::x
Definition: qgspointxy.h:47
QgsGeometryUtils::projectPointOnSegment
static QgsPoint projectPointOnSegment(const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2) SIP_HOLDGIL
Project the point on a segment.
Definition: qgsgeometryutils.h:238
QgsGeometryUtils::SelfIntersection::segment1
int segment1
Definition: qgsgeometryutils.h:249
QgsGeometryUtils
Contains various geometry utility functions.
Definition: qgsgeometryutils.h:38
qgspoint.h
QgsLineString
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:44
SIP_FACTORY
#define SIP_FACTORY
Definition: qgis_sip.h:76
MathUtils::leftOf
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
precision
int precision
Definition: qgswfsgetfeature.cpp:49
SIP_SKIP
#define SIP_SKIP
Definition: qgis_sip.h:126
SIP_HOLDGIL
#define SIP_HOLDGIL
Definition: qgis_sip.h:157
QgsGeometryUtils::closestSegmentFromComponents
static double closestSegmentFromComponents(T &container, ComponentType ctype, const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf, double epsilon)
Definition: qgsgeometryutils.h:739
QgsGeometryUtils::SelfIntersection::point
QgsPoint point
Definition: qgsgeometryutils.h:251
MathUtils::lineIntersection
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
qgis_sip.h
QgsGeometryUtils::Ring
@ Ring
Definition: qgsgeometryutils.h:734
QgsWkbPtr
Definition: qgswkbptr.h:43
QgsAbstractGeometry
Abstract base class for all geometries.
Definition: qgsabstractgeometry.h:74
SIP_INOUT
#define SIP_INOUT
Definition: qgis_sip.h:71
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:44
QgsGeometryUtils::ComponentType
ComponentType
Definition: qgsgeometryutils.h:732
qgsvector3d.h
QgsPointSequence
QVector< QgsPoint > QgsPointSequence
Definition: qgsabstractgeometry.h:46
c
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
Definition: porting_processing.dox:1
QgsVector
A class to represent a vector.
Definition: qgsvector.h:30
QgsVertexId
Utility class for identifying a unique vertex within a geometry.
Definition: qgsabstractgeometry.h:1059
QgsVertexId::ring
int ring
Ring number.
Definition: qgsabstractgeometry.h:1134
QgsWkbTypes
Handles storage of information regarding WKB types and their properties.
Definition: qgswkbtypes.h:42
MathUtils::angle
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
qgsabstractgeometry.h
SIP_PYALTERNATIVETYPE
#define SIP_PYALTERNATIVETYPE(type)
Definition: qgis_sip.h:136
QgsGeometryUtils::SelfIntersection::segment2
int segment2
Definition: qgsgeometryutils.h:250