28#include <nlohmann/json.hpp> 
   33#include <QDomDocument> 
   58  mX.resize( 
points.count() );
 
   59  mY.resize( 
points.count() );
 
   60  double *x = mX.data();
 
   61  double *y = mY.data();
 
   66    mZ.resize( 
points.count() );
 
   71    mM.resize( 
points.count() );
 
 
   86QgsLineString::QgsLineString( 
const QVector<double> &x, 
const QVector<double> &y, 
const QVector<double> &z, 
const QVector<double> &m, 
bool is25DType )
 
   89  int pointCount = std::min( x.size(), y.size() );
 
   90  if ( x.size() == pointCount )
 
   96    mX = x.mid( 0, pointCount );
 
   98  if ( y.size() == pointCount )
 
  104    mY = y.mid( 0, pointCount );
 
  106  if ( !z.isEmpty() && z.count() >= pointCount )
 
  109    if ( z.size() == pointCount )
 
  115      mZ = z.mid( 0, pointCount );
 
  118  if ( !m.isEmpty() && m.count() >= pointCount )
 
  121    if ( m.size() == pointCount )
 
  127      mM = m.mid( 0, pointCount );
 
 
  160  mX.reserve( 
points.size() );
 
  161  mY.reserve( 
points.size() );
 
 
  180static double cubicInterpolate( 
double a, 
double b,
 
  181                                double A, 
double B, 
double C, 
double D )
 
  183  return A * b * b * b + 3 * B * b * b * a + 3 * C * b * a * a + D * a * a * a;
 
  192  x.resize( segments + 1 );
 
  194  y.resize( segments + 1 );
 
  196  double *
zData = 
nullptr;
 
  197  if ( start.
is3D() && end.
is3D() && controlPoint1.
is3D() && controlPoint2.
is3D() )
 
  199    z.resize( segments + 1 );
 
  203  double *
mData = 
nullptr;
 
  206    m.resize( segments + 1 );
 
  210  double *
xData = x.data();
 
  211  double *
yData = y.data();
 
  212  const double step = 1.0 / segments;
 
  215  for ( 
int i = 0; i < segments; i++, a += step, b -= step )
 
  228      *
xData++ = cubicInterpolate( a, b, start.
x(), controlPoint1.
x(), controlPoint2.
x(), end.
x() );
 
  229      *
yData++ = cubicInterpolate( a, b, start.
y(), controlPoint1.
y(), controlPoint2.
y(), end.
y() );
 
  231        *
zData++ = cubicInterpolate( a, b, start.
z(), controlPoint1.
z(), controlPoint2.
z(), end.
z() );
 
  233        *
mData++ = cubicInterpolate( a, b, start.
m(), controlPoint1.
m(), controlPoint2.
m(), end.
m() );
 
 
  251  x.resize( polygon.count() );
 
  252  y.resize( polygon.count() );
 
  253  double *
xData = x.data();
 
  254  double *
yData = y.data();
 
  256  const QPointF *src = polygon.data();
 
  257  for ( 
int i  = 0 ; i < polygon.size(); ++ i )
 
 
  269  const QgsLineString *otherLine = qgsgeometry_cast< const QgsLineString * >( &other );
 
  276  if ( mX.count() != otherLine->mX.count() )
 
  279  for ( 
int i = 0; i < mX.count(); ++i )
 
 
  317  const int size = mX.size();
 
  321  const double *x = mX.constData();
 
  322  const double *y = mY.constData();
 
  323  const bool useZ = 
is3D();
 
  325  const double *z = useZ ? mZ.constData() : 
nullptr;
 
  326  const double *m = useM ? mM.constData() : 
nullptr;
 
  328  for ( 
int i = 0; i < size; ++i )
 
 
  350    error = QObject::tr( 
"LineString has less than 2 points and is not empty." );
 
 
  361  bool res = 
snapToGridPrivate( hSpacing, vSpacing, dSpacing, mSpacing, mX, mY, mZ, mM,
 
  362                                result->mX, result->mY, result->mZ, result->mM );
 
  364    return result.release();
 
 
  371  if ( mX.count() <= 2 )
 
  374  double prevX = mX.at( 0 );
 
  375  double prevY = mY.at( 0 );
 
  377  bool useZ = hasZ && useZValues;
 
  378  double prevZ = useZ ? mZ.at( 0 ) : 0;
 
  380  int remaining = mX.count();
 
  381  while ( i < remaining )
 
  383    double currentX = mX.at( i );
 
  384    double currentY = mY.at( i );
 
  385    double currentZ = useZ ? mZ.at( i ) : 0;
 
 
  422  if ( 
is3D() && closed )
 
  423    closed &= 
qgsDoubleNear( mZ.first(), mZ.last() ) || ( std::isnan( mZ.first() ) && std::isnan( mZ.last() ) );
 
 
  438  const int nb = mX.size();
 
  447    if ( rectangle.
contains( mX.at( 0 ), mY.at( 0 ) ) ||
 
  448         rectangle.
contains( mX.at( 
static_cast< int >( nb * 0.2 ) ), mY.at( 
static_cast< int >( nb * 0.2 ) ) ) ||
 
  449         rectangle.
contains( mX.at( 
static_cast< int >( nb * 0.4 ) ), mY.at( 
static_cast< int >( nb * 0.4 ) ) ) ||
 
  450         rectangle.
contains( mX.at( 
static_cast< int >( nb * 0.6 ) ), mY.at( 
static_cast< int >( nb * 0.6 ) ) ) ||
 
  451         rectangle.
contains( mX.at( 
static_cast< int >( nb * 0.8 ) ), mY.at( 
static_cast< int >( nb * 0.8 ) ) ) ||
 
  452         rectangle.
contains( mX.at( nb - 1 ), mY.at( nb - 1 ) ) )
 
  461  double xmin = std::numeric_limits<double>::max();
 
  462  double ymin = std::numeric_limits<double>::max();
 
  463  double xmax = -std::numeric_limits<double>::max();
 
  464  double ymax = -std::numeric_limits<double>::max();
 
  466  const double *x = mX.constData();
 
  467  const double *y = mY.constData();
 
  468  bool foundPointInRectangle = 
false;
 
  469  for ( 
int i = 0; i < nb; ++i )
 
  471    const double px = *x++;
 
  472    xmin = std::min( xmin, px );
 
  473    xmax = std::max( xmax, px );
 
  474    const double py = *y++;
 
  475    ymin = std::min( ymin, py );
 
  476    ymax = std::max( ymax, py );
 
  478    if ( !foundPointInRectangle && rectangle.
contains( px, py ) )
 
  480      foundPointInRectangle = 
