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() )
329 int size =
mX.size();
331 double *srcX =
mX.data();
332 double *srcY =
mY.data();
333 double *srcM = hasM ?
mM.data() :
nullptr;
334 double *srcZ = hasZ ?
mZ.data() :
nullptr;
336 double *destX = srcX;
337 double *destY = srcY;
338 double *destM = srcM;
339 double *destZ = srcZ;
341 int filteredPoints = 0;
342 for (
int i = 0; i < size; ++i )
346 double z = hasZ ? *srcZ++ : std::numeric_limits<double>::quiet_NaN();
347 double m = hasM ? *srcM++ : std::numeric_limits<double>::quiet_NaN();
349 if ( filter(
QgsPoint( x, y, z, m ) ) )
361 mX.resize( filteredPoints );
362 mY.resize( filteredPoints );
364 mZ.resize( filteredPoints );
366 mM.resize( filteredPoints );
375 int size =
mX.size();
377 double *srcX =
mX.data();
378 double *srcY =
mY.data();
379 double *srcM = hasM ?
mM.data() :
nullptr;
380 double *srcZ = hasZ ?
mZ.data() :
nullptr;
382 for (
int i = 0; i < size; ++i )
386 double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
387 double m = hasM ? *srcM : std::numeric_limits<double>::quiet_NaN();
423 std::reverse( copy->
mX.begin(), copy->
mX.end() );
424 std::reverse( copy->
mY.begin(), copy->
mY.end() );
427 std::reverse( copy->
mZ.begin(), copy->
mZ.end() );
431 std::reverse( copy->
mM.begin(), copy->
mM.end() );
444 const int size =
mX.size();
445 const int otherSize = otherCurve->
mX.size();
446 if ( size > otherSize )
450 else if ( size < otherSize )
455 if (
is3D() && !otherCurve->
is3D() )
457 else if ( !
is3D() && otherCurve->
is3D() )
459 const bool considerZ =
is3D();
467 for (
int i = 0; i < size; i++ )
469 const double x =
mX[i];
470 const double otherX = otherCurve->
mX[i];
475 else if ( x > otherX )
480 const double y =
mY[i];
481 const double otherY = otherCurve->
mY[i];
486 else if ( y > otherY )
493 const double z =
mZ[i];
494 const double otherZ = otherCurve->
mZ[i];
500 else if ( z > otherZ )
508 const double m =
mM[i];
509 const double otherM = otherCurve->
mM[i];
515 else if ( m > otherM )
525 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
528 const bool useZ =
is3D();
531 const int size =
mX.size();
535 index = std::clamp( index, 0, size - 1 );
537 const int part1Size = index + 1;
538 x1.resize( part1Size );
539 y1.resize( part1Size );
540 z1.resize( useZ ? part1Size : 0 );
541 m1.resize( useM ? part1Size : 0 );
543 const double *sourceX =
mX.constData();
544 const double *sourceY =
mY.constData();
545 const double *sourceZ = useZ ?
mZ.constData() :
nullptr;
546 const double *sourceM = useM ?
mM.constData() :
nullptr;
548 double *destX = x1.data();
549 double *destY = y1.data();
550 double *destZ = useZ ? z1.data() :
nullptr;
551 double *destM = useM ? m1.data() :
nullptr;
553 std::copy( sourceX, sourceX + part1Size, destX );
554 std::copy( sourceY, sourceY + part1Size, destY );
556 std::copy( sourceZ, sourceZ + part1Size, destZ );
558 std::copy( sourceM, sourceM + part1Size, destM );
560 const int part2Size = size - index;
561 x2.resize( part2Size );
562 y2.resize( part2Size );
563 z2.resize( useZ ? part2Size : 0 );
564 m2.resize( useM ? part2Size : 0 );
571 destZ = useZ ? z2.data() :
nullptr;
572 destM = useM ? m2.data() :
nullptr;
573 std::copy( sourceX + index, sourceX + size, destX );
574 std::copy( sourceY + index, sourceY + size, destY );
576 std::copy( sourceZ + index, sourceZ + size, destZ );
578 std::copy( sourceM + index, sourceM + size, destM );
628 mZ.insert(
mZ.count(),
mX.size() -
mZ.size(), std::numeric_limits<double>::quiet_NaN() );
641 mM.insert(
mM.count(),
mX.size() -
mM.size(), std::numeric_limits<double>::quiet_NaN() );
652 pts.reserve( nPoints );
653 for (
int i = 0; i < nPoints; ++i )
655 pts.push_back(
pointN( i ) );
671 bool hasZ = firstPt.
is3D();
695 for (
int i = 0; i <
points.size(); ++i )
701 double z =
points.at( i ).z();
702 mZ[i] = std::isnan( z ) ? 0 : z;
706 double m =
points.at( i ).m();
707 mM[i] = std::isnan( m ) ? 0 : m;
714 const int size =
mX.size();
715 if ( index < 1 || index >= size - 1 )
718 const bool useZ =
is3D();
721 QVector<double> newX( size );
722 QVector<double> newY( size );
723 QVector<double> newZ( useZ ? size : 0 );
724 QVector<double> newM( useM ? size : 0 );
725 auto it = std::copy(
mX.constBegin() + index,
mX.constEnd() - 1, newX.begin() );
726 it = std::copy(
mX.constBegin(),
mX.constBegin() + index, it );
727 *it = *newX.constBegin();
728 mX = std::move( newX );
730 it = std::copy(
mY.constBegin() + index,
mY.constEnd() - 1, newY.begin() );
731 it = std::copy(
mY.constBegin(),
mY.constBegin() + index, it );
732 *it = *newY.constBegin();
733 mY = std::move( newY );
736 it = std::copy(
mZ.constBegin() + index,
mZ.constEnd() - 1, newZ.begin() );
737 it = std::copy(
mZ.constBegin(),
mZ.constBegin() + index, it );
738 *it = *newZ.constBegin();
739 mZ = std::move( newZ );
743 it = std::copy(
mM.constBegin() + index,
mM.constEnd() - 1, newM.begin() );
744 it = std::copy(
mM.constBegin(),
mM.constBegin() + index, it );
745 *it = *newM.constBegin();
746 mM = std::move( newM );
769 int size =
mX.size();
771 double *srcX =
mX.data();
772 double *srcY =
mY.data();
773 double *srcM = hasM ?
mM.data() :
nullptr;
774 double *srcZ = hasZ ?
mZ.data() :
nullptr;
777 for (
int i = 0; i < size; ++i )
781 double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
782 double m = hasM ? *srcM : std::numeric_limits<double>::quiet_NaN();
808 double *zArray =
nullptr;
814 std::unique_ptr< double[] > dummyZ;
815 if ( !hasZ || !transformZ )
817 dummyZ = std::make_unique<double[]>( nPoints );
818 zArray = dummyZ.get();
833 double *x =
mX.data();
834 double *y =
mY.data();
835 double *z = hasZ ?
mZ.data() :
nullptr;
836 double *m = hasM ?
mM.data() :
nullptr;
837 for (
int i = 0; i < nPoints; ++i )
840 t.map( *x, *y, &xOut, &yOut );
845 *z = *z * zScale + zTranslate;
850 *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.
bool isSimpleCurve() const override
This method returns true for classes that can be cast to the QgsSimpleCurve class.
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.