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();
 
 1238  QString wkt = QStringLiteral( 
"(" );
 
 1247    wkt += QLatin1String( 
", " );
 
 1249  if ( wkt.endsWith( QLatin1String( 
", " ) ) )
 
 1257  QDomElement elemCoordinates = doc.createElementNS( ns, QStringLiteral( 
"coordinates" ) );
 
 1260  const QString cs = QStringLiteral( 
"," );
 
 1262  const QString ts = QStringLiteral( 
" " );
 
 1264  elemCoordinates.setAttribute( QStringLiteral( 
"cs" ), cs );
 
 1265  elemCoordinates.setAttribute( QStringLiteral( 
"ts" ), ts );
 
 1267  QString strCoordinates;
 
 1270    if ( axisOrder == QgsAbstractGeometry::AxisOrder::XY )
 
 1275  if ( strCoordinates.endsWith( ts ) )
 
 1276    strCoordinates.chop( 1 ); 
 
 1278  elemCoordinates.appendChild( doc.createTextNode( strCoordinates ) );
 
 1279  return elemCoordinates;
 
 1284  QDomElement elemPosList = doc.createElementNS( ns, QStringLiteral( 
"posList" ) );
 
 1285  elemPosList.setAttribute( QStringLiteral( 
"srsDimension" ), is3D ? 3 : 2 );
 
 1287  QString strCoordinates;
 
 1290    if ( axisOrder == QgsAbstractGeometry::AxisOrder::XY )
 
 1297  if ( strCoordinates.endsWith( 
' ' ) )
 
 1298    strCoordinates.chop( 1 ); 
 
 1300  elemPosList.appendChild( doc.createTextNode( strCoordinates ) );
 
 1306  QString json = QStringLiteral( 
"[ " );
 
 1311  if ( json.endsWith( QLatin1String( 
", " ) ) )
 
 1322  json coordinates( json::array() );
 
 1339  double clippedAngle = 