true;
 
  496  if ( foundPointInRectangle )
 
 
  521  const int nb = mX.size();
 
  530    if ( box3d.
contains( mX.at( 0 ), mY.at( 0 ), mZ.at( 0 ) ) ||
 
  531         box3d.
contains( mX.at( 
static_cast< int >( nb * 0.2 ) ), mY.at( 
static_cast< int >( nb * 0.2 ) ), mZ.at( 
static_cast< int >( nb * 0.2 ) ) ) ||
 
  532         box3d.
contains( mX.at( 
static_cast< int >( nb * 0.4 ) ), mY.at( 
static_cast< int >( nb * 0.4 ) ), mZ.at( 
static_cast< int >( nb * 0.4 ) ) ) ||
 
  533         box3d.
contains( mX.at( 
static_cast< int >( nb * 0.6 ) ), mY.at( 
static_cast< int >( nb * 0.6 ) ), mZ.at( 
static_cast< int >( nb * 0.6 ) ) ) ||
 
  534         box3d.
contains( mX.at( 
static_cast< int >( nb * 0.8 ) ), mY.at( 
static_cast< int >( nb * 0.8 ) ), mZ.at( 
static_cast< int >( nb * 0.8 ) ) ) ||
 
  535         box3d.
contains( mX.at( nb - 1 ), mY.at( nb - 1 ), mZ.at( nb - 1 ) ) )
 
  544  double xmin = std::numeric_limits<double>::max();
 
  545  double ymin = std::numeric_limits<double>::max();
 
  546  double zmin = std::numeric_limits<double>::max();
 
  547  double xmax = -std::numeric_limits<double>::max();
 
  548  double ymax = -std::numeric_limits<double>::max();
 
  549  double zmax = -std::numeric_limits<double>::max();
 
  551  const double *x = mX.constData();
 
  552  const double *y = mY.constData();
 
  553  const double *z = mZ.constData();
 
  554  bool foundPointInBox = 
false;
 
  555  for ( 
int i = 0; i < nb; ++i )
 
  557    const double px = *x++;
 
  558    xmin = std::min( xmin, px );
 
  559    xmax = std::max( xmax, px );
 
  560    const double py = *y++;
 
  561    ymin = std::min( ymin, py );
 
  562    ymax = std::max( ymax, py );
 
  563    const double pz = *z++;
 
  564    zmin = std::min( zmin, pz );
 
  565    zmax = std::max( zmax, pz );
 
  567    if ( !foundPointInBox && box3d.
contains( px, py, pz ) )
 
  569      foundPointInBox = 
true;
 
  585  if ( foundPointInBox )
 
 
  598  QVector< QgsVertexId > res;
 
  599  if ( mX.count() <= 1 )
 
  602  const double *x = mX.constData();
 
  603  const double *y = mY.constData();
 
  605  bool useZ = hasZ && useZValues;
 
  606  const double *z = useZ ? mZ.constData() : 
nullptr;
 
  610  double prevZ = z ? *z++ : 0;
 
  613  for ( 
int i = 1; i < mX.count(); ++i )
 
  615    double currentX = *x++;
 
  616    double currentY = *y++;
 
  617    double currentZ = useZ ? *z++ : 0;
 
 
  637  const int nb = mX.size();
 
  640  const double *x = mX.constData();
 
  641  const double *y = mY.constData();
 
  642  QPointF *dest = 
points.data();
 
  643  for ( 
int i = 0; i < nb; ++i )
 
  645    *dest++ = QPointF( *x++, *y++ );
 
 
  663  importVerticesFromWkb( wkbPtr );
 
 
  674  auto result2D = std::minmax_element( mX.begin(), mX.end() );
 
  675  const double xmin = *result2D.first;
 
  676  const double xmax = *result2D.second;
 
  677  result2D = std::minmax_element( mY.begin(), mY.end() );
 
  678  const double ymin = *result2D.first;
 
  679  const double ymax = *result2D.second;
 
  681  double zmin = std::numeric_limits< double >::quiet_NaN();
 
  682  double zmax = std::numeric_limits< double >::quiet_NaN();
 
  686    auto resultZ = std::minmax_element( mZ.begin(), mZ.end() );
 
  687    zmin = *resultZ.first;
 
  688    zmax = *resultZ.second;
 
  691  return QgsBox3D( xmin, ymin, zmin, xmax, ymax, zmax );
 
 
  701  const int size = mX.size();
 
  702  if ( index < 1 || index >= size - 1 )
 
  705  const bool useZ = 
is3D();
 
  708  QVector<double> newX( size );
 
  709  QVector<double> newY( size );
 
  710  QVector<double> newZ( useZ ? size : 0 );
 
  711  QVector<double> newM( useM ? size : 0 );
 
  712  auto it = std::copy( mX.constBegin() + index, mX.constEnd() - 1, newX.begin() );
 
  713  it = std::copy( mX.constBegin(), mX.constBegin() + index, it );
 
  714  *it = *newX.constBegin();
 
  715  mX = std::move( newX );
 
  717  it = std::copy( mY.constBegin() + index, mY.constEnd() - 1, newY.begin() );
 
  718  it = std::copy( mY.constBegin(), mY.constBegin() + index, it );
 
  719  *it = *newY.constBegin();
 
  720  mY = std::move( newY );
 
  723    it = std::copy( mZ.constBegin() + index, mZ.constEnd() - 1, newZ.begin() );
 
  724    it = std::copy( mZ.constBegin(), mZ.constBegin() + index, it );
 
  725    *it = *newZ.constBegin();
 
  726    mZ = std::move( newZ );
 
  730    it = std::copy( mM.constBegin() + index, mM.constEnd() - 1, newM.begin() );
 
  731    it = std::copy( mM.constBegin(), mM.constBegin() + index, it );
 
  732    *it = *newM.constBegin();
 
  733    mM = std::move( newM );
 
 
  752  QString secondWithoutParentheses = 
parts.second;
 
  753  secondWithoutParentheses = secondWithoutParentheses.remove( 
'(' ).remove( 
')' ).simplified().remove( 
' ' );
 
  754  parts.second = 
parts.second.remove( 
'(' ).remove( 
')' );
 
  755  if ( ( 
parts.second.compare( QLatin1String( 
"EMPTY" ), Qt::CaseInsensitive ) == 0 ) ||
 
  756       secondWithoutParentheses.isEmpty() )
 
 
  771  int binarySize = 
