27 #include <nlohmann/json.hpp> 32 #include <QDomDocument> 33 #include <QJsonObject> 49 if ( points.isEmpty() )
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();
187 if ( mX.count() != otherLine->mX.count() )
190 for (
int i = 0; i < mX.count(); ++i )
231 bool res =
snapToGridPrivate( hSpacing, vSpacing, dSpacing, mSpacing, mX, mY, mZ, mM,
232 result->mX, result->mY, result->mZ, result->mM );
234 return result.release();
241 if ( mX.count() <= 2 )
244 double prevX = mX.at( 0 );
245 double prevY = mY.at( 0 );
247 bool useZ = hasZ && useZValues;
248 double prevZ = useZ ? mZ.at( 0 ) : 0;
250 int remaining = mX.count();
251 while ( i < remaining )
253 double currentX = mX.at( i );
254 double currentY = mY.at( i );
255 double currentZ = useZ ? mZ.at( i ) : 0;
281 const int nb = mX.size();
284 const double *x = mX.constData();
285 const double *y = mY.constData();
286 QPointF *dest = points.data();
287 for (
int i = 0; i < nb; ++i )
289 *dest++ = QPointF( *x++, *y++ );
307 importVerticesFromWkb( wkbPtr );
313 double xmin = std::numeric_limits<double>::max();
314 double ymin = std::numeric_limits<double>::max();
315 double xmax = -std::numeric_limits<double>::max();
316 double ymax = -std::numeric_limits<double>::max();
318 for (
double x : mX )
325 for (
double y : mY )
357 int binarySize =
sizeof( char ) +
sizeof( quint32 ) +
sizeof( quint32 );
361 wkbArray.resize( binarySize );
364 wkb << static_cast<quint32>(
wkbType() );
391 QDomElement elemLineString = doc.createElementNS( ns, QStringLiteral(
"LineString" ) );
394 return elemLineString;
398 return elemLineString;
406 QDomElement elemLineString = doc.createElementNS( ns, QStringLiteral(
"LineString" ) );
409 return elemLineString;
412 return elemLineString;
421 {
"type",
"LineString" },
435 int size = mX.size();
437 for (
int i = 1; i < size; ++i )
439 dx = mX.at( i ) - mX.at( i - 1 );
440 dy = mY.at( i ) - mY.at( i - 1 );
441 length += std::sqrt( dx * dx + dy * dy );
472 Q_UNUSED( tolerance )
473 Q_UNUSED( toleranceType )
489 if ( i < 0 || i >= mX.size() )
494 double x = mX.at( i );
495 double y = mY.at( i );
496 double z = std::numeric_limits<double>::quiet_NaN();
497 double m = std::numeric_limits<double>::quiet_NaN();
515 else if ( hasZ && hasM )
538 if ( index >= 0 && index < mX.size() )
539 return mX.at( index );
546 if ( index >= 0 && index < mY.size() )
547 return mY.at( index );
554 if ( index >= 0 && index < mX.size() )
561 if ( index >= 0 && index < mY.size() )
576 for (
int i = 0; i < nPoints; ++i )
578 pts.push_back(
pointN( i ) );
586 if ( points.isEmpty() )
593 const QgsPoint &firstPt = points.at( 0 );
594 bool hasZ = firstPt.
is3D();
599 mX.resize( points.size() );
600 mY.resize( points.size() );
603 mZ.resize( points.size() );
611 mM.resize( points.size() );
618 for (
int i = 0; i < points.size(); ++i )
620 mX[i] = points.at( i ).x();
621 mY[i] = points.at( i ).y();
624 double z = points.at( i ).z();
625 mZ[i] = std::isnan( z ) ? 0 : z;
629 double m = points.at( i ).m();
630 mM[i] = std::isnan( m ) ? 0 : m;
683 mZ.insert( mZ.count(), mX.size() - mZ.size(), std::numeric_limits<double>::quiet_NaN() );
696 mM.insert( mM.count(), mX.size() - mM.size(), std::numeric_limits<double>::quiet_NaN() );
706 std::reverse( copy->mX.begin(), copy->mX.end() );
707 std::reverse( copy->mY.begin(), copy->mY.end() );
710 std::reverse( copy->mZ.begin(), copy->mZ.end() );
714 std::reverse( copy->mM.begin(), copy->mM.end() );
724 double distanceTraversed = 0;
726 if ( totalPoints == 0 )
729 const double *x = mX.constData();
730 const double *y = mY.constData();
731 const double *z =
is3D() ? mZ.constData() :
nullptr;
732 const double *m =
isMeasure() ? mM.constData() :
nullptr;
742 double prevZ = z ? *z++ : 0.0;
743 double prevM = m ? *m++ : 0.0;
747 return new QgsPoint( pointType, prevX, prevY, prevZ, prevM );
750 for (
int i = 1; i < totalPoints; ++i )
754 double thisZ = z ? *z++ : 0.0;
755 double thisM = m ? *m++ : 0.0;
757 const double segmentLength = std::sqrt( ( thisX - prevX ) * ( thisX - prevX ) + ( thisY - prevY ) * ( thisY - prevY ) );
758 if ( distance < distanceTraversed + segmentLength ||
qgsDoubleNear( distance, distanceTraversed + segmentLength ) )
761 const double distanceToPoint = std::min( distance - distanceTraversed, segmentLength );
766 z ? &prevZ :
nullptr, z ? &thisZ :
nullptr, z ? &pZ :
nullptr,
767 m ? &prevM :
nullptr, m ? &thisM :
nullptr, m ? &pM :
nullptr );
768 return new QgsPoint( pointType, pX, pY, pZ, pM );
783 if ( startDistance < 0 && endDistance < 0 )
786 endDistance = std::max( startDistance, endDistance );
788 double distanceTraversed = 0;
790 if ( totalPoints == 0 )
793 QVector< QgsPoint > substringPoints;
801 const double *x = mX.constData();
802 const double *y = mY.constData();
803 const double *z =
is3D() ? mZ.constData() :
nullptr;
804 const double *m =
isMeasure() ? mM.constData() :
nullptr;
808 double prevZ = z ? *z++ : 0.0;
809 double prevM = m ? *m++ : 0.0;
810 bool foundStart =
false;
812 if (
qgsDoubleNear( startDistance, 0.0 ) || startDistance < 0 )
814 substringPoints <<
QgsPoint( pointType, prevX, prevY, prevZ, prevM );
818 substringPoints.reserve( totalPoints );
820 for (
int i = 1; i < totalPoints; ++i )
824 double thisZ = z ? *z++ : 0.0;
825 double thisM = m ? *m++ : 0.0;
827 const double segmentLength = std::sqrt( ( thisX - prevX ) * ( thisX - prevX ) + ( thisY - prevY ) * ( thisY - prevY ) );
828 if ( distanceTraversed < startDistance && distanceTraversed + segmentLength > startDistance )
831 const double distanceToStart = startDistance - distanceTraversed;
832 double startX, startY;
836 z ? &prevZ :
nullptr, z ? &thisZ :
nullptr, z ? &startZ :
nullptr,
837 m ? &prevM :
nullptr, m ? &thisM :
nullptr, m ? &startM :
nullptr );
838 substringPoints <<
QgsPoint( pointType, startX, startY, startZ, startM );
841 if ( foundStart && ( distanceTraversed + segmentLength > endDistance ) )
844 const double distanceToEnd = endDistance - distanceTraversed;
849 z ? &prevZ :
nullptr, z ? &thisZ :
nullptr, z ? &endZ :
nullptr,
850 m ? &prevM :
nullptr, m ? &thisM :
nullptr, m ? &endM :
nullptr );
851 substringPoints <<
QgsPoint( pointType, endX, endY, endZ, endM );
853 else if ( foundStart )
855 substringPoints <<
QgsPoint( pointType, thisX, thisY, thisZ, thisM );
859 if ( distanceTraversed > endDistance )
890 if ( path.isEmpty() || path.currentPosition() != QPointF( mX.at( 0 ), mY.at( 0 ) ) )
892 path.moveTo( mX.at( 0 ), mY.at( 0 ) );
895 for (
int i = 1; i < nPoints; ++i )
897 path.lineTo( mX.at( i ), mY.at( i ) );
910 return compoundCurve;
915 if ( mX.size() < 2 || mY.size() < 2 )
919 if ( startDistance > 0 )
921 double currentLen = std::sqrt( std::pow( mX.at( 0 ) - mX.at( 1 ), 2 ) +
922 std::pow( mY.at( 0 ) - mY.at( 1 ), 2 ) );
923 double newLen = currentLen + startDistance;
924 mX[ 0 ] = mX.at( 1 ) + ( mX.at( 0 ) - mX.at( 1 ) ) / currentLen * newLen;
925 mY[ 0 ] = mY.at( 1 ) + ( mY.at( 0 ) - mY.at( 1 ) ) / currentLen * newLen;
928 if ( endDistance > 0 )
930 int last = mX.size() - 1;
931 double currentLen = std::sqrt( std::pow( mX.at( last ) - mX.at( last - 1 ), 2 ) +
932 std::pow( mY.at( last ) - mY.at( last - 1 ), 2 ) );
933 double newLen = currentLen + endDistance;
934 mX[ last ] = mX.at( last - 1 ) + ( mX.at( last ) - mX.at( last - 1 ) ) / currentLen * newLen;
935 mY[ last ] = mY.at( last - 1 ) + ( mY.at( last ) - mY.at( last - 1 ) ) / currentLen * newLen;
941 auto result = qgis::make_unique< QgsLineString >();
943 return result.release();
948 return QStringLiteral(
"LineString" );
964 double *zArray =
nullptr;
970 std::unique_ptr< double[] > dummyZ;
971 if ( !hasZ || !transformZ )
973 dummyZ.reset(
new double[nPoints]() );
974 zArray = dummyZ.get();
989 for (
int i = 0; i < nPoints; ++i )
992 t.map( mX.at( i ), mY.at( i ), &x, &y );
997 mZ[i] = mZ.at( i ) * zScale + zTranslate;
1001 mM[i] = mM.at( i ) * mScale + mTranslate;
1015 if ( position.
vertex < 0 || position.
vertex > mX.size() )
1025 mX.insert( position.
vertex, vertex.
x() );
1026 mY.insert( position.
vertex, vertex.
y() );
1029 mZ.insert( position.
vertex, vertex.
z() );
1033 mM.insert( position.
vertex, vertex.
m() );
1041 if ( position.
vertex < 0 || position.
vertex >= mX.size() )
1045 mX[position.
vertex] = newPos.
x();
1046 mY[position.
vertex] = newPos.
y();
1049 mZ[position.
vertex] = newPos.
z();
1053 mM[position.
vertex] = newPos.
m();
1061 if ( position.
vertex >= mX.size() || position.
vertex < 0 )
1066 mX.remove( position.
vertex );
1067 mY.remove( position.
vertex );
1070 mZ.remove( position.
vertex );
1074 mM.remove( position.
vertex );
1099 mX.append( pt.
x() );
1100 mY.append( pt.
y() );
1103 mZ.append( pt.
z() );
1107 mM.append( pt.
m() );
1114 double sqrDist = std::numeric_limits<double>::max();
1115 double leftOfDist = std::numeric_limits<double>::max();
1117 double prevLeftOfX = 0.0;
1118 double prevLeftOfY = 0.0;
1119 double testDist = 0;
1120 double segmentPtX, segmentPtY;
1125 int size = mX.size();
1126 if ( size == 0 || size == 1 )
1131 for (
int i = 1; i < size; ++i )
1133 double prevX = mX.at( i - 1 );
1134 double prevY = mY.at( i - 1 );
1135 double currentX = mX.at( i );
1136 double currentY = mY.at( i );
1138 if ( testDist < sqrDist )
1141 segmentPt.
setX( segmentPtX );
1142 segmentPt.
setY( segmentPtY );
1143 vertexAfter.
part = 0;
1144 vertexAfter.
ring = 0;
1155 if (
qgsDoubleNear( testDist, leftOfDist ) && left != prevLeftOf && prevLeftOf != 0 )
1168 leftOfDist = testDist;
1169 prevLeftOfX = prevX;
1170 prevLeftOfY = prevY;
1172 else if ( testDist < leftOfDist )
1175 leftOfDist = testDist;
1206 if ( numPoints == 1 )
1207 return QgsPoint( mX.at( 0 ), mY.at( 0 ) );
1209 double totalLineLength = 0.0;
1210 double prevX = mX.at( 0 );
1211 double prevY = mY.at( 0 );
1217 double currentX = mX.at( i );
1218 double currentY = mY.at( i );
1219 double segmentLength = std::sqrt( std::pow( currentX - prevX, 2.0 ) +
1220 std::pow( currentY - prevY, 2.0 ) );
1225 sumX += segmentLength * 0.5 * ( currentX + prevX );
1226 sumY += segmentLength * 0.5 * ( currentY + prevY );
1232 return QgsPoint( mX.at( 0 ), mY.at( 0 ) );
1234 return QgsPoint( sumX / totalLineLength, sumY / totalLineLength );
1248 for (
int i = 0; i < maxIndex; ++i )
1250 sum += 0.5 * ( mX.at( i ) * mY.at( i + 1 ) - mY.at( i ) * mX.at( i + 1 ) );
1254 void QgsLineString::importVerticesFromWkb(
const QgsConstWkbPtr &wkb )
1260 mX.resize( nVertices );
1261 mY.resize( nVertices );
1262 hasZ ? mZ.resize( nVertices ) : mZ.clear();
1263 hasM ? mM.resize( nVertices ) : mM.clear();
1264 double *x = mX.data();
1265 double *y = mY.data();
1266 double *m = hasM ? mM.data() :
nullptr;
1267 double *z = hasZ ? mZ.data() :
nullptr;
1268 for (
int i = 0; i < nVertices; ++i )
1301 if ( mX.count() < 2 )
1311 double previousX = mX.at(
numPoints() - 2 );
1312 double previousY = mY.at(
numPoints() - 2 );
1313 double currentX = mX.at( 0 );
1314 double currentY = mY.at( 0 );
1315 double afterX = mX.at( 1 );
1316 double afterY = mY.at( 1 );
1319 else if ( vertex.
vertex == 0 )
1332 double previousX = mX.at( vertex.
vertex - 1 );
1333 double previousY = mY.at( vertex.
vertex - 1 );
1334 double currentX = mX.at( vertex.
vertex );
1335 double currentY = mY.at( vertex.
vertex );
1336 double afterX = mX.at( vertex.
vertex + 1 );
1337 double afterY = mY.at( vertex.
vertex + 1 );
1344 if ( startVertex.
vertex < 0 || startVertex.
vertex >= mX.count() - 1 )
1347 double dx = mX.at( startVertex.
vertex + 1 ) - mX.at( startVertex.
vertex );
1348 double dy = mY.at( startVertex.
vertex + 1 ) - mY.at( startVertex.
vertex );
1349 return std::sqrt( dx * dx + dy * dy );
1374 mZ.reserve( nPoints );
1375 for (
int i = 0; i < nPoints; ++i )
1405 mM.reserve( nPoints );
1406 for (
int i = 0; i < nPoints; ++i )
1437 std::swap( mX, mY );
1451 addZValue( std::numeric_limits<double>::quiet_NaN() );
1465 int size = mX.size();
1467 double *srcX = mX.data();
1468 double *srcY = mY.data();
1469 double *srcM = hasM ? mM.data() :
nullptr;
1470 double *srcZ = hasZ ? mZ.data() :
nullptr;
1472 double *destX = srcX;
1473 double *destY = srcY;
1474 double *destM = srcM;
1475 double *destZ = srcZ;
1477 int filteredPoints = 0;
1478 for (
int i = 0; i < size; ++i )
1482 double z = hasZ ? *srcZ++ : std::numeric_limits<double>::quiet_NaN();
1483 double m = hasM ? *srcM++ : std::numeric_limits<double>::quiet_NaN();
1485 if ( filter(
QgsPoint( x, y, z, m ) ) )
1497 mX.resize( filteredPoints );
1498 mY.resize( filteredPoints );
1500 mZ.resize( filteredPoints );
1502 mM.resize( filteredPoints );
1511 int size = mX.size();
1513 double *srcX = mX.data();
1514 double *srcY = mY.data();
1515 double *srcM = hasM ? mM.data() :
nullptr;
1516 double *srcZ = hasZ ? mZ.data() :
nullptr;
1518 for (
int i = 0; i < size; ++i )
1522 double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
1523 double m = hasM ? *srcM : std::numeric_limits<double>::quiet_NaN();
bool isMeasure() const
Returns true if the geometry contains m values.
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
void append(const QgsLineString *line)
Appends the contents of another line string to the end of this line string.
A rectangle specified with double values.
bool isEmpty() const override
Returns true if the geometry is empty.
void setPoints(const QgsPointSequence &points)
Resets the line string to match the specified list of points.
void points(QgsPointSequence &pt) const override
Returns a list of points within the curve.
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.
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
int dimension() const override
Returns the inherent dimension of the geometry.
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 QPair< QgsWkbTypes::Type, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
static double averageAngle(double x1, double y1, double x2, double y2, double x3, double y3)
Calculates the average angle (in radians) between the two linear segments from (x1, y1) to (x2, y2) and (x2, y2) to (x3, y3).
QString geometryType() const override
Returns a unique string representing the geometry type.
bool fromWkb(QgsConstWkbPtr &wkb) override
Sets the geometry from a WKB string.
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.
A class to represent a 2D point.
double endY() const
Returns the segment's end y-coordinate.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
json asJsonObject(int precision=17) const override
Returns a json object representation of the geometry.
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.
QgsLineString * curveSubstring(double startDistance, double endDistance) const override
Returns a new curve representing a substring of this curve.
void setYAt(int index, double y)
Sets the y-coordinate of the specified node in the line string.
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle...
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.
bool pointAt(int node, QgsPoint &point, QgsVertexId::VertexType &type) const override
Returns the point and vertex id of a point within the curve.
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.
QgsPoint endPoint() const override
Returns the end point of the curve.
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
static Type dropM(Type type)
Drops the m dimension (if present) for a WKB type and returns the new type.
void setXAt(int index, double x)
Sets the x-coordinate of the specified node in the line string.
void addCurve(QgsCurve *c)
Adds a curve to the geometry (takes ownership)
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.
QgsWkbTypes::Type mWkbType
int numPoints() const override
Returns the number of points in the curve.
bool convertTo(QgsWkbTypes::Type type) override
Converts the geometry to a specified type.
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.
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
static QString pointsToWKT(const QgsPointSequence &points, int precision, bool is3D, bool isMeasure)
Returns a WKT coordinate list.
Type
The WKB type describes the number of dimensions a geometry has.
double startX() const
Returns the segment's start x-coordinate.
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
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 Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type.
void addVertex(const QgsPoint &pt)
Adds a new vertex to the end of the line string.
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry.
QPolygonF asQPolygonF() const override
Returns a QPolygonF representing the points.
Utility class for identifying a unique vertex within a geometry.
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 * reversed() const override
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
bool equals(const QgsCurve &other) const override
Checks whether this curve exactly equals another curve.
double yAt(int index) const override
Returns the y-coordinate of the specified node in the line string.
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 setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, QgsWkbTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type.
T qgsgeometry_cast(const QgsAbstractGeometry *geom)
void close()
Closes the line string by appending the first point to the end of the line, if it is not already clos...
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) override SIP_THROW(QgsCsException)
Transforms the geometry using a coordinate transform.
Abstract base class for curved geometry type.
void swapXy() override
Swaps the x and y coordinates from the geometry.
void sumUpArea(double &sum) const override
Sums up the area of the curve by iterating over the vertices (shoelace formula).
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the geometry.
Point geometry type, with support for z-dimension and m-values.
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
AxisOrder
Axis order for GML generation.
QgsPoint startPoint() const override
Returns the starting point of the curve.
Represents a single 2D line segment, consisting of a 2D start and end vertex only.
QgsLineString * clone() const override
Clones the geometry by performing a deep copy.
static json pointsToJson(const QgsPointSequence &points, int precision)
Returns coordinates as json object.
void setX(double x)
Sets the point's x-coordinate.
virtual bool isClosed() const
Returns true if the curve is closed.
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.
double segmentLength(QgsVertexId startVertex) const override
Returns the length of the segment of the geometry which begins at startVertex.
void setY(double y)
Sets the point's y-coordinate.
QVector< QgsPoint > QgsPointSequence
static QgsPoint pointOnLineWithDistance(const QgsPoint &startPoint, const QgsPoint &directionPoint, double distance)
Returns a point a specified distance toward a second point.
QgsPoint * interpolatePoint(double distance) const override
Returns an interpolated point on the curve at the specified distance.
double endX() const
Returns the segment's end x-coordinate.
static Type dropZ(Type type)
Drops the z dimension (if present) for a WKB type and returns the new type.
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 drawAsPolygon(QPainter &p) const override
Draws the curve as a polygon on the specified QPainter.
static QgsPointSequence pointsFromWKT(const QString &wktCoordinateList, bool is3D, bool isMeasure)
Returns a list of points contained in a WKT string.
double vertexAngle(QgsVertexId vertex) const override
Returns approximate angle at a vertex.
Line string geometry type, with support for z-dimension and m-values.
QByteArray asWkb() const override
Returns a WKB representation of the geometry.
QgsPoint pointN(int i) const
Returns the specified point from inside the line string.
void addToPainterPath(QPainterPath &path) const override
Adds a curve to a painter path.
bool dropMValue() override
Drops any measure values which exist in the geometry.
static void pointsToWKB(QgsWkbPtr &wkb, const QgsPointSequence &points, bool is3D, bool isMeasure)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }.
double xAt(int index) const override
Returns the x-coordinate of the specified node in the line string.
static Type zmType(Type type, bool hasZ, bool hasM)
Returns the modified input geometry type according to hasZ / hasM.
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.
virtual bool convertTo(QgsWkbTypes::Type type)
Converts the geometry to a specified type.
static bool hasM(Type type)
Tests whether a WKB type contains m values.
Compound curve geometry type.
QgsRectangle calculateBoundingBox() const override
Default calculator for the minimal bounding box for 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 length() const override
Returns the length of the geometry.
QgsCompoundCurve * toCurveType() const override
Returns the geometry converted to the more generic curve type QgsCompoundCurve.
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...
double startY() const
Returns the segment's start y-coordinate.
int nCoordinates() const override
Returns the number of nodes contained in the geometry.
static Type flatType(Type type)
Returns the flat type for a WKB type.
QgsWkbTypes::Type readHeader() const
readHeader
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
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'. Negativ values mean left a...
bool insertVertex(QgsVertexId position, const QgsPoint &vertex) override
Inserts a vertex into the geometry.
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
void draw(QPainter &p) const override
Draws the geometry using the specified QPainter.
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
void extend(double startDistance, double endDistance)
Extends the line geometry by extrapolating out the start or end of the line by a specified distance...