angle;
 
 1340  if ( clippedAngle >= M_PI * 2 || clippedAngle <= -2 * M_PI )
 
 1342    clippedAngle = std::fmod( clippedAngle, 2 * M_PI );
 
 1344  if ( clippedAngle < 0.0 )
 
 1346    clippedAngle += 2 * M_PI;
 
 1348  return clippedAngle;
 
 1353  QString wktParsed = wkt;
 
 1355  if ( wkt.contains( QLatin1String( 
"EMPTY" ), Qt::CaseInsensitive ) )
 
 1357    const thread_local QRegularExpression sWktRegEx( QStringLiteral( 
"^\\s*(\\w+)\\s+(\\w+)\\s*$" ), QRegularExpression::DotMatchesEverythingOption );
 
 1358    const QRegularExpressionMatch match = sWktRegEx.match( wkt );
 
 1359    if ( match.hasMatch() )
 
 1361      wktParsed = match.captured( 1 );
 
 1362      contents = match.captured( 2 ).toUpper();
 
 1367    const int openedParenthesisCount = wktParsed.count( 
'(' );
 
 1368    const int closedParenthesisCount = wktParsed.count( 
')' );
 
 1370    for ( 
int i = 0 ;  i < openedParenthesisCount - closedParenthesisCount; ++i )
 
 1371      wktParsed.push_back( 
')' );
 
 1373    wktParsed.truncate( wktParsed.size() - ( closedParenthesisCount - openedParenthesisCount ) );
 
 1375    const thread_local QRegularExpression cooRegEx( QStringLiteral( 
"^[^\\(]*\\((.*)\\)[^\\)]*$" ), QRegularExpression::DotMatchesEverythingOption );
 
 1376    const QRegularExpressionMatch match = cooRegEx.match( wktParsed );
 
 1377    contents = match.hasMatch() ? match.captured( 1 ) : QString();
 
 1380  return qMakePair( wkbType, contents );
 
 1387  block.reserve( wkt.size() );
 
 1390  const QChar *wktData = wkt.data();
 
 1391  const int wktLength = wkt.length();
 
 1392  for ( 
int i = 0, n = wktLength; i < n; ++i, ++wktData )
 
 1394    if ( ( wktData->isSpace() || *wktData == 
'\n' || *wktData == 
'\t' ) && level == 0 )
 
 1397    if ( *wktData == 
',' && level == 0 )
 
 1399      if ( !block.isEmpty() )
 
 1401        if ( block.startsWith( 
'(' ) && !defaultType.isEmpty() )
 
 1402          block.prepend( defaultType + 
' ' );
 
 1403        blocks.append( block );
 
 1408    if ( *wktData == 
'(' )
 
 1410    else if ( *wktData == 
')' )
 
 1414  if ( !block.isEmpty() )
 
 1416    if ( block.startsWith( 
'(' ) && !defaultType.isEmpty() )
 
 1417      block.prepend( defaultType + 
' ' );
 
 1418    blocks.append( block );
 
 1426  if ( x <= left && y <= bottom )
 
 1428    const double dx = left - x;
 
 1429    const double dy = bottom - y;
 
 1437  else if ( x >= right && y >= top )
 
 1439    const double dx = x - right;
 
 1440    const double dy = y - top;
 
 1448  else if ( x >= right && y <= bottom )
 
 1450    const double dx = x - right;
 
 1451    const double dy = bottom - y;
 
 1459  else if ( x <= left && y >= top )
 
 1461    const double dx = left - x;
 
 1462    const double dy = y - top;
 
 1470  else if ( x <= left )
 
 1472  else if ( x >= right )
 
 1474  else if ( y <= bottom )
 
 1476  else if ( y >= top )
 
 1480  const double smallestX = std::min( right - x, x - left );
 
 1481  const double smallestY = std::min( top - y, y - bottom );
 
 1482  if ( smallestX < smallestY )
 
 1485    if ( right - x < x - left )
 
 1493    if ( top - y < y - bottom )
 
 1505  const double x = ( pt1.
x() + pt2.
x() ) / 2.0;
 
 1506  const double y = ( pt1.
y() + pt2.
y() ) / 2.0;
 
 1507  double z = std::numeric_limits<double>::quiet_NaN();
 
 1508  double m = std::numeric_limits<double>::quiet_NaN();
 
 1513    z = ( pt1.
z() + pt2.
z() ) / 2.0;
 
 1519    m = ( pt1.
m() + pt2.
m() ) / 2.0;
 
 1522  return QgsPoint( pType, x, y, z, m );
 
 1527  const double _fraction = 1 - fraction;
 
 1529                   p1.
x() * _fraction + p2.
x() * fraction,
 
 1530                   p1.
y() * _fraction + p2.
y() * fraction,
 
 1531                   p1.
is3D() ? p1.
z() * _fraction + p2.
z() * fraction : std::numeric_limits<double>::quiet_NaN(),
 
 1532                   p1.
isMeasure() ? p1.
m() * _fraction + p2.
m() * fraction : std::numeric_limits<double>::quiet_NaN() );
 
 1537  const double deltaX = ( x2 - x1 ) * fraction;
 
 1538  const double deltaY = ( y2 - y1 ) * fraction;
 
 1539  return QgsPointXY( x1 + deltaX, y1 + deltaY );
 
 1547  const double fraction = ( value - v1 ) / ( v2 - v1 );
 
 1553  const double delta_x = pt2.
x() - pt1.
x();
 
 1554  const double delta_y = pt2.
y() - pt1.
y();
 
 1560  return delta_y / delta_x;
 
 1579    a = pt1.
y() - pt2.
y();
 
 1580    b = pt2.
x() - pt1.
x();
 
 1581    c = pt1.
x() * pt2.
y() - pt1.
y() * pt2.
x();
 
 1591  if ( ( p == s1 ) || ( p == s2 ) )
 
 1609    const double y = ( -
c - a * p.
x() ) / b;
 
 1610    const double m = 
gradient( s1, s2 );
 
 1611    const double d2 = 1 + m * m;
 
 1612    const double H = p.
y() - y;
 
 1613    const double dx = m * H / d2;
 
 1614    const double dy = m * dx;
 
 1624void QgsGeometryUtils::perpendicularCenterSegment( 
double pointx, 
double pointy, 
double segmentPoint1x, 
double segmentPoint1y, 
double segmentPoint2x, 
double segmentPoint2y, 
double &perpendicularSegmentPoint1x, 
double &perpendicularSegmentPoint1y, 
double &perpendicularSegmentPoint2x, 
double &perpendicularSegmentPoint2y, 
double desiredSegmentLength )
 
 1626  QgsVector segmentVector =  
