29 #include <nlohmann/json.hpp>
34 #include <QDomDocument>
35 #include <QJsonObject>
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() );
86 QgsLineString::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() );
175 mX[1] = segment.
endX();
177 mY[1] = segment.
endY();
180 static 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 )
319 error = QObject::tr(
"LineString has less than 2 points and is not empty." );
330 bool res =
snapToGridPrivate( hSpacing, vSpacing, dSpacing, mSpacing, mX, mY, mZ, mM,
331 result->mX, result->mY, result->mZ, result->mM );
333 return result.release();
340 if ( mX.count() <= 2 )
343 double prevX = mX.at( 0 );
344 double prevY = mY.at( 0 );
346 bool useZ = hasZ && useZValues;
347 double prevZ = useZ ? mZ.at( 0 ) : 0;
349 int remaining = mX.count();
350 while ( i < remaining )
352 double currentX = mX.at( i );
353 double currentY = mY.at( i );
354 double currentZ = useZ ? mZ.at( i ) : 0;
380 QVector< QgsVertexId > res;
381 if ( mX.count() <= 1 )
384 const double *x = mX.constData();
385 const double *y = mY.constData();
387 bool useZ = hasZ && useZValues;
388 const double *z = useZ ? mZ.constData() :
nullptr;
392 double prevZ = z ? *z++ : 0;
395 for (
int i = 1; i < mX.count(); ++i )
397 double currentX = *x++;
398 double currentY = *y++;
399 double currentZ = useZ ? *z++ : 0;
419 const int nb = mX.size();
422 const double *x = mX.constData();
423 const double *y = mY.constData();
424 QPointF *dest =
points.data();
425 for (
int i = 0; i < nb; ++i )
427 *dest++ = QPointF( *x++, *y++ );
445 importVerticesFromWkb( wkbPtr );
451 double xmin = std::numeric_limits<double>::max();
452 double ymin = std::numeric_limits<double>::max();
453 double xmax = -std::numeric_limits<double>::max();
454 double ymax = -std::numeric_limits<double>::max();
456 for (
double x : mX )
463 for (
double y : mY )
488 QString secondWithoutParentheses =
parts.second;
489 secondWithoutParentheses = secondWithoutParentheses.remove(
'(' ).remove(
')' ).simplified().remove(
' ' );
490 parts.second =
parts.second.remove(
'(' ).remove(
')' );
491 if ( (
parts.second.compare( QLatin1String(
"EMPTY" ), Qt::CaseInsensitive ) == 0 ) ||
492 secondWithoutParentheses.isEmpty() )
507 int binarySize =
sizeof( char ) +
sizeof( quint32 ) +
sizeof( quint32 );
518 wkb << static_cast<quint32>(
wkbType() );
536 wkt += QLatin1String(
"EMPTY" );
551 QDomElement elemLineString = doc.createElementNS( ns, QStringLiteral(
"LineString" ) );
554 return elemLineString;
558 return elemLineString;
566 QDomElement elemLineString = doc.createElementNS( ns, QStringLiteral(
"LineString" ) );
569 return elemLineString;
572 return elemLineString;
581 {
"type",
"LineString" },
591 kml.append( QLatin1String(
"<LinearRing>" ) );
595 kml.append( QLatin1String(
"<LineString>" ) );
598 kml.append( QLatin1String(
"<altitudeMode>" ) );
601 kml.append( QLatin1String(
"absolute" ) );
605 kml.append( QLatin1String(
"clampToGround" ) );
607 kml.append( QLatin1String(
"</altitudeMode>" ) );
608 kml.append( QLatin1String(
"<coordinates>" ) );
610 int nPoints = mX.size();
611 for (
int i = 0; i < nPoints; ++i )
615 kml.append( QLatin1String(
" " ) );
618 kml.append( QLatin1String(
"," ) );
622 kml.append( QLatin1String(
"," ) );
627 kml.append( QLatin1String(
",0" ) );
630 kml.append( QLatin1String(
"</coordinates>" ) );
633 kml.append( QLatin1String(
"</LinearRing>" ) );
637 kml.append( QLatin1String(
"</LineString>" ) );
651 int size = mX.size();
653 for (
int i = 1; i < size; ++i )
655 dx = mX.at( i ) - mX.at( i - 1 );
656 dy = mY.at( i ) - mY.at( i - 1 );
657 length += std::sqrt( dx * dx + dy * dy );
667 int size = mX.size();
669 for (
int i = 1; i < size; ++i )
671 dx = mX.at( i ) - mX.at( i - 1 );
672 dy = mY.at( i ) - mY.at( i - 1 );
673 dz = mZ.at( i ) - mZ.at( i - 1 );
674 length += std::sqrt( dx * dx + dy * dy + dz * dz );
710 Q_UNUSED( tolerance )
711 Q_UNUSED( toleranceType )
727 if ( i < 0 || i >= mX.size() )
732 double x = mX.at( i );
733 double y = mY.at( i );
734 double z = std::numeric_limits<double>::quiet_NaN();
735 double m = std::numeric_limits<double>::quiet_NaN();
753 else if ( hasZ && hasM )
776 if ( index >= 0 && index < mX.size() )
777 return mX.at( index );
784 if ( index >= 0 && index < mY.size() )
785 return mY.at( index );
792 if ( index >= 0 && index < mX.size() )
799 if ( index >= 0 && index < mY.size() )
814 pts.reserve( nPoints );
815 for (
int i = 0; i < nPoints; ++i )
817 pts.push_back(
pointN( i ) );
833 bool hasZ = firstPt.
is3D();
838 mX.resize(
points.size() );
839 mY.resize(
points.size() );
842 mZ.resize(
points.size() );
850 mM.resize(
points.size() );
857 for (
int i = 0; i <
points.size(); ++i )
859 mX[i] =
points.at( i ).x();
860 mY[i] =
points.at( i ).y();
863 double z =
points.at( i ).z();
864 mZ[i] = std::isnan( z ) ? 0 : z;
868 double m =
points.at( i ).m();
869 mM[i] = std::isnan( m ) ? 0 : m;
922 mZ.insert( mZ.count(), mX.size() - mZ.size(), std::numeric_limits<double>::quiet_NaN() );
935 mM.insert( mM.count(), mX.size() - mM.size(), std::numeric_limits<double>::quiet_NaN() );
945 std::reverse( copy->mX.begin(), copy->mX.end() );
946 std::reverse( copy->mY.begin(), copy->mY.end() );
949 std::reverse( copy->mZ.begin(), copy->mZ.end() );
953 std::reverse( copy->mM.begin(), copy->mM.end() );
958 void QgsLineString::visitPointsByRegularDistance(
const double distance,
const std::function<
bool (
double,
double,
double,
double,
double,
double,
double,
double,
double,
double,
double,
double )> &visitPoint )
const
963 double distanceTraversed = 0;
965 if ( totalPoints == 0 )
968 const double *x = mX.constData();
969 const double *y = mY.constData();
970 const double *z =
is3D() ? mZ.constData() :
nullptr;
971 const double *m =
isMeasure() ? mM.constData() :
nullptr;
975 double prevZ = z ? *z++ : 0.0;
976 double prevM = m ? *m++ : 0.0;
980 visitPoint( prevX, prevY, prevZ, prevM, prevX, prevY, prevZ, prevM, prevX, prevY, prevZ, prevM );
984 double pZ = std::numeric_limits<double>::quiet_NaN();
985 double pM = std::numeric_limits<double>::quiet_NaN();
986 double nextPointDistance = distance;
987 for (
int i = 1; i < totalPoints; ++i )
991 double thisZ = z ? *z++ : 0.0;
992 double thisM = m ? *m++ : 0.0;
994 const double segmentLength = std::sqrt( ( thisX - prevX ) * ( thisX - prevX ) + ( thisY - prevY ) * ( thisY - prevY ) );
998 const double distanceToPoint = std::min( nextPointDistance - distanceTraversed,
segmentLength );
1001 z ? &prevZ :
nullptr, z ? &thisZ :
nullptr, z ? &pZ :
nullptr,
1002 m ? &prevM :
nullptr, m ? &thisM :
nullptr, m ? &pM :
nullptr );
1004 if ( !visitPoint( pX, pY, pZ, pM, prevX, prevY, prevZ, prevM, thisX, thisY, thisZ, thisM ) )
1007 nextPointDistance += distance;
1029 std::unique_ptr< QgsPoint > res;
1030 visitPointsByRegularDistance( distance, [ & ](
double x,
double y,
double z,
double m,
double,
double,
double,
double,
double,
double,
double,
double )->
bool
1032 res = qgis::make_unique< QgsPoint >( pointType, x, y, z, m );
1035 return res.release();
1040 if ( startDistance < 0 && endDistance < 0 )
1043 endDistance = std::max( startDistance, endDistance );
1046 if ( totalPoints == 0 )
1049 QVector< QgsPoint > substringPoints;
1050 substringPoints.reserve( totalPoints );
1058 const double *x = mX.constData();
1059 const double *y = mY.constData();
1060 const double *z =
is3D() ? mZ.constData() :
nullptr;
1061 const double *m =
isMeasure() ? mM.constData() :
nullptr;
1063 double distanceTraversed = 0;
1064 double prevX = *x++;
1065 double prevY = *y++;
1066 double prevZ = z ? *z++ : 0.0;
1067 double prevM = m ? *m++ : 0.0;
1068 bool foundStart =
false;
1070 if ( startDistance < 0 )
1073 for (
int i = 1; i < totalPoints; ++i )
1075 double thisX = *x++;
1076 double thisY = *y++;
1077 double thisZ = z ? *z++ : 0.0;
1078 double thisM = m ? *m++ : 0.0;
1080 const double segmentLength = std::sqrt( ( thisX - prevX ) * ( thisX - prevX ) + ( thisY - prevY ) * ( thisY - prevY ) );
1082 if ( distanceTraversed <= startDistance && startDistance < distanceTraversed +
segmentLength )
1085 const double distanceToStart = startDistance - distanceTraversed;
1086 double startX, startY;
1090 z ? &prevZ :
nullptr, z ? &thisZ :
nullptr, z ? &startZ :
nullptr,
1091 m ? &prevM :
nullptr, m ? &thisM :
nullptr, m ? &startM :
nullptr );
1092 substringPoints <<
QgsPoint( pointType, startX, startY, startZ, startM );
1095 if ( foundStart && ( distanceTraversed +
segmentLength > endDistance ) )
1098 const double distanceToEnd = endDistance - distanceTraversed;
1103 z ? &prevZ :
nullptr, z ? &thisZ :
nullptr, z ? &endZ :
nullptr,
1104 m ? &prevM :
nullptr, m ? &thisM :
nullptr, m ? &endM :
nullptr );
1105 substringPoints <<
QgsPoint( pointType, endX, endY, endZ, endM );
1107 else if ( foundStart )
1109 substringPoints <<
QgsPoint( pointType, thisX, thisY, thisZ, thisM );
1117 if ( distanceTraversed >= endDistance )
1122 if ( !foundStart &&
qgsDoubleNear( distanceTraversed, startDistance ) )
1124 substringPoints <<
QgsPoint( pointType, prevX, prevY, prevZ, prevM )
1125 <<
QgsPoint( pointType, prevX, prevY, prevZ, prevM );
1150 if ( path.isEmpty() || path.currentPosition() != QPointF( mX.at( 0 ), mY.at( 0 ) ) )
1152 path.moveTo( mX.at( 0 ), mY.at( 0 ) );
1155 for (
int i = 1; i < nPoints; ++i )
1157 path.lineTo( mX.at( i ), mY.at( i ) );
1170 return compoundCurve;
1175 if ( mX.size() < 2 || mY.size() < 2 )
1179 if ( startDistance > 0 )
1181 double currentLen = std::sqrt( std::pow( mX.at( 0 ) - mX.at( 1 ), 2 ) +
1182 std::pow( mY.at( 0 ) - mY.at( 1 ), 2 ) );
1183 double newLen = currentLen + startDistance;
1184 mX[ 0 ] = mX.at( 1 ) + ( mX.at( 0 ) - mX.at( 1 ) ) / currentLen * newLen;
1185 mY[ 0 ] = mY.at( 1 ) + ( mY.at( 0 ) - mY.at( 1 ) ) / currentLen * newLen;
1188 if ( endDistance > 0 )
1190 int last = mX.size() - 1;
1191 double currentLen = std::sqrt( std::pow( mX.at( last ) - mX.at( last - 1 ), 2 ) +
1192 std::pow( mY.at( last ) - mY.at( last - 1 ), 2 ) );
1193 double newLen = currentLen + endDistance;
1194 mX[ last ] = mX.at( last - 1 ) + ( mX.at( last ) - mX.at( last - 1 ) ) / currentLen * newLen;
1195 mY[ last ] = mY.at( last - 1 ) + ( mY.at( last ) - mY.at( last - 1 ) ) / currentLen * newLen;
1201 auto result = qgis::make_unique< QgsLineString >();
1203 return result.release();
1208 return QStringLiteral(
"LineString" );
1224 double *zArray =
nullptr;
1230 std::unique_ptr< double[] > dummyZ;
1231 if ( !hasZ || !transformZ )
1233 dummyZ.reset(
new double[nPoints]() );
1234 zArray = dummyZ.get();
1249 double *x = mX.data();
1250 double *y = mY.data();
1251 double *z = hasZ ? mZ.data() :
nullptr;
1252 double *m = hasM ? mM.data() :
nullptr;
1253 for (
int i = 0; i < nPoints; ++i )
1256 t.map( *x, *y, &xOut, &yOut );
1261 *z = *z * zScale + zTranslate;
1266 *m = *m * mScale + mTranslate;
1281 if ( position.
vertex < 0 || position.
vertex > mX.size() )
1291 mX.insert( position.
vertex, vertex.
x() );
1292 mY.insert( position.
vertex, vertex.
y() );
1295 mZ.insert( position.
vertex, vertex.
z() );
1299 mM.insert( position.
vertex, vertex.
m() );
1307 if ( position.
vertex < 0 || position.
vertex >= mX.size() )
1311 mX[position.
vertex] = newPos.
x();
1312 mY[position.
vertex] = newPos.
y();
1315 mZ[position.
vertex] = newPos.
z();
1319 mM[position.
vertex] = newPos.
m();
1327 if ( position.
vertex >= mX.size() || position.
vertex < 0 )
1332 mX.remove( position.
vertex );
1333 mY.remove( position.
vertex );
1336 mZ.remove( position.
vertex );
1340 mM.remove( position.
vertex );
1365 mX.append( pt.
x() );
1366 mY.append( pt.
y() );
1369 mZ.append( pt.
z() );
1373 mM.append( pt.
m() );
1380 double sqrDist = std::numeric_limits<double>::max();
1381 double leftOfDist = std::numeric_limits<double>::max();
1383 double prevLeftOfX = 0.0;
1384 double prevLeftOfY = 0.0;
1385 double testDist = 0;
1386 double segmentPtX, segmentPtY;
1391 int size = mX.size();
1392 if ( size == 0 || size == 1 )
1397 for (
int i = 1; i < size; ++i )
1399 double prevX = mX.at( i - 1 );
1400 double prevY = mY.at( i - 1 );
1401 double currentX = mX.at( i );
1402 double currentY = mY.at( i );
1404 if ( testDist < sqrDist )
1407 segmentPt.
setX( segmentPtX );
1408 segmentPt.
setY( segmentPtY );
1409 vertexAfter.
part = 0;
1410 vertexAfter.
ring = 0;
1421 if (
qgsDoubleNear( testDist, leftOfDist ) && left != prevLeftOf && prevLeftOf != 0 )
1434 leftOfDist = testDist;
1435 prevLeftOfX = prevX;
1436 prevLeftOfY = prevY;
1438 else if ( testDist < leftOfDist )
1441 leftOfDist = testDist;
1473 return QgsPoint( mX.at( 0 ), mY.at( 0 ) );
1475 double totalLineLength = 0.0;
1476 double prevX = mX.at( 0 );
1477 double prevY = mY.at( 0 );
1483 double currentX = mX.at( i );
1484 double currentY = mY.at( i );
1485 double segmentLength = std::sqrt( std::pow( currentX - prevX, 2.0 ) +
1486 std::pow( currentY - prevY, 2.0 ) );
1498 return QgsPoint( mX.at( 0 ), mY.at( 0 ) );
1500 return QgsPoint( sumX / totalLineLength, sumY / totalLineLength );
1514 for (
int i = 0; i < maxIndex; ++i )
1516 sum += 0.5 * ( mX.at( i ) * mY.at( i + 1 ) - mY.at( i ) * mX.at( i + 1 ) );
1520 void QgsLineString::importVerticesFromWkb(
const QgsConstWkbPtr &wkb )
1526 mX.resize( nVertices );
1527 mY.resize( nVertices );
1528 hasZ ? mZ.resize( nVertices ) : mZ.clear();
1529 hasM ? mM.resize( nVertices ) : mM.clear();
1530 double *x = mX.data();
1531 double *y = mY.data();
1532 double *m = hasM ? mM.data() :
nullptr;
1533 double *z = hasZ ? mZ.data() :
nullptr;
1534 for (
int i = 0; i < nVertices; ++i )
1567 if ( mX.count() < 2 )
1577 double previousX = mX.at(
numPoints() - 2 );
1578 double previousY = mY.at(
numPoints() - 2 );
1579 double currentX = mX.at( 0 );
1580 double currentY = mY.at( 0 );
1581 double afterX = mX.at( 1 );
1582 double afterY = mY.at( 1 );
1585 else if ( vertex.
vertex == 0 )
1598 double previousX = mX.at( vertex.
vertex - 1 );
1599 double previousY = mY.at( vertex.
vertex - 1 );
1600 double currentX = mX.at( vertex.
vertex );
1601 double currentY = mY.at( vertex.
vertex );
1602 double afterX = mX.at( vertex.
vertex + 1 );
1603 double afterY = mY.at( vertex.
vertex + 1 );
1610 if ( startVertex.
vertex < 0 || startVertex.
vertex >= mX.count() - 1 )
1613 double dx = mX.at( startVertex.
vertex + 1 ) - mX.at( startVertex.
vertex );
1614 double dy = mY.at( startVertex.
vertex + 1 ) - mY.at( startVertex.
vertex );
1615 return std::sqrt( dx * dx + dy * dy );
1640 mZ.reserve( nPoints );
1641 for (
int i = 0; i < nPoints; ++i )
1671 mM.reserve( nPoints );
1672 for (
int i = 0; i < nPoints; ++i )
1703 std::swap( mX, mY );
1717 addZValue( std::numeric_limits<double>::quiet_NaN() );
1734 int size = mX.size();
1736 double *srcX = mX.data();
1737 double *srcY = mY.data();
1738 double *srcM = hasM ? mM.data() :
nullptr;
1739 double *srcZ = hasZ ? mZ.data() :
nullptr;
1742 for (
int i = 0; i < size; ++i )
1746 double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
1747 double m = hasM ? *srcM : std::numeric_limits<double>::quiet_NaN();
1775 int size = mX.size();
1777 double *srcX = mX.data();
1778 double *srcY = mY.data();
1779 double *srcM = hasM ? mM.data() :
nullptr;
1780 double *srcZ = hasZ ? mZ.data() :
nullptr;
1782 double *destX = srcX;
1783 double *destY = srcY;
1784 double *destM = srcM;
1785 double *destZ = srcZ;
1787 int filteredPoints = 0;
1788 for (
int i = 0; i < size; ++i )
1792 double z = hasZ ? *srcZ++ : std::numeric_limits<double>::quiet_NaN();
1793 double m = hasM ? *srcM++ : std::numeric_limits<double>::quiet_NaN();
1795 if ( filter(
QgsPoint( x, y, z, m ) ) )
1807 mX.resize( filteredPoints );
1808 mY.resize( filteredPoints );
1810 mZ.resize( filteredPoints );
1812 mM.resize( filteredPoints );
1821 int size = mX.size();
1823 double *srcX = mX.data();
1824 double *srcY = mY.data();
1825 double *srcM = hasM ? mM.data() :
nullptr;
1826 double *srcZ = hasZ ? mZ.data() :
nullptr;
1828 for (
int i = 0; i < size; ++i )
1832 double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
1833 double m = hasM ? *srcM : std::numeric_limits<double>::quiet_NaN();
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
bool is3D() const SIP_HOLDGIL
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.
virtual bool convertTo(QgsWkbTypes::Type type)
Converts the geometry to a specified type.
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
QgsWkbTypes::Type mWkbType
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry.
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, QgsWkbTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
static endian_t endian()
Returns whether this machine uses big or little endian.
Compound curve geometry type.
void addCurve(QgsCurve *c)
Adds a curve to the geometry (takes ownership)
QgsWkbTypes::Type 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.
virtual bool isClosed() const SIP_HOLDGIL
Returns true if the curve is closed.
virtual bool isRing() const SIP_HOLDGIL
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, int flags=0) const override
Checks validity of the geometry, and returns true if the geometry is valid.
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 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 json pointsToJson(const QgsPointSequence &points, int precision)
Returns coordinates as json object.
static void pointsToWKB(QgsWkbPtr &wkb, const QgsPointSequence &points, bool is3D, bool isMeasure)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }.
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 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 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 QgsPoint pointOnLineWithDistance(const QgsPoint &startPoint, const QgsPoint &directionPoint, double distance) SIP_HOLDGIL
Returns a point a specified distance toward a second point.
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 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.
Represents a single 2D line segment, consisting of a 2D start and end vertex only.
double endX() const SIP_HOLDGIL
Returns the segment's end x-coordinate.
double endY() const SIP_HOLDGIL
Returns the segment's end y-coordinate.
double startX() const SIP_HOLDGIL
Returns the segment's start x-coordinate.
double startY() const SIP_HOLDGIL
Returns the segment's start y-coordinate.
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.
QgsPoint startPoint() const override SIP_HOLDGIL
Returns the starting point of the curve.
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.
void swapXy() override
Swaps the x and y coordinates from the geometry.
bool equals(const QgsCurve &other) const override
Checks whether this curve exactly equals another curve.
const double * yData() const
Returns a const pointer to the y vertex data.
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
void points(QgsPointSequence &pt) const override
Returns a list of points within the curve.
int dimension() const override SIP_HOLDGIL
Returns the inherent dimension of the geometry.
double length() const override SIP_HOLDGIL
Returns the planar, 2-dimensional length of the geometry.
void sumUpArea(double &sum) const override
Sums up the area of the curve by iterating over the vertices (shoelace formula).
QgsPoint endPoint() const override SIP_HOLDGIL
Returns the end point of the curve.
void clear() override
Clears the geometry, ie reset it to a null geometry.
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) override SIP_THROW(QgsCsException)
Transforms the geometry using a coordinate transform.
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.
int numPoints() const override SIP_HOLDGIL
Returns the number of points in the curve.
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.
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.
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.
bool isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
QString geometryType() const override SIP_HOLDGIL
Returns a unique string representing the geometry type.
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()
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 convertTo(QgsWkbTypes::Type type) override
Converts the geometry to a specified type.
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 setPoints(const QgsPointSequence &points)
Resets the line string to match the specified list of points.
const double * mData() const
Returns a const pointer to the m vertex data, or nullptr if the linestring does not have m values.
double yAt(int index) const override
Returns the y-coordinate of the specified node in the line string.
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.
double length3D() const SIP_HOLDGIL
Returns the length in 3D world of the line string.
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.
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.
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.
QgsLineString() SIP_HOLDGIL
Constructor for an empty linestring geometry.
void setXAt(int index, double x)
Sets the x-coordinate of the specified node in the line string.
int nCoordinates() const override SIP_HOLDGIL
Returns the number of nodes contained in the geometry.
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.
void addVertex(const QgsPoint &pt)
Adds a new vertex to the end of the line string.
QgsRectangle calculateBoundingBox() const override
Default calculator for the minimal bounding box for the geometry.
QgsLineString * clone() const override
Clones the geometry by performing a deep copy.
bool dropMValue() override
Drops any measure values which exist in the geometry.
bool isValid(QString &error, int flags=0) const override
Checks validity of the geometry, and returns true if the geometry is valid.
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...
bool pointAt(int node, QgsPoint &point, QgsVertexId::VertexType &type) const override
Returns the point and vertex id of a point within the curve.
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.
const double * xData() const
Returns a const pointer to the x vertex data.
const double * zData() const
Returns a const pointer to the z vertex data, or nullptr if the linestring does not have z values.
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 setX(double x) SIP_HOLDGIL
Sets the point's x-coordinate.
void setY(double y) SIP_HOLDGIL
Sets the point's y-coordinate.
A rectangle specified with double values.
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 zmType(Type type, bool hasZ, bool hasM) SIP_HOLDGIL
Returns the modified input geometry type according to hasZ / hasM.
static Type dropZ(Type type) SIP_HOLDGIL
Drops the z dimension (if present) for a WKB type and returns the new type.
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
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.
static Type dropM(Type type) SIP_HOLDGIL
Drops the m dimension (if present) for a WKB type and returns the new type.
double ANALYSIS_EXPORT leftOf(const QgsPoint &thepoint, const QgsPoint *p1, const QgsPoint *p2)
Returns whether 'thepoint' is left or right of the line from 'p1' to 'p2'. Negative values mean left ...
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
Utility class for identifying a unique vertex within a geometry.
VertexType
Type of vertex.
@ SegmentVertex
The actual start or end point of a segment.