sizeof( char ) + 
sizeof( quint32 ) + 
sizeof( quint32 );
 
 
  782  wkb << static_cast<quint32>( 
wkbType() );
 
 
  800    wkt += QLatin1String( 
"EMPTY" );
 
 
  815  QDomElement elemLineString = doc.createElementNS( ns, QStringLiteral( 
"LineString" ) );
 
  818    return elemLineString;
 
  822  return elemLineString;
 
 
  830  QDomElement elemLineString = doc.createElementNS( ns, QStringLiteral( 
"LineString" ) );
 
  833    return elemLineString;
 
  836  return elemLineString;
 
 
  845    {  
"type",  
"LineString" },
 
 
  855    kml.append( QLatin1String( 
"<LinearRing>" ) );
 
  859    kml.append( QLatin1String( 
"<LineString>" ) );
 
  862  kml.append( QLatin1String( 
"<altitudeMode>" ) );
 
  865    kml.append( QLatin1String( 
"absolute" ) );
 
  869    kml.append( QLatin1String( 
"clampToGround" ) );
 
  871  kml.append( QLatin1String( 
"</altitudeMode>" ) );
 
  872  kml.append( QLatin1String( 
"<coordinates>" ) );
 
  874  int nPoints = mX.size();
 
  875  for ( 
int i = 0; i < nPoints; ++i )
 
  879      kml.append( QLatin1String( 
" " ) );
 
  882    kml.append( QLatin1String( 
"," ) );
 
  886      kml.append( QLatin1String( 
"," ) );
 
  891      kml.append( QLatin1String( 
",0" ) );
 
  894  kml.append( QLatin1String( 
"</coordinates>" ) );
 
  897    kml.append( QLatin1String( 
"</LinearRing>" ) );
 
  901    kml.append( QLatin1String( 
"</LineString>" ) );
 
 
  915  const int size = mX.size();
 
  919  const double *x = mX.constData();
 
  920  const double *y = mY.constData();
 
  926  for ( 
int i = 1; i < size; ++i )
 
  930    total += std::sqrt( dx * dx + dy * dy );
 
 
  940  const bool useZ = 
is3D();
 
  943  const int size = mX.size();
 
  945    return std::make_tuple( std::make_unique< QgsLineString >(), std::make_unique< QgsLineString >() );
 
  947  index = std::clamp( index, 0, size - 1 );
 
  949  const int part1Size = index + 1;
 
  950  QVector< double > x1( part1Size );
 
  951  QVector< double > y1( part1Size );
 
  952  QVector< double > z1( useZ ? part1Size : 0 );
 
  953  QVector< double > m1( useM ? part1Size : 0 );
 
  955  const double *sourceX = mX.constData();
 
  956  const double *sourceY = mY.constData();
 
  957  const double *sourceZ = useZ ? mZ.constData() : 
nullptr;
 
  958  const double *sourceM = useM ? mM.constData() : 
nullptr;
 
  960  double *destX = x1.data();
 
  961  double *destY = y1.data();
 
  962  double *destZ = useZ ? z1.data() : 
nullptr;
 
  963  double *destM = useM ? m1.data() : 
nullptr;
 
  965  std::copy( sourceX, sourceX + part1Size, destX );
 
  966  std::copy( sourceY, sourceY + part1Size, destY );
 
  968    std::copy( sourceZ, sourceZ + part1Size, destZ );
 
  970    std::copy( sourceM, sourceM + part1Size, destM );
 
  972  const int part2Size = size - index;
 
  974    return std::make_tuple( std::make_unique< QgsLineString >( x1, y1, z1, m1 ), std::make_unique< QgsLineString >() );
 
  976  QVector< double > x2( part2Size );
 
  977  QVector< double > y2( part2Size );
 
  978  QVector< double > z2( useZ ? part2Size : 0 );
 
  979  QVector< double > m2( useM ? part2Size : 0 );
 
  982  destZ = useZ ? z2.data() : 
nullptr;
 
  983  destM = useM ? m2.data() : 
nullptr;
 
  984  std::copy( sourceX + index, sourceX + size, destX );
 
  985  std::copy( sourceY + index, sourceY + size, destY );
 
  987    std::copy( sourceZ + index, sourceZ + size, destZ );
 
  989    std::copy( sourceM + index, sourceM + size, destM );
 
  992    return std::make_tuple( std::make_unique< QgsLineString >(), std::make_unique< QgsLineString >( x2, y2, z2, m2 ) );
 
  994    return std::make_tuple( std::make_unique< QgsLineString >( x1, y1, z1, m1 ), std::make_unique< QgsLineString >( x2, y2, z2, m2 ) );
 
 
 1002    const int size = mX.size();
 
 1006    const double *x = mX.constData();
 
 1007    const double *y = mY.constData();
 
 1008    const double *z = mZ.constData();
 
 1011    double prevX = *x++;
 
 1012    double prevY = *y++;
 
 1013    double prevZ = *z++;
 
 1015    for ( 
int i = 1; i < size; ++i )
 
 1020      total += std::sqrt( dx * dx + dy * dy + dz * dz );
 
 
 1060  Q_UNUSED( tolerance )
 
 1061  Q_UNUSED( toleranceType )
 
 
 1077  if ( i < 0 || i >= mX.size() )
 
 1082  double x = mX.at( i );
 
 1083  double y = mY.at( i );
 
 1084  double z = std::numeric_limits<double>::quiet_NaN();
 
 1085  double m = std::numeric_limits<double>::quiet_NaN();
 
 1103  else if ( hasZ && hasM )
 
 
 1126  if ( index >= 0 && index < mX.size() )
 
 1127    return mX.at( index );
 
 
 1134  if ( index >= 0 && index < mY.size() )
 
 1135    return mY.at( index );
 
 
 1142  if ( index >= 0 && index < mX.size() )
 
 
 1149  if ( index >= 0 && index < mY.size() )
 
 
 1164  pts.reserve( nPoints );
 
 1165  for ( 
int i = 0; i < nPoints; ++i )
 
 1167    pts.push_back( 
pointN( i ) );
 
 
 1181  const bool hasZ = 
static_cast< bool >( z );
 
 1182  const bool hasM = 
static_cast< bool >( m );
 
 1203  double *destX = mX.data();
 
 1204  double *destY = mY.data();
 
 1205  double *destZ = 
nullptr;
 
 1215  double *destM = 
