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();
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 )
217 *xData++ = start.
x();
218 *yData++ = start.
y();
220 *zData++ = start.
z();
222 *mData++ = start.
m();
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 )
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" },
530 int size = mX.size();
532 for (
int i = 1; i < size; ++i )
534 dx = mX.at( i ) - mX.at( i - 1 );
535 dy = mY.at( i ) - mY.at( i - 1 );
536 length += std::sqrt( dx * dx + dy * dy );
546 int size = mX.size();
548 for (
int i = 1; i < size; ++i )
550 dx = mX.at( i ) - mX.at( i - 1 );
551 dy = mY.at( i ) - mY.at( i - 1 );
552 dz = mZ.at( i ) - mZ.at( i - 1 );
553 length += std::sqrt( dx * dx + dy * dy + dz * dz );
589 Q_UNUSED( tolerance )
590 Q_UNUSED( toleranceType )
606 if ( i < 0 || i >= mX.size() )
611 double x = mX.at( i );
612 double y = mY.at( i );
613 double z = std::numeric_limits<double>::quiet_NaN();
614 double m = std::numeric_limits<double>::quiet_NaN();
632 else if ( hasZ && hasM )
655 if ( index >= 0 && index < mX.size() )
656 return mX.at( index );
663 if ( index >= 0 && index < mY.size() )
664 return mY.at( index );
671 if ( index >= 0 && index < mX.size() )
678 if ( index >= 0 && index < mY.size() )
693 pts.reserve( nPoints );
694 for (
int i = 0; i < nPoints; ++i )
696 pts.push_back(
pointN( i ) );
704 if ( points.isEmpty() )
711 const QgsPoint &firstPt = points.at( 0 );
712 bool hasZ = firstPt.
is3D();
717 mX.resize( points.size() );
718 mY.resize( points.size() );
721 mZ.resize( points.size() );
729 mM.resize( points.size() );
736 for (
int i = 0; i < points.size(); ++i )
738 mX[i] = points.at( i ).x();
739 mY[i] = points.at( i ).y();
742 double z = points.at( i ).z();
743 mZ[i] = std::isnan( z ) ? 0 : z;
747 double m = points.at( i ).m();
748 mM[i] = std::isnan( m ) ? 0 : m;
801 mZ.insert( mZ.count(), mX.size() - mZ.size(), std::numeric_limits<double>::quiet_NaN() );
814 mM.insert( mM.count(), mX.size() - mM.size(), std::numeric_limits<double>::quiet_NaN() );
824 std::reverse( copy->mX.begin(), copy->mX.end() );
825 std::reverse( copy->mY.begin(), copy->mY.end() );
828 std::reverse( copy->mZ.begin(), copy->mZ.end() );
832 std::reverse( copy->mM.begin(), copy->mM.end() );
842 double distanceTraversed = 0;
844 if ( totalPoints == 0 )
847 const double *x = mX.constData();
848 const double *y = mY.constData();
849 const double *z =
is3D() ? mZ.constData() :
nullptr;
850 const double *m =
isMeasure() ? mM.constData() :
nullptr;
860 double prevZ = z ? *z++ : 0.0;
861 double prevM = m ? *m++ : 0.0;
865 return new QgsPoint( pointType, prevX, prevY, prevZ, prevM );
868 for (
int i = 1; i < totalPoints; ++i )
872 double thisZ = z ? *z++ : 0.0;
873 double thisM = m ? *m++ : 0.0;
875 const double segmentLength = std::sqrt( ( thisX - prevX ) * ( thisX - prevX ) + ( thisY - prevY ) * ( thisY - prevY ) );
876 if ( distance < distanceTraversed + segmentLength ||
qgsDoubleNear( distance, distanceTraversed + segmentLength ) )
879 const double distanceToPoint = std::min( distance - distanceTraversed, segmentLength );
884 z ? &prevZ :
nullptr, z ? &thisZ :
nullptr, z ? &pZ :
nullptr,
885 m ? &prevM :
nullptr, m ? &thisM :
nullptr, m ? &pM :
nullptr );
886 return new QgsPoint( pointType, pX, pY, pZ, pM );
901 if ( startDistance < 0 && endDistance < 0 )
904 endDistance = std::max( startDistance, endDistance );
906 double distanceTraversed = 0;
908 if ( totalPoints == 0 )
911 QVector< QgsPoint > substringPoints;
919 const double *x = mX.constData();
920 const double *y = mY.constData();
921 const double *z =
is3D() ? mZ.constData() :
nullptr;
922 const double *m =
isMeasure() ? mM.constData() :
nullptr;
926 double prevZ = z ? *z++ : 0.0;
927 double prevM = m ? *m++ : 0.0;
928 bool foundStart =
false;
930 if (
qgsDoubleNear( startDistance, 0.0 ) || startDistance < 0 )
932 substringPoints <<
QgsPoint( pointType, prevX, prevY, prevZ, prevM );
936 substringPoints.reserve( totalPoints );
938 for (
int i = 1; i < totalPoints; ++i )
942 double thisZ = z ? *z++ : 0.0;
943 double thisM = m ? *m++ : 0.0;
945 const double segmentLength = std::sqrt( ( thisX - prevX ) * ( thisX - prevX ) + ( thisY - prevY ) * ( thisY - prevY ) );
946 if ( distanceTraversed < startDistance && distanceTraversed + segmentLength > startDistance )
949 const double distanceToStart = startDistance - distanceTraversed;
950 double startX, startY;
954 z ? &prevZ :
nullptr, z ? &thisZ :
nullptr, z ? &startZ :
nullptr,
955 m ? &prevM :
nullptr, m ? &thisM :
nullptr, m ? &startM :
nullptr );
956 substringPoints <<
QgsPoint( pointType, startX, startY, startZ, startM );
959 if ( foundStart && ( distanceTraversed + segmentLength > endDistance ) )
962 const double distanceToEnd = endDistance - distanceTraversed;
967 z ? &prevZ :
nullptr, z ? &thisZ :
nullptr, z ? &endZ :
nullptr,
968 m ? &prevM :
nullptr, m ? &thisM :
nullptr, m ? &endM :
nullptr );
969 substringPoints <<
QgsPoint( pointType, endX, endY, endZ, endM );
971 else if ( foundStart )
973 substringPoints <<
QgsPoint( pointType, thisX, thisY, thisZ, thisM );
977 if ( distanceTraversed > endDistance )
1008 if ( path.isEmpty() || path.currentPosition() != QPointF( mX.at( 0 ), mY.at( 0 ) ) )
1010 path.moveTo( mX.at( 0 ), mY.at( 0 ) );
1013 for (
int i = 1; i < nPoints; ++i )
1015 path.lineTo( mX.at( i ), mY.at( i ) );
1028 return compoundCurve;
1033 if ( mX.size() < 2 || mY.size() < 2 )
1037 if ( startDistance > 0 )
1039 double currentLen = std::sqrt( std::pow( mX.at( 0 ) - mX.at( 1 ), 2 ) +
1040 std::pow( mY.at( 0 ) - mY.at( 1 ), 2 ) );
1041 double newLen = currentLen + startDistance;
1042 mX[ 0 ] = mX.at( 1 ) + ( mX.at( 0 ) - mX.at( 1 ) ) / currentLen * newLen;
1043 mY[ 0 ] = mY.at( 1 ) + ( mY.at( 0 ) - mY.at( 1 ) ) / currentLen * newLen;
1046 if ( endDistance > 0 )
1048 int last = mX.size() - 1;
1049 double currentLen = std::sqrt( std::pow( mX.at( last ) - mX.at( last - 1 ), 2 ) +
1050 std::pow( mY.at( last ) - mY.at( last - 1 ), 2 ) );
1051 double newLen = currentLen + endDistance;
1052 mX[ last ] = mX.at( last - 1 ) + ( mX.at( last ) - mX.at( last - 1 ) ) / currentLen * newLen;
1053 mY[ last ] = mY.at( last - 1 ) + ( mY.at( last ) - mY.at( last - 1 ) ) / currentLen * newLen;
1059 auto result = qgis::make_unique< QgsLineString >();
1061 return result.release();
1066 return QStringLiteral(
"LineString" );
1082 double *zArray =
nullptr;
1088 std::unique_ptr< double[] > dummyZ;
1089 if ( !hasZ || !transformZ )
1091 dummyZ.reset(
new double[nPoints]() );
1092 zArray = dummyZ.get();
1107 double *x = mX.data();
1108 double *y = mY.data();
1109 double *z = hasZ ? mZ.data() :
nullptr;
1110 double *m = hasM ? mM.data() :
nullptr;
1111 for (
int i = 0; i < nPoints; ++i )
1114 t.map( *x, *y, &xOut, &yOut );
1119 *z = *z * zScale + zTranslate;
1124 *m = *m * mScale + mTranslate;
1139 if ( position.
vertex < 0 || position.
vertex > mX.size() )
1149 mX.insert( position.
vertex, vertex.
x() );
1150 mY.insert( position.
vertex, vertex.
y() );
1153 mZ.insert( position.
vertex, vertex.
z() );
1157 mM.insert( position.
vertex, vertex.
m() );
1165 if ( position.
vertex < 0 || position.
vertex >= mX.size() )
1169 mX[position.
vertex] = newPos.
x();
1170 mY[position.
vertex] = newPos.
y();
1173 mZ[position.
vertex] = newPos.
z();
1177 mM[position.
vertex] = newPos.
m();
1185 if ( position.
vertex >= mX.size() || position.
vertex < 0 )
1190 mX.remove( position.
vertex );
1191 mY.remove( position.
vertex );
1194 mZ.remove( position.
vertex );
1198 mM.remove( position.
vertex );
1223 mX.append( pt.
x() );
1224 mY.append( pt.
y() );
1227 mZ.append( pt.
z() );
1231 mM.append( pt.
m() );
1238 double sqrDist = std::numeric_limits<double>::max();
1239 double leftOfDist = std::numeric_limits<double>::max();
1241 double prevLeftOfX = 0.0;
1242 double prevLeftOfY = 0.0;
1243 double testDist = 0;
1244 double segmentPtX, segmentPtY;
1249 int size = mX.size();
1250 if ( size == 0 || size == 1 )
1255 for (
int i = 1; i < size; ++i )
1257 double prevX = mX.at( i - 1 );
1258 double prevY = mY.at( i - 1 );
1259 double currentX = mX.at( i );
1260 double currentY = mY.at( i );
1262 if ( testDist < sqrDist )
1265 segmentPt.
setX( segmentPtX );
1266 segmentPt.
setY( segmentPtY );
1267 vertexAfter.
part = 0;
1268 vertexAfter.
ring = 0;
1279 if (
qgsDoubleNear( testDist, leftOfDist ) && left != prevLeftOf && prevLeftOf != 0 )
1292 leftOfDist = testDist;
1293 prevLeftOfX = prevX;
1294 prevLeftOfY = prevY;
1296 else if ( testDist < leftOfDist )
1299 leftOfDist = testDist;
1330 if ( numPoints == 1 )
1331 return QgsPoint( mX.at( 0 ), mY.at( 0 ) );
1333 double totalLineLength = 0.0;
1334 double prevX = mX.at( 0 );
1335 double prevY = mY.at( 0 );
1341 double currentX = mX.at( i );
1342 double currentY = mY.at( i );
1343 double segmentLength = std::sqrt( std::pow( currentX - prevX, 2.0 ) +
1344 std::pow( currentY - prevY, 2.0 ) );
1349 sumX += segmentLength * 0.5 * ( currentX + prevX );
1350 sumY += segmentLength * 0.5 * ( currentY + prevY );
1356 return QgsPoint( mX.at( 0 ), mY.at( 0 ) );
1358 return QgsPoint( sumX / totalLineLength, sumY / totalLineLength );
1372 for (
int i = 0; i < maxIndex; ++i )
1374 sum += 0.5 * ( mX.at( i ) * mY.at( i + 1 ) - mY.at( i ) * mX.at( i + 1 ) );
1378 void QgsLineString::importVerticesFromWkb(
const QgsConstWkbPtr &wkb )
1384 mX.resize( nVertices );
1385 mY.resize( nVertices );
1386 hasZ ? mZ.resize( nVertices ) : mZ.clear();
1387 hasM ? mM.resize( nVertices ) : mM.clear();
1388 double *x = mX.data();
1389 double *y = mY.data();
1390 double *m = hasM ? mM.data() :
nullptr;
1391 double *z = hasZ ? mZ.data() :
nullptr;
1392 for (
int i = 0; i < nVertices; ++i )
1425 if ( mX.count() < 2 )
1435 double previousX = mX.at(
numPoints() - 2 );
1436 double previousY = mY.at(
numPoints() - 2 );
1437 double currentX = mX.at( 0 );
1438 double currentY = mY.at( 0 );
1439 double afterX = mX.at( 1 );
1440 double afterY = mY.at( 1 );
1443 else if ( vertex.
vertex == 0 )
1456 double previousX = mX.at( vertex.
vertex - 1 );
1457 double previousY = mY.at( vertex.
vertex - 1 );
1458 double currentX = mX.at( vertex.
vertex );
1459 double currentY = mY.at( vertex.
vertex );
1460 double afterX = mX.at( vertex.
vertex + 1 );
1461 double afterY = mY.at( vertex.
vertex + 1 );
1468 if ( startVertex.
vertex < 0 || startVertex.
vertex >= mX.count() - 1 )
1471 double dx = mX.at( startVertex.
vertex + 1 ) - mX.at( startVertex.
vertex );
1472 double dy = mY.at( startVertex.
vertex + 1 ) - mY.at( startVertex.
vertex );
1473 return std::sqrt( dx * dx + dy * dy );
1498 mZ.reserve( nPoints );
1499 for (
int i = 0; i < nPoints; ++i )
1529 mM.reserve( nPoints );
1530 for (
int i = 0; i < nPoints; ++i )
1561 std::swap( mX, mY );
1575 addZValue( std::numeric_limits<double>::quiet_NaN() );
1589 int size = mX.size();
1591 double *srcX = mX.data();
1592 double *srcY = mY.data();
1593 double *srcM = hasM ? mM.data() :
nullptr;
1594 double *srcZ = hasZ ? mZ.data() :
nullptr;
1596 double *destX = srcX;
1597 double *destY = srcY;
1598 double *destM = srcM;
1599 double *destZ = srcZ;
1601 int filteredPoints = 0;
1602 for (
int i = 0; i < size; ++i )
1606 double z = hasZ ? *srcZ++ : std::numeric_limits<double>::quiet_NaN();
1607 double m = hasM ? *srcM++ : std::numeric_limits<double>::quiet_NaN();
1609 if ( filter(
QgsPoint( x, y, z, m ) ) )
1621 mX.resize( filteredPoints );
1622 mY.resize( filteredPoints );
1624 mZ.resize( filteredPoints );
1626 mM.resize( filteredPoints );
1635 int size = mX.size();
1637 double *srcX = mX.data();
1638 double *srcY = mY.data();
1639 double *srcM = hasM ? mM.data() :
nullptr;
1640 double *srcZ = hasZ ? mZ.data() :
nullptr;
1642 for (
int i = 0; i < size; ++i )
1646 double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
1647 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...
const double * mData() const
Returns a const pointer to the m vertex data, or nullptr if the linestring does not have m values...
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.
double length3D() const
Returns the length in 3D world of the line string.
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.
const double * xData() const
Returns a const pointer to the x vertex data.
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.
static QgsLineString * fromQPolygonF(const QPolygonF &polygon)
Returns a new linestring from a QPolygonF polygon input.
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.
const double * yData() const
Returns a const pointer to the y vertex data.
AxisOrder
Axis order for GML generation.
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...
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.
const double * zData() const
Returns a const pointer to the z vertex data, or nullptr if the linestring does not have z values...
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 planar, 2-dimensional 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...