30#include <QPainterPath>
31#include <QRegularExpression>
34#include <nlohmann/json.hpp>
53 else if ( std::isnan(
z ) )
55 if ( std::isnan(
m ) )
60 else if ( std::isnan(
m ) )
69 , mZ( std::numeric_limits<double>::quiet_NaN() )
70 , mM( std::numeric_limits<double>::quiet_NaN() )
75 mX = std::numeric_limits<double>::quiet_NaN();
76 mY = std::numeric_limits<double>::quiet_NaN();
83 , mZ( std::numeric_limits<double>::quiet_NaN() )
84 , mM( std::numeric_limits<double>::quiet_NaN() )
92 , mZ(
QgsWkbTypes::hasZ( wkbType ) ? z : std::numeric_limits<double>::quiet_NaN() )
93 , mM(
QgsWkbTypes::hasM( wkbType ) ? m : std::numeric_limits<double>::quiet_NaN() )
113 auto gridifyValue = [](
double value,
double spacing,
bool extraCondition = true ) ->
double
115 if ( spacing > 0 && extraCondition )
116 return std::round( value / spacing ) * spacing;
122 const auto x = gridifyValue( mX, hSpacing );
123 const auto y = gridifyValue( mY, vSpacing );
174 QString secondWithoutParentheses =
parts.second;
175 secondWithoutParentheses = secondWithoutParentheses.remove(
'(' ).remove(
')' ).simplified().remove(
' ' );
176 parts.second =
parts.second.remove(
'(' ).remove(
')' );
177 if ( (
parts.second.compare( QLatin1String(
"EMPTY" ), Qt::CaseInsensitive ) == 0 ) ||
178 secondWithoutParentheses.isEmpty() )
181 const thread_local QRegularExpression
rx( QStringLiteral(
"\\s" ) );
182#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
183 QStringList coordinates =
parts.second.split(
rx, QString::SkipEmptyParts );
185 QStringList coordinates =
parts.second.split(
rx, Qt::SkipEmptyParts );
199 const thread_local QRegularExpression rxIsNumber( QStringLiteral(
"^[+-]?(\\d\\.?\\d*[Ee][+\\-]?\\d+|(\\d+\\.\\d*|\\d*\\.\\d+)|\\d+)$" ) );
200 if ( coordinates.filter( rxIsNumber ).size() != coordinates.size() )
203 if ( coordinates.size() < 2 )
208 else if ( coordinates.size() == 3 && !
is3D() && !
isMeasure() )
214 else if ( coordinates.size() >= 4 && ( !
is3D() || !
isMeasure() ) )
223 mX = coordinates[idx++].toDouble();
224 mY = coordinates[idx++].toDouble();
225 if (
is3D() && coordinates.length() > 2 )
226 mZ = coordinates[idx++].toDouble();
228 mM = coordinates[idx++].toDouble();
241 int binarySize =
sizeof( char ) +
sizeof( quint32 );
242 binarySize += ( 2 +
is3D() +
isMeasure() ) *
sizeof(
double );
252 wkb << static_cast<quint32>(
wkbType() );
270 wkt += QLatin1String(
" EMPTY" );
273 wkt += QLatin1String(
" (" );
286 QDomElement elemPoint = doc.createElementNS( ns, QStringLiteral(
"Point" ) );
287 QDomElement elemCoordinates = doc.createElementNS( ns, QStringLiteral(
"coordinates" ) );
290 const QString cs = QStringLiteral(
"," );
292 const QString ts = QStringLiteral(
" " );
294 elemCoordinates.setAttribute( QStringLiteral(
"cs" ), cs );
295 elemCoordinates.setAttribute( QStringLiteral(
"ts" ), ts );
297 QString strCoordinates;
302 elemCoordinates.appendChild( doc.createTextNode( strCoordinates ) );
303 elemPoint.appendChild( elemCoordinates );
309 QDomElement elemPoint = doc.createElementNS( ns, QStringLiteral(
"Point" ) );
310 QDomElement elemPosList = doc.createElementNS( ns, QStringLiteral(
"pos" ) );
311 elemPosList.setAttribute( QStringLiteral(
"srsDimension" ),
is3D() ? 3 : 2 );
312 QString strCoordinates;
320 elemPosList.appendChild( doc.createTextNode( strCoordinates ) );
321 elemPoint.appendChild( elemPosList );
331 {
"coordinates", json::array() },
352 p.drawRect( QRectF( mX - 2, mY - 2, 4, 4 ) );
357 return QPainterPath();
362 mX = mY = std::numeric_limits<double>::quiet_NaN();
366 mZ = std::numeric_limits<double>::quiet_NaN();
371 mM = std::numeric_limits<double>::quiet_NaN();
414 if (
id.vertex != 0 )
469 Q_UNUSED( segmentPt )
470 Q_UNUSED( vertexAfter )
543 return rectangle.
contains( mX, mY );
548 return box3d.
contains( mX, mY, mZ );
579void QgsPoint::transform(
const QTransform &t,
double zTranslate,
double zScale,
double mTranslate,
double mScale )
583 t.map( mX, mY, &
x, &
y );
589 mZ = mZ * zScale + zTranslate;
593 mM = mM * mScale + mTranslate;
604 mZ = std::numeric_limits<double>::quiet_NaN();
615 mM = std::numeric_limits<double>::quiet_NaN();
636 mZ = std::numeric_limits<double>::quiet_NaN();
637 mM = std::numeric_limits<double>::quiet_NaN();
642 mM = std::numeric_limits<double>::quiet_NaN();
646 mZ = std::numeric_limits<double>::quiet_NaN();
688 double zDistSquared = 0.0;
689 if (
is3D() || !std::isnan(
z ) )
690 zDistSquared = ( mZ -
z ) * ( mZ -
z );
692 return std::sqrt( ( mX -
x ) * ( mX -
x ) + ( mY -
y ) * ( mY -
y ) + zDistSquared );
697 double zDistSquared = 0.0;
699 zDistSquared = ( mZ - other.
z() ) * ( mZ - other.
z() );
701 return std::sqrt( ( mX - other.
x() ) * ( mX - other.
x() ) + ( mY - other.
y() ) * ( mY - other.
y() ) + zDistSquared );
706 double zDistSquared = 0.0;
707 if (
is3D() || !std::isnan(
z ) )
708 zDistSquared = ( mZ -
z ) * ( mZ -
z );
710 return ( mX -
x ) * ( mX -
x ) + ( mY -
y ) * ( mY -
y ) + zDistSquared;
715 double zDistSquared = 0.0;
717 zDistSquared = ( mZ - other.
z() ) * ( mZ - other.
z() );
719 return ( mX - other.
x() ) * ( mX - other.
x() ) + ( mY - other.
y() ) * ( mY - other.
y() ) + zDistSquared;
724 const double dx = other.
x() - mX;
725 const double dy = other.
y() - mY;
726 return ( std::atan2( dx, dy ) * 180.0 / M_PI );
736 const double dz = other.
z() - mZ;
738 return ( std::acos( dz /
distance ) * 180.0 / M_PI );
744 const double radsXy =
azimuth * M_PI / 180.0;
745 double dx = 0.0, dy = 0.0, dz = 0.0;
760 dx =
distance * std::sin( radsZ ) * std::sin( radsXy );
761 dy =
distance * std::sin( radsZ ) * std::cos( radsXy );
765 return QgsPoint( mX + dx, mY + dy, mZ + dz, mM, pType );
775 return std::isnan( mX ) || std::isnan( mY );
780 return QgsBox3D( mX, mY, mZ, mX, mY, mZ );
785 return QStringLiteral(
"Point" );
800 Q_ASSERT( index == 0 );
806 const double nan = std::numeric_limits<double>::quiet_NaN();
812 const QgsPoint *otherPoint = qgsgeometry_cast< const QgsPoint * >( other );
816 if ( mX < otherPoint->mX )
820 else if ( mX > otherPoint->mX )
825 if ( mY < otherPoint->mY )
829 else if ( mY > otherPoint->mY )
834 if (
is3D() && !otherPoint->
is3D() )
836 else if ( !
is3D() && otherPoint->
is3D() )
838 else if (
is3D() && otherPoint->
is3D() )
840 if ( mZ < otherPoint->mZ )
844 else if ( mZ > otherPoint->mZ )
856 if ( mM < otherPoint->mM )
860 else if ( mM > otherPoint->mM )
WkbType
The WKB type describes the number of dimensions a geometry has.
TransformDirection
Flags for raster layer temporal capabilities.
Abstract base class for all geometries.
bool isMeasure() const
Returns true if the geometry contains m values.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
AxisOrder
Axis order for GML generation.
@ XY
X comes before Y (or lon before lat)
QString wktTypeStr() const
Returns the WKT type string of the geometry.
virtual void clearCache() const
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
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.
A 3-dimensional box composed of x, y, z coordinates.
bool contains(const QgsBox3D &other) const
Returns true when box contains other box.
Qgis::WkbType readHeader() const
readHeader
Base class for feedback objects to be used for cancellation of something running in a worker thread.
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 (...
A class to represent a 2D point.
bool isEmpty() const
Returns true if the geometry is empty.
Point geometry type, with support for z-dimension and m-values.
int wkbSize(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
Returns the length of the QByteArray returned by asWkb()
QgsBox3D boundingBox3D() const override
Returns the 3D bounding box for the geometry.
bool fromWkb(QgsConstWkbPtr &wkb) override
Sets the geometry from a WKB string.
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 inclination(const QgsPoint &other) const
Calculates Cartesian inclination between this point and other one (starting from zenith = 0 to nadir ...
QgsCoordinateSequence coordinateSequence() const override
Retrieves the sequence of geometries, rings and nodes.
double vertexAngle(QgsVertexId vertex) const override
Angle undefined.
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.
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
QPainterPath asQPainterPath() const override
Returns the geometry represented as a QPainterPath.
QByteArray asWkb(QgsAbstractGeometry::WkbFlags=QgsAbstractGeometry::WkbFlags()) const override
double & rx()
Returns a reference to the x-coordinate of this point.
void clear() override
Clears the geometry, ie reset it to a null geometry.
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
bool boundingBoxIntersects(const QgsRectangle &rectangle) const override
Returns true if the bounding box of this geometry intersects with a rectangle.
bool dropMValue() override
Drops any measure values which exist in the geometry.
bool insertVertex(QgsVertexId position, const QgsPoint &vertex) override
Inserts a vertex into the geometry.
double azimuth(const QgsPoint &other) const
Calculates Cartesian azimuth between this point and other one (clockwise in degree,...
void adjacentVertices(QgsVertexId vertex, QgsVertexId &previousVertex, QgsVertexId &nextVertex) const override
Returns the vertices adjacent to a specified vertex within a geometry.
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
QgsAbstractGeometry * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
void draw(QPainter &p) const override
Draws the geometry using the specified QPainter.
QgsPoint * toCurveType() const override
Returns the geometry converted to the more generic curve type.
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
QgsPoint childPoint(int index) const override
Returns point at index (for geometries without child geometries - i.e.
bool isValid(QString &error, Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const override
Checks validity of the geometry, and returns true if the geometry is valid.
int dimension() const override
Returns the inherent dimension of the geometry.
QgsPoint * clone() const override
Clones the geometry by performing a deep copy.
double distance3D(double x, double y, double z) const
Returns the Cartesian 3D distance between this point and a specified x, y, z coordinate.
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.
double distanceSquared3D(double x, double y, double z) const
Returns the Cartesian 3D squared distance between this point and a specified x, y,...
int ringCount(int=0) const override
Returns the number of rings of which this geometry is built.
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.
QgsPoint vertexAt(QgsVertexId) const override
Returns the point corresponding to a specified vertex id.
QgsPoint * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
void normalize() final
Reorganizes the geometry into a normalized form (or "canonical" form).
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the 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.
QgsPoint * 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.
bool convertTo(Qgis::WkbType type) override
Converts the geometry to a specified type.
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 vertexNumberFromVertexId(QgsVertexId id) const override
Returns the vertex number corresponding to a vertex id.
int childCount() const override
Returns number of child geometries (for geometries with child geometries) or child points (for geomet...
bool isEmpty() const override
Returns true if the geometry is empty.
json asJsonObject(int precision=17) const override
Returns a json object representation of the geometry.
void transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection d=Qgis::TransformDirection::Forward, bool transformZ=false) override
Transforms the geometry using a coordinate transform.
double distance(double x, double y) const
Returns the Cartesian 2D distance between this point and a specified x, y coordinate.
int vertexCount(int=0, int=0) const override
Returns the number of vertices of which this geometry is built.
int nCoordinates() const override
Returns the number of nodes contained in the geometry.
void swapXy() override
Swaps the x and y coordinates from the geometry.
QString geometryType() const override
Returns a unique string representing the geometry type.
double segmentLength(QgsVertexId startVertex) const override
Returns the length of the segment of the geometry which begins at startVertex.
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
QgsPoint project(double distance, double azimuth, double inclination=90.0) const
Returns a new point which corresponds to this point projected by a specified distance with specified ...
QgsPoint(double x=std::numeric_limits< double >::quiet_NaN(), double y=std::numeric_limits< double >::quiet_NaN(), double z=std::numeric_limits< double >::quiet_NaN(), double m=std::numeric_limits< double >::quiet_NaN(), Qgis::WkbType wkbType=Qgis::WkbType::Unknown)
Construct a point with the provided initial coordinate values.
bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const override
Returns next vertex id and coordinates.
int partCount() const override
Returns count of parts contained in the geometry.
QString asKml(int precision=17) const override
Returns a KML representation of the geometry.
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...
A rectangle specified with double values.
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
Handles storage of information regarding WKB types and their properties.
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 bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static 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.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QVector< QgsRingSequence > QgsCoordinateSequence
QVector< QgsPointSequence > QgsRingSequence
QVector< QgsPoint > QgsPointSequence
Utility class for identifying a unique vertex within a geometry.