nullptr;
 
 1226  for ( 
size_t i = 0; i < size; ++i )
 
 
 1253  bool hasZ = firstPt.
is3D();
 
 1258  mX.resize( 
points.size() );
 
 1259  mY.resize( 
points.size() );
 
 1262    mZ.resize( 
points.size() );
 
 1270    mM.resize( 
points.size() );
 
 1277  for ( 
int i = 0; i < 
points.size(); ++i )
 
 1279    mX[i] = 
points.at( i ).x();
 
 1280    mY[i] = 
points.at( i ).y();
 
 1283      double z = 
points.at( i ).z();
 
 1284      mZ[i] = std::isnan( z ) ? 0 : z;
 
 1288      double m = 
points.at( i ).m();
 
 1289      mM[i] = std::isnan( m ) ? 0 : m;
 
 
 1342      mZ.insert( mZ.count(), mX.size() - mZ.size(), std::numeric_limits<double>::quiet_NaN() );
 
 1355      mM.insert( mM.count(), mX.size() - mM.size(), std::numeric_limits<double>::quiet_NaN() );
 
 
 1365  std::reverse( copy->mX.begin(), copy->mX.end() );
 
 1366  std::reverse( copy->mY.begin(), copy->mY.end() );
 
 1369    std::reverse( copy->mZ.begin(), copy->mZ.end() );
 
 1373    std::reverse( copy->mM.begin(), copy->mM.end() );
 
 
 1378void QgsLineString::visitPointsByRegularDistance( 
const double distance, 
const std::function<
bool ( 
double, 
double, 
double, 
double, 
double, 
double, 
double, 
double, 
double, 
double, 
double, 
double )> &visitPoint )
 const 
 1383  double distanceTraversed = 0;
 
 1385  if ( totalPoints == 0 )
 
 1388  const double *x = mX.constData();
 
 1389  const double *y = mY.constData();
 
 1390  const double *z = 
is3D() ? mZ.constData() : 
nullptr;
 
 1391  const double *m = 
isMeasure() ? mM.constData() : 
nullptr;
 
 1393  double prevX = *x++;
 
 1394  double prevY = *y++;
 
 1395  double prevZ = z ? *z++ : 0.0;
 
 1396  double prevM = m ? *m++ : 0.0;
 
 1400    visitPoint( prevX, prevY, prevZ, prevM, prevX, prevY, prevZ, prevM, prevX, prevY, prevZ, prevM );
 
 1404  double pZ = std::numeric_limits<double>::quiet_NaN();
 
 1405  double pM = std::numeric_limits<double>::quiet_NaN();
 
 1406  double nextPointDistance = distance;
 
 1407  for ( 
int i = 1; i < totalPoints; ++i )
 
 1409    double thisX = *x++;
 
 1410    double thisY = *y++;
 
 1411    double thisZ = z ? *z++ : 0.0;
 
 1412    double thisM = m ? *m++ : 0.0;
 
 1414    const double segmentLength = std::sqrt( ( thisX - prevX ) * ( thisX - prevX ) + ( thisY - prevY ) * ( thisY - prevY ) );
 
 1418      const double distanceToPoint = std::min( nextPointDistance - distanceTraversed, 
segmentLength );
 
 1421          z ? &prevZ : 
nullptr, z ? &thisZ : 
nullptr, z ? &pZ : 
nullptr,
 
 1422          m ? &prevM : 
nullptr, m ? &thisM : 
nullptr, m ? &pM : nullptr );
 
 1424      if ( !visitPoint( pX, pY, pZ, pM, prevX, prevY, prevZ, prevM, thisX, thisY, thisZ, thisM ) )
 
 1427      nextPointDistance += distance;
 
 
 1449  std::unique_ptr< QgsPoint > res;
 
 1450  visitPointsByRegularDistance( distance, [ & ]( 
double x, 
double y, 
double z, 
double m, 
double, 
double, 
double, 
double, 
double, 
double, 
double, 
double )->
bool 
 1452    res = std::make_unique< QgsPoint >( pointType, x, y, z, m );
 
 1455  return res.release();
 
 
 1460  if ( startDistance < 0 && endDistance < 0 )
 
 1463  endDistance = std::max( startDistance, endDistance );
 
 1466  if ( totalPoints == 0 )
 
 1469  QVector< QgsPoint > substringPoints;
 
 1470  substringPoints.reserve( totalPoints );
 
 1478  const double *x = mX.constData();
 
 1479  const double *y = mY.constData();
 
 1480  const double *z = 
is3D() ? mZ.constData() : 
nullptr;
 
 1481  const double *m = 
isMeasure() ? mM.constData() : 
nullptr;
 
 1483  double distanceTraversed = 0;
 
 1484  double prevX = *x++;
 
 1485  double prevY = *y++;
 
 1486  double prevZ = z ? *z++ : 0.0;
 
 1487  double prevM = m ? *m++ : 0.0;
 
 1488  bool foundStart = 
false;
 
 1490  if ( startDistance < 0 )
 
 1493  for ( 
int i = 1; i < totalPoints; ++i )
 
 1495    double thisX = *x++;
 
 1496    double thisY = *y++;
 
 1497    double thisZ = z ? *z++ : 0.0;
 
 1498    double thisM = m ? *m++ : 0.0;
 
 1500    const double segmentLength = std::sqrt( ( thisX - prevX ) * ( thisX - prevX ) + ( thisY - prevY ) * ( thisY - prevY ) );
 
 1502    if ( distanceTraversed <= startDistance && startDistance < distanceTraversed + 
segmentLength )
 
 1505      const double distanceToStart = startDistance - distanceTraversed;
 
 1506      double startX, startY;
 
 1510          z ? &prevZ : 
nullptr, z ? &thisZ : 
nullptr, z ? &startZ : 
nullptr,
 
 1511          m ? &prevM : 
nullptr, m ? &thisM : 
nullptr, m ? &startM : nullptr );
 
 1512      substringPoints << 
QgsPoint( pointType, startX, startY, startZ, startM );
 
 1515    if ( foundStart && ( distanceTraversed + 
segmentLength > endDistance ) )
 
 1518      const double distanceToEnd = endDistance - distanceTraversed;
 
 1523          z ? &prevZ : 
nullptr, z ? &thisZ : 
nullptr, z ? &endZ : 
nullptr,
 
 1524          m ? &prevM : 
nullptr, m ? &thisM : 
nullptr, m ? &endM : nullptr );
 
 1525      substringPoints << 
