27#include <QRegularExpression>
28#include <nlohmann/json.hpp>
32 QVector< QgsLineString * > linestrings;
36 QVector< const QgsAbstractGeometry * > geometries;
38 while ( ! geometries.isEmpty() )
41 if (
const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( g ) )
43 linestrings << static_cast< QgsLineString * >( curve->segmentize() );
45 else if (
const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( g ) )
47 for (
int i = 0; i < collection->numGeometries(); ++i )
49 geometries.append( collection->geometryN( i ) );
52 else if (
const QgsCurvePolygon *curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( g ) )
54 if ( curvePolygon->exteriorRing() )
55 linestrings << static_cast< QgsLineString * >( curvePolygon->exteriorRing()->segmentize() );
57 for (
int i = 0; i < curvePolygon->numInteriorRings(); ++i )
59 linestrings << static_cast< QgsLineString * >( curvePolygon->interiorRing( i )->segmentize() );
68 double minDist = std::numeric_limits<double>::max();
69 double currentDist = 0;
86 if ( currentDist <= minDist )
88 minDist = currentDist;
89 minDistPoint = vertex;
90 id.part = vertexId.
part;
91 id.ring = vertexId.
ring;
92 id.vertex = vertexId.
vertex;
93 id.type = vertexId.
type;
108 if ( vertexAfter.
vertex > 0 )
113 const double length = pointBefore.
distance( pointAfter );
135 double currentDist = 0;
140 if ( vertexId ==
id )
154 double currentDist = 0;
169 nextVertex = previousVertex;
174 while ( currentDist < distance && geometry.
nextVertex( nextVertex, point ) )
176 if ( !first && nextVertex.
part == previousVertex.
part && nextVertex.
ring == previousVertex.
ring )
184 previousVertex = nextVertex;
188 if ( currentDist > distance )
193 previousVertex = nextVertex;
194 previousPoint = point;
204 return ( pt1.
x() - pt2.
x() ) * ( pt1.
x() - pt2.
x() ) + ( pt1.
y() - pt2.
y() ) * ( pt1.
y() - pt2.
y() );
217 const double t = ( ( ptX - x1 ) * dx + ( ptY - y1 ) * dy ) / ( dx * dx + dy * dy );
233 const double dist = dx * dx + dy * dy;
248 const double area = std::abs(
249 ( linePoint1.
x() - linePoint2.
x() ) * ( point.
y() - linePoint2.
y() ) -
250 ( linePoint1.
y() - linePoint2.
y() ) * ( point.
x() - linePoint2.
x() )
253 const double length = std::sqrt(
254 std::pow( linePoint1.
x() - linePoint2.
x(), 2 ) +
255 std::pow( linePoint1.
y() - linePoint2.
y(), 2 )
258 const double distance = area / length;
259 return qgsDoubleNear( distance, 0.0, epsilon ) ? 0.0 : distance;
264 const double d = v1.
y() * v2.
x() - v1.
x() * v2.
y();
269 const double dx = p2.
x() - p1.
x();
270 const double dy = p2.
y() - p1.
y();
271 const double k = ( dy * v2.
x() - dx * v2.
y() ) / d;
273 intersection =
QgsPoint( p1.
x() + v1.
x() * k, p1.
y() + v1.
y() * k );
283 isIntersection =
false;
287 const double vl = v.
length();
288 const double wl = w.
length();
302 isIntersection =
true;
303 if ( acceptImproperIntersection )
305 if ( ( p1 == q1 ) || ( p1 == q2 ) )
307 intersectionPoint = p1;
310 else if ( ( p2 == q1 ) || ( p2 == q2 ) )
312 intersectionPoint = p2;
319 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( p1.
x(), p1.
y(), q1.
x(), q1.
y(), q2.
x(), q2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
321 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( p2.
x(), p2.
y(), q1.
x(), q1.
y(), q2.
x(), q2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
323 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( q1.
x(), q1.
y(), p1.
x(), p1.
y(), p2.
x(), p2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
325 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( q2.
x(), q2.
y(), p1.
x(), p1.
y(), p2.
x(), p2.
y(), x, y, tolerance ), 0.0, tolerance )
332 const double lambdav =
QgsVector( intersectionPoint.
x() - p1.
x(), intersectionPoint.
y() - p1.
y() ) * v;
333 if ( lambdav < 0. + tolerance || lambdav > vl - tolerance )
336 const double lambdaw =
QgsVector( intersectionPoint.
x() - q1.
x(), intersectionPoint.
y() - q1.
y() ) * w;
337 return !( lambdaw < 0. + tolerance || lambdaw >= wl - tolerance );
347 const double x1 = linePoint1.
x() - center.
x();
348 const double y1 = linePoint1.
y() - center.
y();
349 const double x2 = linePoint2.
x() - center.
x();
350 const double y2 = linePoint2.
y() - center.
y();
351 const double dx = x2 - x1;
352 const double dy = y2 - y1;
354 const double dr2 = std::pow( dx, 2 ) + std::pow( dy, 2 );
355 const double d = x1 * y2 - x2 * y1;
357 const double disc = std::pow( radius, 2 ) * dr2 - std::pow( d, 2 );
367 const int sgnDy = dy < 0 ? -1 : 1;
369 const double sqrDisc = std::sqrt( disc );
371 const double ax = center.
x() + ( d * dy + sgnDy * dx * sqrDisc ) / dr2;
372 const double ay = center.
y() + ( -d * dx + std::fabs( dy ) * sqrDisc ) / dr2;
375 const double bx = center.
x() + ( d * dy - sgnDy * dx * sqrDisc ) / dr2;
376 const double by = center.
y() + ( -d * dx - std::fabs( dy ) * sqrDisc ) / dr2;
383 intersection.
set( p1.
x(), p1.
y() );
387 intersection.
set( p2.
x(), p2.
y() );
398 const double d = center1.
distance( center2 );
402 const bool singleSolutionInt =
qgsDoubleNear( d, std::fabs( r1 - r2 ) );
405 if ( !singleSolutionExt && d > ( r1 + r2 ) )
410 else if ( !singleSolutionInt && d < std::fabs( r1 - r2 ) )
430 const double a = singleSolutionExt ? r1 : ( singleSolutionInt ? ( r1 > r2 ? r1 : -r1 ) : ( ( r1 * r1 ) - ( r2 * r2 ) + ( d * d ) ) / ( 2.0 * d ) );
435 const double dx = center2.
x() - center1.
x();
436 const double dy = center2.
y() - center1.
y();
439 const double x2 = center1.
x() + ( dx * a / d );
440 const double y2 = center1.
y() + ( dy * a / d );
443 if ( singleSolutionExt || singleSolutionInt )
456 const double h = std::sqrt( ( r1 * r1 ) - ( a * a ) );
461 const double rx = dy * ( h / d );
462 const double ry = dx * ( h / d );
465 intersection1 =
QgsPointXY( x2 + rx, y2 - ry );
466 intersection2 =
QgsPointXY( x2 - rx, y2 + ry );
476 const double dx = center.
x() - p.
x();
477 const double dy = center.
y() - p.
y();
478 const double distanceSquared = dx * dx + dy * dy;
479 const double radiusSquared = radius * radius;
480 if ( distanceSquared < radiusSquared )
487 const double distanceToTangent = std::sqrt( distanceSquared - radiusSquared );
499 if ( radius1 > radius2 )
502 const double radius2a = radius2 - radius1;
511 QgsVector v1( -( line1P2.
y() - center1.
y() ), line1P2.
x() - center1.
x() );
512 const double v1Length = v1.
length();
513 v1 = v1 * ( radius1 / v1Length );
516 line1P1 = center1 + v1;
517 line1P2 = line1P2 + v1;
521 QgsVector v2( line2P2.
y() - center1.
y(), -( line2P2.
x() - center1.
x() ) );
522 const double v2Length = v2.
length();
523 v2 = v2 * ( radius1 / v2Length );
526 line2P1 = center1 + v2;
527 line2P2 = line2P2 + v2;
535 if ( radius1 > radius2 )
539 const double d = center1.
distance( center2 );
540 const double radius1a = radius1 + radius2;
557 QgsVector v1( ( line1P2.
y() - center2.
y() ), -( line1P2.
x() - center2.
x() ) );
558 const double v1Length = v1.
length();
559 v1 = v1 * ( radius2 / v1Length );
562 line1P1 = center2 + v1;
563 line1P2 = line1P2 + v1;
567 QgsVector v2( -( line2P2.
y() - center2.
y() ), line2P2.
x() - center2.
x() );
568 const double v2Length = v2.
length();
569 v2 = v2 * ( radius2 / v2Length );
572 line2P1 = center2 + v2;
573 line2P2 = line2P2 + v2;
580 QVector<SelfIntersection> intersections;
586 for (
int i = 0, j = 1; j < n; i = j++ )
593 const int start = j + 1;
594 const int end = i == 0 && isClosed ? n - 1 : n;
595 for (
int k = start, l = start + 1; l < end; k = l++ )
601 bool intersection =
false;
612 intersections.append( s );
615 return intersections;
625 const double f1 = x - x1;
626 const double f2 = y2 - y1;
627 const double f3 = y - y1;
628 const double f4 = x2 - x1;
629 const double test = ( f1 * f2 - f3 * f4 );
631 return qgsDoubleNear( test, 0.0 ) ? 0 : ( test < 0 ? -1 : 1 );
641void QgsGeometryUtils::pointOnLineWithDistance(
double x1,
double y1,
double x2,
double y2,
double distance,
double &x,
double &y,
double *z1,
double *z2,
double *z,
double *m1,
double *m2,
double *m )
643 const double dx = x2 - x1;
644 const double dy = y2 - y1;
645 const double length = std::sqrt( dx * dx + dy * dy );
658 const double scaleFactor = distance / length;
659 x = x1 + dx * scaleFactor;
660 y = y1 + dy * scaleFactor;
662 *z = *z1 + ( *z2 - *z1 ) * scaleFactor;
664 *m = *m1 + ( *m2 - *m1 ) * scaleFactor;
671 const double mX = x1 + ( x2 - x1 ) * proportion;
672 const double mY = y1 + ( y2 - y1 ) * proportion;
673 const double pX = x1 - x2;
674 const double pY = y1 - y2;
675 double normalX = -pY;
677 const double normalLength = sqrt( ( normalX * normalX ) + ( normalY * normalY ) );
678 normalX /= normalLength;
679 normalY /= normalLength;
681 *x = mX + offset * normalX;
682 *y = mY + offset * normalY;
687 double centerX, centerY, radius;
690 const double theta = distance / radius;
691 const double anglePt1 = std::atan2( pt1.
y() - centerY, pt1.
x() - centerX );
692 const double anglePt2 = std::atan2( pt2.
y() - centerY, pt2.
x() - centerX );
693 const double anglePt3 = std::atan2( pt3.
y() - centerY, pt3.
x() - centerX );
695 const double angleDest = anglePt1 + (
isClockwise ? -theta : theta );
697 const double x = centerX + radius * ( std::cos( angleDest ) );
698 const double y = centerY + radius * ( std::sin( angleDest ) );
700 const double z = pt1.
is3D() ?
712 const double angle = std::atan2( dy, dx ) * 180 / M_PI;
717 else if ( angle > 360 )
726 double dx21, dy21, dx31, dy31, h21, h31, d;
731 centerX = ( pt1.
x() + pt2.
x() ) / 2.0;
732 centerY = ( pt1.
y() + pt2.
y() ) / 2.0;
733 radius = std::sqrt( std::pow( centerX - pt1.
x(), 2.0 ) + std::pow( centerY - pt1.
y(), 2.0 ) );
738 dx21 = pt2.
x() - pt1.
x();
739 dy21 = pt2.
y() - pt1.
y();
740 dx31 = pt3.
x() - pt1.
x();
741 dy31 = pt3.
y() - pt1.
y();
743 h21 = std::pow( dx21, 2.0 ) + std::pow( dy21, 2.0 );
744 h31 = std::pow( dx31, 2.0 ) + std::pow( dy31, 2.0 );
747 d = 2 * ( dx21 * dy31 - dx31 * dy21 );
757 centerX = pt1.
x() + ( h21 * dy31 - h31 * dy21 ) / d;
758 centerY = pt1.
y() - ( h21 * dx31 - h31 * dx21 ) / d;
759 radius = std::sqrt( std::pow( centerX - pt1.
x(), 2.0 ) + std::pow( centerY - pt1.
y(), 2.0 ) );
764 if ( angle3 >= angle1 )
766 return !( angle2 > angle1 && angle2 < angle3 );
770 return !( angle2 > angle1 || angle2 < angle3 );
778 if ( angle2 < angle1 )
780 return ( angle <= angle1 && angle >= angle2 );
784 return ( angle <= angle1 || angle >= angle2 );
789 if ( angle2 > angle1 )
791 return ( angle >= angle1 && angle <= angle2 );
795 return ( angle >= angle1 || angle <= angle2 );
808 double centerX, centerY, radius;
810 double length = M_PI / 180.0 * radius *
sweepAngle( centerX, centerY, x1, y1, x2, y2, x3, y3 );
824 if ( p3Angle >= p1Angle )
826 if ( p2Angle > p1Angle && p2Angle < p3Angle )
828 return ( p3Angle - p1Angle );
832 return ( - ( p1Angle + ( 360 - p3Angle ) ) );
837 if ( p2Angle < p1Angle && p2Angle > p3Angle )
839 return ( -( p1Angle - p3Angle ) );
843 return ( p3Angle + ( 360 - p1Angle ) );
850 const QgsPoint midPoint( ( p1.
x() + p2.
x() ) / 2.0, ( p1.
y() + p2.
y() ) / 2.0 );
851 const double midDist = std::sqrt(
sqrDistance2D( p1, midPoint ) );
852 if ( radius < midDist )
856 const double centerMidDist = std::sqrt( radius * radius - midDist * midDist );
857 const double dist = radius - centerMidDist;
859 const double midDx = midPoint.
x() - p1.
x();
860 const double midDy = midPoint.
y() - p1.
y();
863 QVector<QgsPoint> possibleMidPoints;
870 double minDist = std::numeric_limits<double>::max();
871 int minDistIndex = -1;
872 for (
int i = 0; i < possibleMidPoints.size(); ++i )
874 const double currentDist =
sqrDistance2D( mousePos, possibleMidPoints.at( i ) );
875 if ( currentDist < minDist )
878 minDist = currentDist;
882 if ( minDistIndex == -1 )
887 result = possibleMidPoints.at( minDistIndex );
899 if ( !useShortestArc )
900 midPointAngle += M_PI;
901 return center.
project( center.
distance( p1 ), midPointAngle * 180 / M_PI );
908 double mX, mY, radius;
917 angle =
lineAngle( tangentPoint.
x(), tangentPoint.
y(), mX, mY ) - M_PI_2;
921 angle =
lineAngle( mX, mY, tangentPoint.
x(), tangentPoint.
y() ) - M_PI_2;
941 const double bDistance = std::sqrt( ( b.
x() - centerX ) * ( b.
x() - centerX ) +
942 ( b.
y() - centerY ) * ( b.
y() - centerY ) );
944 double diff = std::fabs( radius - bDistance );
948 const double abX = b.
x() - a.
x();
949 const double abY = b.
y() - a.
y();
951 const double cbX = b.
x() -
c.x();
952 const double cbY = b.
y() -
c.y();
954 const double dot = ( abX * cbX + abY * cbY );
955 const double cross = ( abX * cbY - abY * cbX );
957 const double alpha = std::atan2( cross, dot );
963 if ( diff < distanceTolerance )
965 const double angle1 = arcAngle( a1, a2, a3 );
966 const double angle2 = arcAngle( a2, a3, b );
971 diff = std::fabs( angle1 - angle2 );
972 if ( diff > pointSpacingAngleTolerance )
977 const int a2Side =
leftOfLine( a2.
x(), a2.
y(), a1.
x(), a1.
y(), a3.
x(), a3.
y() );
978 const int bSide =
leftOfLine( b.
x(), b.
y(), a1.
x(), a1.
y(), a3.
x(), a3.
y() );
982 if ( bSide != a2Side )
990 bool reversed =
false;
1014 circleCenterRadius( circlePoint1, circlePoint2, circlePoint3, radius, centerX, centerY );
1016 if ( circlePoint1 != circlePoint3 && ( radius < 0 ||
qgsDoubleNear( segSide, 0.0 ) ) )
1018 points.append( p1 );
1019 points.append( p2 );
1020 points.append( p3 );
1024 double increment = tolerance;
1028 tolerance = std::min( tolerance, radius * 2 );
1029 const double halfAngle = std::acos( -tolerance / radius + 1 );
1030 increment = 2 * halfAngle;
1034 const double a1 = std::atan2( circlePoint1.
y() - centerY, circlePoint1.
x() - centerX );
1035 double a2 = std::atan2( circlePoint2.
y() - centerY, circlePoint2.
x() - centerX );
1036 double a3 = std::atan2( circlePoint3.
y() - centerY, circlePoint3.
x() - centerX );
1039 const bool symmetric =
true;
1042 double angle = a3 - a1;
1044 if ( angle <= 0 ) angle += M_PI * 2;
1047 const int segs = ceil( angle / increment );
1049 increment = angle / segs;
1063 QVector<QgsPoint> stringPoints;
1064 stringPoints.insert( 0, circlePoint1 );
1065 if ( circlePoint2 != circlePoint3 && circlePoint1 != circlePoint2 )
1079 const double tolError = increment / 100;
1080 const double stopAngle = a3 - tolError;
1081 for (
double angle = a1 + increment; angle < stopAngle; angle += increment )
1083 x = centerX + radius * std::cos( angle );
1084 y = centerY + radius * std::sin( angle );
1095 stringPoints.insert( stringPoints.size(),
QgsPoint( pointWkbType, x, y, z, m ) );
1098 stringPoints.insert( stringPoints.size(), circlePoint3 );
1103 std::reverse( stringPoints.begin(), stringPoints.end() );
1105 if ( ! points.empty() && stringPoints.front() == points.back() ) stringPoints.pop_front();
1106 points.append( stringPoints );
1111 const double side = ( ( pt2.
x() - pt1.
x() ) * ( pt3.
y() - pt1.
y() ) - ( pt3.
x() - pt1.
x() ) * ( pt2.
y() - pt1.
y() ) );
1136 return zm1 + ( zm2 - zm1 ) * ( angle - a1 ) / ( a2 - a1 );
1138 return zm2 + ( zm3 - zm2 ) * ( angle - a2 ) / ( a3 - a2 );
1144 return zm1 + ( zm2 - zm1 ) * ( a1 - angle ) / ( a1 - a2 );
1146 return zm2 + ( zm3 - zm2 ) * ( a2 - angle ) / ( a2 - a3 );
1152 const int dim = 2 + is3D + isMeasure;
1155#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
1156 const QStringList coordList = wktCoordinateList.split(
',', QString::SkipEmptyParts );
1158 const QStringList coordList = wktCoordinateList.split(
',', Qt::SkipEmptyParts );
1162 bool foundZ =
false;
1163 bool foundM =
false;
1164 const thread_local QRegularExpression rx( QStringLiteral(
"\\s" ) );
1165 const thread_local QRegularExpression rxIsNumber( QStringLiteral(
"^[+-]?(\\d\\.?\\d*[Ee][+\\-]?\\d+|(\\d+\\.\\d*|\\d*\\.\\d+)|\\d+)$" ) );
1166 for (
const QString &pointCoordinates : coordList )
1168#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
1169 QStringList coordinates = pointCoordinates.split( rx, QString::SkipEmptyParts );
1171 const QStringList coordinates = pointCoordinates.split( rx, Qt::SkipEmptyParts );
1175 if ( coordinates.filter( rxIsNumber ).size() != coordinates.size() )
1178 if ( coordinates.size() == 3 && !foundZ && !foundM && !is3D && !isMeasure )
1184 else if ( coordinates.size() >= 4 && ( !( is3D || foundZ ) || !( isMeasure || foundM ) ) )
1193 for (
const QString &pointCoordinates : coordList )
1195#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
1196 QStringList coordinates = pointCoordinates.split( rx, QString::SkipEmptyParts );
1198 QStringList coordinates = pointCoordinates.split( rx, Qt::SkipEmptyParts );
1200 if ( coordinates.size() < dim )
1204 const double x = coordinates[idx++].toDouble();
1205 const double y = coordinates[idx++].toDouble();
1208 if ( ( is3D || foundZ ) && coordinates.length() > idx )
1209 z = coordinates[idx++].toDouble();
1212 if ( ( isMeasure || foundM ) && coordinates.length() > idx )
1213 m = coordinates[idx++].toDouble();
1216 if ( is3D || foundZ )
1218 if ( isMeasure || foundM )
1225 if ( isMeasure || foundM )
1231 points.append(
QgsPoint( t, x, y, z, m ) );
1239 wkb << static_cast<quint32>( points.size() );
1240 for (
const QgsPoint &point : points )
1242 wkb << point.x() << point.y();
1245 double z = point.z();
1247 && std::isnan( z ) )
1248 z = -std::numeric_limits<double>::max();
1254 double m = point.m();
1256 && std::isnan( m ) )
1257 m = -std::numeric_limits<double>::max();
1266 QString wkt = QStringLiteral(
"(" );
1275 wkt += QLatin1String(
", " );
1277 if ( wkt.endsWith( QLatin1String(
", " ) ) )
1285 QDomElement elemCoordinates = doc.createElementNS( ns, QStringLiteral(
"coordinates" ) );
1288 const QString cs = QStringLiteral(
"," );
1290 const QString ts = QStringLiteral(
" " );
1292 elemCoordinates.setAttribute( QStringLiteral(
"cs" ), cs );
1293 elemCoordinates.setAttribute( QStringLiteral(
"ts" ), ts );
1295 QString strCoordinates;
1303 if ( strCoordinates.endsWith( ts ) )
1304 strCoordinates.chop( 1 );
1306 elemCoordinates.appendChild( doc.createTextNode( strCoordinates ) );
1307 return elemCoordinates;
1312 QDomElement elemPosList = doc.createElementNS( ns, QStringLiteral(
"posList" ) );
1313 elemPosList.setAttribute( QStringLiteral(
"srsDimension" ), is3D ? 3 : 2 );
1315 QString strCoordinates;
1325 if ( strCoordinates.endsWith(
' ' ) )
1326 strCoordinates.chop( 1 );
1328 elemPosList.appendChild( doc.createTextNode( strCoordinates ) );
1334 QString json = QStringLiteral(
"[ " );
1339 if ( json.endsWith( QLatin1String(
", " ) ) )
1350 json coordinates( json::array() );
1367 double clippedAngle = angle;
1368 if ( clippedAngle >= M_PI * 2 || clippedAngle <= -2 * M_PI )
1370 clippedAngle = std::fmod( clippedAngle, 2 * M_PI );
1372 if ( clippedAngle < 0.0 )
1374 clippedAngle += 2 * M_PI;
1376 return clippedAngle;
1381 QString wktParsed = wkt;
1383 const QLatin1String empty {
"EMPTY" };
1384 if ( wkt.contains( empty, Qt::CaseInsensitive ) )
1386 const thread_local QRegularExpression whiteSpaces(
"\\s" );
1387 wktParsed.remove( whiteSpaces );
1388 const int index = wktParsed.indexOf( empty, 0, Qt::CaseInsensitive );
1390 if ( index == wktParsed.length() - empty.size() )
1394 wktParsed = wktParsed.left( index );
1400 const int openedParenthesisCount = wktParsed.count(
'(' );
1401 const int closedParenthesisCount = wktParsed.count(
')' );
1403 for (
int i = 0 ; i < openedParenthesisCount - closedParenthesisCount; ++i )
1404 wktParsed.push_back(
')' );
1406 wktParsed.truncate( wktParsed.size() - ( closedParenthesisCount - openedParenthesisCount ) );
1408 const thread_local QRegularExpression cooRegEx( QStringLiteral(
"^[^\\(]*\\((.*)\\)[^\\)]*$" ), QRegularExpression::DotMatchesEverythingOption );
1409 const QRegularExpressionMatch match = cooRegEx.match( wktParsed );
1410 contents = match.hasMatch() ? match.captured( 1 ) : QString();
1413 return qMakePair( wkbType, contents );
1420 block.reserve( wkt.size() );
1423 const QChar *wktData = wkt.data();
1424 const int wktLength = wkt.length();
1425 for (
int i = 0, n = wktLength; i < n; ++i, ++wktData )
1427 if ( ( wktData->isSpace() || *wktData ==
'\n' || *wktData ==
'\t' ) && level == 0 )
1430 if ( *wktData ==
',' && level == 0 )
1432 if ( !block.isEmpty() )
1434 if ( block.startsWith(
'(' ) && !defaultType.isEmpty() )
1435 block.prepend( defaultType +
' ' );
1436 blocks.append( block );
1441 if ( *wktData ==
'(' )
1443 else if ( *wktData ==
')' )
1447 if ( !block.isEmpty() )
1449 if ( block.startsWith(
'(' ) && !defaultType.isEmpty() )
1450 block.prepend( defaultType +
' ' );
1451 blocks.append( block );
1459 if ( x <= left && y <= bottom )
1461 const double dx = left - x;
1462 const double dy = bottom - y;
1470 else if ( x >= right && y >= top )
1472 const double dx = x - right;
1473 const double dy = y - top;
1481 else if ( x >= right && y <= bottom )
1483 const double dx = x - right;
1484 const double dy = bottom - y;
1492 else if ( x <= left && y >= top )
1494 const double dx = left - x;
1495 const double dy = y - top;
1503 else if ( x <= left )
1505 else if ( x >= right )
1507 else if ( y <= bottom )
1509 else if ( y >= top )
1513 const double smallestX = std::min( right - x, x - left );
1514 const double smallestY = std::min( top - y, y - bottom );
1515 if ( smallestX < smallestY )
1518 if ( right - x < x - left )
1526 if ( top - y < y - bottom )
1538 const double x = ( pt1.
x() + pt2.
x() ) / 2.0;
1539 const double y = ( pt1.
y() + pt2.
y() ) / 2.0;
1540 double z = std::numeric_limits<double>::quiet_NaN();
1541 double m = std::numeric_limits<double>::quiet_NaN();
1546 z = ( pt1.
z() + pt2.
z() ) / 2.0;
1552 m = ( pt1.
m() + pt2.
m() ) / 2.0;
1555 return QgsPoint( pType, x, y, z, m );
1560 const double _fraction = 1 - fraction;
1562 p1.
x() * _fraction + p2.
x() * fraction,
1563 p1.
y() * _fraction + p2.
y() * fraction,
1564 p1.
is3D() ? p1.
z() * _fraction + p2.
z() * fraction : std::numeric_limits<double>::quiet_NaN(),
1565 p1.
isMeasure() ? p1.
m() * _fraction + p2.
m() * fraction : std::numeric_limits<double>::quiet_NaN() );
1570 const double deltaX = ( x2 - x1 ) * fraction;
1571 const double deltaY = ( y2 - y1 ) * fraction;
1572 return QgsPointXY( x1 + deltaX, y1 + deltaY );
1580 const double fraction = ( value - v1 ) / ( v2 - v1 );
1586 const double delta_x = pt2.
x() - pt1.
x();
1587 const double delta_y = pt2.
y() - pt1.
y();
1593 return delta_y / delta_x;
1612 a = pt1.
y() - pt2.
y();
1613 b = pt2.
x() - pt1.
x();
1614 c = pt1.
x() * pt2.
y() - pt1.
y() * pt2.
x();
1624 if ( ( p == s1 ) || ( p == s2 ) )
1642 const double y = ( -
c - a * p.
x() ) / b;
1643 const double m =
gradient( s1, s2 );
1644 const double d2 = 1 + m * m;
1645 const double H = p.
y() - y;
1646 const double dx = m * H / d2;
1647 const double dy = m * dx;
1657void QgsGeometryUtils::perpendicularCenterSegment(
double pointx,
double pointy,
double segmentPoint1x,
double segmentPoint1y,
double segmentPoint2x,
double segmentPoint2y,
double &perpendicularSegmentPoint1x,
double &perpendicularSegmentPoint1y,
double &perpendicularSegmentPoint2x,
double &perpendicularSegmentPoint2y,
double desiredSegmentLength )
1659 QgsVector segmentVector =
QgsVector( segmentPoint2x - segmentPoint1x, segmentPoint2y - segmentPoint1y );
1661 if ( desiredSegmentLength != 0 )
1663 perpendicularVector = perpendicularVector.
normalized() * ( desiredSegmentLength ) / 2;
1666 perpendicularSegmentPoint1x = pointx - perpendicularVector.
x();
1667 perpendicularSegmentPoint1y = pointy - perpendicularVector.
y();
1668 perpendicularSegmentPoint2x = pointx + perpendicularVector.
x();
1669 perpendicularSegmentPoint2y = pointy + perpendicularVector.
y();
1674 const double at = std::atan2( y2 - y1, x2 - x1 );
1675 const double a = -at + M_PI_2;
1681 const double angle1 = std::atan2( y1 - y2, x1 - x2 );
1682 const double angle2 = std::atan2( y3 - y2, x3 - x2 );
1696 const double a1 =
lineAngle( x1, y1, x2, y2 );
1697 const double a2 =
lineAngle( x2, y2, x3, y3 );
1705 double clockwiseDiff = 0.0;
1708 clockwiseDiff = a2 - a1;
1712 clockwiseDiff = a2 + ( 2 * M_PI - a1 );
1714 const double counterClockwiseDiff = 2 * M_PI - clockwiseDiff;
1716 double resultAngle = 0;
1717 if ( clockwiseDiff <= counterClockwiseDiff )
1719 resultAngle = a1 + clockwiseDiff / 2.0;
1723 resultAngle = a1 - counterClockwiseDiff / 2.0;
1734 if ( u3.
length() == 0 )
return 1;
1751 if ( std::fabs( u3.
x() ) <= epsilon &&
1752 std::fabs( u3.
y() ) <= epsilon &&
1753 std::fabs( u3.
z() ) <= epsilon )
1765 if ( !( std::fabs( b1 ) > epsilon ) )
1770 if ( !( a2 != -1 && a2 != 1 ) )
1776 const double r1 = ( c2 - b2 * c1 / b1 ) / ( a2 - b2 * a1 / b1 );
1792 bool isIntersection;
1801 intersection.
set( ptInter.
x(), ptInter.
y(), La1.
z() );
1841 if ( !firstIsDone || !secondIsDone )
1847 intersection = ( X1 + X2 ) / 2.0;
1853 return 0.5 * std::abs( ( aX - cX ) * ( bY - aY ) - ( aX - bX ) * ( cY - aY ) );
1858 const double dxp = px - x1;
1859 const double dyp = py - y1;
1861 const double dxl = x2 - x1;
1862 const double dyl = y2 - y1;
1864 return std::sqrt( ( dxp * dxp ) + ( dyp * dyp ) ) / std::sqrt( ( dxl * dxl ) + ( dyl * dyl ) );
1868 double weightB,
double weightC,
double &pointX,
double &pointY )
1871 if ( weightB + weightC > 1 )
1873 weightB = 1 - weightB;
1874 weightC = 1 - weightC;
1877 const double rBx = weightB * ( bX - aX );
1878 const double rBy = weightB * ( bY - aY );
1879 const double rCx = weightC * ( cX - aX );
1880 const double rCy = weightC * ( cY - aY );
1882 pointX = rBx + rCx + aX;
1883 pointY = rBy + rCy + aY;
1888 return qgsDoubleNear( x1 * ( y2 - y3 ) + x2 * ( y3 - y1 ) + x3 * ( y1 - y2 ), 0, epsilon );
1895 for (
const QgsPoint &pt : points )
1897 if ( pt.isMeasure() )
1900 point.
setM( pt.m() );
1913 for (
const QgsPoint &pt : points )
1918 point.
setZ( pt.z() );
1937 bool intersection =
false;
1943 return intersection;
1952 const double angle = ( pA.
azimuth( pB ) + pA.
azimuth( pC ) ) / 2.0;
1955 bool intersection =
false;
1961 return intersection;
WkbType
The WKB type describes the number of dimensions a geometry has.
Abstract base class for all geometries.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
@ MaximumDifference
Maximum distance between an arbitrary point on the original curve and closest point on its approximat...
virtual int vertexCount(int part=0, int ring=0) const =0
Returns the number of vertices of which this geometry is built.
bool isMeasure() const
Returns true if the geometry contains m values.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
AxisOrder
Axis order for GML generation.
@ XY
X comes before Y (or lon before lat)
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
virtual bool isEmpty() const
Returns true if the geometry is empty.
@ FlagExportNanAsDoubleMin
Use -DOUBLE_MAX to represent NaN (since QGIS 3.30)
virtual double segmentLength(QgsVertexId startVertex) const =0
Returns the length of the segment of the geometry which begins at startVertex.
virtual bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const =0
Returns next vertex id and coordinates.
virtual double closestSegment(const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf=nullptr, double epsilon=4 *std::numeric_limits< double >::epsilon()) const =0
Searches for the closest segment of the geometry to a given point.
Curve polygon geometry type.
Abstract base class for curved geometry type.
static int circleCircleIntersections(const QgsPointXY ¢er1, double radius1, const QgsPointXY ¢er2, double radius2, QgsPointXY &intersection1, QgsPointXY &intersection2)
Calculates the intersections points between the circle with center center1 and radius radius1 and the...
static bool linesIntersection3D(const QgsVector3D &La1, const QgsVector3D &La2, const QgsVector3D &Lb1, const QgsVector3D &Lb2, QgsVector3D &intersection)
An algorithm to calculate an (approximate) intersection of two lines in 3D.
static QString pointsToJSON(const QgsPointSequence &points, int precision)
Returns a geoJSON coordinates string.
static double sqrDistance2D(const QgsPoint &pt1, const QgsPoint &pt2)
Returns the squared 2D distance between two points.
static QgsPointXY interpolatePointOnLine(double x1, double y1, double x2, double y2, double fraction)
Interpolates the position of a point a fraction of the way along the line from (x1,...
static double circleTangentDirection(const QgsPoint &tangentPoint, const QgsPoint &cp1, const QgsPoint &cp2, const QgsPoint &cp3)
Calculates the direction angle of a circle tangent (clockwise from north in radians)
static double normalizedAngle(double angle)
Ensures that an angle is in the range 0 <= angle < 2 pi.
static QgsPoint pointOnLineWithDistance(const QgsPoint &startPoint, const QgsPoint &directionPoint, double distance)
Returns a point a specified distance toward a second point.
static double gradient(const QgsPoint &pt1, const QgsPoint &pt2)
Returns the gradient of a line defined by points pt1 and pt2.
static json pointsToJson(const QgsPointSequence &points, int precision)
Returns coordinates as json object.
static double interpolateArcValue(double angle, double a1, double a2, double a3, double zm1, double zm2, double zm3)
Interpolate a value at given angle on circular arc given values (zm1, zm2, zm3) at three different an...
static QVector< QgsLineString * > extractLineStrings(const QgsAbstractGeometry *geom)
Returns list of linestrings extracted from the passed geometry.
static bool lineIntersection(const QgsPoint &p1, QgsVector v1, const QgsPoint &p2, QgsVector v2, QgsPoint &intersection)
Computes the intersection between two lines.
static bool angleOnCircle(double angle, double angle1, double angle2, double angle3)
Returns true if an angle is between angle1 and angle3 on a circle described by angle1,...
static QVector< SelfIntersection > selfIntersections(const QgsAbstractGeometry *geom, int part, int ring, double tolerance)
Find self intersections in a polyline.
static bool transferFirstZValueToPoint(const QgsPointSequence &points, QgsPoint &point)
A Z dimension is added to point if one of the point in the list points is in 3D.
static bool segmentMidPoint(const QgsPoint &p1, const QgsPoint &p2, QgsPoint &result, double radius, const QgsPoint &mousePos)
Calculates midpoint on circle passing through p1 and p2, closest to the given coordinate mousePos.
static QgsPointXY interpolatePointOnLineByValue(double x1, double y1, double v1, double x2, double y2, double v2, double value)
Interpolates the position of a point along the line from (x1, y1) to (x2, y2).
static bool segmentIntersection(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &q1, const QgsPoint &q2, QgsPoint &intersectionPoint, bool &isIntersection, double tolerance=1e-8, bool acceptImproperIntersection=false)
Compute the intersection between two segments.
static QgsPoint closestPoint(const QgsAbstractGeometry &geometry, const QgsPoint &point)
Returns the nearest point on a segment of a geometry for the specified point.
static bool circleClockwise(double angle1, double angle2, double angle3)
Returns true if the circle defined by three angles is ordered clockwise.
static double pointFractionAlongLine(double x1, double y1, double x2, double y2, double px, double py)
Given the line (x1, y1) to (x2, y2) and a point (px, py) returns the fraction of the line length at w...
static double triangleArea(double aX, double aY, double bX, double bY, double cX, double cY)
Returns the area of the triangle denoted by the points (aX, aY), (bX, bY) and (cX,...
static double sweepAngle(double centerX, double centerY, double x1, double y1, double x2, double y2, double x3, double y3)
Calculates angle of a circular string part defined by pt1, pt2, pt3.
static bool verticesAtDistance(const QgsAbstractGeometry &geometry, double distance, QgsVertexId &previousVertex, QgsVertexId &nextVertex)
Retrieves the vertices which are before and after the interpolated point at a specified distance alon...
static QStringList wktGetChildBlocks(const QString &wkt, const QString &defaultType=QString())
Parses a WKT string and returns of list of blocks contained in the WKT.
static double circleLength(double x1, double y1, double x2, double y2, double x3, double y3)
Length of a circular string segment defined by pt1, pt2, pt3.
static QgsLineString perpendicularSegment(const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2)
Create a perpendicular line segment from p to segment [s1, s2].
static double sqrDistToLine(double ptX, double ptY, double x1, double y1, double x2, double y2, double &minDistX, double &minDistY, double epsilon)
Returns the squared distance between a point and a line.
static int segmentSide(const QgsPoint &pt1, const QgsPoint &pt3, const QgsPoint &pt2)
For line defined by points pt1 and pt3, find out on which side of the line is point pt3.
static void pointsToWKB(QgsWkbPtr &wkb, const QgsPointSequence &points, bool is3D, bool isMeasure, QgsAbstractGeometry::WkbFlags flags)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }.
static double distanceToVertex(const QgsAbstractGeometry &geom, QgsVertexId id)
Returns the distance along a geometry from its first vertex to the specified vertex.
static void weightedPointInTriangle(double aX, double aY, double bX, double bY, double cX, double cY, double weightB, double weightC, double &pointX, double &pointY)
Returns a weighted point inside the triangle denoted by the points (aX, aY), (bX, bY) and (cX,...
static QPair< Qgis::WkbType, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
static bool lineCircleIntersection(const QgsPointXY ¢er, double radius, const QgsPointXY &linePoint1, const QgsPointXY &linePoint2, QgsPointXY &intersection)
Compute the intersection of a line and a circle.
static double distToInfiniteLine(const QgsPoint &point, const QgsPoint &linePoint1, const QgsPoint &linePoint2, double epsilon=1e-7)
Returns the distance between a point and an infinite line.
static double lineAngle(double x1, double y1, double x2, double y2)
Calculates the direction of line joining two points in radians, clockwise from the north direction.
static void perpendicularOffsetPointAlongSegment(double x1, double y1, double x2, double y2, double proportion, double offset, double *x, double *y)
Calculates a point a certain proportion of the way along the segment from (x1, y1) to (x2,...
static void coefficients(const QgsPoint &pt1, const QgsPoint &pt2, double &a, double &b, double &c)
Returns the coefficients (a, b, c for equation "ax + by + c = 0") of a line defined by points pt1 and...
static double linePerpendicularAngle(double x1, double y1, double x2, double y2)
Calculates the perpendicular angle to a line joining two points.
static bool transferFirstMValueToPoint(const QgsPointSequence &points, QgsPoint &point)
A M dimension is added to point if one of the points in the list points contains an M value.
static QgsPoint midpoint(const QgsPoint &pt1, const QgsPoint &pt2)
Returns a middle point between points pt1 and pt2.
static QgsPoint closestVertex(const QgsAbstractGeometry &geom, const QgsPoint &pt, QgsVertexId &id)
Returns the closest vertex to a geometry for a specified point.
static bool pointContinuesArc(const QgsPoint &a1, const QgsPoint &a2, const QgsPoint &a3, const QgsPoint &b, double distanceTolerance, double pointSpacingAngleTolerance)
Returns true if point b is on the arc formed by points a1, a2, and a3, but not within that arc portio...
static QgsPoint interpolatePointOnArc(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double distance)
Interpolates a point on an arc defined by three points, pt1, pt2 and pt3.
static bool circleAngleBetween(double angle, double angle1, double angle2, bool clockwise)
Returns true if, in a circle, angle is between angle1 and angle2.
static double angleBetweenThreePoints(double x1, double y1, double x2, double y2, double x3, double y3)
Calculates the angle between the lines AB and BC, where AB and BC described by points a,...
static void perpendicularCenterSegment(double centerPointX, double centerPointY, double segmentPoint1x, double segmentPoint1y, double segmentPoint2x, double segmentPoint2y, double &perpendicularSegmentPoint1x, double &perpendicularSegmentPoint1y, double &perpendicularSegmentPoint2x, double &perpendicularSegmentPoint2y, double segmentLength=0)
Create a perpendicular line segment to a given segment [segmentPoint1,segmentPoint2] with its center ...
static bool tangentPointAndCircle(const QgsPointXY ¢er, double radius, const QgsPointXY &p, QgsPointXY &pt1, QgsPointXY &pt2)
Calculates the tangent points between the circle with the specified center and radius and the point p...
static bool bisector(double aX, double aY, double bX, double bY, double cX, double cY, double &pointX, double &pointY)
Returns the point (pointX, pointY) forming the bisector from point (aX, aY) to the segment (bX,...
static double ccwAngle(double dy, double dx)
Returns the counter clockwise angle between a line with components dx, dy and the line with dx > 0 an...
static int circleCircleOuterTangents(const QgsPointXY ¢er1, double radius1, const QgsPointXY ¢er2, double radius2, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2)
Calculates the outer tangent points for two circles, centered at center1 and center2 and with radii o...
static int closestSideOfRectangle(double right, double bottom, double left, double top, double x, double y)
Returns a number representing the closest side of a rectangle defined by /a right,...
static double skewLinesDistance(const QgsVector3D &P1, const QgsVector3D &P12, const QgsVector3D &P2, const QgsVector3D &P22)
An algorithm to calculate the shortest distance between two skew lines.
static QgsPointSequence pointsFromWKT(const QString &wktCoordinateList, bool is3D, bool isMeasure)
Returns a list of points contained in a WKT string.
static void segmentizeArc(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &p3, QgsPointSequence &points, double tolerance=M_PI_2/90, QgsAbstractGeometry::SegmentationToleranceType toleranceType=QgsAbstractGeometry::MaximumAngle, bool hasZ=false, bool hasM=false)
Convert circular arc defined by p1, p2, p3 (p1/p3 being start resp.
static QDomElement pointsToGML2(const QgsPointSequence &points, QDomDocument &doc, int precision, const QString &ns, QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY)
Returns a gml::coordinates DOM element.
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.
static QDomElement pointsToGML3(const QgsPointSequence &points, QDomDocument &doc, int precision, const QString &ns, bool is3D, QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY)
Returns a gml::posList DOM element.
static int circleCircleInnerTangents(const QgsPointXY ¢er1, double radius1, const QgsPointXY ¢er2, double radius2, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2)
Calculates the inner tangent points for two circles, centered at center1 and center2 and with radii o...
static bool angleBisector(double aX, double aY, double bX, double bY, double cX, double cY, double dX, double dY, double &pointX, double &pointY, double &angle)
Returns the point (pointX, pointY) forming the bisector from segment (aX aY) (bX bY) and segment (bX,...
static bool skewLinesProjection(const QgsVector3D &P1, const QgsVector3D &P12, const QgsVector3D &P2, const QgsVector3D &P22, QgsVector3D &X1, double epsilon=0.0001)
A method to project one skew line onto another.
static bool pointsAreCollinear(double x1, double y1, double x2, double y2, double x3, double y3, double epsilon)
Given the points (x1, y1), (x2, y2) and (x3, y3) returns true if these points can be considered colli...
static QString pointsToWKT(const QgsPointSequence &points, int precision, bool is3D, bool isMeasure)
Returns a WKT coordinate list.
static QgsPoint segmentMidPointFromCenter(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint ¢er, bool useShortestArc=true)
Calculates the midpoint on the circle passing through p1 and p2, with the specified center coordinate...
static int leftOfLine(const double x, const double y, const double x1, const double y1, const double x2, const double y2)
Returns a value < 0 if the point (x, y) is left of the line from (x1, y1) -> (x2, y2).
static double averageAngle(double x1, double y1, double x2, double y2, double x3, double y3)
Calculates the average angle (in radians) between the two linear segments from (x1,...
static void circleCenterRadius(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double &radius, double ¢erX, double ¢erY)
Returns radius and center of the circle through pt1, pt2, pt3.
Line string geometry type, with support for z-dimension and m-values.
void addVertex(const QgsPoint &pt)
Adds a new vertex to the end of the line string.
A class to represent a 2D point.
double sqrDist(double x, double y) const
Returns the squared distance between this point a specified x, y coordinate.
double distance(double x, double y) const
Returns the distance between this point and a specified x, y coordinate.
void set(double x, double y)
Sets the x and y value of the point.
Point geometry type, with support for z-dimension and m-values.
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
double azimuth(const QgsPoint &other) const
Calculates Cartesian azimuth between this point and other one (clockwise in degree,...
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
void setM(double m)
Sets the point's m-value.
bool convertTo(Qgis::WkbType type) override
Converts the geometry to a specified type.
bool isEmpty() const override
Returns true if the geometry is empty.
double distance(double x, double y) const
Returns the Cartesian 2D distance between this point and a specified x, y coordinate.
void setZ(double z)
Sets the point's z-coordinate.
QgsPoint project(double distance, double azimuth, double inclination=90.0) const
Returns a new point which corresponds to this point projected by a specified distance with specified ...
Class for storage of 3D vectors similar to QVector3D, with the difference that it uses double precisi...
double y() const
Returns Y coordinate.
double z() const
Returns Z coordinate.
static double dotProduct(const QgsVector3D &v1, const QgsVector3D &v2)
Returns the dot product of two vectors.
double x() const
Returns X coordinate.
void normalize()
Normalizes the current vector in place.
static QgsVector3D crossProduct(const QgsVector3D &v1, const QgsVector3D &v2)
Returns the cross product of two vectors.
void set(double x, double y, double z)
Sets vector coordinates.
double length() const
Returns the length of the vector.
A class to represent a vector.
double y() const
Returns the vector's y-component.
QgsVector normalized() const
Returns the vector's normalized (or "unit") vector (ie same angle but length of 1....
QgsVector perpVector() const
Returns the perpendicular vector to this vector (rotated 90 degrees counter-clockwise)
double x() const
Returns the vector's x-component.
double length() const
Returns the length of the vector.
static Qgis::WkbType parseType(const QString &wktStr)
Attempts to extract the WKB type from a WKT string.
static Qgis::WkbType addM(Qgis::WkbType type)
Adds the m dimension to a WKB type and returns the new type.
static Qgis::WkbType addZ(Qgis::WkbType type)
Adds the z dimension to a WKB type and returns the new type.
static bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.
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
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
const double DEFAULT_SEGMENT_EPSILON
Default snapping tolerance for segments.
QVector< QgsPoint > QgsPointSequence
bool isClockwise(std::array< Direction, 4 > dirs)
Checks whether the 4 directions in dirs make up a clockwise rectangle.
Utility class for identifying a unique vertex within a geometry.
bool isValid() const
Returns true if the vertex id is valid.
Qgis::VertexType type
Vertex type.