QGIS API Documentation  2.12.0-Lyon
qgspointv2.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgspointv2.cpp
3  --------------
4  begin : September 2014
5  copyright : (C) 2014 by Marco Hugentobler
6  email : marco at sourcepole dot ch
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 
19 #include "qgspointv2.h"
20 #include "qgsapplication.h"
21 #include "qgscoordinatetransform.h"
22 #include "qgsgeometryutils.h"
23 #include "qgsmaptopixel.h"
24 #include "qgswkbptr.h"
25 #include <QPainter>
26 
27 QgsPointV2::QgsPointV2( double x, double y ): QgsAbstractGeometryV2(), mX( x ), mY( y ), mZ( 0.0 ), mM( 0.0 )
28 {
30 }
31 
32 QgsPointV2::QgsPointV2( const QgsPoint& p ): QgsAbstractGeometryV2(), mX( p.x() ), mY( p.y() ), mZ( 0.0 ), mM( 0.0 )
33 {
35 }
36 
37 QgsPointV2::QgsPointV2( QgsWKBTypes::Type type, double x, double y, double z, double m ): mX( x ), mY( y ), mZ( z ), mM( m )
38 {
39  mWkbType = type;
40 }
41 
42 bool QgsPointV2::operator==( const QgsPointV2& pt ) const
43 {
44  return ( pt.wkbType() == wkbType() &&
45  qgsDoubleNear( pt.x(), mX, 1E-8 ) &&
46  qgsDoubleNear( pt.y(), mY, 1E-8 ) &&
47  qgsDoubleNear( pt.z(), mZ, 1E-8 ) &&
48  qgsDoubleNear( pt.m(), mM, 1E-8 ) );
49 }
50 
51 bool QgsPointV2::operator!=( const QgsPointV2& pt ) const
52 {
53  return !operator==( pt );
54 }
55 
57 {
58  return new QgsPointV2( *this );
59 }
60 
61 bool QgsPointV2::fromWkb( const unsigned char* wkb )
62 {
63  QgsConstWkbPtr wkbPtr( wkb );
64  QgsWKBTypes::Type type = wkbPtr.readHeader();
66  {
67  return false;
68  }
69  mWkbType = type;
70 
71  wkbPtr >> mX;
72  wkbPtr >> mY;
73  if ( is3D() )
74  wkbPtr >> mZ;
75  if ( isMeasure() )
76  wkbPtr >> mM;
77 
78  return true;
79 }
80 
81 bool QgsPointV2::fromWkt( const QString& wkt )
82 {
83  clear();
84 
86 
87  if ( QgsWKBTypes::flatType( parts.first ) != QgsWKBTypes::parseType( geometryType() ) )
88  return false;
89  mWkbType = parts.first;
90 
91  QStringList coordinates = parts.second.split( " ", QString::SkipEmptyParts );
92  if ( coordinates.size() < 2 + is3D() + isMeasure() )
93  {
94  clear();
95  return false;
96  }
97  else if ( coordinates.size() == 3 && !is3D() && !isMeasure() )
98  {
99  // 3 dimensional coordinates, but not specifically marked as such. We allow this
100  // anyway and upgrade geometry to have Z dimension
102  }
103  else if ( coordinates.size() >= 4 && ( !is3D() || !isMeasure() ) )
104  {
105  // 4 (or more) dimensional coordinates, but not specifically marked as such. We allow this
106  // anyway and upgrade geometry to have Z&M dimensions
109  }
110 
111  int idx = 0;
112  mX = coordinates[idx++].toDouble();
113  mY = coordinates[idx++].toDouble();
114  if ( is3D() )
115  mZ = coordinates[idx++].toDouble();
116  if ( isMeasure() )
117  mM = coordinates[idx++].toDouble();
118 
119  return true;
120 }
121 
123 {
124  int size = sizeof( char ) + sizeof( quint32 );
125  size += ( 2 + is3D() + isMeasure() ) * sizeof( double );
126  return size;
127 }
128 
129 unsigned char* QgsPointV2::asWkb( int& binarySize ) const
130 {
131  binarySize = wkbSize();
132  unsigned char* geomPtr = new unsigned char[binarySize];
133  QgsWkbPtr wkb( geomPtr );
134  wkb << static_cast<char>( QgsApplication::endian() );
135  wkb << static_cast<quint32>( wkbType() );
136  wkb << mX << mY;
137  if ( is3D() )
138  {
139  wkb << mZ;
140  }
141  if ( isMeasure() )
142  {
143  wkb << mM;
144  }
145  return geomPtr;
146 }
147 
148 QString QgsPointV2::asWkt( int precision ) const
149 {
150  QString wkt = wktTypeStr() + " (";
151  wkt += qgsDoubleToString( mX, precision ) + " " + qgsDoubleToString( mY, precision );
152  if ( is3D() )
153  wkt += " " + qgsDoubleToString( mZ, precision );
154  if ( isMeasure() )
155  wkt += " " + qgsDoubleToString( mM, precision );
156  wkt += ")";
157  return wkt;
158 }
159 
160 QDomElement QgsPointV2::asGML2( QDomDocument& doc, int precision, const QString& ns ) const
161 {
162  QDomElement elemPoint = doc.createElementNS( ns, "Point" );
163  QDomElement elemCoordinates = doc.createElementNS( ns, "coordinates" );
164  QString strCoordinates = qgsDoubleToString( mX, precision ) + "," + qgsDoubleToString( mY, precision );
165  elemCoordinates.appendChild( doc.createTextNode( strCoordinates ) );
166  elemPoint.appendChild( elemCoordinates );
167  return elemPoint;
168 }
169 
170 QDomElement QgsPointV2::asGML3( QDomDocument& doc, int precision, const QString& ns ) const
171 {
172  QDomElement elemPoint = doc.createElementNS( ns, "Point" );
173  QDomElement elemPosList = doc.createElementNS( ns, "posList" );
174  elemPosList.setAttribute( "srsDimension", is3D() ? 3 : 2 );
175  QString strCoordinates = qgsDoubleToString( mX, precision ) + " " + qgsDoubleToString( mY, precision );
176  if ( is3D() )
177  strCoordinates += " " + qgsDoubleToString( mZ, precision );
178 
179  elemPosList.appendChild( doc.createTextNode( strCoordinates ) );
180  elemPoint.appendChild( elemPosList );
181  return elemPoint;
182 }
183 
184 QString QgsPointV2::asJSON( int precision ) const
185 {
186  return "{\"type\": \"Point\", \"coordinates\": ["
187  + qgsDoubleToString( mX, precision ) + ", " + qgsDoubleToString( mY, precision )
188  + "]}";
189 }
190 
191 void QgsPointV2::draw( QPainter& p ) const
192 {
193  p.drawRect( mX - 2, mY - 2, 4, 4 );
194 }
195 
197 {
199  mX = mY = mZ = mM = 0.;
200 }
201 
203 {
204  ct.transformInPlace( mX, mY, mZ, d );
205 }
206 
208 {
209  coord.clear();
210  QList< QList< QgsPointV2 > > featureCoord;
211  featureCoord.append( QList< QgsPointV2 >() << QgsPointV2( *this ) );
212  coord.append( featureCoord );
213 }
214 
215 bool QgsPointV2::moveVertex( const QgsVertexId& position, const QgsPointV2& newPos )
216 {
217  Q_UNUSED( position );
218  mX = newPos.mX;
219  mY = newPos.mY;
220  if ( is3D() && newPos.is3D() )
221  {
222  mZ = newPos.mZ;
223  }
224  if ( isMeasure() && newPos.isMeasure() )
225  {
226  mM = newPos.mM;
227  }
228  mBoundingBox = QgsRectangle(); //set bounding box invalid
229  return true;
230 }
231 
232 double QgsPointV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
233 {
234  Q_UNUSED( segmentPt ); Q_UNUSED( vertexAfter ); Q_UNUSED( leftOf ); Q_UNUSED( leftOf ); Q_UNUSED( epsilon );
235  return QgsGeometryUtils::sqrDistance2D( *this, pt );
236 }
237 
239 {
240  if ( id.vertex < 0 )
241  {
242  id.vertex = 0;
243  if ( id.part < 0 )
244  {
245  id.part = 0;
246  }
247  if ( id.ring < 0 )
248  {
249  id.ring = 0;
250  }
251  vertex = *this;
252  return true;
253  }
254  else
255  {
256  return false;
257  }
258 }
259 
260 bool QgsPointV2::addZValue( double zValue )
261 {
262  if ( QgsWKBTypes::hasZ( mWkbType ) )
263  return false;
264 
266  mZ = zValue;
267  return true;
268 }
269 
270 bool QgsPointV2::addMValue( double mValue )
271 {
272  if ( QgsWKBTypes::hasM( mWkbType ) )
273  return false;
274 
276  mM = mValue;
277  return true;
278 }
279 
281 {
282  qreal x, y;
283  t.map( mX, mY, &x, &y );
284  mX = x; mY = y;
285 }
QgsWKBTypes::Type wkbType() const
Returns the WKB type of the geometry.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
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 (...
QDomElement asGML3(QDomDocument &doc, int precision=17, const QString &ns="gml") const override
Returns a GML3 representation of the geometry.
Definition: qgspointv2.cpp:170
QDomNode appendChild(const QDomNode &newChild)
double x() const
Definition: qgspointv2.h:42
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform) override
Transforms the geometry using a coordinate transform.
Definition: qgspointv2.cpp:202
QPoint map(const QPoint &point) const
Abstract base class for all geometries.
void draw(QPainter &p) const override
Draws the geometry using the specified QPainter.
Definition: qgspointv2.cpp:191
TransformDirection
Enum used to indicate the direction (forward or inverse) of the transform.
bool operator==(const QgsPointV2 &pt) const
Definition: qgspointv2.cpp:42
QDomElement createElementNS(const QString &nsURI, const QString &qName)
bool operator!=(const QgsPointV2 &pt) const
Definition: qgspointv2.cpp:51
static endian_t endian()
Returns whether this machine uses big or little endian.
QString wktTypeStr() const
Returns the WKT type string of the geometry.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Definition: qgis.h:268
int size() const
bool nextVertex(QgsVertexId &id, QgsPointV2 &vertex) const override
Returns next vertex id and coordinates.
Definition: qgspointv2.cpp:238
double y() const
Definition: qgspointv2.h:43
QgsWKBTypes::Type readHeader() const
Definition: qgswkbptr.cpp:8
void drawRect(const QRectF &rectangle)
static Type flatType(Type type)
Definition: qgswkbtypes.cpp:46
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
void transformInPlace(double &x, double &y, double &z, TransformDirection direction=ForwardTransform) const
virtual QString geometryType() const override
Returns a unique string representing the geometry type.
Definition: qgspointv2.h:52
void append(const T &value)
static bool hasM(Type type)
Tests whether a WKB type contains m values.
QgsPointV2(double x=0.0, double y=0.0)
Definition: qgspointv2.cpp:27
static double sqrDistance2D(const QgsPointV2 &pt1, const QgsPointV2 &pt2)
Returns the squared 2D distance between two points.
Utility class for identifying a unique vertex within a geometry.
bool isMeasure() const
Returns true if the geometry contains m values.
double z() const
Definition: qgspointv2.h:44
void setAttribute(const QString &name, const QString &value)
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type.
void clear() override
Clears the geometry, ie reset it to a null geometry.
Definition: qgspointv2.cpp:196
Point geometry type.
Definition: qgspointv2.h:29
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
virtual QgsPointV2 * clone() const override
Clones the geometry by performing a deep copy.
Definition: qgspointv2.cpp:56
virtual void coordinateSequence(QList< QList< QList< QgsPointV2 > > > &coord) const override
Retrieves the sequence of geometries, rings and nodes.
Definition: qgspointv2.cpp:207
QDomElement asGML2(QDomDocument &doc, int precision=17, const QString &ns="gml") const override
Returns a GML2 representation of the geometry.
Definition: qgspointv2.cpp:160
virtual bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
Definition: qgspointv2.cpp:81
A class to represent a point.
Definition: qgspoint.h:63
QDomText createTextNode(const QString &value)
virtual bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
Definition: qgspointv2.cpp:270
QString qgsDoubleToString(const double &a, const int &precision=17)
Definition: qgis.h:257
double closestSegment(const QgsPointV2 &pt, QgsPointV2 &segmentPt, QgsVertexId &vertexAfter, bool *leftOf, double epsilon) const override
Searches for the closest segment of the geometry to a given point.
Definition: qgspointv2.cpp:232
virtual bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
Definition: qgspointv2.cpp:260
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
Definition: qgspointv2.cpp:148
unsigned char * asWkb(int &binarySize) const override
Returns a WKB representation of the geometry.
Definition: qgspointv2.cpp:129
QString asJSON(int precision=17) const override
Returns a GeoJSON representation of the geometry.
Definition: qgspointv2.cpp:184
virtual bool fromWkb(const unsigned char *wkb) override
Sets the geometry from a WKB string.
Definition: qgspointv2.cpp:61
Class for doing transforms between two map coordinate systems.
double m() const
Definition: qgspointv2.h:45
static Type parseType(const QString &wktStr)
Definition: qgswkbtypes.cpp:56
double ANALYSIS_EXPORT leftOf(Point3D *thepoint, Point3D *p1, Point3D *p2)
Returns whether 'thepoint' is left or right of the line from 'p1' to 'p2'.
virtual bool moveVertex(const QgsVertexId &position, const QgsPointV2 &newPos) override
Moves a vertex within the geometry.
Definition: qgspointv2.cpp:215
int wkbSize() const override
Returns the size of the WKB representation of the geometry.
Definition: qgspointv2.cpp:122
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type.