QgsPoint( pointType, endX, endY, endZ, endM );
 
 1527    else if ( foundStart )
 
 1529      substringPoints << 
QgsPoint( pointType, thisX, thisY, thisZ, thisM );
 
 1537    if ( distanceTraversed >= endDistance )
 
 1542  if ( !foundStart && 
qgsDoubleNear( distanceTraversed, startDistance ) )
 
 1544    substringPoints << 
QgsPoint( pointType, prevX, prevY, prevZ, prevM )
 
 1545                    << 
QgsPoint( pointType, prevX, prevY, prevZ, prevM );
 
 
 1570  if ( path.isEmpty() || path.currentPosition() != QPointF( mX.at( 0 ), mY.at( 0 ) ) )
 
 1572    path.moveTo( mX.at( 0 ), mY.at( 0 ) );
 
 1575  for ( 
int i = 1; i < nPoints; ++i )
 
 1577    path.lineTo( mX.at( i ), mY.at( i ) );
 
 
 1590  return compoundCurve;
 
 
 1595  if ( mX.size() < 2 || mY.size() < 2 )
 
 1598  const bool extendStart = startDistance > 0;
 
 1599  const bool extendEnd = endDistance > 0;
 
 1604    const double currentLen = std::sqrt( std::pow( mX.at( 0 ) - mX.at( 1 ), 2 ) +
 
 1605                                         std::pow( mY.at( 0 ) - mY.at( 1 ), 2 ) );
 
 1606    const double newLen = currentLen + startDistance;
 
 1607    mX[ 0 ] = mX.at( 1 ) + ( mX.at( 0 ) - mX.at( 1 ) ) / currentLen * newLen;
 
 1608    mY[ 0 ] = mY.at( 1 ) + ( mY.at( 0 ) - mY.at( 1 ) ) / currentLen * newLen;
 
 1613    const int last = mX.size() - 1;
 
 1614    const double currentLen = std::sqrt( std::pow( mX.at( last ) - mX.at( last - 1 ), 2 ) +
 
 1615                                         std::pow( mY.at( last ) - mY.at( last - 1 ), 2 ) );
 
 1616    const double newLen = currentLen + endDistance;
 
 1617    mX[ last ] = mX.at( last - 1 ) + ( mX.at( last ) - mX.at( last - 1 ) ) / currentLen * newLen;
 
 1618    mY[ last ] = mY.at( last - 1 ) + ( mY.at( last ) - mY.at( last - 1 ) ) / currentLen * newLen;
 
 1621  if ( extendStart || extendEnd )
 
 
 1627  auto result = std::make_unique< QgsLineString >();
 
 1629  return result.release();
 
 
 1634  const QgsLineString *otherLine = qgsgeometry_cast<const QgsLineString *>( other );
 
 1638  const int size = mX.size();
 
 1639  const int otherSize = otherLine->mX.size();
 
 1640  if ( size > otherSize )
 
 1644  else if ( size < otherSize )
 
 1649  if ( 
is3D() && !otherLine->
is3D() )
 
 1651  else if ( !
is3D() && otherLine->
is3D() )
 
 1653  const bool considerZ = 
is3D();
 
 1661  for ( 
int i = 0; i < size; i++ )
 
 1663    const double x = mX[i];
 
 1664    const double otherX = otherLine->mX[i];
 
 1669    else if ( x > otherX )
 
 1674    const double y = mY[i];
 
 1675    const double otherY = otherLine->mY[i];
 
 1680    else if ( y > otherY )
 
 1687      const double z = mZ[i];
 
 1688      const double otherZ = otherLine->mZ[i];
 
 1694      else if ( z > otherZ )
 
 1702      const double m = mM[i];
 
 1703      const double otherM = otherLine->mM[i];
 
 1709      else if ( m > otherM )
 
 
 1720  return QStringLiteral( 
"LineString" );
 
 
 1736  double *zArray = 
nullptr;
 
 1742  std::unique_ptr< double[] > dummyZ;
 
 1743  if ( !hasZ || !transformZ )
 
 1745    dummyZ.reset( 
new double[nPoints]() );
 
 1746    zArray = dummyZ.get();
 
 
 1761  double *x = mX.data();
 
 1762  double *y = mY.data();
 
 1763  double *z = hasZ ? mZ.data() : 
nullptr;
 
 1764  double *m = hasM ? mM.data() : 
nullptr;
 
 1765  for ( 
int i = 0; i < nPoints; ++i )
 
 1768    t.map( *x, *y, &xOut, &yOut );
 
 1773      *z = *z * zScale + zTranslate;
 
 1778      *m = *m * mScale + mTranslate;
 
 
 1793  if ( position.
vertex < 0 || position.
vertex > mX.size() )
 
 1803  mX.insert( position.
vertex, vertex.
x() );
 
 1804  mY.insert( position.
vertex, vertex.
y() );
 
 1807    mZ.insert( position.
vertex, vertex.
z() );
 
 1811    mM.insert( position.
vertex, vertex.
m() );
 
 
 1819  if ( position.
vertex < 0 || position.
vertex >= mX.size() )
 
 1823  mX[position.
vertex] = newPos.
x();
 
 1824  mY[position.
vertex] = newPos.
y();
 
 1827    mZ[position.
vertex] = newPos.
z();
 
 1831    mM[position.
vertex] = newPos.
m();
 
 
 1839  if ( position.
vertex >= mX.size() || position.
vertex < 0 )
 
 1844  mX.remove( position.
vertex );
 
 1845  mY.remove( position.
vertex );
 
 1848    mZ.remove( position.
vertex );
 
 1852    mM.remove( position.
vertex );
 
 
 1877  mX.append( pt.
x() );
 
 1878  mY.append( pt.
y() );
 
 1881    mZ.append( pt.
z() );
 
 1885    mM.append( pt.
m() );
 
 
 1892  double sqrDist = std::numeric_limits<double>::max();
 
 1893  double leftOfDist = std::numeric_limits<double>::max();
 
 1895  double prevLeftOfX = 0.0;
 
 1896  double prevLeftOfY = 0.0;
 
 1897  double testDist = 0;
 
 1898  double segmentPtX, segmentPtY;
 
 1903  int size = mX.size();
 
 1904  if ( size == 0 || size == 1 )
 
 1909  for ( 
int i = 1; i < size; ++i )
 
 1911    double prevX = mX.at( i - 1 );
 
 1912    double prevY = mY.at( i - 1 );
 
 1913    double currentX = mX.at( i );
 
 1914    double currentY = mY.at( i );
 
 1916    if ( testDist < sqrDist )
 
 1919      segmentPt.
