QGIS API Documentation
3.14.0-Pi (9f7028fd23)
|
Go to the documentation of this file.
27 #include <nlohmann/json.hpp>
32 #include <QDomDocument>
33 #include <QJsonObject>
56 mX.resize(
points.count() );
57 mY.resize(
points.count() );
58 double *x = mX.data();
59 double *y = mY.data();
64 mZ.resize(
points.count() );
69 mM.resize(
points.count() );
84 QgsLineString::QgsLineString(
const QVector<double> &x,
const QVector<double> &y,
const QVector<double> &z,
const QVector<double> &m,
bool is25DType )
87 int pointCount = std::min( x.size(), y.size() );
88 if ( x.size() == pointCount )
94 mX = x.mid( 0, pointCount );
96 if ( y.size() == pointCount )
102 mY = y.mid( 0, pointCount );
104 if ( !z.isEmpty() && z.count() >= pointCount )
107 if ( z.size() == pointCount )
113 mZ = z.mid( 0, pointCount );
116 if ( !m.isEmpty() && m.count() >= pointCount )
119 if ( m.size() == pointCount )
125 mM = m.mid( 0, pointCount );
158 mX.reserve(
points.size() );
159 mY.reserve(
points.size() );
173 mX[1] = segment.
endX();
175 mY[1] = segment.
endY();
178 static double cubicInterpolate(
double a,
double b,
179 double A,
double B,
double C,
double D )
181 return A * b * b * b + 3 * B * b * b * a + 3 * C * b * a * a + D * a * a * a;
190 x.resize( segments + 1 );
192 y.resize( segments + 1 );
194 double *
zData =
nullptr;
195 if ( start.
is3D() && end.
is3D() && controlPoint1.
is3D() && controlPoint2.
is3D() )
197 z.resize( segments + 1 );
201 double *
mData =
nullptr;
204 m.resize( segments + 1 );
208 double *
xData = x.data();
209 double *
yData = y.data();
210 const double step = 1.0 / segments;
213 for (
int i = 0; i < segments; i++, a += step, b -= step )
226 *
xData++ = cubicInterpolate( a, b, start.
x(), controlPoint1.
x(), controlPoint2.
x(), end.
x() );
227 *
yData++ = cubicInterpolate( a, b, start.
y(), controlPoint1.
y(), controlPoint2.
y(), end.
y() );
229 *
zData++ = cubicInterpolate( a, b, start.
z(), controlPoint1.
z(), controlPoint2.
z(), end.
z() );
231 *
mData++ = cubicInterpolate( a, b, start.
m(), controlPoint1.
m(), controlPoint2.
m(), end.
m() );
249 x.resize( polygon.count() );
250 y.resize( polygon.count() );
251 double *
xData = x.data();
252 double *
yData = y.data();
254 const QPointF *src = polygon.data();
255 for (
int i = 0 ; i < polygon.size(); ++ i )
267 const QgsLineString *otherLine = qgsgeometry_cast< const QgsLineString * >( &other );
274 if ( mX.count() != otherLine->mX.count() )
277 for (
int i = 0; i < mX.count(); ++i )
318 bool res =
snapToGridPrivate( hSpacing, vSpacing, dSpacing, mSpacing, mX, mY, mZ, mM,
319 result->mX, result->mY, result->mZ, result->mM );
321 return result.release();
328 if ( mX.count() <= 2 )
331 double prevX = mX.at( 0 );
332 double prevY = mY.at( 0 );
334 bool useZ = hasZ && useZValues;
335 double prevZ = useZ ? mZ.at( 0 ) : 0;
337 int remaining = mX.count();
338 while ( i < remaining )
340 double currentX = mX.at( i );
341 double currentY = mY.at( i );
342 double currentZ = useZ ? mZ.at( i ) : 0;
368 const int nb = mX.size();
371 const double *x = mX.constData();
372 const double *y = mY.constData();
373 QPointF *dest =
points.data();
374 for (
int i = 0; i < nb; ++i )
376 *dest++ = QPointF( *x++, *y++ );
394 importVerticesFromWkb( wkbPtr );
400 double xmin = std::numeric_limits<double>::max();
401 double ymin = std::numeric_limits<double>::max();
402 double xmax = -std::numeric_limits<double>::max();
403 double ymax = -std::numeric_limits<double>::max();
405 for (
double x : mX )
412 for (
double y : mY )
437 if (
parts.second ==
"EMPTY" )
446 int binarySize =
sizeof( char ) +
sizeof( quint32 ) +
sizeof( quint32 );
450 wkbArray.resize( binarySize );
453 wkb << static_cast<quint32>(
wkbType() );
471 wkt += QStringLiteral(
"EMPTY" );
486 QDomElement elemLineString = doc.createElementNS( ns, QStringLiteral(
"LineString" ) );
489 return elemLineString;
493 return elemLineString;
501 QDomElement elemLineString = doc.createElementNS( ns, QStringLiteral(
"LineString" ) );
504 return elemLineString;
507 return elemLineString;
516 {
"type",
"LineString" },
526 kml.append( QLatin1String(
"<LinearRing>" ) );
530 kml.append( QLatin1String(
"<LineString>" ) );
533 kml.append( QLatin1String(
"<altitudeMode>" ) );
536 kml.append( QLatin1String(
"absolute" ) );
540 kml.append( QLatin1String(
"clampToGround" ) );
542 kml.append( QLatin1String(
"</altitudeMode>" ) );
543 kml.append( QLatin1String(
"<coordinates>" ) );
545 int nPoints = mX.size();
546 for (
int i = 0; i < nPoints; ++i )
550 kml.append( QLatin1String(
" " ) );
553 kml.append( QLatin1String(
"," ) );
557 kml.append( QLatin1String(
"," ) );
562 kml.append( QLatin1String(
",0" ) );
565 kml.append( QLatin1String(
"</coordinates>" ) );
568 kml.append( QLatin1String(
"</LinearRing>" ) );
572 kml.append( QLatin1String(
"</LineString>" ) );
586 int size = mX.size();
588 for (
int i = 1; i < size; ++i )
590 dx = mX.at( i ) - mX.at( i - 1 );
591 dy = mY.at( i ) - mY.at( i - 1 );
592 length += std::sqrt( dx * dx + dy * dy );
602 int size = mX.size();
604 for (
int i = 1; i < size; ++i )
606 dx = mX.at( i ) - mX.at( i - 1 );
607 dy = mY.at( i ) - mY.at( i - 1 );
608 dz = mZ.at( i ) - mZ.at( i - 1 );
609 length += std::sqrt( dx * dx + dy * dy + dz * dz );
645 Q_UNUSED( tolerance )
646 Q_UNUSED( toleranceType )
662 if ( i < 0 || i >= mX.size() )
667 double x = mX.at( i );
668 double y = mY.at( i );
669 double z = std::numeric_limits<double>::quiet_NaN();
670 double m = std::numeric_limits<double>::quiet_NaN();
688 else if ( hasZ && hasM )
711 if ( index >= 0 && index < mX.size() )
712 return mX.at( index );
719 if ( index >= 0 && index < mY.size() )
720 return mY.at( index );
727 if ( index >= 0 && index < mX.size() )
734 if ( index >= 0 && index < mY.size() )
749 pts.reserve( nPoints );
750 for (
int i = 0; i < nPoints; ++i )
752 pts.push_back(
pointN( i ) );
768 bool hasZ = firstPt.
is3D();
773 mX.resize(
points.size() );
774 mY.resize(
points.size() );
777 mZ.resize(
points.size() );
785 mM.resize(
points.size() );
792 for (
int i = 0; i <
points.size(); ++i )
794 mX[i] =
points.at( i ).x();
795 mY[i] =
points.at( i ).y();
798 double z =
points.at( i ).z();
799 mZ[i] = std::isnan( z ) ? 0 : z;
803 double m =
points.at( i ).m();
804 mM[i] = std::isnan( m ) ? 0 : m;
857 mZ.insert( mZ.count(), mX.size() - mZ.size(), std::numeric_limits<double>::quiet_NaN() );
870 mM.insert( mM.count(), mX.size() - mM.size(), std::numeric_limits<double>::quiet_NaN() );
880 std::reverse( copy->mX.begin(), copy->mX.end() );
881 std::reverse( copy->mY.begin(), copy->mY.end() );
884 std::reverse( copy->mZ.begin(), copy->mZ.end() );
888 std::reverse( copy->mM.begin(), copy->mM.end() );
893 void QgsLineString::visitPointsByRegularDistance(
const double distance,
const std::function<
bool (
double,
double,
double,
double,
double,
double,
double,
double,
double,
double,
double,
double )> &visitPoint )
const
898 double distanceTraversed = 0;
900 if ( totalPoints == 0 )
903 const double *x = mX.constData();
904 const double *y = mY.constData();
905 const double *z =
is3D() ? mZ.constData() :
nullptr;
906 const double *m =
isMeasure() ? mM.constData() :
nullptr;
910 double prevZ = z ? *z++ : 0.0;
911 double prevM = m ? *m++ : 0.0;
915 visitPoint( prevX, prevY, prevZ, prevM, prevX, prevY, prevZ, prevM, prevX, prevY, prevZ, prevM );
919 double pZ = std::numeric_limits<double>::quiet_NaN();
920 double pM = std::numeric_limits<double>::quiet_NaN();
921 double nextPointDistance = distance;
922 for (
int i = 1; i < totalPoints; ++i )
926 double thisZ = z ? *z++ : 0.0;
927 double thisM = m ? *m++ : 0.0;
929 const double segmentLength = std::sqrt( ( thisX - prevX ) * ( thisX - prevX ) + ( thisY - prevY ) * ( thisY - prevY ) );
933 const double distanceToPoint = std::min( nextPointDistance - distanceTraversed,
segmentLength );
936 z ? &prevZ :
nullptr, z ? &thisZ :
nullptr, z ? &pZ :
nullptr,
937 m ? &prevM :
nullptr, m ? &thisM :
nullptr, m ? &pM :
nullptr );
939 if ( !visitPoint( pX, pY, pZ, pM, prevX, prevY, prevZ, prevM, thisX, thisY, thisZ, thisM ) )
942 nextPointDistance += distance;
964 std::unique_ptr< QgsPoint > res;
965 visitPointsByRegularDistance( distance, [ & ](
double x,
double y,
double z,
double m,
double,
double,
double,
double,
double,
double,
double,
double )->
bool
967 res = qgis::make_unique< QgsPoint >( pointType, x, y, z, m );
970 return res.release();
975 if ( startDistance < 0 && endDistance < 0 )
978 endDistance = std::max( startDistance, endDistance );
980 double distanceTraversed = 0;
982 if ( totalPoints == 0 )
985 QVector< QgsPoint > substringPoints;
993 const double *x = mX.constData();
994 const double *y = mY.constData();
995 const double *z =
is3D() ? mZ.constData() :
nullptr;
996 const double *m =
isMeasure() ? mM.constData() :
nullptr;
1000 double prevZ = z ? *z++ : 0.0;
1001 double prevM = m ? *m++ : 0.0;
1002 bool foundStart =
false;
1004 if (
qgsDoubleNear( startDistance, 0.0 ) || startDistance < 0 )
1006 substringPoints <<
QgsPoint( pointType, prevX, prevY, prevZ, prevM );
1010 substringPoints.reserve( totalPoints );
1012 for (
int i = 1; i < totalPoints; ++i )
1014 double thisX = *x++;
1015 double thisY = *y++;
1016 double thisZ = z ? *z++ : 0.0;
1017 double thisM = m ? *m++ : 0.0;
1019 const double segmentLength = std::sqrt( ( thisX - prevX ) * ( thisX - prevX ) + ( thisY - prevY ) * ( thisY - prevY ) );
1020 if ( distanceTraversed < startDistance && distanceTraversed + segmentLength > startDistance )
1023 const double distanceToStart = startDistance - distanceTraversed;
1024 double startX, startY;
1028 z ? &prevZ :
nullptr, z ? &thisZ :
nullptr, z ? &startZ :
nullptr,
1029 m ? &prevM :
nullptr, m ? &thisM :
nullptr, m ? &startM :
nullptr );
1030 substringPoints <<
QgsPoint( pointType, startX, startY, startZ, startM );
1033 if ( foundStart && ( distanceTraversed +
segmentLength > endDistance ) )
1036 const double distanceToEnd = endDistance - distanceTraversed;
1041 z ? &prevZ :
nullptr, z ? &thisZ :
nullptr, z ? &endZ :
nullptr,
1042 m ? &prevM :
nullptr, m ? &thisM :
nullptr, m ? &endM :
nullptr );
1043 substringPoints <<
QgsPoint( pointType, endX, endY, endZ, endM );
1045 else if ( foundStart )
1047 substringPoints <<
QgsPoint( pointType, thisX, thisY, thisZ, thisM );
1051 if ( distanceTraversed > endDistance )
1082 if ( path.isEmpty() || path.currentPosition() != QPointF( mX.at( 0 ), mY.at( 0 ) ) )
1084 path.moveTo( mX.at( 0 ), mY.at( 0 ) );
1087 for (
int i = 1; i < nPoints; ++i )
1089 path.lineTo( mX.at( i ), mY.at( i ) );
1102 return compoundCurve;
1107 if ( mX.size() < 2 || mY.size() < 2 )
1111 if ( startDistance > 0 )
1113 double currentLen = std::sqrt( std::pow( mX.at( 0 ) - mX.at( 1 ), 2 ) +
1114 std::pow( mY.at( 0 ) - mY.at( 1 ), 2 ) );
1115 double newLen = currentLen + startDistance;
1116 mX[ 0 ] = mX.at( 1 ) + ( mX.at( 0 ) - mX.at( 1 ) ) / currentLen * newLen;
1117 mY[ 0 ] = mY.at( 1 ) + ( mY.at( 0 ) - mY.at( 1 ) ) / currentLen * newLen;
1120 if ( endDistance > 0 )
1122 int last = mX.size() - 1;
1123 double currentLen = std::sqrt( std::pow( mX.at( last ) - mX.at( last - 1 ), 2 ) +
1124 std::pow( mY.at( last ) - mY.at( last - 1 ), 2 ) );
1125 double newLen = currentLen + endDistance;
1126 mX[ last ] = mX.at( last - 1 ) + ( mX.at( last ) - mX.at( last - 1 ) ) / currentLen * newLen;
1127 mY[ last ] = mY.at( last - 1 ) + ( mY.at( last ) - mY.at( last - 1 ) ) / currentLen * newLen;
1133 auto result = qgis::make_unique< QgsLineString >();
1135 return result.release();
1140 return QStringLiteral(
"LineString" );
1156 double *zArray =
nullptr;
1162 std::unique_ptr< double[] > dummyZ;
1163 if ( !hasZ || !transformZ )
1165 dummyZ.reset(
new double[nPoints]() );
1166 zArray = dummyZ.get();
1181 double *x = mX.data();
1182 double *y = mY.data();
1183 double *z = hasZ ? mZ.data() :
nullptr;
1184 double *m = hasM ? mM.data() :
nullptr;
1185 for (
int i = 0; i < nPoints; ++i )
1188 t.map( *x, *y, &xOut, &yOut );
1193 *z = *z * zScale + zTranslate;
1198 *m = *m * mScale + mTranslate;
1213 if ( position.
vertex < 0 || position.
vertex > mX.size() )
1223 mX.insert( position.
vertex, vertex.
x() );
1224 mY.insert( position.
vertex, vertex.
y() );
1227 mZ.insert( position.
vertex, vertex.
z() );
1231 mM.insert( position.
vertex, vertex.
m() );
1239 if ( position.
vertex < 0 || position.
vertex >= mX.size() )
1243 mX[position.
vertex] = newPos.
x();
1244 mY[position.
vertex] = newPos.
y();
1247 mZ[position.
vertex] = newPos.
z();
1251 mM[position.
vertex] = newPos.
m();
1259 if ( position.
vertex >= mX.size() || position.
vertex < 0 )
1264 mX.remove( position.
vertex );
1265 mY.remove( position.
vertex );
1268 mZ.remove( position.
vertex );
1272 mM.remove( position.
vertex );
1297 mX.append( pt.
x() );
1298 mY.append( pt.
y() );
1301 mZ.append( pt.
z() );
1305 mM.append( pt.
m() );
1312 double sqrDist = std::numeric_limits<double>::max();
1313 double leftOfDist = std::numeric_limits<double>::max();
1315 double prevLeftOfX = 0.0;
1316 double prevLeftOfY = 0.0;
1317 double testDist = 0;
1318 double segmentPtX, segmentPtY;
1323 int size = mX.size();
1324 if ( size == 0 || size == 1 )
1329 for (
int i = 1; i < size; ++i )
1331 double prevX = mX.at( i - 1 );
1332 double prevY = mY.at( i - 1 );
1333 double currentX = mX.at( i );
1334 double currentY = mY.at( i );
1336 if ( testDist < sqrDist )
1339 segmentPt.
setX( segmentPtX );
1340 segmentPt.
setY( segmentPtY );
1341 vertexAfter.
part = 0;
1342 vertexAfter.
ring = 0;
1353 if (
qgsDoubleNear( testDist, leftOfDist ) && left != prevLeftOf && prevLeftOf != 0 )
1366 leftOfDist = testDist;
1367 prevLeftOfX = prevX;
1368 prevLeftOfY = prevY;
1370 else if ( testDist < leftOfDist )
1373 leftOfDist = testDist;
1405 return QgsPoint( mX.at( 0 ), mY.at( 0 ) );
1407 double totalLineLength = 0.0;
1408 double prevX = mX.at( 0 );
1409 double prevY = mY.at( 0 );
1415 double currentX = mX.at( i );
1416 double currentY = mY.at( i );
1417 double segmentLength = std::sqrt( std::pow( currentX - prevX, 2.0 ) +
1418 std::pow( currentY - prevY, 2.0 ) );
1430 return QgsPoint( mX.at( 0 ), mY.at( 0 ) );
1432 return QgsPoint( sumX / totalLineLength, sumY / totalLineLength );
1446 for (
int i = 0; i < maxIndex; ++i )
1448 sum += 0.5 * ( mX.at( i ) * mY.at( i + 1 ) - mY.at( i ) * mX.at( i + 1 ) );
1452 void QgsLineString::importVerticesFromWkb(
const QgsConstWkbPtr &wkb )
1458 mX.resize( nVertices );
1459 mY.resize( nVertices );
1460 hasZ ? mZ.resize( nVertices ) : mZ.clear();
1461 hasM ? mM.resize( nVertices ) : mM.clear();
1462 double *x = mX.data();
1463 double *y = mY.data();
1464 double *m = hasM ? mM.data() :
nullptr;
1465 double *z = hasZ ? mZ.data() :
nullptr;
1466 for (
int i = 0; i < nVertices; ++i )
1499 if ( mX.count() < 2 )
1509 double previousX = mX.at(
numPoints() - 2 );
1510 double previousY = mY.at(
numPoints() - 2 );
1511 double currentX = mX.at( 0 );
1512 double currentY = mY.at( 0 );
1513 double afterX = mX.at( 1 );
1514 double afterY = mY.at( 1 );
1517 else if ( vertex.
vertex == 0 )
1530 double previousX = mX.at( vertex.
vertex - 1 );
1531 double previousY = mY.at( vertex.
vertex - 1 );
1532 double currentX = mX.at( vertex.
vertex );
1533 double currentY = mY.at( vertex.
vertex );
1534 double afterX = mX.at( vertex.
vertex + 1 );
1535 double afterY = mY.at( vertex.
vertex + 1 );
1542 if ( startVertex.
vertex < 0 || startVertex.
vertex >= mX.count() - 1 )
1545 double dx = mX.at( startVertex.
vertex + 1 ) - mX.at( startVertex.
vertex );
1546 double dy = mY.at( startVertex.
vertex + 1 ) - mY.at( startVertex.
vertex );
1547 return std::sqrt( dx * dx + dy * dy );
1572 mZ.reserve( nPoints );
1573 for (
int i = 0; i < nPoints; ++i )
1603 mM.reserve( nPoints );
1604 for (
int i = 0; i < nPoints; ++i )
1635 std::swap( mX, mY );
1649 addZValue( std::numeric_limits<double>::quiet_NaN() );
1663 int size = mX.size();
1665 double *srcX = mX.data();
1666 double *srcY = mY.data();
1667 double *srcM = hasM ? mM.data() :
nullptr;
1668 double *srcZ = hasZ ? mZ.data() :
nullptr;
1670 double *destX = srcX;
1671 double *destY = srcY;
1672 double *destM = srcM;
1673 double *destZ = srcZ;
1675 int filteredPoints = 0;
1676 for (
int i = 0; i < size; ++i )
1680 double z = hasZ ? *srcZ++ : std::numeric_limits<double>::quiet_NaN();
1681 double m = hasM ? *srcM++ : std::numeric_limits<double>::quiet_NaN();
1683 if ( filter(
QgsPoint( x, y, z, m ) ) )
1695 mX.resize( filteredPoints );
1696 mY.resize( filteredPoints );
1698 mZ.resize( filteredPoints );
1700 mM.resize( filteredPoints );
1709 int size = mX.size();
1711 double *srcX = mX.data();
1712 double *srcY = mY.data();
1713 double *srcM = hasM ? mM.data() :
nullptr;
1714 double *srcZ = hasZ ? mZ.data() :
nullptr;
1716 for (
int i = 0; i < size; ++i )
1720 double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
1721 double m = hasM ? *srcM : std::numeric_limits<double>::quiet_NaN();
Abstract base class for curved geometry type.
double endX() const
Returns the segment's end x-coordinate.
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) override SIP_THROW(QgsCsException)
Transforms the geometry using a coordinate transform.
void setY(double y)
Sets the point's y-coordinate.
QgsPoint pointN(int i) const
Returns the specified point from inside the line string.
void setYAt(int index, double y)
Sets the y-coordinate of the specified node in the line string.
double xAt(int index) const override
Returns the x-coordinate of the specified node in the line string.
const double * zData() const
Returns a const pointer to the z vertex data, or nullptr if the linestring does not have z values.
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the geometry.
void setPoints(const QgsPointSequence &points)
Resets the line string to match the specified list of points.
static json pointsToJson(const QgsPointSequence &points, int precision)
Returns coordinates as json object.
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
Point geometry type, with support for z-dimension and m-values.
static QgsPoint pointOnLineWithDistance(const QgsPoint &startPoint, const QgsPoint &directionPoint, double distance)
Returns a point a specified distance toward a second point.
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.
int dimension() const override
Returns the inherent dimension of the geometry.
int numPoints() const override
Returns the number of points in the curve.
void addToPainterPath(QPainterPath &path) const override
Adds a curve to a painter path.
double yAt(int index) const override
Returns the y-coordinate of the specified node in the line string.
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry.
QgsPoint centroid() const override
Returns the centroid of the geometry.
void addCurve(QgsCurve *c)
Adds a curve to the geometry (takes ownership)
QgsPoint endPoint() const override
Returns the end 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.
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.
QString wktTypeStr() const
Returns the WKT type string of the geometry.
void drawAsPolygon(QPainter &p) const override
Draws the curve as a polygon on the specified QPainter.
const double * yData() const
Returns a const pointer to the y vertex data.
int nCoordinates() const override
Returns the number of nodes contained in the geometry.
double segmentLength(QgsVertexId startVertex) const override
Returns the length of the segment of the geometry which begins at startVertex.
void setXAt(int index, double x)
Sets the x-coordinate of the specified node in the line string.
Type
The WKB type describes the number of dimensions a geometry has.
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
QgsWkbTypes::Type mWkbType
static Type dropM(Type type)
Drops the m dimension (if present) for a WKB type and returns the new type.
Line string geometry type, with support for z-dimension and m-values.
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type.
void draw(QPainter &p) const override
Draws the geometry using the specified QPainter.
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
QgsCompoundCurve * toCurveType() const override
Returns the geometry converted to the more generic curve type QgsCompoundCurve.
static QgsPointSequence pointsFromWKT(const QString &wktCoordinateList, bool is3D, bool isMeasure)
Returns a list of points contained in a WKT string.
const double * xData() const
Returns a const pointer to the x vertex data.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
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,...
double startY() const
Returns the segment's start y-coordinate.
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 ...
QgsLineString * clone() const override
Clones the geometry by performing a deep copy.
QString asKml(int precision=17) const override
Returns a KML representation of the geometry.
QString geometryType() const override
Returns a unique string representing the geometry type.
bool pointAt(int node, QgsPoint &point, QgsVertexId::VertexType &type) const override
Returns the point and vertex id of a point within the curve.
AxisOrder
Axis order for GML generation.
bool convertTo(QgsWkbTypes::Type type) override
Converts the geometry to a specified type.
bool insertVertex(QgsVertexId position, const QgsPoint &vertex) override
Inserts a vertex into the geometry.
static void pointsToWKB(QgsWkbPtr &wkb, const QgsPointSequence &points, bool is3D, bool isMeasure)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
void setX(double x)
Sets the point's x-coordinate.
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.
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
QPolygonF asQPolygonF() const override
Returns a QPolygonF representing the points.
QByteArray asWkb(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
virtual bool isRing() const
Returns true if the curve is a ring.
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,...
json asJsonObject(int precision=17) const override
Returns a json object representation of the geometry.
static QgsLineString * fromQPolygonF(const QPolygonF &polygon)
Returns a new linestring from a QPolygonF polygon input.
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.
static endian_t endian()
Returns whether this machine uses big or little endian.
void clear() override
Clears the geometry, ie reset it to a null geometry.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
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.
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.
const double * mData() const
Returns a const pointer to the m vertex data, or nullptr if the linestring does not have m values.
void sumUpArea(double &sum) const override
Sums up the area of the curve by iterating over the vertices (shoelace formula).
QgsPoint startPoint() const override
Returns the starting point of the curve.
QgsPoint * interpolatePoint(double distance) const override
Returns an interpolated point on the curve at the specified distance.
QgsLineString * curveSubstring(double startDistance, double endDistance) const override
Returns a new curve representing a substring of this curve.
void extend(double startDistance, double endDistance)
Extends the line geometry by extrapolating out the start or end of the line by a specified distance.
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type.
bool dropMValue() override
Drops any measure values which exist in the geometry.
static Type zmType(Type type, bool hasZ, bool hasM)
Returns the modified input geometry type according to hasZ / hasM.
bool isEmpty() const override
Returns true if the geometry is empty.
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.
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
static bool hasM(Type type)
Tests whether a WKB type contains m values.
void append(const QgsLineString *line)
Appends the contents of another line string to the end of this line string.
virtual bool isClosed() const
Returns true if the curve is closed.
void swapXy() override
Swaps the x and y coordinates from the geometry.
QVector< QgsPoint > QgsPointSequence
void close()
Closes the line string by appending the first point to the end of the line, if it is not already clos...
void addVertex(const QgsPoint &pt)
Adds a new vertex to the end of the line string.
static QString pointsToWKT(const QgsPointSequence &points, int precision, bool is3D, bool isMeasure)
Returns a WKT coordinate list.
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...
Utility class for identifying a unique vertex within a geometry.
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 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).
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
bool isMeasure() const
Returns true if the geometry contains m values.
QgsRectangle calculateBoundingBox() const override
Default calculator for the minimal bounding box for the geometry.
bool fromWkb(QgsConstWkbPtr &wkb) override
Sets the geometry from a WKB string.
virtual bool convertTo(QgsWkbTypes::Type type)
Converts the geometry to a specified type.
double endY() const
Returns the segment's end y-coordinate.
double startX() const
Returns the segment's start x-coordinate.
bool equals(const QgsCurve &other) const override
Checks whether this curve exactly equals another curve.
static Type dropZ(Type type)
Drops the z dimension (if present) for a WKB type and returns the new type.
QgsWkbTypes::Type readHeader() const
readHeader
QgsLineString * reversed() const override
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
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 (...
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, QgsWkbTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
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.
void points(QgsPointSequence &pt) const override
Returns a list of points within the curve.
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...
double length() const override
Returns the planar, 2-dimensional length of the geometry.
QgsLineString * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
double length3D() const
Returns the length in 3D world of the line string.
double vertexAngle(QgsVertexId vertex) const override
Returns approximate angle at a vertex.
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 Type flatType(Type type)
Returns the flat type for a WKB type.
Compound curve geometry type.
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.
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.