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" },
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 ) );
760 if ( points.isEmpty() )
767 const QgsPoint &firstPt = points.at( 0 );
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() );
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;
916 double prevZ = z ? *z++ : 0.0;
917 double prevM = m ? *m++ : 0.0;
921 return new QgsPoint( pointType, prevX, prevY, prevZ, prevM );
924 for (
int i = 1; i < totalPoints; ++i )
928 double thisZ = z ? *z++ : 0.0;
929 double thisM = m ? *m++ : 0.0;
931 const double segmentLength = std::sqrt( ( thisX - prevX ) * ( thisX - prevX ) + ( thisY - prevY ) * ( thisY - prevY ) );
932 if ( distance < distanceTraversed + segmentLength ||
qgsDoubleNear( distance, distanceTraversed + segmentLength ) )
935 const double distanceToPoint = std::min( distance - distanceTraversed, segmentLength );
940 z ? &prevZ :
nullptr, z ? &thisZ :
nullptr, z ? &pZ :
nullptr,
941 m ? &prevM :
nullptr, m ? &thisM :
nullptr, m ? &pM :
nullptr );
942 return new QgsPoint( pointType, pX, pY, pZ, pM );
957 if ( startDistance < 0 && endDistance < 0 )
960 endDistance = std::max( startDistance, endDistance );
962 double distanceTraversed = 0;
964 if ( totalPoints == 0 )
967 QVector< QgsPoint > substringPoints;
975 const double *x = mX.constData();
976 const double *y = mY.constData();
977 const double *z =
is3D() ? mZ.constData() :
nullptr;
978 const double *m =
isMeasure() ? mM.constData() :
nullptr;
982 double prevZ = z ? *z++ : 0.0;
983 double prevM = m ? *m++ : 0.0;
984 bool foundStart =
false;
986 if (
qgsDoubleNear( startDistance, 0.0 ) || startDistance < 0 )
988 substringPoints <<
QgsPoint( pointType, prevX, prevY, prevZ, prevM );
992 substringPoints.reserve( totalPoints );
994 for (
int i = 1; i < totalPoints; ++i )
998 double thisZ = z ? *z++ : 0.0;
999 double thisM = m ? *m++ : 0.0;
1001 const double segmentLength = std::sqrt( ( thisX - prevX ) * ( thisX - prevX ) + ( thisY - prevY ) * ( thisY - prevY ) );
1002 if ( distanceTraversed < startDistance && distanceTraversed + segmentLength > startDistance )
1005 const double distanceToStart = startDistance - distanceTraversed;
1006 double startX, startY;
1010 z ? &prevZ :
nullptr, z ? &thisZ :
nullptr, z ? &startZ :
nullptr,
1011 m ? &prevM :
nullptr, m ? &thisM :
nullptr, m ? &startM :
nullptr );
1012 substringPoints <<
QgsPoint( pointType, startX, startY, startZ, startM );
1015 if ( foundStart && ( distanceTraversed + segmentLength > endDistance ) )
1018 const double distanceToEnd = endDistance - distanceTraversed;
1023 z ? &prevZ :
nullptr, z ? &thisZ :
nullptr, z ? &endZ :
nullptr,
1024 m ? &prevM :
nullptr, m ? &thisM :
nullptr, m ? &endM :
nullptr );
1025 substringPoints <<
QgsPoint( pointType, endX, endY, endZ, endM );
1027 else if ( foundStart )
1029 substringPoints <<
QgsPoint( pointType, thisX, thisY, thisZ, thisM );
1033 if ( distanceTraversed > endDistance )
1064 if ( path.isEmpty() || path.currentPosition() != QPointF( mX.at( 0 ), mY.at( 0 ) ) )
1066 path.moveTo( mX.at( 0 ), mY.at( 0 ) );
1069 for (
int i = 1; i < nPoints; ++i )
1071 path.lineTo( mX.at( i ), mY.at( i ) );
1084 return compoundCurve;
1089 if ( mX.size() < 2 || mY.size() < 2 )
1093 if ( startDistance > 0 )
1095 double currentLen = std::sqrt( std::pow( mX.at( 0 ) - mX.at( 1 ), 2 ) +
1096 std::pow( mY.at( 0 ) - mY.at( 1 ), 2 ) );
1097 double newLen = currentLen + startDistance;
1098 mX[ 0 ] = mX.at( 1 ) + ( mX.at( 0 ) - mX.at( 1 ) ) / currentLen * newLen;
1099 mY[ 0 ] = mY.at( 1 ) + ( mY.at( 0 ) - mY.at( 1 ) ) / currentLen * newLen;
1102 if ( endDistance > 0 )
1104 int last = mX.size() - 1;
1105 double currentLen = std::sqrt( std::pow( mX.at( last ) - mX.at( last - 1 ), 2 ) +
1106 std::pow( mY.at( last ) - mY.at( last - 1 ), 2 ) );
1107 double newLen = currentLen + endDistance;
1108 mX[ last ] = mX.at( last - 1 ) + ( mX.at( last ) - mX.at( last - 1 ) ) / currentLen * newLen;
1109 mY[ last ] = mY.at( last - 1 ) + ( mY.at( last ) - mY.at( last - 1 ) ) / currentLen * newLen;
1115 auto result = qgis::make_unique< QgsLineString >();
1117 return result.release();
1122 return QStringLiteral(
"LineString" );
1138 double *zArray =
nullptr;
1144 std::unique_ptr< double[] > dummyZ;
1145 if ( !hasZ || !transformZ )
1147 dummyZ.reset(
new double[nPoints]() );
1148 zArray = dummyZ.get();
1163 double *x = mX.data();
1164 double *y = mY.data();
1165 double *z = hasZ ? mZ.data() :
nullptr;
1166 double *m = hasM ? mM.data() :
nullptr;
1167 for (
int i = 0; i < nPoints; ++i )
1170 t.map( *x, *y, &xOut, &yOut );
1175 *z = *z * zScale + zTranslate;
1180 *m = *m * mScale + mTranslate;
1195 if ( position.
vertex < 0 || position.
vertex > mX.size() )
1205 mX.insert( position.
vertex, vertex.
x() );
1206 mY.insert( position.
vertex, vertex.
y() );
1209 mZ.insert( position.
vertex, vertex.
z() );
1213 mM.insert( position.
vertex, vertex.
m() );
1221 if ( position.
vertex < 0 || position.
vertex >= mX.size() )
1225 mX[position.
vertex] = newPos.
x();
1226 mY[position.
vertex] = newPos.
y();
1229 mZ[position.
vertex] = newPos.
z();
1233 mM[position.
vertex] = newPos.
m();
1241 if ( position.
vertex >= mX.size() || position.
vertex < 0 )
1246 mX.remove( position.
vertex );
1247 mY.remove( position.
vertex );
1250 mZ.remove( position.
vertex );
1254 mM.remove( position.
vertex );
1279 mX.append( pt.
x() );
1280 mY.append( pt.
y() );
1283 mZ.append( pt.
z() );
1287 mM.append( pt.
m() );
1294 double sqrDist = std::numeric_limits<double>::max();
1295 double leftOfDist = std::numeric_limits<double>::max();
1297 double prevLeftOfX = 0.0;
1298 double prevLeftOfY = 0.0;
1299 double testDist = 0;
1300 double segmentPtX, segmentPtY;
1305 int size = mX.size();
1306 if ( size == 0 || size == 1 )
1311 for (
int i = 1; i < size; ++i )
1313 double prevX = mX.at( i - 1 );
1314 double prevY = mY.at( i - 1 );
1315 double currentX = mX.at( i );
1316 double currentY = mY.at( i );
1318 if ( testDist < sqrDist )
1321 segmentPt.
setX( segmentPtX );
1322 segmentPt.
setY( segmentPtY );
1323 vertexAfter.
part = 0;
1324 vertexAfter.
ring = 0;
1335 if (
qgsDoubleNear( testDist, leftOfDist ) && left != prevLeftOf && prevLeftOf != 0 )
1348 leftOfDist = testDist;
1349 prevLeftOfX = prevX;
1350 prevLeftOfY = prevY;
1352 else if ( testDist < leftOfDist )
1355 leftOfDist = testDist;
1386 if ( numPoints == 1 )
1387 return QgsPoint( mX.at( 0 ), mY.at( 0 ) );
1389 double totalLineLength = 0.0;
1390 double prevX = mX.at( 0 );
1391 double prevY = mY.at( 0 );
1397 double currentX = mX.at( i );
1398 double currentY = mY.at( i );
1399 double segmentLength = std::sqrt( std::pow( currentX - prevX, 2.0 ) +
1400 std::pow( currentY - prevY, 2.0 ) );
1405 sumX += segmentLength * 0.5 * ( currentX + prevX );
1406 sumY += segmentLength * 0.5 * ( currentY + prevY );
1412 return QgsPoint( mX.at( 0 ), mY.at( 0 ) );
1414 return QgsPoint( sumX / totalLineLength, sumY / totalLineLength );
1428 for (
int i = 0; i < maxIndex; ++i )
1430 sum += 0.5 * ( mX.at( i ) * mY.at( i + 1 ) - mY.at( i ) * mX.at( i + 1 ) );
1434 void QgsLineString::importVerticesFromWkb(
const QgsConstWkbPtr &wkb )
1440 mX.resize( nVertices );
1441 mY.resize( nVertices );
1442 hasZ ? mZ.resize( nVertices ) : mZ.clear();
1443 hasM ? mM.resize( nVertices ) : mM.clear();
1444 double *x = mX.data();
1445 double *y = mY.data();
1446 double *m = hasM ? mM.data() :
nullptr;
1447 double *z = hasZ ? mZ.data() :
nullptr;
1448 for (
int i = 0; i < nVertices; ++i )
1481 if ( mX.count() < 2 )
1491 double previousX = mX.at(
numPoints() - 2 );
1492 double previousY = mY.at(
numPoints() - 2 );
1493 double currentX = mX.at( 0 );
1494 double currentY = mY.at( 0 );
1495 double afterX = mX.at( 1 );
1496 double afterY = mY.at( 1 );
1499 else if ( vertex.
vertex == 0 )
1512 double previousX = mX.at( vertex.
vertex - 1 );
1513 double previousY = mY.at( vertex.
vertex - 1 );
1514 double currentX = mX.at( vertex.
vertex );
1515 double currentY = mY.at( vertex.
vertex );
1516 double afterX = mX.at( vertex.
vertex + 1 );
1517 double afterY = mY.at( vertex.
vertex + 1 );
1524 if ( startVertex.
vertex < 0 || startVertex.
vertex >= mX.count() - 1 )
1527 double dx = mX.at( startVertex.
vertex + 1 ) - mX.at( startVertex.
vertex );
1528 double dy = mY.at( startVertex.
vertex + 1 ) - mY.at( startVertex.
vertex );
1529 return std::sqrt( dx * dx + dy * dy );
1554 mZ.reserve( nPoints );
1555 for (
int i = 0; i < nPoints; ++i )
1585 mM.reserve( nPoints );
1586 for (
int i = 0; i < nPoints; ++i )
1617 std::swap( mX, mY );
1631 addZValue( std::numeric_limits<double>::quiet_NaN() );
1645 int size = mX.size();
1647 double *srcX = mX.data();
1648 double *srcY = mY.data();
1649 double *srcM = hasM ? mM.data() :
nullptr;
1650 double *srcZ = hasZ ? mZ.data() :
nullptr;
1652 double *destX = srcX;
1653 double *destY = srcY;
1654 double *destM = srcM;
1655 double *destZ = srcZ;
1657 int filteredPoints = 0;
1658 for (
int i = 0; i < size; ++i )
1662 double z = hasZ ? *srcZ++ : std::numeric_limits<double>::quiet_NaN();
1663 double m = hasM ? *srcM++ : std::numeric_limits<double>::quiet_NaN();
1665 if ( filter(
QgsPoint( x, y, z, m ) ) )
1677 mX.resize( filteredPoints );
1678 mY.resize( filteredPoints );
1680 mZ.resize( filteredPoints );
1682 mM.resize( filteredPoints );
1691 int size = mX.size();
1693 double *srcX = mX.data();
1694 double *srcY = mY.data();
1695 double *srcM = hasM ? mM.data() :
nullptr;
1696 double *srcZ = hasZ ? mZ.data() :
nullptr;
1698 for (
int i = 0; i < size; ++i )
1702 double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
1703 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.
QString asKml(int precision=17) const override
Returns a KML representation of the geometry.
virtual bool isRing() const
Returns true if the curve is a ring.
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.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
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'. Negative values mean left ...
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...