QGIS API Documentation  2.9.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsgeometry.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgeometry.h - Geometry (stored as Open Geospatial Consortium WKB)
3  -------------------------------------------------------------------
4 Date : 02 May 2005
5 Copyright : (C) 2005 by Brendan Morley
6 email : morb at ozemail dot com dot au
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #ifndef QGSGEOMETRY_H
17 #define QGSGEOMETRY_H
18 
19 #include <QString>
20 #include <QVector>
21 #include <QDomDocument>
22 
23 #include "qgis.h"
24 
25 #include <geos_c.h>
26 
27 #include "qgspoint.h"
28 #include "qgscoordinatetransform.h"
29 #include "qgsfeature.h"
30 
31 #include <QSet>
32 
34 
36 typedef QVector<QgsPoint> QgsPolyline;
37 
39 typedef QVector<QgsPolyline> QgsPolygon;
40 
42 typedef QVector<QgsPoint> QgsMultiPoint;
43 
45 typedef QVector<QgsPolyline> QgsMultiPolyline;
46 
48 typedef QVector<QgsPolygon> QgsMultiPolygon;
49 
50 class QgsRectangle;
51 
66 class QgsConstWkbPtr;
67 class QgsWkbPtr;
68 
69 class CORE_EXPORT QgsGeometry
70 {
71  public:
73  QgsGeometry();
74 
76  QgsGeometry( const QgsGeometry & );
77 
81  QgsGeometry & operator=( QgsGeometry const & rhs );
82 
84  ~QgsGeometry();
85 
90  static GEOSContextHandle_t getGEOSHandler();
91 
93  static QgsGeometry* fromWkt( QString wkt );
94 
96  static QgsGeometry* fromPoint( const QgsPoint& point );
98  static QgsGeometry* fromMultiPoint( const QgsMultiPoint& multipoint );
100  static QgsGeometry* fromPolyline( const QgsPolyline& polyline );
102  static QgsGeometry* fromMultiPolyline( const QgsMultiPolyline& multiline );
104  static QgsGeometry* fromPolygon( const QgsPolygon& polygon );
106  static QgsGeometry* fromMultiPolygon( const QgsMultiPolygon& multipoly );
108  static QgsGeometry* fromRect( const QgsRectangle& rect );
113  static QgsGeometry* fromQPointF( const QPointF& point );
114 
121  static QgsGeometry* fromQPolygonF( const QPolygonF& polygon );
122 
128  void fromGeos( GEOSGeometry* geos );
133  void fromWkb( unsigned char * wkb, size_t length );
134 
139  const unsigned char* asWkb() const;
140 
144  size_t wkbSize() const;
145 
149  const GEOSGeometry* asGeos() const;
150 
152  QGis::WkbType wkbType() const;
153 
155  QGis::GeometryType type() const;
156 
158  bool isMultipart() const;
159 
161  bool isGeosEqual( const QgsGeometry & ) const;
162 
164  bool isGeosValid() const;
165 
167  bool isGeosEmpty() const;
168 
170  double area() const;
171 
173  double length() const;
174 
175  double distance( const QgsGeometry &geom ) const;
176 
181  QgsPoint closestVertex( const QgsPoint& point, int& atVertex, int& beforeVertex, int& afterVertex, double& sqrDist ) const;
182 
195  void adjacentVertices( int atVertex, int& beforeVertex, int& afterVertex ) const;
196 
208  bool insertVertex( double x, double y, int beforeVertex );
209 
216  bool moveVertex( double x, double y, int atVertex );
217 
228  bool deleteVertex( int atVertex );
229 
235  QgsPoint vertexAt( int atVertex ) const;
236 
242  double sqrDistToVertexAt( QgsPoint& point, int atVertex ) const;
243 
250  double closestVertexWithContext( const QgsPoint& point, int& atVertex ) const;
251 
262  double closestSegmentWithContext( const QgsPoint& point, QgsPoint& minDistPoint, int& afterVertex, double* leftOf = 0, double epsilon = DEFAULT_SEGMENT_EPSILON ) const;
263 
267  int addRing( const QList<QgsPoint>& ring );
268 
272  int addPart( const QList<QgsPoint> &points, QGis::GeometryType geomType = QGis::UnknownGeometry );
273 
279  int addPart( GEOSGeometry *newPart );
280 
286  int addPart( QgsGeometry *newPart );
287 
290  int translate( double dx, double dy );
291 
294  int transform( const QgsCoordinateTransform& ct );
295 
299  int transform( const QTransform& ct );
300 
306  int rotate( double rotation, const QgsPoint& center );
307 
315  int splitGeometry( const QList<QgsPoint>& splitLine,
316  QList<QgsGeometry*>&newGeometries,
317  bool topological,
318  QList<QgsPoint> &topologyTestPoints );
319 
322  int reshapeGeometry( const QList<QgsPoint>& reshapeWithLine );
323 
327  int makeDifference( const QgsGeometry *other );
328 
330  QgsRectangle boundingBox() const;
331 
333  bool intersects( const QgsRectangle& r ) const;
334 
336  bool intersects( const QgsGeometry* geometry ) const;
337 
339  bool contains( const QgsPoint* p ) const;
340 
342  bool contains( const QgsGeometry* geometry ) const;
343 
345  bool disjoint( const QgsGeometry* geometry ) const;
346 
348  bool equals( const QgsGeometry* geometry ) const;
349 
351  bool touches( const QgsGeometry* geometry ) const;
352 
354  bool overlaps( const QgsGeometry* geometry ) const;
355 
357  bool within( const QgsGeometry* geometry ) const;
358 
360  bool crosses( const QgsGeometry* geometry ) const;
361 
364  QgsGeometry* buffer( double distance, int segments ) const;
365 
375  QgsGeometry* buffer( double distance, int segments, int endCapStyle, int joinStyle, double mitreLimit ) const;
376 
382  QgsGeometry* offsetCurve( double distance, int segments, int joinStyle, double mitreLimit ) const;
383 
385  QgsGeometry* simplify( double tolerance ) const;
386 
396  QgsGeometry* smooth( const unsigned int iterations = 1, const double offset = 0.25 ) const;
397 
401  QgsGeometry* centroid() const;
402 
404  QgsGeometry* pointOnSurface() const;
405 
407  QgsGeometry* convexHull() const;
408 
410  QgsGeometry* interpolate( double distance ) const;
411 
413  QgsGeometry* intersection( const QgsGeometry *geometry ) const;
414 
418  QgsGeometry* combine( const QgsGeometry* geometry ) const;
419 
421  QgsGeometry* difference( const QgsGeometry* geometry ) const;
422 
424  QgsGeometry* symDifference( const QgsGeometry* geometry ) const;
425 
430  QString exportToWkt( const int &precision = 17 ) const;
431 
436  QString exportToGeoJSON( const int &precision = 17 ) const;
437 
444  QgsGeometry* convertToType( QGis::GeometryType destType, bool destMultipart = false ) const;
445 
446  /* Accessor functions for getting geometry data */
447 
450  QgsPoint asPoint() const;
451 
454  QgsPolyline asPolyline() const;
455 
458  QgsPolygon asPolygon() const;
459 
462  QgsMultiPoint asMultiPoint() const;
463 
466  QgsMultiPolyline asMultiPolyline() const;
467 
470  QgsMultiPolygon asMultiPolygon() const;
471 
473  QList<QgsGeometry*> asGeometryCollection() const;
474 
479  QPointF asQPointF() const;
480 
486  QPolygonF asQPolygonF() const;
487 
491  bool deleteRing( int ringNum, int partNum = 0 );
492 
495  bool deletePart( int partNum );
496 
500  bool convertToMultiType();
501 
509  int avoidIntersections( QMap<QgsVectorLayer*, QSet<QgsFeatureId> > ignoreFeatures = ( QMap<QgsVectorLayer*, QSet<QgsFeatureId> >() ) );
510 
511  class Error
512  {
513  QString message;
514  QgsPoint location;
515  bool hasLocation;
516  public:
517  Error() : message( "none" ), hasLocation( false ) {}
518  Error( QString m ) : message( m ), hasLocation( false ) {}
519  Error( QString m, QgsPoint p ) : message( m ), location( p ), hasLocation( true ) {}
520 
521  QString what() { return message; }
522  QgsPoint where() { return location; }
523  bool hasWhere() { return hasLocation; }
524  };
525 
527  void validateGeometry( QList<Error> &errors );
528 
533  static QgsGeometry *unaryUnion( const QList< QgsGeometry*>& geometryList );
534 
543  static bool compare( const QgsPolyline& p1, const QgsPolyline& p2, double epsilon = 4 * DBL_EPSILON );
544 
553  static bool compare( const QgsPolygon& p1, const QgsPolygon& p2, double epsilon = 4 * DBL_EPSILON );
554 
564  static bool compare( const QgsMultiPolygon& p1, const QgsMultiPolygon& p2, double epsilon = 4 * DBL_EPSILON );
565 
566  private:
567  // Private variables
568 
569  // All of these are mutable since there may be on-the-fly
570  // conversions between WKB, GEOS and Wkt;
571  // However the intent is the const functions do not
572  // semantically change the value that this object represents.
573 
577  mutable unsigned char * mGeometry;
578 
580  mutable size_t mGeometrySize;
581 
583  mutable GEOSGeometry* mGeos;
584 
586  mutable bool mDirtyWkb;
587 
589  mutable bool mDirtyGeos;
590 
591 
592  // Private functions
593 
597  bool exportWkbToGeos() const;
598 
602  bool exportGeosToWkb() const;
603 
617  bool insertVertex( double x, double y,
618  int beforeVertex,
619  const GEOSCoordSequence* old_sequence,
620  GEOSCoordSequence** new_sequence );
621 
626  void transformVertex( QgsWkbPtr &wkbPtr, const QTransform& trans, bool hasZValue );
627 
632  void transformVertex( QgsWkbPtr &wkbPtr, const QgsCoordinateTransform& ct, bool hasZValue );
633 
634  //helper functions for geometry splitting
635 
640  int splitLinearGeometry( GEOSGeometry *splitLine, QList<QgsGeometry*>& newGeometries );
643  int splitPolygonGeometry( GEOSGeometry *splitLine, QList<QgsGeometry*>& newGeometries );
645  GEOSGeometry* linePointDifference( GEOSGeometry* GEOSsplitPoint );
646 
649  int topologicalTestPointsSplit( const GEOSGeometry* splitLine, QList<QgsPoint>& testPoints ) const;
650 
656  static GEOSGeometry* reshapeLine( const GEOSGeometry* origLine, const GEOSGeometry* reshapeLineGeos );
657 
663  static GEOSGeometry* reshapePolygon( const GEOSGeometry* polygon, const GEOSGeometry* reshapeLineGeos );
664 
666  QgsPolygon smoothPolygon( const QgsPolygon &polygon, const unsigned int iterations = 1, const double offset = 0.25 ) const;
668  QgsPolyline smoothLine( const QgsPolyline &polyline, const unsigned int iterations = 1, const double offset = 0.25 ) const;
669 
672  static GEOSGeometry* nodeGeometries( const GEOSGeometry *splitLine, const GEOSGeometry *poly );
673 
676  static int lineContainedInLine( const GEOSGeometry* line1, const GEOSGeometry* line2 );
677 
682  static int pointContainedInLine( const GEOSGeometry* point, const GEOSGeometry* line );
683 
685  static int geomDigits( const GEOSGeometry* geom );
686 
688  int numberOfGeometries( GEOSGeometry* g ) const;
689 
690  int mergeGeometriesMultiTypeSplit( QVector<GEOSGeometry*>& splitResult );
691 
693  QgsPoint asPoint( QgsConstWkbPtr &wkbPtr, bool hasZValue ) const;
694 
696  QgsPolyline asPolyline( QgsConstWkbPtr &wkbPtr, bool hasZValue ) const;
697 
699  QgsPolygon asPolygon( QgsConstWkbPtr &wkbPtr, bool hasZValue ) const;
700 
701  static bool geosRelOp( char( *op )( GEOSContextHandle_t handle, const GEOSGeometry*, const GEOSGeometry * ),
702  const QgsGeometry* a, const QgsGeometry* b );
703 
705  double leftOf( double x, double y, double& x1, double& y1, double& x2, double& y2 ) const;
706 
707  static inline bool moveVertex( QgsWkbPtr &wkbPtr, const double &x, const double &y, int atVertex, bool hasZValue, int &pointIndex, bool isRing );
708  static inline int deleteVertex( QgsConstWkbPtr &srcPtr, QgsWkbPtr &dstPtr, int atVertex, bool hasZValue, int &pointIndex, bool isRing, bool lastItem );
709  static inline bool insertVertex( QgsConstWkbPtr &srcPtr, QgsWkbPtr &dstPtr, int beforeVertex, const double &x, const double &y, bool hasZValue, int &pointIndex, bool isRing );
710 
712  QgsGeometry* convertToPoint( bool destMultipart ) const;
714  QgsGeometry* convertToLine( bool destMultipart ) const;
716  QgsGeometry* convertToPolygon( bool destMultipart ) const;
717 
718  static QgsPolyline createPolylineFromQPolygonF( const QPolygonF &polygon );
719  static QgsPolygon createPolygonFromQPolygonF( const QPolygonF &polygon );
720 }; // class QgsGeometry
721 
723 
725 CORE_EXPORT QDataStream& operator<<( QDataStream& out, const QgsGeometry& geometry );
727 CORE_EXPORT QDataStream& operator>>( QDataStream& in, QgsGeometry& geometry );
728 
729 class CORE_EXPORT QgsWkbPtr
730 {
731  mutable unsigned char *mP;
732 
733  public:
734  QgsWkbPtr( unsigned char *p ) { mP = p; }
735 
736  inline const QgsWkbPtr &operator>>( double &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
737  inline const QgsWkbPtr &operator>>( int &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
738  inline const QgsWkbPtr &operator>>( unsigned int &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
739  inline const QgsWkbPtr &operator>>( char &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
740  inline const QgsWkbPtr &operator>>( QGis::WkbType &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
741 #ifdef QT_ARCH_ARM
742  inline const QgsWkbPtr &operator>>( qreal &v ) const { double d; memcpy( &d, mP, sizeof( d ) ); mP += sizeof( d ); v = d; return *this; }
743 #endif
744 
745  inline QgsWkbPtr &operator<<( const double &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
746  inline QgsWkbPtr &operator<<( const int &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
747  inline QgsWkbPtr &operator<<( const unsigned int &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
748  inline QgsWkbPtr &operator<<( const char &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
749  inline QgsWkbPtr &operator<<( const QGis::WkbType &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
750 #ifdef QT_ARCH_ARM
751  inline QgsWkbPtr &operator<<( const qreal &v ) { double d = v; memcpy( mP, &d, sizeof( d ) ); mP += sizeof( d ); return *this; }
752 #endif
753 
754  inline void operator+=( int n ) { mP += n; }
755 
756  inline operator unsigned char *() const { return mP; }
757 };
758 
759 class CORE_EXPORT QgsConstWkbPtr
760 {
761  mutable unsigned char *mP;
762 
763  public:
764  QgsConstWkbPtr( const unsigned char *p ) { mP = ( unsigned char * ) p; }
765 
766  inline const QgsConstWkbPtr &operator>>( double &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
767  inline const QgsConstWkbPtr &operator>>( int &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
768  inline const QgsConstWkbPtr &operator>>( unsigned int &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
769  inline const QgsConstWkbPtr &operator>>( char &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
770  inline const QgsConstWkbPtr &operator>>( QGis::WkbType &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
771 #ifdef QT_ARCH_ARM
772  inline const QgsConstWkbPtr &operator>>( qreal &v ) const { double d; memcpy( &d, mP, sizeof( d ) ); mP += sizeof( d ); v = d; return *this; }
773 #endif
774 
775  inline void operator+=( int n ) { mP += n; }
776 
777  inline operator const unsigned char *() const { return mP; }
778 };
779 
780 #endif