setX( segmentPtX );
 
 1920      segmentPt.
setY( segmentPtY );
 
 1921      vertexAfter.
part = 0;
 
 1922      vertexAfter.
ring = 0;
 
 1933        if ( 
qgsDoubleNear( testDist, leftOfDist ) && left != prevLeftOf && prevLeftOf != 0 )
 
 1945        prevLeftOf = *leftOf;
 
 1946        leftOfDist = testDist;
 
 1947        prevLeftOfX = prevX;
 
 1948        prevLeftOfY = prevY;
 
 1950      else if ( testDist < leftOfDist )
 
 1953        leftOfDist = testDist;
 
 
 1985    return QgsPoint( mX.at( 0 ), mY.at( 0 ) );
 
 1987  double totalLineLength = 0.0;
 
 1988  double prevX = mX.at( 0 );
 
 1989  double prevY = mY.at( 0 );
 
 1995    double currentX = mX.at( i );
 
 1996    double currentY = mY.at( i );
 
 1997    double segmentLength = std::sqrt( std::pow( currentX - prevX, 2.0 ) +
 
 1998                                      std::pow( currentY - prevY, 2.0 ) );
 
 2012    return QgsPoint( mX.at( 0 ), mY.at( 0 ) );
 
 2014    return QgsPoint( sumX / totalLineLength, sumY / totalLineLength );
 
 
 2033  const int maxIndex = mX.size();
 
 2040  const double *x = mX.constData();
 
 2041  const double *y = mY.constData();
 
 2042  double prevX = *x++;
 
 2043  double prevY = *y++;
 
 2044  for ( 
int i = 1; i < maxIndex; ++i )
 
 2046    mSummedUpArea += prevX * ( *y - prevY ) - prevY * ( *x - prevX );
 
 
 2056void QgsLineString::importVerticesFromWkb( 
const QgsConstWkbPtr &wkb )
 
 2062  mX.resize( nVertices );
 
 2063  mY.resize( nVertices );
 
 2064  hasZ ? mZ.resize( nVertices ) : mZ.clear();
 
 2065  hasM ? mM.resize( nVertices ) : mM.clear();
 
 2066  double *x = mX.data();
 
 2067  double *y = mY.data();
 
 2068  double *m = hasM ? mM.data() : 
nullptr;
 
 2069  double *z = hasZ ? mZ.data() : 
nullptr;
 
 2070  for ( 
int i = 0; i < nVertices; ++i )
 
 2103  if ( mX.count() < 2 )
 
 2113      double previousX = mX.at( 
numPoints() - 2 );
 
 2114      double previousY = mY.at( 
numPoints() - 2 );
 
 2115      double currentX = mX.at( 0 );
 
 2116      double currentY = mY.at( 0 );
 
 2117      double afterX = mX.at( 1 );
 
 2118      double afterY = mY.at( 1 );
 
 2121    else if ( vertex.
vertex == 0 )
 
 2134    double previousX = mX.at( vertex.
vertex - 1 );
 
 2135    double previousY = mY.at( vertex.
vertex - 1 );
 
 2136    double currentX = mX.at( vertex.
vertex );
 
 2137    double currentY = mY.at( vertex.
vertex );
 
 2138    double afterX = mX.at( vertex.
vertex + 1 );
 
 2139    double afterY = mY.at( vertex.
vertex + 1 );
 
 
 2146  if ( startVertex.
vertex < 0 || startVertex.
vertex >= mX.count() - 1 )
 
 2149  double dx = mX.at( startVertex.
vertex + 1 ) - mX.at( startVertex.
vertex );
 
 2150  double dy = mY.at( startVertex.
vertex + 1 ) - mY.at( startVertex.
vertex );
 
 2151  return std::sqrt( dx * dx + dy * dy );
 
 
 2176  mZ.reserve( nPoints );
 
 2177  for ( 
int i = 0; i < nPoints; ++i )
 
 
 2207  mM.reserve( nPoints );
 
 2208  for ( 
int i = 0; i < nPoints; ++i )
 
 
 2239  std::swap( mX, mY );
 
 
 2253    addZValue( std::numeric_limits<double>::quiet_NaN() );
 
 
 2270  int size = mX.size();
 
 2272  double *srcX = mX.data();
 
 2273  double *srcY = mY.data();
 
 2274  double *srcM = hasM ? mM.data() : 
nullptr;
 
 2275  double *srcZ = hasZ ? mZ.data() : 
nullptr;
 
 2278  for ( 
int i = 0; i < size; ++i )
 
 2282    double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
 
 2283    double m = hasM ? *srcM : std::numeric_limits<double>::quiet_NaN();
 
 
 2311  int size = mX.size();
 
 2313  double *srcX = mX.data();
 
 2314  double *srcY = mY.data();
 
 2315  double *srcM = hasM ? mM.data() : 
nullptr;
 
 2316  double *srcZ = hasZ ? mZ.data() : 
nullptr;
 
 2318  double *destX = srcX;
 
 2319  double *destY = srcY;
 
 2320  double *destM = srcM;
 
 2321  double *destZ = srcZ;
 
 2323  int filteredPoints = 0;
 
 2324  for ( 
int i = 0; i < size; ++i )
 
 2328    double z = hasZ ? *srcZ++ : std::numeric_limits<double>::quiet_NaN();
 
 2329    double m = hasM ? *srcM++ : std::numeric_limits<double>::quiet_NaN();
 
 2331    if ( filter( 
QgsPoint( x, y, z, m ) ) )
 
 2343  mX.resize( filteredPoints );
 
 2344  mY.resize( filteredPoints );
 
 2346    mZ.resize( filteredPoints );
 
 2348    mM.resize( filteredPoints );
 
 
 2357  int size = mX.size();
 
 2359  double *srcX = mX.data();
 
 2360  double *srcY = mY.data();
 
 2361  double *srcM = hasM ? mM.data() : 
nullptr;
 
 2362  double *srcZ = hasZ ? mZ.data() : 
nullptr;
 
 2364  for ( 
int i = 0; i < size; ++i )
 
 2368    double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
 
 2369    double m = hasM ? *srcM : std::numeric_limits<double>::quiet_NaN();
 
 
VertexType
Types of vertex.
 
@ Segment
The actual start or end point of a segment.
 
WkbType
The WKB type describes the number of dimensions a geometry has.
 
@ LineString25D
LineString25D.
 
