26 #include <QStringList> 28 #include <QRegularExpression> 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;
83 if ( currentDist <= minDist )
85 minDist = currentDist;
86 minDistPoint = vertex;
87 id.part = vertexId.
part;
88 id.ring = vertexId.
ring;
89 id.vertex = vertexId.
vertex;
90 id.type = vertexId.
type;
105 if ( vertexAfter.
vertex > 0 )
111 double distance = pointBefore.
distance( closestPoint );
114 closestPoint = pointBefore;
116 closestPoint = pointAfter;
120 closestPoint.
addZValue( pointBefore.
z() + ( pointAfter.
z() - pointBefore.
z() ) * distance / length );
122 closestPoint.
addMValue( pointBefore.
m() + ( pointAfter.
m() - pointBefore.
m() ) * distance / length );
132 double currentDist = 0;
137 if ( vertexId ==
id )
151 double currentDist = 0;
161 nextVertex = previousVertex;
166 while ( currentDist < distance && geometry.
nextVertex( nextVertex, point ) )
180 if ( currentDist > distance )
186 previousPoint = point;
196 return ( pt1.
x() - pt2.
x() ) * ( pt1.
x() - pt2.
x() ) + ( pt1.
y() - pt2.
y() ) * ( pt1.
y() - pt2.
y() );
209 double t = ( ( ptX - x1 ) * dx + ( ptY - y1 ) * dy ) / ( dx * dx + dy * dy );
225 double dist = dx * dx + dy * dy;
240 double d = v1.
y() * v2.
x() - v1.
x() * v2.
y();
245 double dx = p2.
x() - p1.
x();
246 double dy = p2.
y() - p1.
y();
247 double k = ( dy * v2.
x() - dx * v2.
y() ) / d;
249 intersection =
QgsPoint( p1.
x() + v1.
x() * k, p1.
y() + v1.
y() * k );
259 isIntersection =
false;
264 double wl = w.length();
278 isIntersection =
true;
279 if ( acceptImproperIntersection )
281 if ( ( p1 == q1 ) || ( p1 == q2 ) )
283 intersectionPoint = p1;
286 else if ( ( p2 == q1 ) || ( p2 == q2 ) )
288 intersectionPoint = p2;
295 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( p1.
x(), p1.
y(), q1.
x(), q1.
y(), q2.
x(), q2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
297 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( p2.
x(), p2.
y(), q1.
x(), q1.
y(), q2.
x(), q2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
299 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( q1.
x(), q1.
y(), p1.
x(), p1.
y(), p2.
x(), p2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
301 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( q2.
x(), q2.
y(), p1.
x(), p1.
y(), p2.
x(), p2.
y(), x, y, tolerance ), 0.0, tolerance )
308 double lambdav =
QgsVector( intersectionPoint.
x() - p1.
x(), intersectionPoint.
y() - p1.
y() ) * v;
309 if ( lambdav < 0. + tolerance || lambdav > vl - tolerance )
312 double lambdaw =
QgsVector( intersectionPoint.
x() - q1.
x(), intersectionPoint.
y() - q1.
y() ) * w;
313 return !( lambdaw < 0. + tolerance || lambdaw >= wl - tolerance );
323 const double x1 = linePoint1.
x() - center.
x();
324 const double y1 = linePoint1.
y() - center.
y();
325 const double x2 = linePoint2.
x() - center.
x();
326 const double y2 = linePoint2.
y() - center.
y();
327 const double dx = x2 - x1;
328 const double dy = y2 - y1;
330 const double dr = std::sqrt( std::pow( dx, 2 ) + std::pow( dy, 2 ) );
331 const double d = x1 * y2 - x2 * y1;
333 const double disc = std::pow( radius, 2 ) * std::pow( dr, 2 ) - std::pow( d, 2 );
343 const int sgnDy = dy < 0 ? -1 : 1;
345 const double ax = center.
x() + ( d * dy + sgnDy * dx * std::sqrt( std::pow( radius, 2 ) * std::pow( dr, 2 ) - std::pow( d, 2 ) ) ) / ( std::pow( dr, 2 ) );
346 const double ay = center.
y() + ( -d * dx + std::fabs( dy ) * std::sqrt( std::pow( radius, 2 ) * std::pow( dr, 2 ) - std::pow( d, 2 ) ) ) / ( std::pow( dr, 2 ) );
349 const double bx = center.
x() + ( d * dy - sgnDy * dx * std::sqrt( std::pow( radius, 2 ) * std::pow( dr, 2 ) - std::pow( d, 2 ) ) ) / ( std::pow( dr, 2 ) );
350 const double by = center.
y() + ( -d * dx - std::fabs( dy ) * std::sqrt( std::pow( radius, 2 ) * std::pow( dr, 2 ) - std::pow( d, 2 ) ) ) / ( std::pow( dr, 2 ) );
357 intersection.
set( p1.
x(), p1.
y() );
361 intersection.
set( p2.
x(), p2.
y() );
372 const double d = center0.
distance( center1 );
375 if ( d > ( r0 + r1 ) )
380 else if ( d < std::fabs( r0 - r1 ) )
397 const double a = ( ( r0 * r0 ) - ( r1 * r1 ) + ( d * d ) ) / ( 2.0 * d ) ;
402 const double dx = center1.
x() - center0.
x();
403 const double dy = center1.
y() - center0.
y();
406 const double x2 = center0.
x() + ( dx * a / d );
407 const double y2 = center0.
y() + ( dy * a / d );
412 const double h = std::sqrt( ( r0 * r0 ) - ( a * a ) );
417 const double rx = dy * ( h / d );
418 const double ry = dx * ( h / d );
421 intersection1 =
QgsPointXY( x2 + rx, y2 - ry );
422 intersection2 =
QgsPointXY( x2 - rx, y2 + ry );
436 const double dx = center.
x() - p.
x();
437 const double dy = center.
y() - p.
y();
438 const double distanceSquared = dx * dx + dy * dy;
439 const double radiusSquared = radius * radius;
440 if ( distanceSquared < radiusSquared )
447 const double distanceToTangent = std::sqrt( distanceSquared - radiusSquared );
459 if ( radius1 > radius2 )
462 const double radius2a = radius2 - radius1;
471 QgsVector v1( -( line1P2.
y() - center1.
y() ), line1P2.
x() - center1.
x() );
472 const double v1Length = v1.
length();
473 v1 = v1 * ( radius1 / v1Length );
476 line1P1 = center1 + v1;
477 line1P2 = line1P2 + v1;
481 QgsVector v2( line2P2.
y() - center1.
y(), -( line2P2.
x() - center1.
x() ) );
482 const double v2Length = v2.
length();
483 v2 = v2 * ( radius1 / v2Length );
486 line2P1 = center1 + v2;
487 line2P2 = line2P2 + v2;
495 if ( radius1 > radius2 )
499 const double d = center1.
distance( center2 );
500 const double radius1a = radius1 + radius2;
517 QgsVector v1( ( line1P2.
y() - center2.
y() ), -( line1P2.
x() - center2.
x() ) );
518 const double v1Length = v1.
length();
519 v1 = v1 * ( radius2 / v1Length );
522 line1P1 = center2 + v1;
523 line1P2 = line1P2 + v1;
527 QgsVector v2( -( line2P2.
y() - center2.
y() ), line2P2.
x() - center2.
x() );
528 const double v2Length = v2.
length();
529 v2 = v2 * ( radius2 / v2Length );
532 line2P1 = center2 + v2;
533 line2P2 = line2P2 + v2;
540 QVector<SelfIntersection> intersections;
546 for (
int i = 0, j = 1; j < n; i = j++ )
554 int end = i == 0 && isClosed ? n - 1 : n;
555 for (
int k = start, l = start + 1; l < end; k = l++ )
561 bool intersection =
false;
572 intersections.append( s );
575 return intersections;
589 double test = ( f1 * f2 - f3 * f4 );
591 return qgsDoubleNear( test, 0.0 ) ? 0 : ( test < 0 ? -1 : 1 );
601 void 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 )
603 const double dx = x2 - x1;
604 const double dy = y2 - y1;
605 const double length = std::sqrt( dx * dx + dy * dy );
618 const double scaleFactor = distance /
length;
619 x = x1 + dx * scaleFactor;
620 y = y1 + dy * scaleFactor;
622 *z = *z1 + ( *z2 - *z1 ) * scaleFactor;
624 *m = *m1 + ( *m2 - *m1 ) * scaleFactor;
630 double centerX, centerY, radius;
633 const double theta = distance / radius;
634 const double anglePt1 = std::atan2( pt1.
y() - centerY, pt1.
x() - centerX );
635 const double anglePt2 = std::atan2( pt2.
y() - centerY, pt2.
x() - centerX );
636 const double anglePt3 = std::atan2( pt3.
y() - centerY, pt3.
x() - centerX );
637 const bool isClockwise =
circleClockwise( anglePt1, anglePt2, anglePt3 );
638 const double angleDest = anglePt1 + ( isClockwise ? -theta : theta );
640 const double x = centerX + radius * ( std::cos( angleDest ) );
641 const double y = centerY + radius * ( std::sin( angleDest ) );
643 const double z = pt1.
is3D() ?
655 double angle = std::atan2( dy, dx ) * 180 / M_PI;
660 else if ( angle > 360 )
669 double dx21, dy21, dx31, dy31, h21, h31, d;
674 centerX = ( pt1.
x() + pt2.
x() ) / 2.0;
675 centerY = ( pt1.
y() + pt2.
y() ) / 2.0;
676 radius = std::sqrt( std::pow( centerX - pt1.
x(), 2.0 ) + std::pow( centerY - pt1.
y(), 2.0 ) );
681 dx21 = pt2.
x() - pt1.
x();
682 dy21 = pt2.
y() - pt1.
y();
683 dx31 = pt3.
x() - pt1.
x();
684 dy31 = pt3.
y() - pt1.
y();
686 h21 = std::pow( dx21, 2.0 ) + std::pow( dy21, 2.0 );
687 h31 = std::pow( dx31, 2.0 ) + std::pow( dy31, 2.0 );
690 d = 2 * ( dx21 * dy31 - dx31 * dy21 );
700 centerX = pt1.
x() + ( h21 * dy31 - h31 * dy21 ) / d;
701 centerY = pt1.
y() - ( h21 * dx31 - h31 * dx21 ) / d;
702 radius = std::sqrt( std::pow( centerX - pt1.
x(), 2.0 ) + std::pow( centerY - pt1.
y(), 2.0 ) );
707 if ( angle3 >= angle1 )
709 return !( angle2 > angle1 && angle2 < angle3 );
713 return !( angle2 > angle1 || angle2 < angle3 );
721 if ( angle2 < angle1 )
723 return ( angle <= angle1 && angle >= angle2 );
727 return ( angle <= angle1 || angle >= angle2 );
732 if ( angle2 > angle1 )
734 return ( angle >= angle1 && angle <= angle2 );
738 return ( angle >= angle1 || angle <= angle2 );
751 double centerX, centerY, radius;
753 double length = M_PI / 180.0 * radius *
sweepAngle( centerX, centerY, x1, y1, x2, y2, x3, y3 );
767 if ( p3Angle >= p1Angle )
769 if ( p2Angle > p1Angle && p2Angle < p3Angle )
771 return ( p3Angle - p1Angle );
775 return ( - ( p1Angle + ( 360 - p3Angle ) ) );
780 if ( p2Angle < p1Angle && p2Angle > p3Angle )
782 return ( -( p1Angle - p3Angle ) );
786 return ( p3Angle + ( 360 - p1Angle ) );
793 QgsPoint midPoint( ( p1.
x() + p2.
x() ) / 2.0, ( p1.
y() + p2.
y() ) / 2.0 );
795 if ( radius < midDist )
799 double centerMidDist = std::sqrt( radius * radius - midDist * midDist );
800 double dist = radius - centerMidDist;
802 double midDx = midPoint.
x() - p1.
x();
803 double midDy = midPoint.
y() - p1.
y();
806 QVector<QgsPoint> possibleMidPoints;
813 double minDist = std::numeric_limits<double>::max();
814 int minDistIndex = -1;
815 for (
int i = 0; i < possibleMidPoints.size(); ++i )
817 double currentDist =
sqrDistance2D( mousePos, possibleMidPoints.at( i ) );
818 if ( currentDist < minDist )
821 minDist = currentDist;
825 if ( minDistIndex == -1 )
830 result = possibleMidPoints.at( minDistIndex );
842 if ( !useShortestArc )
843 midPointAngle += M_PI;
844 return center.
project( center.
distance( p1 ), midPointAngle * 180 / M_PI );
851 double mX, mY, radius;
860 angle =
lineAngle( tangentPoint.
x(), tangentPoint.
y(), mX, mY ) - M_PI_2;
864 angle =
lineAngle( mX, mY, tangentPoint.
x(), tangentPoint.
y() ) - M_PI_2;
873 bool reversed =
false;
897 circleCenterRadius( circlePoint1, circlePoint2, circlePoint3, radius, centerX, centerY );
899 if ( circlePoint1 != circlePoint3 && ( radius < 0 ||
qgsDoubleNear( segSide, 0.0 ) ) )
907 double increment = tolerance;
910 double halfAngle = std::acos( -tolerance / radius + 1 );
911 increment = 2 * halfAngle;
915 double a1 = std::atan2( circlePoint1.
y() - centerY, circlePoint1.
x() - centerX );
916 double a2 = std::atan2( circlePoint2.
y() - centerY, circlePoint2.
x() - centerX );
917 double a3 = std::atan2( circlePoint3.
y() - centerY, circlePoint3.
x() - centerX );
920 const bool symmetric =
true;
923 double angle = a3 - a1;
924 if ( angle < 0 ) angle += M_PI * 2;
927 int segs = ceil( angle / increment );
929 increment = angle / segs;
942 QVector<QgsPoint> stringPoints;
943 stringPoints.insert( 0, circlePoint1 );
944 if ( circlePoint2 != circlePoint3 && circlePoint1 != circlePoint2 )
958 double tolError = increment / 100;
959 double stopAngle = a3 - tolError;
960 for (
double angle = a1 + increment;
angle < stopAngle;
angle += increment )
962 x = centerX + radius * std::cos(
angle );
963 y = centerY + radius * std::sin(
angle );
974 stringPoints.insert( stringPoints.size(),
QgsPoint( pointWkbType, x, y, z, m ) );
977 stringPoints.insert( stringPoints.size(), circlePoint3 );
982 std::reverse( stringPoints.begin(), stringPoints.end() );
984 if ( ! points.empty() && stringPoints.front() == points.back() ) stringPoints.pop_front();
985 points.append( stringPoints );
990 double side = ( ( pt2.
x() - pt1.
x() ) * ( pt3.
y() - pt1.
y() ) - ( pt3.
x() - pt1.
x() ) * ( pt2.
y() - pt1.
y() ) );
1015 return zm1 + ( zm2 - zm1 ) * ( angle - a1 ) / ( a2 - a1 );
1017 return zm2 + ( zm3 - zm2 ) * ( angle - a2 ) / ( a3 - a2 );
1023 return zm1 + ( zm2 - zm1 ) * ( a1 - angle ) / ( a1 - a2 );
1025 return zm2 + ( zm3 - zm2 ) * ( a2 - angle ) / ( a2 - a3 );
1033 const QStringList coordList = wktCoordinateList.split(
',', QString::SkipEmptyParts );
1036 bool foundZ =
false;
1037 bool foundM =
false;
1038 QRegularExpression rx( QStringLiteral(
"\\s" ) );
1039 for (
const QString &pointCoordinates : coordList )
1041 QStringList coordinates = pointCoordinates.split( rx, QString::SkipEmptyParts );
1042 if ( coordinates.size() == 3 && !foundZ && !foundM && !is3D && !
isMeasure )
1048 else if ( coordinates.size() >= 4 && ( !( is3D || foundZ ) || !( isMeasure || foundM ) ) )
1057 for (
const QString &pointCoordinates : coordList )
1059 QStringList coordinates = pointCoordinates.split( rx, QString::SkipEmptyParts );
1060 if ( coordinates.size() < dim )
1064 double x = coordinates[idx++].toDouble();
1065 double y = coordinates[idx++].toDouble();
1068 if ( ( is3D || foundZ ) && coordinates.length() > idx )
1069 z = coordinates[idx++].toDouble();
1072 if ( ( isMeasure || foundM ) && coordinates.length() > idx )
1073 m = coordinates[idx++].toDouble();
1076 if ( is3D || foundZ )
1078 if ( isMeasure || foundM )
1085 if ( isMeasure || foundM )
1091 points.append(
QgsPoint( t, x, y, z, m ) );
1099 wkb << static_cast<quint32>( points.size() );
1100 for (
const QgsPoint &point : points )
1102 wkb << point.x() << point.y();
1116 QString wkt = QStringLiteral(
"(" );
1125 wkt += QLatin1String(
", " );
1127 if ( wkt.endsWith( QLatin1String(
", " ) ) )
1135 QDomElement elemCoordinates = doc.createElementNS( ns, QStringLiteral(
"coordinates" ) );
1138 QString cs = QStringLiteral(
"," );
1140 QString ts = QStringLiteral(
" " );
1142 elemCoordinates.setAttribute( QStringLiteral(
"cs" ), cs );
1143 elemCoordinates.setAttribute( QStringLiteral(
"ts" ), ts );
1145 QString strCoordinates;
1148 if ( axisOrder == QgsAbstractGeometry::AxisOrder::XY )
1153 if ( strCoordinates.endsWith( ts ) )
1154 strCoordinates.chop( 1 );
1156 elemCoordinates.appendChild( doc.createTextNode( strCoordinates ) );
1157 return elemCoordinates;
1162 QDomElement elemPosList = doc.createElementNS( ns, QStringLiteral(
"posList" ) );
1163 elemPosList.setAttribute( QStringLiteral(
"srsDimension" ), is3D ? 3 : 2 );
1165 QString strCoordinates;
1168 if ( axisOrder == QgsAbstractGeometry::AxisOrder::XY )
1175 if ( strCoordinates.endsWith(
' ' ) )
1176 strCoordinates.chop( 1 );
1178 elemPosList.appendChild( doc.createTextNode( strCoordinates ) );
1184 QString json = QStringLiteral(
"[ " );
1189 if ( json.endsWith( QLatin1String(
", " ) ) )
1199 double clippedAngle =
angle;
1200 if ( clippedAngle >= M_PI * 2 || clippedAngle <= -2 * M_PI )
1202 clippedAngle = std::fmod( clippedAngle, 2 * M_PI );
1204 if ( clippedAngle < 0.0 )
1206 clippedAngle += 2 * M_PI;
1208 return clippedAngle;
1215 QRegularExpression cooRegEx( QStringLiteral(
"^[^\\(]*\\((.*)\\)[^\\)]*$" ) );
1216 cooRegEx.setPatternOptions( QRegularExpression::DotMatchesEverythingOption );
1217 QRegularExpressionMatch match = cooRegEx.match( wkt );
1218 QString contents = match.hasMatch() ? match.captured( 1 ) : QString();
1219 return qMakePair( wkbType, contents );
1227 for (
int i = 0, n = wkt.length(); i < n; ++i )
1229 if ( ( wkt[i].isSpace() || wkt[i] ==
'\n' || wkt[i] ==
'\t' ) && level == 0 )
1232 if ( wkt[i] ==
',' && level == 0 )
1234 if ( !block.isEmpty() )
1236 if ( block.startsWith(
'(' ) && !defaultType.isEmpty() )
1237 block.prepend( defaultType +
' ' );
1238 blocks.append( block );
1243 if ( wkt[i] ==
'(' )
1245 else if ( wkt[i] ==
')' )
1249 if ( !block.isEmpty() )
1251 if ( block.startsWith(
'(' ) && !defaultType.isEmpty() )
1252 block.prepend( defaultType +
' ' );
1253 blocks.append( block );
1263 double x = ( pt1.
x() + pt2.
x() ) / 2.0;
1264 double y = ( pt1.
y() + pt2.
y() ) / 2.0;
1265 double z = std::numeric_limits<double>::quiet_NaN();
1266 double m = std::numeric_limits<double>::quiet_NaN();
1271 z = ( pt1.
z() + pt2.
z() ) / 2.0;
1277 m = ( pt1.
m() + pt2.
m() ) / 2.0;
1280 return QgsPoint( pType, x, y, z, m );
1285 const double _fraction = 1 - fraction;
1287 p1.
x() * _fraction + p2.
x() * fraction,
1288 p1.
y() * _fraction + p2.
y() * fraction,
1289 p1.
is3D() ? p1.
z() * _fraction + p2.
z() * fraction : std::numeric_limits<double>::quiet_NaN(),
1290 p1.
isMeasure() ? p1.
m() * _fraction + p2.
m() * fraction : std::numeric_limits<double>::quiet_NaN() );
1295 const double deltaX = ( x2 - x1 ) * fraction;
1296 const double deltaY = ( y2 - y1 ) * fraction;
1297 return QgsPointXY( x1 + deltaX, y1 + deltaY );
1305 const double fraction = ( value - v1 ) / ( v2 - v1 );
1311 double delta_x = pt2.
x() - pt1.
x();
1312 double delta_y = pt2.
y() - pt1.
y();
1318 return delta_y / delta_x;
1337 a = pt1.
y() - pt2.
y();
1338 b = pt2.
x() - pt1.
x();
1339 c = pt1.
x() * pt2.
y() - pt1.
y() * pt2.
x();
1349 if ( ( p == s1 ) || ( p == s2 ) )
1367 double y = ( -c - a * p.
x() ) / b;
1369 double d2 = 1 + m * m;
1370 double H = p.
y() - y;
1371 double dx = m * H / d2;
1384 double at = std::atan2( y2 - y1, x2 - x1 );
1385 double a = -at + M_PI_2;
1391 double angle1 = std::atan2( y1 - y2, x1 - x2 );
1392 double angle2 = std::atan2( y3 - y2, x3 - x2 );
1406 double a1 =
lineAngle( x1, y1, x2, y2 );
1407 double a2 =
lineAngle( x2, y2, x3, y3 );
1415 double clockwiseDiff = 0.0;
1418 clockwiseDiff = a2 - a1;
1422 clockwiseDiff = a2 + ( 2 * M_PI - a1 );
1424 double counterClockwiseDiff = 2 * M_PI - clockwiseDiff;
1426 double resultAngle = 0;
1427 if ( clockwiseDiff <= counterClockwiseDiff )
1429 resultAngle = a1 + clockwiseDiff / 2.0;
1433 resultAngle = a1 - counterClockwiseDiff / 2.0;
1444 if ( u3.
length() == 0 )
return 1;
1461 if ( std::fabs( u3.
x() ) <= epsilon &&
1462 std::fabs( u3.
y() ) <= epsilon &&
1463 std::fabs( u3.
z() ) <= epsilon )
1475 if ( !( std::fabs( b1 ) > epsilon ) )
1480 if ( !( a2 != -1 && a2 != 1 ) )
1486 double r1 = ( c2 - b2 * c1 / b1 ) / ( a2 - b2 * a1 / b1 );
1502 bool isIntersection;
1511 intersection.
set( ptInter.
x(), ptInter.
y(), La1.
z() );
1551 if ( !firstIsDone || !secondIsDone )
1557 intersection = ( X1 + X2 ) / 2.0;
1565 for (
const QgsPoint &pt : points )
1570 point.
setZ( pt.z() );
bool isMeasure() const
Returns true if the geometry contains m values.
Maximum distance between an arbitrary point on the original curve and closest point on its approximat...
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.
3 Class for storage of 3D vectors similar to QVector3D, with the difference that it uses double preci...
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 QString pointsToJSON(const QgsPointSequence &points, int precision)
Returns a geoJSON coordinates string.
void set(double x, double y)
Sets the x and y value of the point.
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 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 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 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 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 QVector< SelfIntersection > selfIntersections(const QgsAbstractGeometry *geom, int part, int ring, double tolerance)
Find self intersections in a polyline.
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...
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
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...
bool isValid() const
Returns true if the vertex id is valid.
void setZ(double z)
Sets the point's z-coordinate.
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 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, y1) to (x2, y2) and (x2, y2) to (x3, y3).
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...
double distance(double x, double y) const
Returns the distance between this point and a specified x, y coordinate.
static double gradient(const QgsPoint &pt1, const QgsPoint &pt2)
Returns the gradient of a line defined by points pt1 and pt2.
double length() const
Returns the length of the vector.
A class to represent a 2D point.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
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 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.
Curve polygon geometry type.
static double linePerpendicularAngle(double x1, double y1, double x2, double y2)
Calculates the perpendicular angle to a line joining two points.
static Type parseType(const QString &wktStr)
Attempts to extract the WKB type from a WKT string.
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 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.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle...
static QgsPoint closestVertex(const QgsAbstractGeometry &geom, const QgsPoint &pt, QgsVertexId &id)
Returns the closest vertex to a geometry for a specified point.
virtual bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const =0
Returns next vertex id and coordinates.
double y() const
Returns Y coordinate.
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
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...
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)
static QStringList wktGetChildBlocks(const QString &wkt, const QString &defaultType=QString())
Parses a WKT string and returns of list of blocks contained in the WKT.
void set(double x, double y, double z)
Sets vector coordinates.
static double dotProduct(const QgsVector3D &v1, const QgsVector3D &v2)
Returns the dot product of two vectors.
static QgsVector3D crossProduct(const QgsVector3D &v1, const QgsVector3D &v2)
Returns the cross product of two vectors.
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.
void normalize()
Normalizes the current vector in place.
double sqrDist(double x, double y) const
Returns the squared distance between this point a specified x, y coordinate.
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
virtual double length() const
Returns the length of the geometry.
static bool circleClockwise(double angle1, double angle2, double angle3)
Returns true if the circle defined by three angles is ordered clockwise.
double z() const
Returns Z coordinate.
static QString pointsToWKT(const QgsPointSequence &points, int precision, bool is3D, bool isMeasure)
Returns a WKT coordinate list.
Type
The WKB type describes the number of dimensions a geometry has.
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.
static bool setZValueFromPoints(const QgsPointSequence &points, QgsPoint &point)
A Z dimension is added to point if one of the point in the list points is in 3D.
virtual double segmentLength(QgsVertexId startVertex) const =0
Returns the length of the segment of the geometry which begins at startVertex.
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type.
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).
void addVertex(const QgsPoint &pt)
Adds a new vertex to the end of the line string.
Utility class for identifying a unique vertex within a geometry.
const double DEFAULT_SEGMENT_EPSILON
Default snapping tolerance for segments.
static QgsPoint midpoint(const QgsPoint &pt1, const QgsPoint &pt2)
Returns a middle point between points pt1 and pt2.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type.
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 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, angle2 and angle3.
Abstract base class for curved geometry type.
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 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, y1) to (x2, y2).
Abstract base class for all geometries.
static QVector< QgsLineString * > extractLineStrings(const QgsAbstractGeometry *geom)
Returns list of linestrings extracted from the passed geometry.
static double normalizedAngle(double angle)
Ensures that an angle is in the range 0 <= angle < 2 pi.
double distance(double x, double y) const
Returns the distance between this point and a specified x, y coordinate.
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the geometry.
QgsPoint project(double distance, double azimuth, double inclination=90.0) const
Returns a new point which correspond to this point projected by a specified distance with specified a...
Point geometry type, with support for z-dimension and m-values.
AxisOrder
Axis order for GML generation.
double length() const
Returns the length of the vector.
static bool lineIntersection(const QgsPoint &p1, QgsVector v1, const QgsPoint &p2, QgsVector v2, QgsPoint &intersection)
Computes the intersection between two lines.
A class to represent a vector.
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.
QVector< QgsPoint > QgsPointSequence
static QgsPoint pointOnLineWithDistance(const QgsPoint &startPoint, const QgsPoint &directionPoint, double distance)
Returns a point a specified distance toward a second point.
static double sqrDistance2D(const QgsPoint &pt1, const QgsPoint &pt2)
Returns the squared 2D distance between two points.
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 QgsLineString perpendicularSegment(const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2)
Create a perpendicular line segment from p to segment [s1, s2].
static QgsPointSequence pointsFromWKT(const QString &wktCoordinateList, bool is3D, bool isMeasure)
Returns a list of points contained in a WKT string.
Line string geometry type, with support for z-dimension and m-values.
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.
virtual int vertexCount(int part=0, int ring=0) const =0
Returns the number of vertices of which this geometry is built.
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 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.
bool convertTo(QgsWkbTypes::Type type) override
Converts the geometry to a specified type.
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
static void pointsToWKB(QgsWkbPtr &wkb, const QgsPointSequence &points, bool is3D, bool isMeasure)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }.
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 int circleCircleIntersections(QgsPointXY center1, double radius1, QgsPointXY center2, double radius2, QgsPointXY &intersection1, QgsPointXY &intersection2)
Calculates the intersections points between the circle with center center1 and radius radius1 and the...
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 bool hasM(Type type)
Tests whether a WKB type contains m values.
double x() const
Returns the vector's x-component.
static QgsPoint closestPoint(const QgsAbstractGeometry &geometry, const QgsPoint &point)
Returns the nearest point on a segment of a geometry for the specified point.
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
double y() const
Returns the vector's y-component.
static double distanceToVertex(const QgsAbstractGeometry &geom, QgsVertexId id)
Returns the distance along a geometry from its first vertex to the specified vertex.
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).
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
double x() const
Returns X coordinate.
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 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...