30using namespace Qt::StringLiterals;
34 int binarySize =
sizeof( char ) +
sizeof( quint32 ) +
sizeof( quint32 );
45 wkb << static_cast<quint32>(
wkbType() );
90 mX.resize( nVertices );
91 mY.resize( nVertices );
92 hasZ ?
mZ.resize( nVertices ) :
mZ.clear();
93 hasM ?
mM.resize( nVertices ) :
mM.clear();
94 double *x =
mX.data();
95 double *y =
mY.data();
96 double *m = hasM ?
mM.data() :
nullptr;
97 double *z = hasZ ?
mZ.data() :
nullptr;
98 for (
int i = 0; i < nVertices; ++i )
124 parts.second =
parts.second.remove(
'(' ).remove(
')' );
125 QString secondWithoutParentheses =
parts.second;
126 secondWithoutParentheses = secondWithoutParentheses.simplified().remove(
' ' );
127 if ( (
parts.second.compare(
"EMPTY"_L1, Qt::CaseInsensitive ) == 0 ) || secondWithoutParentheses.isEmpty() )
151 if ( i < 0 || i >=
mX.size() )
156 double x =
mX.at( i );
157 double y =
mY.at( i );
158 double z = std::numeric_limits<double>::quiet_NaN();
159 double m = std::numeric_limits<double>::quiet_NaN();
177 else if ( hasZ && hasM )
212 mM.reserve( nPoints );
213 for (
int i = 0; i < nPoints; ++i )
236 mZ.reserve( nPoints );
237 for (
int i = 0; i < nPoints; ++i )
269 if ( index >= 0 && index <
mX.size() )
270 return mX.at( index );
277 if ( index >= 0 && index <
mY.size() )
278 return mY.at( index );
285 if ( index >= 0 && index <
mX.size() )
292 if ( index >= 0 && index <
mY.size() )
324 int size =
mX.size();
326 double *srcX =
mX.data();
327 double *srcY =
mY.data();
328 double *srcM = hasM ?
mM.data() :
nullptr;
329 double *srcZ = hasZ ?
mZ.data() :
nullptr;
331 double *destX = srcX;
332 double *destY = srcY;
333 double *destM = srcM;
334 double *destZ = srcZ;
336 int filteredPoints = 0;
337 for (
int i = 0; i < size; ++i )
341 double z = hasZ ? *srcZ++ : std::numeric_limits<double>::quiet_NaN();
342 double m = hasM ? *srcM++ : std::numeric_limits<double>::quiet_NaN();
344 if ( filter(
QgsPoint( x, y, z, m ) ) )
356 mX.resize( filteredPoints );
357 mY.resize( filteredPoints );
359 mZ.resize( filteredPoints );
361 mM.resize( filteredPoints );
370 int size =
mX.size();
372 double *srcX =
mX.data();
373 double *srcY =
mY.data();
374 double *srcM = hasM ?
mM.data() :
nullptr;
375 double *srcZ = hasZ ?
mZ.data() :
nullptr;
377 for (
int i = 0; i < size; ++i )
381 double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
382 double m = hasM ? *srcM : std::numeric_limits<double>::quiet_NaN();
418 std::reverse( copy->
mX.begin(), copy->
mX.end() );
419 std::reverse( copy->
mY.begin(), copy->
mY.end() );
422 std::reverse( copy->
mZ.begin(), copy->
mZ.end() );
426 std::reverse( copy->
mM.begin(), copy->
mM.end() );
439 const int size =
mX.size();
440 const int otherSize = otherCurve->
mX.size();
441 if ( size > otherSize )
445 else if ( size < otherSize )
450 if (
is3D() && !otherCurve->
is3D() )
452 else if ( !
is3D() && otherCurve->
is3D() )
454 const bool considerZ =
is3D();
462 for (
int i = 0; i < size; i++ )
464 const double x =
mX[i];
465 const double otherX = otherCurve->
mX[i];
470 else if ( x > otherX )
475 const double y =
mY[i];
476 const double otherY = otherCurve->
mY[i];
481 else if ( y > otherY )
488 const double z =
mZ[i];
489 const double otherZ = otherCurve->
mZ[i];
495 else if ( z > otherZ )
503 const double m =
mM[i];
504 const double otherM = otherCurve->
mM[i];
510 else if ( m > otherM )
520 int index, QVector< double > &x1, QVector< double > &y1, QVector< double > &z1, QVector< double > &m1, QVector< double > &x2, QVector< double > &y2, QVector< double > &z2, QVector< double > &m2
523 const bool useZ =
is3D();
526 const int size =
mX.size();
530 index = std::clamp( index, 0, size - 1 );
532 const int part1Size = index + 1;
533 x1.resize( part1Size );
534 y1.resize( part1Size );
535 z1.resize( useZ ? part1Size : 0 );
536 m1.resize( useM ? part1Size : 0 );
538 const double *sourceX =
mX.constData();
539 const double *sourceY =
mY.constData();
540 const double *sourceZ = useZ ?
mZ.constData() :
nullptr;
541 const double *sourceM = useM ?
mM.constData() :
nullptr;
543 double *destX = x1.data();
544 double *destY = y1.data();
545 double *destZ = useZ ? z1.data() :
nullptr;
546 double *destM = useM ? m1.data() :
nullptr;
548 std::copy( sourceX, sourceX + part1Size, destX );
549 std::copy( sourceY, sourceY + part1Size, destY );
551 std::copy( sourceZ, sourceZ + part1Size, destZ );
553 std::copy( sourceM, sourceM + part1Size, destM );
555 const int part2Size = size - index;
556 x2.resize( part2Size );
557 y2.resize( part2Size );
558 z2.resize( useZ ? part2Size : 0 );
559 m2.resize( useM ? part2Size : 0 );
566 destZ = useZ ? z2.data() :
nullptr;
567 destM = useM ? m2.data() :
nullptr;
568 std::copy( sourceX + index, sourceX + size, destX );
569 std::copy( sourceY + index, sourceY + size, destY );
571 std::copy( sourceZ + index, sourceZ + size, destZ );
573 std::copy( sourceM + index, sourceM + size, destM );
623 mZ.insert(
mZ.count(),
mX.size() -
mZ.size(), std::numeric_limits<double>::quiet_NaN() );
636 mM.insert(
mM.count(),
mX.size() -
mM.size(), std::numeric_limits<double>::quiet_NaN() );
647 pts.reserve( nPoints );
648 for (
int i = 0; i < nPoints; ++i )
650 pts.push_back(
pointN( i ) );
666 bool hasZ = firstPt.
is3D();
690 for (
int i = 0; i <
points.size(); ++i )
696 double z =
points.at( i ).z();
697 mZ[i] = std::isnan( z ) ? 0 : z;
701 double m =
points.at( i ).m();
702 mM[i] = std::isnan( m ) ? 0 : m;
709 const int size =
mX.size();
710 if ( index < 1 || index >= size - 1 )
713 const bool useZ =
is3D();
716 QVector<double> newX( size );
717 QVector<double> newY( size );
718 QVector<double> newZ( useZ ? size : 0 );
719 QVector<double> newM( useM ? size : 0 );
720 auto it = std::copy(
mX.constBegin() + index,
mX.constEnd() - 1, newX.begin() );
721 it = std::copy(
mX.constBegin(),
mX.constBegin() + index, it );
722 *it = *newX.constBegin();
723 mX = std::move( newX );
725 it = std::copy(
mY.constBegin() + index,
mY.constEnd() - 1, newY.begin() );
726 it = std::copy(
mY.constBegin(),
mY.constBegin() + index, it );
727 *it = *newY.constBegin();
728 mY = std::move( newY );
731 it = std::copy(
mZ.constBegin() + index,
mZ.constEnd() - 1, newZ.begin() );
732 it = std::copy(
mZ.constBegin(),
mZ.constBegin() + index, it );
733 *it = *newZ.constBegin();
734 mZ = std::move( newZ );
738 it = std::copy(
mM.constBegin() + index,
mM.constEnd() - 1, newM.begin() );
739 it = std::copy(
mM.constBegin(),
mM.constBegin() + index, it );
740 *it = *newM.constBegin();
741 mM = std::move( newM );
764 int size =
mX.size();
766 double *srcX =
mX.data();
767 double *srcY =
mY.data();
768 double *srcM = hasM ?
mM.data() :
nullptr;
769 double *srcZ = hasZ ?
mZ.data() :
nullptr;
772 for (
int i = 0; i < size; ++i )
776 double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
777 double m = hasM ? *srcM : std::numeric_limits<double>::quiet_NaN();
803 double *zArray =
nullptr;
809 std::unique_ptr< double[] > dummyZ;
810 if ( !hasZ || !transformZ )
812 dummyZ = std::make_unique<double[]>( nPoints );
813 zArray = dummyZ.get();
828 double *x =
mX.data();
829 double *y =
mY.data();
830 double *z = hasZ ?
mZ.data() :
nullptr;
831 double *m = hasM ?
mM.data() :
nullptr;
832 for (
int i = 0; i < nPoints; ++i )
835 t.map( *x, *y, &xOut, &yOut );
840 *z = *z * zScale + zTranslate;
845 *m = *m * mScale + mTranslate;
WkbType
The WKB type describes the number of dimensions a geometry has.
@ LineString25D
LineString25D.
@ LineStringZ
LineStringZ.
TransformDirection
Indicates the direction (forward or inverse) of a transform.
bool isMeasure() const
Returns true if the geometry contains m values.
QFlags< WkbFlag > WkbFlags
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
QString wktTypeStr() const
Returns the WKT type string of the geometry.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, Qgis::WkbType baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
QgsAbstractGeometry()=default
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry.
static endian_t endian()
Returns whether this machine uses big or little endian.
Qgis::WkbType readHeader() const
readHeader
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
QgsCurve * clone() const override=0
Clones the geometry by performing a deep copy.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
bool isCanceled() const
Tells whether the operation has been canceled already.
static void pointsToWKB(QgsWkbPtr &wkb, const QgsPointSequence &points, bool is3D, bool isMeasure, QgsAbstractGeometry::WkbFlags flags)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }.
static QPair< Qgis::WkbType, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
static QgsPointSequence pointsFromWKT(const QString &wktCoordinateList, bool is3D, bool isMeasure)
Returns a list of points contained in a WKT string.
static QString pointsToWKT(const QgsPointSequence &points, int precision, bool is3D, bool isMeasure)
Returns a WKT coordinate list.
Point geometry type, with support for z-dimension and m-values.
double yAt(int index) const override
Returns the y-coordinate of the specified node in the line string.
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
void setYAt(int index, double y)
Sets the y-coordinate of the specified node in the simple curve.
bool dropMValue() override
Drops any measure values which exist in the geometry.
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
int numPoints() const override
Returns the number of points in the curve.
int wkbSize(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
Returns the length of the QByteArray returned by asWkb().
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 isEmpty() const override
Returns true if the geometry is empty.
QByteArray asWkb(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
Returns a WKB representation of the geometry.
int compareToSameClass(const QgsAbstractGeometry *other) const final
Compares to an other geometry of the same class, and returns a integer for sorting of the two geometr...
int nCoordinates() const override
Returns the number of nodes contained in the geometry.
void splitCurveAtVertexProtected(int index, QVector< double > &x1, QVector< double > &y1, QVector< double > &z1, QVector< double > &m1, QVector< double > &x2, QVector< double > &y2, QVector< double > &z2, QVector< double > &m2) const
Returns coordinate vectors for the split curves.
bool transform(QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback=nullptr) override
Transforms the vertices from the geometry in place, using the specified geometry transformer object.
double xAt(int index) const override
Returns the x-coordinate of the specified node in the line string.
void points(QgsPointSequence &pts) const override
Returns a list of points within the curve.
void setXAt(int index, double x)
Sets the x-coordinate of the specified node in the simple curve.
void clear() override
Clears the geometry, ie reset it to a null geometry.
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
QgsPoint startPoint() const override
Returns the starting point of the curve.
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
bool fromWkb(QgsConstWkbPtr &wkb) override
Sets the geometry from a WKB string.
int dimension() const override
Returns the inherent dimension of the geometry.
void filterVertices(const std::function< bool(const QgsPoint &) > &filter) override
Filters the vertices from the geometry in place, removing any which do not return true for the filter...
void setPoints(const QgsPointSequence &points)
Resets the simple curve to match the specified list of points.
QgsPoint endPoint() const override
Returns the end point of the curve.
QgsPoint pointN(int i) const
Returns the specified point from inside the simple curve.
void scroll(int firstVertexIndex) final
Scrolls the curve vertices so that they start with the vertex at the given index.
void importVerticesFromWkb(const QgsConstWkbPtr &wkb)
Imports vertices from wkb geometry representation.
QgsSimpleCurve * reversed() const override
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
void append(const QgsSimpleCurve *curve)
Appends the contents of another simple curve to the end of this simple curve.
void swapXy() override
Swaps the x and y coordinates from the geometry.
static Qgis::WkbType dropM(Qgis::WkbType type)
Drops the m dimension (if present) for a WKB type and returns the new type.
static Qgis::WkbType dropZ(Qgis::WkbType type)
Drops the z dimension (if present) for a WKB type and returns the new type.
static Qgis::WkbType addM(Qgis::WkbType type)
Adds the m dimension to a WKB type and returns the new type.
static Qgis::WkbType addZ(Qgis::WkbType type)
Adds the z dimension to a WKB type and returns the new type.
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static Q_INVOKABLE bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsPoint > QgsPointSequence
Utility class for identifying a unique vertex within a geometry.