@ LineStringM
LineStringM.
 
@ LineStringZM
LineStringZM.
 
@ LineStringZ
LineStringZ.
 
TransformDirection
Flags for raster layer temporal capabilities.
 
Abstract base class for all geometries.
 
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
 
virtual bool convertTo(Qgis::WkbType type)
Converts the geometry to a specified type.
 
bool isMeasure() const
Returns true if the geometry contains m values.
 
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
 
AxisOrder
Axis order for GML generation.
 
QString wktTypeStr() const
Returns the WKT type string of the geometry.
 
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
 
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, Qgis::WkbType baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
 
virtual bool boundingBoxIntersects(const QgsRectangle &rectangle) const
Returns true if the bounding box of this geometry intersects with a rectangle.
 
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry.
 
static endian_t endian()
Returns whether this machine uses big or little endian.
 
A 3-dimensional box composed of x, y, z coordinates.
 
bool intersects(const QgsBox3D &other) const
Returns true if box intersects with another box.
 
bool contains(const QgsBox3D &other) const
Returns true when box contains other box.
 
QgsRectangle toRectangle() const
Converts the box to a 2D rectangle.
 
bool isNull() const
Test if the box is null (holding no spatial information).
 
Compound curve geometry type.
 
void addCurve(QgsCurve *c, bool extendPrevious=false)
Adds a curve to the geometry (takes ownership).
 
Qgis::WkbType readHeader() const
readHeader
 
Abstract base class for curved geometry type.
 
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
 
bool mHasCachedSummedUpArea
 
virtual bool isRing() const
Returns true if the curve is a ring.
 
bool snapToGridPrivate(double hSpacing, double vSpacing, double dSpacing, double mSpacing, const QVector< double > &srcX, const QVector< double > &srcY, const QVector< double > &srcZ, const QVector< double > &srcM, QVector< double > &outX, QVector< double > &outY, QVector< double > &outZ, QVector< double > &outM) const
Helper function for QgsCurve subclasses to snap to grids.
 
bool isValid(QString &error, Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const override
Checks validity of the geometry, and returns true if the geometry is valid.
 
QgsBox3D mBoundingBox
Cached bounding box.
 
Base class for feedback objects to be used for cancellation of something running in a worker thread.
 
bool isCanceled() const
Tells whether the operation has been canceled already.
 
static QgsPoint pointOnLineWithDistance(const QgsPoint &startPoint, const QgsPoint &directionPoint, double distance)
Returns a point a specified distance toward a second point.
 
static json pointsToJson(const QgsPointSequence &points, int precision)
Returns coordinates as json object.
 
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 void pointsToWKB(QgsWkbPtr &wkb, const QgsPointSequence &points, bool is3D, bool isMeasure, QgsAbstractGeometry::WkbFlags flags)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }.
 
static QPair< Qgis::WkbType, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
 
static double lineAngle(double x1, double y1, double x2, double y2)
Calculates the direction of line joining two points in radians, clockwise from the north direction.
 
static QgsPointSequence pointsFromWKT(const QString &wktCoordinateList, bool is3D, bool isMeasure)
Returns a list of points contained in a WKT string.
 
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 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 QString pointsToWKT(const QgsPointSequence &points, int precision, bool is3D, bool isMeasure)
Returns a WKT coordinate list.
 
static int leftOfLine(const double x, const double y, const double x1, const double y1, const double x2, const double y2)
Returns a value < 0 if the point (x, y) is left of the line from (x1, y1) -> (x2, y2).
 