QgsVector( segmentPoint2x - segmentPoint1x, segmentPoint2y - segmentPoint1y );
 
 1628  if ( desiredSegmentLength )
 
 1630    if ( desiredSegmentLength != 0 )
 
 1632      perpendicularVector = perpendicularVector.
normalized() * ( desiredSegmentLength ) / 2;
 
 1635  perpendicularSegmentPoint1x = pointx - perpendicularVector.
x();
 
 1636  perpendicularSegmentPoint1y = pointy - perpendicularVector.
y();
 
 1637  perpendicularSegmentPoint2x = pointx + perpendicularVector.
x();
 
 1638  perpendicularSegmentPoint2y = pointy + perpendicularVector.
y();
 
 1643  const double at = std::atan2( y2 - y1, x2 - x1 );
 
 1644  const double a = -at + M_PI_2;
 
 1650  const double angle1 = std::atan2( y1 - y2, x1 - x2 );
 
 1651  const double angle2 = std::atan2( y3 - y2, x3 - x2 );
 
 1665  const double a1 = 
lineAngle( x1, y1, x2, y2 );
 
 1666  const double a2 = 
lineAngle( x2, y2, x3, y3 );
 
 1674  double clockwiseDiff = 0.0;
 
 1677    clockwiseDiff = a2 - a1;
 
 1681    clockwiseDiff = a2 + ( 2 * M_PI - a1 );
 
 1683  const double counterClockwiseDiff = 2 * M_PI - clockwiseDiff;
 
 1685  double resultAngle = 0;
 
 1686  if ( clockwiseDiff <= counterClockwiseDiff )
 
 1688    resultAngle = a1 + clockwiseDiff / 2.0;
 
 1692    resultAngle = a1 - counterClockwiseDiff / 2.0;
 
 1703  if ( u3.
length() == 0 ) 
return 1;
 
 1720  if ( std::fabs( u3.
x() ) <= epsilon &&
 
 1721       std::fabs( u3.
y() ) <= epsilon &&
 
 1722       std::fabs( u3.
z() ) <= epsilon )
 
 1734  if ( !( std::fabs( b1 ) > epsilon ) )
 
 1739  if ( !( a2 != -1 && a2 != 1 ) )
 
 1745  const double r1 = ( c2 - b2 * c1 / b1 ) / ( a2 - b2 * a1 / b1 );
 
 1761    bool isIntersection;
 
 1770    intersection.
set( ptInter.
x(), ptInter.
y(), La1.
z() );
 
 1810  if ( !firstIsDone || !secondIsDone )
 
 1816  intersection = ( X1 + X2 ) / 2.0;
 
 1822  return 0.5 * std::abs( ( aX - cX ) * ( bY - aY ) - ( aX - bX ) * ( cY - aY ) );
 
 1826    double weightB, 
double weightC, 
double &pointX, 
double &pointY )
 
 1829  if ( weightB + weightC > 1 )
 
 1831    weightB = 1 - weightB;
 
 1832    weightC = 1 - weightC;
 
 1835  const double rBx = weightB * ( bX - aX );
 
 1836  const double rBy = weightB * ( bY - aY );
 
 1837  const double rCx = weightC * ( cX - aX );
 
 1838  const double rCy = weightC * ( cY - aY );
 
 1840  pointX = rBx + rCx + aX;
 
 1841  pointY = rBy + rCy + aY;
 
 1848  for ( 
const QgsPoint &pt : points )
 
 1850    if ( pt.isMeasure() )
 
 1853      point.
setM( pt.m() );
 
 1866  for ( 
const QgsPoint &pt : points )
 
 1871      point.
setZ( pt.z() );
 
 1890  bool intersection = 
false;
 
 1896  return intersection;
 
 1908  bool intersection = 
false;
 
 1914  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.
 
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 void pointsToWKB(QgsWkbPtr &wkb, const QgsPointSequence &points, bool is3D, bool isMeasure)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }.
 
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 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.