28#include <QRegularExpression>
29#include <nlohmann/json.hpp>
33 QVector< QgsLineString * > linestrings;
37 QVector< const QgsAbstractGeometry * > geometries;
39 while ( ! geometries.isEmpty() )
42 if (
const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( g ) )
44 linestrings << static_cast< QgsLineString * >( curve->segmentize() );
46 else if (
const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( g ) )
48 for (
int i = 0; i < collection->numGeometries(); ++i )
50 geometries.append( collection->geometryN( i ) );
53 else if (
const QgsCurvePolygon *curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( g ) )
55 if ( curvePolygon->exteriorRing() )
56 linestrings << static_cast< QgsLineString * >( curvePolygon->exteriorRing()->segmentize() );
58 for (
int i = 0; i < curvePolygon->numInteriorRings(); ++i )
60 linestrings << static_cast< QgsLineString * >( curvePolygon->interiorRing( i )->segmentize() );
69 double minDist = std::numeric_limits<double>::max();
70 double currentDist = 0;
87 if ( currentDist <= minDist )
89 minDist = currentDist;
90 minDistPoint = vertex;
91 id.part = vertexId.
part;
92 id.ring = vertexId.
ring;
93 id.vertex = vertexId.
vertex;
94 id.type = vertexId.
type;
109 if ( vertexAfter.
vertex > 0 )
114 const double length = pointBefore.
distance( pointAfter );
136 double currentDist = 0;
141 if ( vertexId ==
id )
155 double currentDist = 0;
165 nextVertex = previousVertex;
170 while ( currentDist < distance && geometry.
nextVertex( nextVertex, point ) )
172 if ( !first && nextVertex.
part == previousVertex.
part && nextVertex.
ring == previousVertex.
ring )
180 previousVertex = nextVertex;
184 if ( currentDist > distance )
189 previousVertex = nextVertex;
190 previousPoint = point;
200 return ( pt1.
x() - pt2.
x() ) * ( pt1.
x() - pt2.
x() ) + ( pt1.
y() - pt2.
y() ) * ( pt1.
y() - pt2.
y() );
213 const double t = ( ( ptX - x1 ) * dx + ( ptY - y1 ) * dy ) / ( dx * dx + dy * dy );
229 const double dist = dx * dx + dy * dy;
244 const double area = std::abs(
245 ( linePoint1.
x() - linePoint2.
x() ) * ( point.
y() - linePoint2.
y() ) -
246 ( linePoint1.
y() - linePoint2.
y() ) * ( point.
x() - linePoint2.
x() )
249 const double length = std::sqrt(
250 std::pow( linePoint1.
x() - linePoint2.
x(), 2 ) +
251 std::pow( linePoint1.
y() - linePoint2.
y(), 2 )
254 const double distance = area / length;
255 return qgsDoubleNear( distance, 0.0, epsilon ) ? 0.0 : distance;
260 const double d = v1.
y() * v2.
x() - v1.
x() * v2.
y();
265 const double dx = p2.
x() - p1.
x();
266 const double dy = p2.
y() - p1.
y();
267 const double k = ( dy * v2.
x() - dx * v2.
y() ) / d;
269 intersection =
QgsPoint( p1.
x() + v1.
x() * k, p1.
y() + v1.
y() * k );
279 isIntersection =
false;
283 const double vl = v.
length();
284 const double wl = w.
length();
298 isIntersection =
true;
299 if ( acceptImproperIntersection )
301 if ( ( p1 == q1 ) || ( p1 == q2 ) )
303 intersectionPoint = p1;
306 else if ( ( p2 == q1 ) || ( p2 == q2 ) )
308 intersectionPoint = p2;
315 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( p1.
x(), p1.
y(), q1.
x(), q1.
y(), q2.
x(), q2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
317 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( p2.
x(), p2.
y(), q1.
x(), q1.
y(), q2.
x(), q2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
319 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( q1.
x(), q1.
y(), p1.
x(), p1.
y(), p2.
x(), p2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
321 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( q2.
x(), q2.
y(), p1.
x(), p1.
y(), p2.
x(), p2.
y(), x, y, tolerance ), 0.0, tolerance )
328 const double lambdav =
QgsVector( intersectionPoint.
x() - p1.
x(), intersectionPoint.
y() - p1.
y() ) * v;
329 if ( lambdav < 0. + tolerance || lambdav > vl - tolerance )
332 const double lambdaw =
QgsVector( intersectionPoint.
x() - q1.
x(), intersectionPoint.
y() - q1.
y() ) * w;
333 return !( lambdaw < 0. + tolerance || lambdaw >= wl - tolerance );
343 const double x1 = linePoint1.
x() - center.
x();
344 const double y1 = linePoint1.
y() - center.
y();
345 const double x2 = linePoint2.
x() - center.
x();
346 const double y2 = linePoint2.
y() - center.
y();
347 const double dx = x2 - x1;
348 const double dy = y2 - y1;
350 const double dr2 = std::pow( dx, 2 ) + std::pow( dy, 2 );
351 const double d = x1 * y2 - x2 * y1;
353 const double disc = std::pow( radius, 2 ) * dr2 - std::pow( d, 2 );
363 const int sgnDy = dy < 0 ? -1 : 1;
365 const double sqrDisc = std::sqrt( disc );
367 const double ax = center.
x() + ( d * dy + sgnDy * dx * sqrDisc ) / dr2;
368 const double ay = center.
y() + ( -d * dx + std::fabs( dy ) * sqrDisc ) / dr2;
371 const double bx = center.
x() + ( d * dy - sgnDy * dx * sqrDisc ) / dr2;
372 const double by = center.
y() + ( -d * dx - std::fabs( dy ) * sqrDisc ) / dr2;
379 intersection.
set( p1.
x(), p1.
y() );
383 intersection.
set( p2.
x(), p2.
y() );
394 const double d = center1.
distance( center2 );
397 if ( d > ( r1 + r2 ) )
402 else if ( d < std::fabs( r1 - r2 ) )
419 const double a = ( ( r1 * r1 ) - ( r2 * r2 ) + ( d * d ) ) / ( 2.0 * d ) ;
424 const double dx = center2.
x() - center1.
x();
425 const double dy = center2.
y() - center1.
y();
428 const double x2 = center1.
x() + ( dx * a / d );
429 const double y2 = center1.
y() + ( dy * a / d );
434 const double h = std::sqrt( ( r1 * r1 ) - ( a * a ) );
439 const double rx = dy * ( h / d );
440 const double ry = dx * ( h / d );
443 intersection1 =
QgsPointXY( x2 + rx, y2 - ry );
444 intersection2 =
QgsPointXY( x2 - rx, y2 + ry );
458 const double dx = center.
x() - p.
x();
459 const double dy = center.
y() - p.
y();
460 const double distanceSquared = dx * dx + dy * dy;
461 const double radiusSquared = radius * radius;
462 if ( distanceSquared < radiusSquared )
469 const double distanceToTangent = std::sqrt( distanceSquared - radiusSquared );
481 if ( radius1 > radius2 )
484 const double radius2a = radius2 - radius1;
493 QgsVector v1( -( line1P2.
y() - center1.
y() ), line1P2.
x() - center1.
x() );
494 const double v1Length = v1.
length();
495 v1 = v1 * ( radius1 / v1Length );
498 line1P1 = center1 + v1;
499 line1P2 = line1P2 + v1;
503 QgsVector v2( line2P2.
y() - center1.
y(), -( line2P2.
x() - center1.
x() ) );
504 const double v2Length = v2.
length();
505 v2 = v2 * ( radius1 / v2Length );
508 line2P1 = center1 + v2;
509 line2P2 = line2P2 + v2;
517 if ( radius1 > radius2 )
521 const double d = center1.
distance( center2 );
522 const double radius1a = radius1 + radius2;
539 QgsVector v1( ( line1P2.
y() - center2.
y() ), -( line1P2.
x() - center2.
x() ) );
540 const double v1Length = v1.
length();
541 v1 = v1 * ( radius2 / v1Length );
544 line1P1 = center2 + v1;
545 line1P2 = line1P2 + v1;
549 QgsVector v2( -( line2P2.
y() - center2.
y() ), line2P2.
x() - center2.
x() );
550 const double v2Length = v2.
length();
551 v2 = v2 * ( radius2 / v2Length );
554 line2P1 = center2 + v2;
555 line2P2 = line2P2 + v2;
562 QVector<SelfIntersection> intersections;
568 for (
int i = 0, j = 1; j < n; i = j++ )
575 const int start = j + 1;
576 const int end = i == 0 && isClosed ? n - 1 : n;
577 for (
int k = start, l = start + 1; l < end; k = l++ )
583 bool intersection =
false;
594 intersections.append( s );
597 return intersections;
607 const double f1 = x - x1;
608 const double f2 = y2 - y1;
609 const double f3 = y - y1;
610 const double f4 = x2 - x1;
611 const double test = ( f1 * f2 - f3 * f4 );
613 return qgsDoubleNear( test, 0.0 ) ? 0 : ( test < 0 ? -1 : 1 );
623void 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 )
625 const double dx = x2 - x1;
626 const double dy = y2 - y1;
627 const double length = std::sqrt( dx * dx + dy * dy );
640 const double scaleFactor = distance / length;
641 x = x1 + dx * scaleFactor;
642 y = y1 + dy * scaleFactor;
644 *z = *z1 + ( *z2 - *z1 ) * scaleFactor;
646 *m = *m1 + ( *m2 - *m1 ) * scaleFactor;
653 const double mX = x1 + ( x2 - x1 ) * proportion;
654 const double mY = y1 + ( y2 - y1 ) * proportion;
655 const double pX = x1 - x2;
656 const double pY = y1 - y2;
657 double normalX = -pY;
659 const double normalLength = sqrt( ( normalX * normalX ) + ( normalY * normalY ) );
660 normalX /= normalLength;
661 normalY /= normalLength;
663 *x = mX + offset * normalX;
664 *y = mY + offset * normalY;
669 double centerX, centerY, radius;
672 const double theta = distance / radius;
673 const double anglePt1 = std::atan2( pt1.
y() - centerY, pt1.
x() - centerX );
674 const double anglePt2 = std::atan2( pt2.
y() - centerY, pt2.
x() - centerX );
675 const double anglePt3 = std::atan2( pt3.
y() - centerY, pt3.
x() - centerX );
677 const double angleDest = anglePt1 + (
isClockwise ? -theta : theta );
679 const double x = centerX + radius * ( std::cos( angleDest ) );
680 const double y = centerY + radius * ( std::sin( angleDest ) );
682 const double z = pt1.
is3D() ?
694 const double angle = std::atan2( dy, dx ) * 180 / M_PI;
699 else if (
angle > 360 )
708 double dx21, dy21, dx31, dy31, h21, h31, d;
713 centerX = ( pt1.
x() + pt2.
x() ) / 2.0;
714 centerY = ( pt1.
y() + pt2.
y() ) / 2.0;
715 radius = std::sqrt( std::pow( centerX - pt1.
x(), 2.0 ) + std::pow( centerY - pt1.
y(), 2.0 ) );
720 dx21 = pt2.
x() - pt1.
x();
721 dy21 = pt2.
y() - pt1.
y();
722 dx31 = pt3.
x() - pt1.
x();
723 dy31 = pt3.
y() - pt1.
y();
725 h21 = std::pow( dx21, 2.0 ) + std::pow( dy21, 2.0 );
726 h31 = std::pow( dx31, 2.0 ) + std::pow( dy31, 2.0 );
729 d = 2 * ( dx21 * dy31 - dx31 * dy21 );
739 centerX = pt1.
x() + ( h21 * dy31 - h31 * dy21 ) / d;
740 centerY = pt1.
y() - ( h21 * dx31 - h31 * dx21 ) / d;
741 radius = std::sqrt( std::pow( centerX - pt1.
x(), 2.0 ) + std::pow( centerY - pt1.
y(), 2.0 ) );
746 if ( angle3 >= angle1 )
748 return !( angle2 > angle1 && angle2 < angle3 );
752 return !( angle2 > angle1 || angle2 < angle3 );
760 if ( angle2 < angle1 )
762 return ( angle <= angle1 && angle >= angle2 );
766 return ( angle <= angle1 || angle >= angle2 );
771 if ( angle2 > angle1 )
773 return (
angle >= angle1 &&
angle <= angle2 );
777 return (
angle >= angle1 ||
angle <= angle2 );
790 double centerX, centerY, radius;
792 double length = M_PI / 180.0 * radius *
sweepAngle( centerX, centerY, x1, y1, x2, y2, x3, y3 );
806 if ( p3Angle >= p1Angle )
808 if ( p2Angle > p1Angle && p2Angle < p3Angle )
810 return ( p3Angle - p1Angle );
814 return ( - ( p1Angle + ( 360 - p3Angle ) ) );
819 if ( p2Angle < p1Angle && p2Angle > p3Angle )
821 return ( -( p1Angle - p3Angle ) );
825 return ( p3Angle + ( 360 - p1Angle ) );
832 const QgsPoint midPoint( ( p1.
x() + p2.
x() ) / 2.0, ( p1.
y() + p2.
y() ) / 2.0 );
833 const double midDist = std::sqrt(
sqrDistance2D( p1, midPoint ) );
834 if ( radius < midDist )
838 const double centerMidDist = std::sqrt( radius * radius - midDist * midDist );
839 const double dist = radius - centerMidDist;
841 const double midDx = midPoint.
x() - p1.
x();
842 const double midDy = midPoint.
y() - p1.
y();
845 QVector<QgsPoint> possibleMidPoints;
852 double minDist = std::numeric_limits<double>::max();
853 int minDistIndex = -1;
854 for (
int i = 0; i < possibleMidPoints.size(); ++i )
856 const double currentDist =
sqrDistance2D( mousePos, possibleMidPoints.at( i ) );
857 if ( currentDist < minDist )
860 minDist = currentDist;
864 if ( minDistIndex == -1 )
869 result = possibleMidPoints.at( minDistIndex );
881 if ( !useShortestArc )
882 midPointAngle += M_PI;
883 return center.
project( center.
distance( p1 ), midPointAngle * 180 / M_PI );
890 double mX, mY, radius;
923 const double bDistance = std::sqrt( ( b.
x() - centerX ) * ( b.
x() - centerX ) +
924 ( b.
y() - centerY ) * ( b.
y() - centerY ) );
926 double diff = std::fabs( radius - bDistance );
930 const double abX = b.
x() - a.
x();
931 const double abY = b.
y() - a.
y();
933 const double cbX = b.
x() -
c.x();
934 const double cbY = b.
y() -
c.y();
936 const double dot = ( abX * cbX + abY * cbY );
937 const double cross = ( abX * cbY - abY * cbX );
939 const double alpha = std::atan2( cross, dot );
945 if ( diff < distanceTolerance )
947 const double angle1 = arcAngle( a1, a2, a3 );
948 const double angle2 = arcAngle( a2, a3, b );
953 diff = std::fabs( angle1 - angle2 );
954 if ( diff > pointSpacingAngleTolerance )
959 const int a2Side =
leftOfLine( a2.
x(), a2.
y(), a1.
x(), a1.
y(), a3.
x(), a3.
y() );
960 const int bSide =
leftOfLine( b.
x(), b.
y(), a1.
x(), a1.
y(), a3.
x(), a3.
y() );
964 if ( bSide != a2Side )
972 bool reversed =
false;
996 circleCenterRadius( circlePoint1, circlePoint2, circlePoint3, radius, centerX, centerY );
998 if ( circlePoint1 != circlePoint3 && ( radius < 0 ||
qgsDoubleNear( segSide, 0.0 ) ) )
1000 points.append( p1 );
1001 points.append( p2 );
1002 points.append( p3 );
1006 double increment = tolerance;
1010 tolerance = std::min( tolerance, radius * 2 );
1011 const double halfAngle = std::acos( -tolerance / radius + 1 );
1012 increment = 2 * halfAngle;
1016 const double a1 = std::atan2( circlePoint1.
y() - centerY, circlePoint1.
x() - centerX );
1017 double a2 = std::atan2( circlePoint2.
y() - centerY, circlePoint2.
x() - centerX );
1018 double a3 = std::atan2( circlePoint3.
y() - centerY, circlePoint3.
x() - centerX );
1021 const bool symmetric =
true;
1024 double angle = a3 - a1;
1029 const int segs = ceil(
angle / increment );
1031 increment =
angle / segs;
1045 QVector<QgsPoint> stringPoints;
1046 stringPoints.insert( 0, circlePoint1 );
1047 if ( circlePoint2 != circlePoint3 && circlePoint1 != circlePoint2 )
1061 const double tolError = increment / 100;
1062 const double stopAngle = a3 - tolError;
1063 for (
double angle = a1 + increment;
angle < stopAngle;
angle += increment )
1065 x = centerX + radius * std::cos(
angle );
1066 y = centerY + radius * std::sin(
angle );
1077 stringPoints.insert( stringPoints.size(),
QgsPoint( pointWkbType, x, y, z, m ) );
1080 stringPoints.insert( stringPoints.size(), circlePoint3 );
1085 std::reverse( stringPoints.begin(), stringPoints.end() );
1087 if ( ! points.empty() && stringPoints.front() == points.back() ) stringPoints.pop_front();
1088 points.append( stringPoints );
1093 const double side = ( ( pt2.
x() - pt1.
x() ) * ( pt3.
y() - pt1.
y() ) - ( pt3.
x() - pt1.
x() ) * ( pt2.
y() - pt1.
y() ) );
1118 return zm1 + ( zm2 - zm1 ) * (
angle - a1 ) / ( a2 - a1 );
1120 return zm2 + ( zm3 - zm2 ) * (
angle - a2 ) / ( a3 - a2 );
1126 return zm1 + ( zm2 - zm1 ) * ( a1 -
angle ) / ( a1 - a2 );
1128 return zm2 + ( zm3 - zm2 ) * ( a2 -
angle ) / ( a2 - a3 );
1134 const int dim = 2 + is3D + isMeasure;
1137#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
1138 const QStringList coordList = wktCoordinateList.split(
',', QString::SkipEmptyParts );
1140 const QStringList coordList = wktCoordinateList.split(
',', Qt::SkipEmptyParts );
1144 bool foundZ =
false;
1145 bool foundM =
false;
1146 const thread_local QRegularExpression rx( QStringLiteral(
"\\s" ) );
1147 const thread_local QRegularExpression rxIsNumber( QStringLiteral(
"^[+-]?(\\d\\.?\\d*[Ee][+\\-]?\\d+|(\\d+\\.\\d*|\\d*\\.\\d+)|\\d+)$" ) );
1148 for (
const QString &pointCoordinates : coordList )
1150#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
1151 QStringList coordinates = pointCoordinates.split( rx, QString::SkipEmptyParts );
1153 const QStringList coordinates = pointCoordinates.split( rx, Qt::SkipEmptyParts );
1157 if ( coordinates.filter( rxIsNumber ).size() != coordinates.size() )
1160 if ( coordinates.size() == 3 && !foundZ && !foundM && !is3D && !isMeasure )
1166 else if ( coordinates.size() >= 4 && ( !( is3D || foundZ ) || !( isMeasure || foundM ) ) )
1175 for (
const QString &pointCoordinates : coordList )
1177#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
1178 QStringList coordinates = pointCoordinates.split( rx, QString::SkipEmptyParts );
1180 QStringList coordinates = pointCoordinates.split( rx, Qt::SkipEmptyParts );
1182 if ( coordinates.size() < dim )
1186 const double x = coordinates[idx++].toDouble();
1187 const double y = coordinates[idx++].toDouble();
1190 if ( ( is3D || foundZ ) && coordinates.length() > idx )
1191 z = coordinates[idx++].toDouble();
1194 if ( ( isMeasure || foundM ) && coordinates.length() > idx )
1195 m = coordinates[idx++].toDouble();
1198 if ( is3D || foundZ )
1200 if ( isMeasure || foundM )
1207 if ( isMeasure || foundM )
1213 points.append(
QgsPoint( t, x, y, z, m ) );
1221 wkb << static_cast<quint32>( points.size() );
1222 for (
const QgsPoint &point : points )
1224 wkb << point.x() << point.y();
1227 double z = point.z();
1229 && std::isnan( z ) )
1230 z = -std::numeric_limits<double>::max();
1236 double m = point.m();
1238 && std::isnan( m ) )
1239 m = -std::numeric_limits<double>::max();
1248 QString wkt = QStringLiteral(
"(" );
1257 wkt += QLatin1String(
", " );
1259 if ( wkt.endsWith( QLatin1String(
", " ) ) )
1267 QDomElement elemCoordinates = doc.createElementNS( ns, QStringLiteral(
"coordinates" ) );
1270 const QString cs = QStringLiteral(
"," );
1272 const QString ts = QStringLiteral(
" " );
1274 elemCoordinates.setAttribute( QStringLiteral(
"cs" ), cs );
1275 elemCoordinates.setAttribute( QStringLiteral(
"ts" ), ts );
1277 QString strCoordinates;
1280 if ( axisOrder == QgsAbstractGeometry::AxisOrder::XY )
1285 if ( strCoordinates.endsWith( ts ) )
1286 strCoordinates.chop( 1 );
1288 elemCoordinates.appendChild( doc.createTextNode( strCoordinates ) );
1289 return elemCoordinates;
1294 QDomElement elemPosList = doc.createElementNS( ns, QStringLiteral(
"posList" ) );
1295 elemPosList.setAttribute( QStringLiteral(
"srsDimension" ), is3D ? 3 : 2 );
1297 QString strCoordinates;
1300 if ( axisOrder == QgsAbstractGeometry::AxisOrder::XY )
1307 if ( strCoordinates.endsWith(
' ' ) )
1308 strCoordinates.chop( 1 );
1310 elemPosList.appendChild( doc.createTextNode( strCoordinates ) );
1316 QString json = QStringLiteral(
"[ " );
1321 if ( json.endsWith( QLatin1String(
", " ) ) )
1332 json coordinates( json::array() );
1349 double clippedAngle =
angle;
1350 if ( clippedAngle >= M_PI * 2 || clippedAngle <= -2 * M_PI )
1352 clippedAngle = std::fmod( clippedAngle, 2 * M_PI );
1354 if ( clippedAngle < 0.0 )
1356 clippedAngle += 2 * M_PI;
1358 return clippedAngle;
1363 QString wktParsed = wkt;
1365 if ( wkt.contains( QLatin1String(
"EMPTY" ), Qt::CaseInsensitive ) )
1367 const thread_local QRegularExpression sWktRegEx( QStringLiteral(
"^\\s*(\\w+)\\s+(\\w+)\\s*$" ), QRegularExpression::DotMatchesEverythingOption );
1368 const QRegularExpressionMatch match = sWktRegEx.match( wkt );
1369 if ( match.hasMatch() )
1371 wktParsed = match.captured( 1 );
1372 contents = match.captured( 2 ).toUpper();
1377 const int openedParenthesisCount = wktParsed.count(
'(' );
1378 const int closedParenthesisCount = wktParsed.count(
')' );
1380 for (
int i = 0 ; i < openedParenthesisCount - closedParenthesisCount; ++i )
1381 wktParsed.push_back(
')' );
1383 wktParsed.truncate( wktParsed.size() - ( closedParenthesisCount - openedParenthesisCount ) );
1385 const thread_local QRegularExpression cooRegEx( QStringLiteral(
"^[^\\(]*\\((.*)\\)[^\\)]*$" ), QRegularExpression::DotMatchesEverythingOption );
1386 const QRegularExpressionMatch match = cooRegEx.match( wktParsed );
1387 contents = match.hasMatch() ? match.captured( 1 ) : QString();
1390 return qMakePair( wkbType, contents );
1397 block.reserve( wkt.size() );
1400 const QChar *wktData = wkt.data();
1401 const int wktLength = wkt.length();
1402 for (
int i = 0, n = wktLength; i < n; ++i, ++wktData )
1404 if ( ( wktData->isSpace() || *wktData ==
'\n' || *wktData ==
'\t' ) && level == 0 )
1407 if ( *wktData ==
',' && level == 0 )
1409 if ( !block.isEmpty() )
1411 if ( block.startsWith(
'(' ) && !defaultType.isEmpty() )
1412 block.prepend( defaultType +
' ' );
1413 blocks.append( block );
1418 if ( *wktData ==
'(' )
1420 else if ( *wktData ==
')' )
1424 if ( !block.isEmpty() )
1426 if ( block.startsWith(
'(' ) && !defaultType.isEmpty() )
1427 block.prepend( defaultType +
' ' );
1428 blocks.append( block );
1436 if ( x <= left && y <= bottom )
1438 const double dx = left - x;
1439 const double dy = bottom - y;
1447 else if ( x >= right && y >= top )
1449 const double dx = x - right;
1450 const double dy = y - top;
1458 else if ( x >= right && y <= bottom )
1460 const double dx = x - right;
1461 const double dy = bottom - y;
1469 else if ( x <= left && y >= top )
1471 const double dx = left - x;
1472 const double dy = y - top;
1480 else if ( x <= left )
1482 else if ( x >= right )
1484 else if ( y <= bottom )
1486 else if ( y >= top )
1490 const double smallestX = std::min( right - x, x - left );
1491 const double smallestY = std::min( top - y, y - bottom );
1492 if ( smallestX < smallestY )
1495 if ( right - x < x - left )
1503 if ( top - y < y - bottom )
1515 const double x = ( pt1.
x() + pt2.
x() ) / 2.0;
1516 const double y = ( pt1.
y() + pt2.
y() ) / 2.0;
1517 double z = std::numeric_limits<double>::quiet_NaN();
1518 double m = std::numeric_limits<double>::quiet_NaN();
1523 z = ( pt1.
z() + pt2.
z() ) / 2.0;
1529 m = ( pt1.
m() + pt2.
m() ) / 2.0;
1532 return QgsPoint( pType, x, y, z, m );
1537 const double _fraction = 1 - fraction;
1539 p1.
x() * _fraction + p2.
x() * fraction,
1540 p1.
y() * _fraction + p2.
y() * fraction,
1541 p1.
is3D() ? p1.
z() * _fraction + p2.
z() * fraction : std::numeric_limits<double>::quiet_NaN(),
1542 p1.
isMeasure() ? p1.
m() * _fraction + p2.
m() * fraction : std::numeric_limits<double>::quiet_NaN() );
1547 const double deltaX = ( x2 - x1 ) * fraction;
1548 const double deltaY = ( y2 - y1 ) * fraction;
1549 return QgsPointXY( x1 + deltaX, y1 + deltaY );
1557 const double fraction = ( value - v1 ) / ( v2 - v1 );
1563 const double delta_x = pt2.
x() - pt1.
x();
1564 const double delta_y = pt2.
y() - pt1.
y();
1570 return delta_y / delta_x;
1589 a = pt1.
y() - pt2.
y();
1590 b = pt2.
x() - pt1.
x();
1591 c = pt1.
x() * pt2.
y() - pt1.
y() * pt2.
x();
1601 if ( ( p == s1 ) || ( p == s2 ) )
1619 const double y = ( -
c - a * p.
x() ) / b;
1620 const double m =
gradient( s1, s2 );
1621 const double d2 = 1 + m * m;
1622 const double H = p.
y() - y;
1623 const double dx = m * H / d2;
1624 const double dy = m * dx;
1634void QgsGeometryUtils::perpendicularCenterSegment(
double pointx,
double pointy,
double segmentPoint1x,
double segmentPoint1y,
double segmentPoint2x,
double segmentPoint2y,
double &perpendicularSegmentPoint1x,
double &perpendicularSegmentPoint1y,
double &perpendicularSegmentPoint2x,
double &perpendicularSegmentPoint2y,
double desiredSegmentLength )
1636 QgsVector segmentVector =
QgsVector( segmentPoint2x - segmentPoint1x, segmentPoint2y - segmentPoint1y );
1638 if ( desiredSegmentLength )
1640 if ( desiredSegmentLength != 0 )
1642 perpendicularVector = perpendicularVector.
normalized() * ( desiredSegmentLength ) / 2;
1645 perpendicularSegmentPoint1x = pointx - perpendicularVector.
x();
1646 perpendicularSegmentPoint1y = pointy - perpendicularVector.
y();
1647 perpendicularSegmentPoint2x = pointx + perpendicularVector.
x();
1648 perpendicularSegmentPoint2y = pointy + perpendicularVector.
y();
1653 const double at = std::atan2( y2 - y1, x2 - x1 );
1654 const double a = -at + M_PI_2;
1660 const double angle1 = std::atan2( y1 - y2, x1 - x2 );
1661 const double angle2 = std::atan2( y3 - y2, x3 - x2 );
1675 const double a1 =
lineAngle( x1, y1, x2, y2 );
1676 const double a2 =
lineAngle( x2, y2, x3, y3 );
1684 double clockwiseDiff = 0.0;
1687 clockwiseDiff = a2 - a1;
1691 clockwiseDiff = a2 + ( 2 * M_PI - a1 );
1693 const double counterClockwiseDiff = 2 * M_PI - clockwiseDiff;
1695 double resultAngle = 0;
1696 if ( clockwiseDiff <= counterClockwiseDiff )
1698 resultAngle = a1 + clockwiseDiff / 2.0;
1702 resultAngle = a1 - counterClockwiseDiff / 2.0;
1713 if ( u3.
length() == 0 )
return 1;
1730 if ( std::fabs( u3.
x() ) <= epsilon &&
1731 std::fabs( u3.
y() ) <= epsilon &&
1732 std::fabs( u3.
z() ) <= epsilon )
1744 if ( !( std::fabs( b1 ) > epsilon ) )
1749 if ( !( a2 != -1 && a2 != 1 ) )
1755 const double r1 = ( c2 - b2 * c1 / b1 ) / ( a2 - b2 * a1 / b1 );
1771 bool isIntersection;
1780 intersection.
set( ptInter.
x(), ptInter.
y(), La1.
z() );
1820 if ( !firstIsDone || !secondIsDone )
1826 intersection = ( X1 + X2 ) / 2.0;
1832 return 0.5 * std::abs( ( aX - cX ) * ( bY - aY ) - ( aX - bX ) * ( cY - aY ) );
1836 double weightB,
double weightC,
double &pointX,
double &pointY )
1839 if ( weightB + weightC > 1 )
1841 weightB = 1 - weightB;
1842 weightC = 1 - weightC;
1845 const double rBx = weightB * ( bX - aX );
1846 const double rBy = weightB * ( bY - aY );
1847 const double rCx = weightC * ( cX - aX );
1848 const double rCy = weightC * ( cY - aY );
1850 pointX = rBx + rCx + aX;
1851 pointY = rBy + rCy + aY;
1858 for (
const QgsPoint &pt : points )
1860 if ( pt.isMeasure() )
1863 point.
setM( pt.m() );
1876 for (
const QgsPoint &pt : points )
1881 point.
setZ( pt.z() );
1900 bool intersection =
false;
1906 return intersection;
1918 bool intersection =
false;
1924 return intersection;
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...
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
virtual int vertexCount(int part=0, int ring=0) const =0
Returns the number of vertices of which this geometry is built.
AxisOrder
Axis order for GML generation.
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
virtual bool isEmpty() const
Returns true if the geometry is empty.
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
@ 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.
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
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 QPair< QgsWkbTypes::Type, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
static double circleTangentDirection(const QgsPoint &tangentPoint, const QgsPoint &cp1, const QgsPoint &cp2, const QgsPoint &cp3) SIP_HOLDGIL
Calculates the direction angle of a circle tangent (clockwise from north in radians)
static QString pointsToJSON(const QgsPointSequence &points, int precision)
Returns a geoJSON coordinates string.
static QgsPoint midpoint(const QgsPoint &pt1, const QgsPoint &pt2) SIP_HOLDGIL
Returns a middle point between points pt1 and pt2.
static bool bisector(double aX, double aY, double bX, double bY, double cX, double cY, double &pointX, double &pointY) SIP_HOLDGIL
Returns the point (pointX, pointY) forming the bisector from point (aX, aY) to the segment (bX,...
static double sqrDistance2D(const QgsPoint &pt1, const QgsPoint &pt2) SIP_HOLDGIL
Returns the squared 2D distance between two points.
static bool skewLinesProjection(const QgsVector3D &P1, const QgsVector3D &P12, const QgsVector3D &P2, const QgsVector3D &P22, QgsVector3D &X1, double epsilon=0.0001) SIP_HOLDGIL
A method to project one skew line onto another.
static double ccwAngle(double dy, double dx) SIP_HOLDGIL
Returns the counter clockwise angle between a line with components dx, dy and the line with dx > 0 an...
static double triangleArea(double aX, double aY, double bX, double bY, double cX, double cY) SIP_HOLDGIL
Returns the area of the triangle denoted by the points (aX, aY), (bX, bY) and (cX,...
static bool segmentMidPoint(const QgsPoint &p1, const QgsPoint &p2, QgsPoint &result, double radius, const QgsPoint &mousePos) SIP_HOLDGIL
Calculates midpoint on circle passing through p1 and p2, closest to the given coordinate mousePos.
static json pointsToJson(const QgsPointSequence &points, int precision)
Returns coordinates as json object.
static int circleCircleInnerTangents(const QgsPointXY ¢er1, double radius1, const QgsPointXY ¢er2, double radius2, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2) SIP_HOLDGIL
Calculates the inner tangent points for two circles, centered at center1 and center2 and with radii o...
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) SIP_HOLDGIL
Computes the intersection between two lines.
static double normalizedAngle(double angle) SIP_HOLDGIL
Ensures that an angle is in the range 0 <= angle < 2 pi.
static QgsPointXY interpolatePointOnLineByValue(double x1, double y1, double v1, double x2, double y2, double v2, double value) SIP_HOLDGIL
Interpolates the position of a point along the line from (x1, y1) to (x2, y2).
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 QgsPoint closestPoint(const QgsAbstractGeometry &geometry, const QgsPoint &point)
Returns the nearest point on a segment of a geometry for the specified point.
static int segmentSide(const QgsPoint &pt1, const QgsPoint &pt3, const QgsPoint &pt2) SIP_HOLDGIL
For line defined by points pt1 and pt3, find out on which side of the line is point 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 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) SIP_HOLDGIL
Create a perpendicular line segment to a given segment [segmentPoint1,segmentPoint2] with its center ...
static QgsPoint segmentMidPointFromCenter(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint ¢er, bool useShortestArc=true) SIP_HOLDGIL
Calculates the midpoint on the circle passing through p1 and p2, with the specified center coordinate...
static bool lineCircleIntersection(const QgsPointXY ¢er, double radius, const QgsPointXY &linePoint1, const QgsPointXY &linePoint2, QgsPointXY &intersection) SIP_HOLDGIL
Compute the intersection of a line and a circle.
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) SIP_HOLDGIL
Compute the intersection between two segments.
static void circleCenterRadius(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double &radius, double ¢erX, double ¢erY) SIP_HOLDGIL
Returns radius and center of the circle through pt1, pt2, 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 double skewLinesDistance(const QgsVector3D &P1, const QgsVector3D &P12, const QgsVector3D &P2, const QgsVector3D &P22) SIP_HOLDGIL
An algorithm to calculate the shortest distance between two skew lines.
static double averageAngle(double x1, double y1, double x2, double y2, double x3, double y3) SIP_HOLDGIL
Calculates the average angle (in radians) between the two linear segments from (x1,...
static bool angleOnCircle(double angle, double angle1, double angle2, double angle3) SIP_HOLDGIL
Returns true if an angle is between angle1 and angle3 on a circle described by angle1,...
static double lineAngle(double x1, double y1, double x2, double y2) SIP_HOLDGIL
Calculates the direction of line joining two points in radians, clockwise from the north direction.
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 sqrDistToLine(double ptX, double ptY, double x1, double y1, double x2, double y2, double &minDistX, double &minDistY, double epsilon) SIP_HOLDGIL
Returns the squared distance between a point and a line.
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 bool circleClockwise(double angle1, double angle2, double angle3) SIP_HOLDGIL
Returns true if the circle defined by three angles is ordered clockwise.
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) SIP_HOLDGIL
Returns the point (pointX, pointY) forming the bisector from segment (aX aY) (bX bY) and segment (bX,...
static int circleCircleOuterTangents(const QgsPointXY ¢er1, double radius1, const QgsPointXY ¢er2, double radius2, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2) SIP_HOLDGIL
Calculates the outer tangent points for two circles, centered at center1 and center2 and with radii o...
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 double gradient(const QgsPoint &pt1, const QgsPoint &pt2) SIP_HOLDGIL
Returns the gradient of a line defined by points pt1 and pt2.
static double sweepAngle(double centerX, double centerY, double x1, double y1, double x2, double y2, double x3, double y3) SIP_HOLDGIL
Calculates angle of a circular string part defined by pt1, pt2, pt3.
static double angleBetweenThreePoints(double x1, double y1, double x2, double y2, double x3, double y3) SIP_HOLDGIL
Calculates the angle between the lines AB and BC, where AB and BC described by points a,...
static QgsPoint closestVertex(const QgsAbstractGeometry &geom, const QgsPoint &pt, QgsVertexId &id)
Returns the closest vertex to a geometry for a specified point.
static double interpolateArcValue(double angle, double a1, double a2, double a3, double zm1, double zm2, double zm3) SIP_HOLDGIL
Interpolate a value at given angle on circular arc given values (zm1, zm2, zm3) at three different an...
static double circleLength(double x1, double y1, double x2, double y2, double x3, double y3) SIP_HOLDGIL
Length of a circular string segment defined by pt1, pt2, pt3.
static QgsLineString perpendicularSegment(const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2) SIP_HOLDGIL
Create a perpendicular line segment from p to segment [s1, s2].
static int circleCircleIntersections(const QgsPointXY ¢er1, double radius1, const QgsPointXY ¢er2, double radius2, QgsPointXY &intersection1, QgsPointXY &intersection2) SIP_HOLDGIL
Calculates the intersections points between the circle with center center1 and radius radius1 and the...
static void coefficients(const QgsPoint &pt1, const QgsPoint &pt2, double &a, double &b, double &c) SIP_HOLDGIL
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) SIP_HOLDGIL
Calculates the perpendicular angle to a line joining two points.
static bool tangentPointAndCircle(const QgsPointXY ¢er, double radius, const QgsPointXY &p, QgsPointXY &pt1, QgsPointXY &pt2) SIP_HOLDGIL
Calculates the tangent points between the circle with the specified center and radius and the point p...
static QgsPoint pointOnLineWithDistance(const QgsPoint &startPoint, const QgsPoint &directionPoint, double distance) SIP_HOLDGIL
Returns a point a specified distance toward a second point.
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 bool pointContinuesArc(const QgsPoint &a1, const QgsPoint &a2, const QgsPoint &a3, const QgsPoint &b, double distanceTolerance, double pointSpacingAngleTolerance) SIP_HOLDGIL
Returns true if point b is on the arc formed by points a1, a2, and a3, but not within that arc portio...
static void weightedPointInTriangle(double aX, double aY, double bX, double bY, double cX, double cY, double weightB, double weightC, double &pointX, double &pointY) SIP_HOLDGIL
Returns a weighted point inside the triangle denoted by the points (aX, aY), (bX, bY) and (cX,...
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 bool circleAngleBetween(double angle, double angle1, double angle2, bool clockwise) SIP_HOLDGIL
Returns true if, in a circle, angle is between angle1 and angle2.
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 QgsPoint interpolatePointOnArc(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double distance) SIP_HOLDGIL
Interpolates a point on an arc defined by three points, pt1, pt2 and pt3.
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 bool linesIntersection3D(const QgsVector3D &La1, const QgsVector3D &La2, const QgsVector3D &Lb1, const QgsVector3D &Lb2, QgsVector3D &intersection) SIP_HOLDGIL
An algorithm to calculate an (approximate) intersection of two lines in 3D.
static int leftOfLine(const double x, const double y, const double x1, const double y1, const double x2, const double y2) SIP_HOLDGIL
Returns a value < 0 if the point (x, y) is left of the line from (x1, y1) -> (x2, y2).
static QString pointsToWKT(const QgsPointSequence &points, int precision, bool is3D, bool isMeasure)
Returns a WKT coordinate list.
static QgsPointXY interpolatePointOnLine(double x1, double y1, double x2, double y2, double fraction) SIP_HOLDGIL
Interpolates the position of a point a fraction of the way along the line from (x1,...
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.
void set(double x, double y) SIP_HOLDGIL
Sets the x and y value of the point.
double sqrDist(double x, double y) const SIP_HOLDGIL
Returns the squared distance between this point a specified x, y coordinate.
double distance(double x, double y) const SIP_HOLDGIL
Returns the distance between this point and a specified x, y coordinate.
Point geometry type, with support for z-dimension and m-values.
double distance(double x, double y) const SIP_HOLDGIL
Returns the Cartesian 2D distance between this point and a specified x, y coordinate.
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
bool isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
QgsPoint project(double distance, double azimuth, double inclination=90.0) const SIP_HOLDGIL
Returns a new point which corresponds to this point projected by a specified distance with specified ...
bool convertTo(QgsWkbTypes::Type type) override
Converts the geometry to a specified type.
void setZ(double z) SIP_HOLDGIL
Sets the point's z-coordinate.
double azimuth(const QgsPoint &other) const SIP_HOLDGIL
Calculates Cartesian azimuth between this point and other one (clockwise in degree,...
void setM(double m) SIP_HOLDGIL
Sets the point's m-value.
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.
QgsVector perpVector() const SIP_HOLDGIL
Returns the perpendicular vector to this vector (rotated 90 degrees counter-clockwise)
QgsVector normalized() const SIP_THROW(QgsException)
Returns the vector's normalized (or "unit") vector (ie same angle but length of 1....
double y() const SIP_HOLDGIL
Returns the vector's y-component.
double x() const SIP_HOLDGIL
Returns the vector's x-component.
double length() const SIP_HOLDGIL
Returns the length of the vector.
static Type parseType(const QString &wktStr)
Attempts to extract the WKB type from a WKT string.
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Type
The WKB type describes the number of dimensions a geometry has.
static Type addZ(Type type) SIP_HOLDGIL
Adds the z dimension to a WKB type and returns the new type.
static bool hasZ(Type type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
static Type addM(Type type) SIP_HOLDGIL
Adds the m dimension to a WKB type and returns the new type.
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)
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.
Qgis::VertexType type
Vertex type.
bool isValid() const SIP_HOLDGIL
Returns true if the vertex id is valid.