static double averageAngle(double x1, double y1, double x2, double y2, double x3, double y3)
Calculates the average angle (in radians) between the two linear segments from (x1,...
 
Represents a single 2D line segment, consisting of a 2D start and end vertex only.
 
Line string geometry type, with support for z-dimension and m-values.
 
double segmentLength(QgsVertexId startVertex) const override
Returns the length of the segment of the geometry which begins at startVertex.
 
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
 
QgsLineString * snappedToGrid(double hSpacing, double vSpacing, double dSpacing=0, double mSpacing=0) const override
Makes a new geometry with all the points or vertices snapped to the closest point of the grid.
 
bool pointAt(int node, QgsPoint &point, Qgis::VertexType &type) const override
Returns the point and vertex id of a point within the curve.
 
bool isClosed() const override
Returns true if the curve is closed.
 
void swapXy() override
Swaps the x and y coordinates from the geometry.
 
const double * yData() const
Returns a const pointer to the y vertex data.
 
bool equals(const QgsCurve &other) const override
Checks whether this curve exactly equals another curve.
 
bool isValid(QString &error, Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const override
Checks validity of the geometry, and returns true if the geometry is valid.
 
const double * xData() const
Returns a const pointer to the x vertex data.
 
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
 
double length() const override
Returns the planar, 2-dimensional length of the geometry.
 
double length3D() const
Returns the length in 3D world of the line string.
 
void points(QgsPointSequence &pt) const override
Returns a list of points within the curve.
 
int dimension() const override
Returns the inherent dimension of the geometry.
 
void sumUpArea(double &sum) const override
Calculates the shoelace/triangle formula sum for the points in the linestring.
 
void clear() override
Clears the geometry, ie reset it to a null geometry.
 
const double * zData() const
Returns a const pointer to the z vertex data, or nullptr if the linestring does not have z values.
 
bool fromWkb(QgsConstWkbPtr &wkb) override
Sets the geometry from a WKB string.
 
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
 
QgsPoint startPoint() const override
Returns the starting point of the curve.
 
void transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection d=Qgis::TransformDirection::Forward, bool transformZ=false) override
Transforms the geometry using a coordinate transform.
 
QgsLineString * curveToLine(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a new line string geometry corresponding to a segmentized approximation of the curve.
 
bool isEmpty() const override
Returns true if the geometry is empty.
 
static QgsLineString * fromBezierCurve(const QgsPoint &start, const QgsPoint &controlPoint1, const QgsPoint &controlPoint2, const QgsPoint &end, int segments=30)
Returns a new linestring created by segmentizing the bezier curve between start and end,...
 
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
 
int numPoints() const override
Returns the number of points in the curve.
 
QgsPoint pointN(int i) const
Returns the specified point from inside the line string.
 
void drawAsPolygon(QPainter &p) const override
Draws the curve as a polygon on the specified QPainter.
 
int nCoordinates() const override
Returns the number of nodes contained in the geometry.
 
QgsLineString()
Constructor for an empty linestring geometry.
 
void draw(QPainter &p) const override
Draws the geometry using the specified QPainter.
 
QString asKml(int precision=17) const override
Returns a KML representation of the geometry.
 
int wkbSize(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
Returns the length of the QByteArray returned by asWkb()
 
void setPoints(size_t size, const double *x, const double *y, const double *z=nullptr, const double *m=nullptr)
Resets the line string to match the specified point data.
 
QgsPoint centroid() const override
Returns the centroid of the geometry.
 
QDomElement asGml3(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const override
Returns a GML3 representation of the geometry.
 
QPolygonF asQPolygonF() const override
Returns a QPolygonF representing the points.
 
bool removeDuplicateNodes(double epsilon=4 *std::numeric_limits< double >::epsilon(), bool useZValues=false) override
Removes duplicate nodes from the geometry, wherever removing the nodes does not result in a degenerat...
 
void scroll(int firstVertexIndex) final
Scrolls the curve vertices so that they start with the vertex at the given index.
 
bool boundingBoxIntersects(const QgsRectangle &rectangle) const override
Returns true if the bounding box of this geometry intersects with a rectangle.
 
QString geometryType() const override
Returns a unique string representing the geometry type.
 
double yAt(int index) const override
Returns the y-coordinate of the specified node in the line string.
 
QgsPoint endPoint() const override
Returns the end point of the curve.
 
void setYAt(int index, double y)
Sets the y-coordinate of the specified node in the line string.
 
QDomElement asGml2(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const override
Returns a GML2 representation of the geometry.
 
QgsLineString * reversed() const override
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
 
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
 
static QgsLineString * fromQPolygonF(const QPolygonF &polygon)
Returns a new linestring from a QPolygonF polygon input.
 
void close()
Closes the line string by appending the first point to the end of the line, if it is not already clos...
 
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
 
int indexOf(const QgsPoint &point) const final
Returns the index of the first vertex matching the given point, or -1 if a matching vertex is not fou...
 
double vertexAngle(QgsVertexId vertex) const override
Returns approximate angle at a vertex.
 
void extend(double startDistance, double endDistance)
Extends the line geometry by extrapolating out the start or end of the line by a specified distance.
 
QgsCompoundCurve * toCurveType() const override
Returns the geometry converted to the more generic curve type QgsCompoundCurve.
 
void append(const QgsLineString *line)
Appends the contents of another line string to the end of this line string.
 
QgsLineString * curveSubstring(double startDistance, double endDistance) const override
Returns a new curve representing a substring of this curve.
 
QgsBox3D calculateBoundingBox3D() const override
Calculates the minimal 3D bounding box for the geometry.
 
std::tuple< std::unique_ptr< QgsCurve >, std::unique_ptr< QgsCurve > > splitCurveAtVertex(int index) const final
Splits the curve at the specified vertex index, returning two curves which represent the portion of t...
 
void addToPainterPath(QPainterPath &path) const override
Adds a curve to a painter path.
 
void visitPointsByRegularDistance(double distance, const std::function< bool(double x, double y, double z, double m, double startSegmentX, double startSegmentY, double startSegmentZ, double startSegmentM, double endSegmentX, double endSegmentY, double endSegmentZ, double endSegmentM) > &visitPoint) const
Visits regular points along the linestring, spaced by distance.
 
void setXAt(int index, double x)
Sets the x-coordinate of the specified node in the line string.
 
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
 
double closestSegment(const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf=nullptr, double epsilon=4 *std::numeric_limits< double >::epsilon()) const override
Searches for the closest segment of the geometry to a given point.
 
QVector< QgsVertexId > collectDuplicateNodes(double epsilon=4 *std::numeric_limits< double >::epsilon(), bool useZValues=false) const
Returns a list of any duplicate nodes contained in the geometry, within the specified tolerance.
 
bool insertVertex(QgsVertexId position, const QgsPoint &vertex) override
Inserts a vertex into the geometry.
 
const double * mData() const
Returns a const pointer to the m vertex data, or nullptr if the linestring does not have m values.
 
void addVertex(const QgsPoint &pt)
Adds a new vertex to the end of the line string.
 
QgsLineString * clone() const override
Clones the geometry by performing a deep copy.
 
int compareToSameClass(const QgsAbstractGeometry *other) const final
Compares to an other geometry of the same class, and returns a integer for sorting of the two geometr...
 
bool dropMValue() override
Drops any measure values which exist in the geometry.
 
Q_DECL_DEPRECATED QgsBox3D calculateBoundingBox3d() const
Calculates the minimal 3D bounding box for the geometry.
 
json asJsonObject(int precision=17) const override
Returns a json object representation of the geometry.
 
void filterVertices(const std::function< bool(const QgsPoint &) > &filter) override
Filters the vertices from the geometry in place, removing any which do not return true for the filter...
 
QByteArray asWkb(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
 
void transformVertices(const std::function< QgsPoint(const QgsPoint &) > &transform) override
Transforms the vertices from the geometry in place, applying the transform function to every vertex.
 
QgsLineString * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
 
bool convertTo(Qgis::WkbType type) override
Converts the geometry to a specified type.
 
bool isClosed2D() const override
Returns true if the curve is closed.
 
double xAt(int index) const override
Returns the x-coordinate of the specified node in the line string.
 
QgsPoint * interpolatePoint(double distance) const override
Returns an interpolated point on the curve at the specified distance.
 
A class to represent a 2D point.
 
Point geometry type, with support for z-dimension and m-values.
 
void setY(double y)
Sets the point's y-coordinate.
 
void setX(double x)
Sets the point's x-coordinate.
 
A rectangle specified with double values.
 
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
 
static Qgis::WkbType dropM(Qgis::WkbType type)
Drops the m dimension (if present) for a WKB type and returns the new type.
 
static Qgis::WkbType zmType(Qgis::WkbType type, bool hasZ, bool hasM)
Returns the modified input geometry type according to hasZ / hasM.
 
static Qgis::WkbType dropZ(Qgis::WkbType type)
Drops the z dimension (if present) for a WKB type and returns the new type.
 
static Qgis::WkbType addM(Qgis::WkbType type)
Adds the m dimension to a WKB type and returns the new type.
 
static Qgis::WkbType addZ(Qgis::WkbType type)
Adds the z dimension to a WKB type and returns the new type.
 
static bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
 
static bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.
 
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
 
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
 
QVector< QgsPoint > QgsPointSequence
 
QLineF segment(int index, QRectF rect, double radius)
 
Utility class for identifying a unique vertex within a geometry.