26 #include <QStringList> 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;
84 if ( currentDist <= minDist )
86 minDist = currentDist;
87 minDistPoint = vertex;
88 id.part = vertexId.
part;
89 id.ring = vertexId.
ring;
90 id.vertex = vertexId.
vertex;
91 id.type = vertexId.
type;
106 if ( vertexAfter.
vertex > 0 )
112 double distance = pointBefore.
distance( closestPoint );
115 closestPoint = pointBefore;
117 closestPoint = pointAfter;
121 closestPoint.
addZValue( pointBefore.
z() + ( pointAfter.
z() - pointBefore.
z() ) * distance / length );
123 closestPoint.
addMValue( pointBefore.
m() + ( pointAfter.
m() - pointBefore.
m() ) * distance / length );
133 double currentDist = 0;
138 if ( vertexId ==
id )
152 double currentDist = 0;
162 nextVertex = previousVertex;
167 while ( currentDist < distance && geometry.
nextVertex( nextVertex, point ) )
181 if ( currentDist > distance )
187 previousPoint = point;
197 return ( pt1.
x() - pt2.
x() ) * ( pt1.
x() - pt2.
x() ) + ( pt1.
y() - pt2.
y() ) * ( pt1.
y() - pt2.
y() );
210 double t = ( ( ptX - x1 ) * dx + ( ptY - y1 ) * dy ) / ( dx * dx + dy * dy );
226 double dist = dx * dx + dy * dy;
241 double d = v1.
y() * v2.
x() - v1.
x() * v2.
y();
246 double dx = p2.
x() - p1.
x();
247 double dy = p2.
y() - p1.
y();
248 double k = ( dy * v2.
x() - dx * v2.
y() ) / d;
250 intersection =
QgsPoint( p1.
x() + v1.
x() * k, p1.
y() + v1.
y() * k );
260 isIntersection =
false;
265 double wl = w.length();
279 isIntersection =
true;
280 if ( acceptImproperIntersection )
282 if ( ( p1 == q1 ) || ( p1 == q2 ) )
284 intersectionPoint = p1;
287 else if ( ( p2 == q1 ) || ( p2 == q2 ) )
289 intersectionPoint = p2;
296 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( p1.
x(), p1.
y(), q1.
x(), q1.
y(), q2.
x(), q2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
298 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( p2.
x(), p2.
y(), q1.
x(), q1.
y(), q2.
x(), q2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
300 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( q1.
x(), q1.
y(), p1.
x(), p1.
y(), p2.
x(), p2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
302 qgsDoubleNear(
QgsGeometryUtils::sqrDistToLine( q2.
x(), q2.
y(), p1.
x(), p1.
y(), p2.
x(), p2.
y(), x, y, tolerance ), 0.0, tolerance )
309 double lambdav =
QgsVector( intersectionPoint.
x() - p1.
x(), intersectionPoint.
y() - p1.
y() ) * v;
310 if ( lambdav < 0. + tolerance || lambdav > vl - tolerance )
313 double lambdaw =
QgsVector( intersectionPoint.
x() - q1.
x(), intersectionPoint.
y() - q1.
y() ) * w;
314 return !( lambdaw < 0. + tolerance || lambdaw >= wl - tolerance );
324 const double x1 = linePoint1.
x() - center.
x();
325 const double y1 = linePoint1.
y() - center.
y();
326 const double x2 = linePoint2.
x() - center.
x();
327 const double y2 = linePoint2.
y() - center.
y();
328 const double dx = x2 - x1;
329 const double dy = y2 - y1;
331 const double dr2 = std::pow( dx, 2 ) + std::pow( dy, 2 );
332 const double d = x1 * y2 - x2 * y1;
334 const double disc = std::pow( radius, 2 ) * dr2 - std::pow( d, 2 );
344 const int sgnDy = dy < 0 ? -1 : 1;
346 const double sqrDisc = std::sqrt( disc );
348 const double ax = center.
x() + ( d * dy + sgnDy * dx * sqrDisc ) / dr2;
349 const double ay = center.
y() + ( -d * dx + std::fabs( dy ) * sqrDisc ) / dr2;
352 const double bx = center.
x() + ( d * dy - sgnDy * dx * sqrDisc ) / dr2;
353 const double by = center.
y() + ( -d * dx - std::fabs( dy ) * sqrDisc ) / dr2;
360 intersection.
set( p1.
x(), p1.
y() );
364 intersection.
set( p2.
x(), p2.
y() );
375 const double d = center0.
distance( center1 );
378 if ( d > ( r0 + r1 ) )
383 else if ( d < std::fabs( r0 - r1 ) )
400 const double a = ( ( r0 * r0 ) - ( r1 * r1 ) + ( d * d ) ) / ( 2.0 * d ) ;
405 const double dx = center1.
x() - center0.
x();
406 const double dy = center1.
y() - center0.
y();
409 const double x2 = center0.
x() + ( dx * a / d );
410 const double y2 = center0.
y() + ( dy * a / d );
415 const double h = std::sqrt( ( r0 * r0 ) - ( a * a ) );
420 const double rx = dy * ( h / d );
421 const double ry = dx * ( h / d );
424 intersection1 =
QgsPointXY( x2 + rx, y2 - ry );
425 intersection2 =
QgsPointXY( x2 - rx, y2 + ry );
439 const double dx = center.
x() - p.
x();
440 const double dy = center.
y() - p.
y();
441 const double distanceSquared = dx * dx + dy * dy;
442 const double radiusSquared = radius * radius;
443 if ( distanceSquared < radiusSquared )
450 const double distanceToTangent = std::sqrt( distanceSquared - radiusSquared );
462 if ( radius1 > radius2 )
465 const double radius2a = radius2 - radius1;
474 QgsVector v1( -( line1P2.
y() - center1.
y() ), line1P2.
x() - center1.
x() );
475 const double v1Length = v1.
length();
476 v1 = v1 * ( radius1 / v1Length );
479 line1P1 = center1 + v1;
480 line1P2 = line1P2 + v1;
484 QgsVector v2( line2P2.
y() - center1.
y(), -( line2P2.
x() - center1.
x() ) );
485 const double v2Length = v2.
length();
486 v2 = v2 * ( radius1 / v2Length );
489 line2P1 = center1 + v2;
490 line2P2 = line2P2 + v2;
498 if ( radius1 > radius2 )
502 const double d = center1.
distance( center2 );
503 const double radius1a = radius1 + radius2;
520 QgsVector v1( ( line1P2.
y() - center2.
y() ), -( line1P2.
x() - center2.
x() ) );
521 const double v1Length = v1.
length();
522 v1 = v1 * ( radius2 / v1Length );
525 line1P1 = center2 + v1;
526 line1P2 = line1P2 + v1;
530 QgsVector v2( -( line2P2.
y() - center2.
y() ), line2P2.
x() - center2.
x() );
531 const double v2Length = v2.
length();
532 v2 = v2 * ( radius2 / v2Length );
535 line2P1 = center2 + v2;
536 line2P2 = line2P2 + v2;
543 QVector<SelfIntersection> intersections;
549 for (
int i = 0, j = 1; j < n; i = j++ )
557 int end = i == 0 && isClosed ? n - 1 : n;
558 for (
int k = start, l = start + 1; l < end; k = l++ )
564 bool intersection =
false;
575 intersections.append( s );
578 return intersections;
592 double test = ( f1 * f2 - f3 * f4 );
594 return qgsDoubleNear( test, 0.0 ) ? 0 : ( test < 0 ? -1 : 1 );
604 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 )
606 const double dx = x2 - x1;
607 const double dy = y2 - y1;
608 const double length = std::sqrt( dx * dx + dy * dy );
621 const double scaleFactor = distance /
length;
622 x = x1 + dx * scaleFactor;
623 y = y1 + dy * scaleFactor;
625 *z = *z1 + ( *z2 - *z1 ) * scaleFactor;
627 *m = *m1 + ( *m2 - *m1 ) * scaleFactor;
633 double centerX, centerY, radius;
636 const double theta = distance / radius;
637 const double anglePt1 = std::atan2( pt1.
y() - centerY, pt1.
x() - centerX );
638 const double anglePt2 = std::atan2( pt2.
y() - centerY, pt2.
x() - centerX );
639 const double anglePt3 = std::atan2( pt3.
y() - centerY, pt3.
x() - centerX );
640 const bool isClockwise =
circleClockwise( anglePt1, anglePt2, anglePt3 );
641 const double angleDest = anglePt1 + ( isClockwise ? -theta : theta );
643 const double x = centerX + radius * ( std::cos( angleDest ) );
644 const double y = centerY + radius * ( std::sin( angleDest ) );
646 const double z = pt1.
is3D() ?
658 double angle = std::atan2( dy, dx ) * 180 / M_PI;
663 else if ( angle > 360 )
672 double dx21, dy21, dx31, dy31, h21, h31, d;
677 centerX = ( pt1.
x() + pt2.
x() ) / 2.0;
678 centerY = ( pt1.
y() + pt2.
y() ) / 2.0;
679 radius = std::sqrt( std::pow( centerX - pt1.
x(), 2.0 ) + std::pow( centerY - pt1.
y(), 2.0 ) );
684 dx21 = pt2.
x() - pt1.
x();
685 dy21 = pt2.
y() - pt1.
y();
686 dx31 = pt3.
x() - pt1.
x();
687 dy31 = pt3.
y() - pt1.
y();
689 h21 = std::pow( dx21, 2.0 ) + std::pow( dy21, 2.0 );
690 h31 = std::pow( dx31, 2.0 ) + std::pow( dy31, 2.0 );
693 d = 2 * ( dx21 * dy31 - dx31 * dy21 );
703 centerX = pt1.
x() + ( h21 * dy31 - h31 * dy21 ) / d;
704 centerY = pt1.
y() - ( h21 * dx31 - h31 * dx21 ) / d;
705 radius = std::sqrt( std::pow( centerX - pt1.
x(), 2.0 ) + std::pow( centerY - pt1.
y(), 2.0 ) );
710 if ( angle3 >= angle1 )
712 return !( angle2 > angle1 && angle2 < angle3 );
716 return !( angle2 > angle1 || angle2 < angle3 );
724 if ( angle2 < angle1 )
726 return ( angle <= angle1 && angle >= angle2 );
730 return ( angle <= angle1 || angle >= angle2 );
735 if ( angle2 > angle1 )
737 return ( angle >= angle1 && angle <= angle2 );
741 return ( angle >= angle1 || angle <= angle2 );
754 double centerX, centerY, radius;
756 double length = M_PI / 180.0 * radius *
sweepAngle( centerX, centerY, x1, y1, x2, y2, x3, y3 );
770 if ( p3Angle >= p1Angle )
772 if ( p2Angle > p1Angle && p2Angle < p3Angle )
774 return ( p3Angle - p1Angle );
778 return ( - ( p1Angle + ( 360 - p3Angle ) ) );
783 if ( p2Angle < p1Angle && p2Angle > p3Angle )
785 return ( -( p1Angle - p3Angle ) );
789 return ( p3Angle + ( 360 - p1Angle ) );
796 QgsPoint midPoint( ( p1.
x() + p2.
x() ) / 2.0, ( p1.
y() + p2.
y() ) / 2.0 );
798 if ( radius < midDist )
802 double centerMidDist = std::sqrt( radius * radius - midDist * midDist );
803 double dist = radius - centerMidDist;
805 double midDx = midPoint.
x() - p1.
x();
806 double midDy = midPoint.
y() - p1.
y();
809 QVector<QgsPoint> possibleMidPoints;
816 double minDist = std::numeric_limits<double>::max();
817 int minDistIndex = -1;
818 for (
int i = 0; i < possibleMidPoints.size(); ++i )
820 double currentDist =
sqrDistance2D( mousePos, possibleMidPoints.at( i ) );
821 if ( currentDist < minDist )
824 minDist = currentDist;
828 if ( minDistIndex == -1 )
833 result = possibleMidPoints.at( minDistIndex );
845 if ( !useShortestArc )
846 midPointAngle += M_PI;
847 return center.
project( center.
distance( p1 ), midPointAngle * 180 / M_PI );
854 double mX, mY, radius;
863 angle =
lineAngle( tangentPoint.
x(), tangentPoint.
y(), mX, mY ) - M_PI_2;
867 angle =
lineAngle( mX, mY, tangentPoint.
x(), tangentPoint.
y() ) - M_PI_2;
876 bool reversed =
false;
900 circleCenterRadius( circlePoint1, circlePoint2, circlePoint3, radius, centerX, centerY );
902 if ( circlePoint1 != circlePoint3 && ( radius < 0 ||
qgsDoubleNear( segSide, 0.0 ) ) )
910 double increment = tolerance;
914 tolerance = std::min( tolerance, radius * 2 );
915 double halfAngle = std::acos( -tolerance / radius + 1 );
916 increment = 2 * halfAngle;
920 double a1 = std::atan2( circlePoint1.
y() - centerY, circlePoint1.
x() - centerX );
921 double a2 = std::atan2( circlePoint2.
y() - centerY, circlePoint2.
x() - centerX );
922 double a3 = std::atan2( circlePoint3.
y() - centerY, circlePoint3.
x() - centerX );
925 const bool symmetric =
true;
928 double angle = a3 - a1;
930 if ( angle <= 0 ) angle += M_PI * 2;
933 int segs = ceil( angle / increment );
935 increment = angle / segs;
949 QVector<QgsPoint> stringPoints;
950 stringPoints.insert( 0, circlePoint1 );
951 if ( circlePoint2 != circlePoint3 && circlePoint1 != circlePoint2 )
965 double tolError = increment / 100;
966 double stopAngle = a3 - tolError;
967 for (
double angle = a1 + increment;
angle < stopAngle;
angle += increment )
969 x = centerX + radius * std::cos(
angle );
970 y = centerY + radius * std::sin(
angle );
981 stringPoints.insert( stringPoints.size(),
QgsPoint( pointWkbType, x, y, z, m ) );
984 stringPoints.insert( stringPoints.size(), circlePoint3 );
989 std::reverse( stringPoints.begin(), stringPoints.end() );
991 if ( ! points.empty() && stringPoints.front() == points.back() ) stringPoints.pop_front();
992 points.append( stringPoints );
997 double side = ( ( pt2.
x() - pt1.
x() ) * ( pt3.
y() - pt1.
y() ) - ( pt3.
x() - pt1.
x() ) * ( pt2.
y() - pt1.
y() ) );
1022 return zm1 + ( zm2 - zm1 ) * ( angle - a1 ) / ( a2 - a1 );
1024 return zm2 + ( zm3 - zm2 ) * ( angle - a2 ) / ( a3 - a2 );
1030 return zm1 + ( zm2 - zm1 ) * ( a1 - angle ) / ( a1 - a2 );
1032 return zm2 + ( zm3 - zm2 ) * ( a2 - angle ) / ( a2 - a3 );
1040 const QStringList coordList = wktCoordinateList.split(
',', QString::SkipEmptyParts );
1043 bool foundZ =
false;
1044 bool foundM =
false;
1045 QRegularExpression rx( QStringLiteral(
"\\s" ) );
1046 for (
const QString &pointCoordinates : coordList )
1048 QStringList coordinates = pointCoordinates.split( rx, QString::SkipEmptyParts );
1049 if ( coordinates.size() == 3 && !foundZ && !foundM && !is3D && !
isMeasure )
1055 else if ( coordinates.size() >= 4 && ( !( is3D || foundZ ) || !( isMeasure || foundM ) ) )
1064 for (
const QString &pointCoordinates : coordList )
1066 QStringList coordinates = pointCoordinates.split( rx, QString::SkipEmptyParts );
1067 if ( coordinates.size() < dim )
1071 double x = coordinates[idx++].toDouble();
1072 double y = coordinates[idx++].toDouble();
1075 if ( ( is3D || foundZ ) && coordinates.length() > idx )
1076 z = coordinates[idx++].toDouble();
1079 if ( ( isMeasure || foundM ) && coordinates.length() > idx )
1080 m = coordinates[idx++].toDouble();
1083 if ( is3D || foundZ )
1085 if ( isMeasure || foundM )
1092 if ( isMeasure || foundM )
1098 points.append(
QgsPoint( t, x, y, z, m ) );
1106 wkb << static_cast<quint32>( points.size() );
1107 for (
const QgsPoint &point : points )
1109 wkb << point.x() << point.y();
1123 QString wkt = QStringLiteral(
"(" );
1132 wkt += QLatin1String(
", " );
1134 if ( wkt.endsWith( QLatin1String(
", " ) ) )
1142 QDomElement elemCoordinates = doc.createElementNS( ns, QStringLiteral(
"coordinates" ) );
1145 QString cs = QStringLiteral(
"," );
1147 QString ts = QStringLiteral(
" " );
1149 elemCoordinates.setAttribute( QStringLiteral(
"cs" ), cs );
1150 elemCoordinates.setAttribute( QStringLiteral(
"ts" ), ts );
1152 QString strCoordinates;
1155 if ( axisOrder == QgsAbstractGeometry::AxisOrder::XY )
1160 if ( strCoordinates.endsWith( ts ) )
1161 strCoordinates.chop( 1 );
1163 elemCoordinates.appendChild( doc.createTextNode( strCoordinates ) );
1164 return elemCoordinates;
1169 QDomElement elemPosList = doc.createElementNS( ns, QStringLiteral(
"posList" ) );
1170 elemPosList.setAttribute( QStringLiteral(
"srsDimension" ), is3D ? 3 : 2 );
1172 QString strCoordinates;
1175 if ( axisOrder == QgsAbstractGeometry::AxisOrder::XY )
1182 if ( strCoordinates.endsWith(
' ' ) )
1183 strCoordinates.chop( 1 );
1185 elemPosList.appendChild( doc.createTextNode( strCoordinates ) );
1191 QString json = QStringLiteral(
"[ " );
1196 if ( json.endsWith( QLatin1String(
", " ) ) )
1207 json coordinates( json::array() );
1224 double clippedAngle =
angle;
1225 if ( clippedAngle >= M_PI * 2 || clippedAngle <= -2 * M_PI )
1227 clippedAngle = std::fmod( clippedAngle, 2 * M_PI );
1229 if ( clippedAngle < 0.0 )
1231 clippedAngle += 2 * M_PI;
1233 return clippedAngle;
1238 QString wktParsed = wkt;
1240 if ( wkt.contains( QString(
"EMPTY" ), Qt::CaseInsensitive ) )
1242 QRegularExpression wktRegEx( QStringLiteral(
"^\\s*(\\w+)\\s+(\\w+)\\s*$" ) );
1243 wktRegEx.setPatternOptions( QRegularExpression::DotMatchesEverythingOption );
1244 QRegularExpressionMatch match = wktRegEx.match( wkt );
1245 if ( match.hasMatch() )
1247 wktParsed = match.captured( 1 );
1248 contents = match.captured( 2 ).toUpper();
1253 QRegularExpression cooRegEx( QStringLiteral(
"^[^\\(]*\\((.*)\\)[^\\)]*$" ) );
1254 cooRegEx.setPatternOptions( QRegularExpression::DotMatchesEverythingOption );
1255 QRegularExpressionMatch match = cooRegEx.match( wktParsed );
1256 contents = match.hasMatch() ? match.captured( 1 ) : QString();
1259 return qMakePair( wkbType, contents );
1267 for (
int i = 0, n = wkt.length(); i < n; ++i )
1269 if ( ( wkt[i].isSpace() || wkt[i] ==
'\n' || wkt[i] ==
'\t' ) && level == 0 )
1272 if ( wkt[i] ==
',' && level == 0 )
1274 if ( !block.isEmpty() )
1276 if ( block.startsWith(
'(' ) && !defaultType.isEmpty() )
1277 block.prepend( defaultType +
' ' );
1278 blocks.append( block );
1283 if ( wkt[i] ==
'(' )
1285 else if ( wkt[i] ==
')' )
1289 if ( !block.isEmpty() )
1291 if ( block.startsWith(
'(' ) && !defaultType.isEmpty() )
1292 block.prepend( defaultType +
' ' );
1293 blocks.append( block );
1303 double x = ( pt1.
x() + pt2.
x() ) / 2.0;
1304 double y = ( pt1.
y() + pt2.
y() ) / 2.0;
1305 double z = std::numeric_limits<double>::quiet_NaN();
1306 double m = std::numeric_limits<double>::quiet_NaN();
1311 z = ( pt1.
z() + pt2.
z() ) / 2.0;
1317 m = ( pt1.
m() + pt2.
m() ) / 2.0;
1320 return QgsPoint( pType, x, y, z, m );
1325 const double _fraction = 1 - fraction;
1327 p1.
x() * _fraction + p2.
x() * fraction,
1328 p1.
y() * _fraction + p2.
y() * fraction,
1329 p1.
is3D() ? p1.
z() * _fraction + p2.
z() * fraction : std::numeric_limits<double>::quiet_NaN(),
1330 p1.
isMeasure() ? p1.
m() * _fraction + p2.
m() * fraction : std::numeric_limits<double>::quiet_NaN() );
1335 const double deltaX = ( x2 - x1 ) * fraction;
1336 const double deltaY = ( y2 - y1 ) * fraction;
1337 return QgsPointXY( x1 + deltaX, y1 + deltaY );
1345 const double fraction = ( value - v1 ) / ( v2 - v1 );
1351 double delta_x = pt2.
x() - pt1.
x();
1352 double delta_y = pt2.
y() - pt1.
y();
1358 return delta_y / delta_x;
1377 a = pt1.
y() - pt2.
y();
1378 b = pt2.
x() - pt1.
x();
1379 c = pt1.
x() * pt2.
y() - pt1.
y() * pt2.
x();
1389 if ( ( p == s1 ) || ( p == s2 ) )
1407 double y = ( -c - a * p.
x() ) / b;
1409 double d2 = 1 + m * m;
1410 double H = p.
y() - y;
1411 double dx = m * H / d2;
1424 double at = std::atan2( y2 - y1, x2 - x1 );
1425 double a = -at + M_PI_2;
1431 double angle1 = std::atan2( y1 - y2, x1 - x2 );
1432 double angle2 = std::atan2( y3 - y2, x3 - x2 );
1446 double a1 =
lineAngle( x1, y1, x2, y2 );
1447 double a2 =
lineAngle( x2, y2, x3, y3 );
1455 double clockwiseDiff = 0.0;
1458 clockwiseDiff = a2 - a1;
1462 clockwiseDiff = a2 + ( 2 * M_PI - a1 );
1464 double counterClockwiseDiff = 2 * M_PI - clockwiseDiff;
1466 double resultAngle = 0;
1467 if ( clockwiseDiff <= counterClockwiseDiff )
1469 resultAngle = a1 + clockwiseDiff / 2.0;
1473 resultAngle = a1 - counterClockwiseDiff / 2.0;
1484 if ( u3.
length() == 0 )
return 1;
1501 if ( std::fabs( u3.
x() ) <= epsilon &&
1502 std::fabs( u3.
y() ) <= epsilon &&
1503 std::fabs( u3.
z() ) <= epsilon )
1515 if ( !( std::fabs( b1 ) > epsilon ) )
1520 if ( !( a2 != -1 && a2 != 1 ) )
1526 double r1 = ( c2 - b2 * c1 / b1 ) / ( a2 - b2 * a1 / b1 );
1542 bool isIntersection;
1551 intersection.
set( ptInter.
x(), ptInter.
y(), La1.
z() );
1591 if ( !firstIsDone || !secondIsDone )
1597 intersection = ( X1 + X2 ) / 2.0;
1603 return 0.5 * std::abs( ( aX - cX ) * ( bY - aY ) - ( aX - bX ) * ( cY - aY ) );
1607 double weightB,
double weightC,
double &pointX,
double &pointY )
1610 if ( weightB + weightC > 1 )
1612 weightB = 1 - weightB;
1613 weightC = 1 - weightC;
1616 const double rBx = weightB * ( bX - aX );
1617 const double rBy = weightB * ( bY - aY );
1618 const double rCx = weightC * ( cX - aX );
1619 const double rCy = weightC * ( cY - aY );
1621 pointX = rBx + rCx + aX;
1622 pointY = rBy + rCy + aY;
1629 for (
const QgsPoint &pt : points )
1634 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 Cartesian 2D 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 planar, 2-dimensional 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.
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, cY).
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 json pointsToJson(const QgsPointSequence &points, int precision)
Returns coordinates as json object.
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.
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places...
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.
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...
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...