QGIS API Documentation  2.11.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
qgsgeometry.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgeometry.cpp - 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 #include <limits>
17 #include <cstdarg>
18 #include <cstdio>
19 #include <cmath>
20 
21 #include "qgis.h"
22 #include "qgsgeometry.h"
23 #include "qgsgeometryeditutils.h"
24 #include "qgsgeometryfactory.h"
25 #include "qgsgeometryutils.h"
26 #include "qgsgeos.h"
27 #include "qgsapplication.h"
28 #include "qgslogger.h"
29 #include "qgsmessagelog.h"
30 #include "qgspoint.h"
31 #include "qgsrectangle.h"
32 
33 #include "qgsmaplayerregistry.h"
34 #include "qgsvectorlayer.h"
35 #include "qgsproject.h"
36 #include "qgsgeometryvalidator.h"
37 
38 #include "qgsmulticurvev2.h"
39 #include "qgsmultilinestringv2.h"
40 #include "qgsmultipointv2.h"
41 #include "qgsmultipolygonv2.h"
42 #include "qgsmultisurfacev2.h"
43 #include "qgspointv2.h"
44 #include "qgspolygonv2.h"
45 #include "qgslinestringv2.h"
46 
47 #ifndef Q_WS_WIN
48 #include <netinet/in.h>
49 #else
50 #include <winsock.h>
51 #endif
52 
54 {
55  QgsGeometryPrivate(): ref( 1 ), geometry( 0 ), mWkb( 0 ), mWkbSize( 0 ), mGeos( 0 ) {}
56  ~QgsGeometryPrivate() { delete geometry; delete[] mWkb; GEOSGeom_destroy_r( QgsGeos::getGEOSHandler(), mGeos ); }
59  mutable const unsigned char* mWkb; //store wkb pointer for backward compatibility
60  mutable int mWkbSize;
61  mutable GEOSGeometry* mGeos;
62 };
63 
65 {
66 }
67 
69 {
70  if ( d )
71  {
72  if ( !d->ref.deref() )
73  {
74  delete d;
75  }
76  }
77 }
78 
80 {
81  d->geometry = geom;
82  d->ref = QAtomicInt( 1 );
83 }
84 
86 {
87  d = other.d;
88  d->ref.ref();
89 }
90 
92 {
93  if ( !d->ref.deref() )
94  {
95  delete d;
96  }
97 
98  d = other.d;
99  d->ref.ref();
100  return *this;
101 }
102 
103 void QgsGeometry::detach( bool cloneGeom )
104 {
105  if ( !d )
106  {
107  return;
108  }
109 
110  if ( d->ref > 1 )
111  {
112  ( void )d->ref.deref();
113  QgsAbstractGeometryV2* cGeom = 0;
114 
115  if ( d->geometry && cloneGeom )
116  {
117  cGeom = d->geometry->clone();
118  }
119 
120  d = new QgsGeometryPrivate();
121  d->geometry = cGeom;
122  }
123 }
124 
125 void QgsGeometry::removeWkbGeos()
126 {
127  delete[] d->mWkb;
128  d->mWkb = 0;
129  d->mWkbSize = 0;
130  if ( d->mGeos )
131  {
132  GEOSGeom_destroy_r( QgsGeos::getGEOSHandler(), d->mGeos );
133  d->mGeos = 0;
134  }
135 }
136 
138 {
139  if ( !d )
140  {
141  return 0;
142  }
143  return d->geometry;
144 }
145 
147 {
148  detach( false );
149  if ( d->geometry )
150  {
151  delete d->geometry;
152  d->geometry = 0;
153  }
154  removeWkbGeos();
155 
156  d->geometry = geometry;
157 }
158 
160 {
161  return !d || !d->geometry;
162 }
163 
165 {
167  if ( !geom )
168  {
169  return 0;
170  }
171  return new QgsGeometry( geom );
172 }
173 
175 {
177  if ( geom )
178  {
179  return new QgsGeometry( geom );
180  }
181  return 0;
182 }
183 
185 {
187  if ( geom )
188  {
189  return new QgsGeometry( geom );
190  }
191  return 0;
192 }
193 
195 {
197  if ( geom )
198  {
199  return new QgsGeometry( geom );
200  }
201  return 0;
202 }
203 
205 {
207  if ( geom )
208  {
209  return new QgsGeometry( geom );
210  }
211  return 0;
212 }
213 
215 {
217  if ( geom )
218  {
219  return new QgsGeometry( geom );
220  }
221  return 0;
222 }
223 
225 {
227  if ( geom )
228  {
229  return new QgsGeometry( geom );
230  }
231  return 0;
232 }
233 
235 {
236  QgsPolyline ring;
237  ring.append( QgsPoint( rect.xMinimum(), rect.yMinimum() ) );
238  ring.append( QgsPoint( rect.xMaximum(), rect.yMinimum() ) );
239  ring.append( QgsPoint( rect.xMaximum(), rect.yMaximum() ) );
240  ring.append( QgsPoint( rect.xMinimum(), rect.yMaximum() ) );
241  ring.append( QgsPoint( rect.xMinimum(), rect.yMinimum() ) );
242 
243  QgsPolygon polygon;
244  polygon.append( ring );
245 
246  return fromPolygon( polygon );
247 }
248 
249 void QgsGeometry::fromWkb( unsigned char *wkb, size_t length )
250 {
251  Q_UNUSED( length );
252  if ( !d )
253  {
254  return;
255  }
256 
257  detach( false );
258 
259  if ( d->geometry )
260  {
261  delete d->geometry;
262  removeWkbGeos();
263  }
265  d->mWkb = wkb;
266  d->mWkbSize = length;
267 }
268 
269 const unsigned char *QgsGeometry::asWkb() const
270 {
271  if ( !d || !d->geometry )
272  {
273  return 0;
274  }
275 
276  if ( !d->mWkb )
277  {
278  d->mWkb = d->geometry->asWkb( d->mWkbSize );
279  }
280  return d->mWkb;
281 }
282 
283 size_t QgsGeometry::wkbSize() const
284 {
285  if ( !d || !d->geometry )
286  {
287  return 0;
288  }
289 
290  if ( !d->mWkb )
291  {
292  d->mWkb = d->geometry->asWkb( d->mWkbSize );
293  }
294  return d->mWkbSize;
295 }
296 
297 const GEOSGeometry* QgsGeometry::asGeos() const
298 {
299  if ( !d || !d->geometry )
300  {
301  return 0;
302  }
303 
304  if ( !d->mGeos )
305  {
306  d->mGeos = QgsGeos::asGeos( d->geometry );
307  }
308  return d->mGeos;
309 }
310 
311 
313 {
314  if ( !d || !d->geometry )
315  {
316  return QGis::WKBUnknown;
317  }
318  else
319  {
320  return ( QGis::WkbType )d->geometry->wkbType();
321  }
322 }
323 
324 
326 {
327  if ( !d || !d->geometry )
328  {
329  return QGis::UnknownGeometry;
330  }
332 }
333 
335 {
336  if ( !d || !d->geometry )
337  {
338  return false;
339  }
340  return QgsWKBTypes::isMultiType( d->geometry->wkbType() );
341 }
342 
343 void QgsGeometry::fromGeos( GEOSGeometry *geos )
344 {
345  if ( d )
346  {
347  detach( false );
348  delete d->geometry;
349  d->geometry = QgsGeos::fromGeos( geos );
350  d->mGeos = geos;
351  }
352 }
353 
354 QgsPoint QgsGeometry::closestVertex( const QgsPoint& point, int& atVertex, int& beforeVertex, int& afterVertex, double& sqrDist ) const
355 {
356  if ( !d || !d->geometry )
357  {
358  return QgsPoint( 0, 0 );
359  }
360  QgsPointV2 pt( point.x(), point.y() );
361  QgsVertexId id;
362 
363  QgsPointV2 vp = QgsGeometryUtils::closestVertex( *( d->geometry ), pt, id );
364  if ( !id.isValid() )
365  {
366  sqrDist = -1;
367  return QgsPoint( 0, 0 );
368  }
369  sqrDist = QgsGeometryUtils::sqrDistance2D( pt, vp );
370 
371  atVertex = vertexNrFromVertexId( id );
372  adjacentVertices( atVertex, beforeVertex, afterVertex );
373  return QgsPoint( vp.x(), vp.y() );
374 }
375 
376 void QgsGeometry::adjacentVertices( int atVertex, int& beforeVertex, int& afterVertex ) const
377 {
378  if ( !d || !d->geometry )
379  {
380  return;
381  }
382 
383  QgsVertexId id;
384  if ( !vertexIdFromVertexNr( atVertex, id ) )
385  {
386  beforeVertex = -1; afterVertex = -1;
387  return;
388  }
389 
390  QgsVertexId beforeVertexId, afterVertexId;
391  QgsGeometryUtils::adjacentVertices( *( d->geometry ), id, beforeVertexId, afterVertexId );
392  beforeVertex = vertexNrFromVertexId( beforeVertexId );
393  afterVertex = vertexNrFromVertexId( afterVertexId );
394 }
395 
396 bool QgsGeometry::moveVertex( double x, double y, int atVertex )
397 {
398  if ( !d || !d->geometry )
399  {
400  return false;
401  }
402 
403  QgsVertexId id;
404  if ( !vertexIdFromVertexNr( atVertex, id ) )
405  {
406  return false;
407  }
408 
409  detach( true );
410 
411  removeWkbGeos();
412  return d->geometry->moveVertex( id, QgsPointV2( x, y ) );
413 }
414 
415 bool QgsGeometry::moveVertex( const QgsPointV2& p, int atVertex )
416 {
417  if ( !d || !d->geometry )
418  {
419  return false;
420  }
421 
422  QgsVertexId id;
423  if ( !vertexIdFromVertexNr( atVertex, id ) )
424  {
425  return false;
426  }
427 
428  detach( true );
429 
430  removeWkbGeos();
431  return d->geometry->moveVertex( id, p );
432 }
433 
434 bool QgsGeometry::deleteVertex( int atVertex )
435 {
436  if ( !d || !d->geometry )
437  {
438  return false;
439  }
440 
441  QgsVertexId id;
442  if ( !vertexIdFromVertexNr( atVertex, id ) )
443  {
444  return false;
445  }
446 
447  detach( true );
448 
449  removeWkbGeos();
450  return d->geometry->deleteVertex( id );
451 }
452 
453 bool QgsGeometry::insertVertex( double x, double y, int beforeVertex )
454 {
455  if ( !d || !d->geometry )
456  {
457  return false;
458  }
459 
460  detach( true );
461 
462  QgsVertexId id;
463  if ( !vertexIdFromVertexNr( beforeVertex, id ) )
464  {
465  return false;
466  }
467 
468  removeWkbGeos();
469  return d->geometry->insertVertex( id, QgsPointV2( x, y ) );
470 }
471 
472 QgsPoint QgsGeometry::vertexAt( int atVertex ) const
473 {
474  if ( !d || !d->geometry )
475  {
476  return QgsPoint( 0, 0 );
477  }
478 
479  QgsVertexId vId;
480  ( void )vertexIdFromVertexNr( atVertex, vId );
481  if ( vId.vertex < 0 )
482  {
483  return QgsPoint( 0, 0 );
484  }
485  QgsPointV2 pt = d->geometry->vertexAt( vId );
486  return QgsPoint( pt.x(), pt.y() );
487 }
488 
489 double QgsGeometry::sqrDistToVertexAt( QgsPoint& point, int atVertex ) const
490 {
491  QgsPoint vertexPoint = vertexAt( atVertex );
492  return QgsGeometryUtils::sqrDistance2D( QgsPointV2( vertexPoint.x(), vertexPoint.y() ), QgsPointV2( point.x(), point.y() ) );
493 }
494 
495 double QgsGeometry::closestVertexWithContext( const QgsPoint& point, int& atVertex ) const
496 {
497  if ( !d || !d->geometry )
498  {
499  return 0.0;
500  }
501 
502  QgsVertexId vId;
503  QgsPointV2 pt( point.x(), point.y() );
504  QgsPointV2 closestPoint = QgsGeometryUtils::closestVertex( *( d->geometry ), pt, vId );
505  atVertex = vertexNrFromVertexId( vId );
506  return QgsGeometryUtils::sqrDistance2D( closestPoint, pt );
507 }
508 
510  const QgsPoint& point,
511  QgsPoint& minDistPoint,
512  int& afterVertex,
513  double *leftOf,
514  double epsilon ) const
515 {
516  if ( !d || !d->geometry )
517  {
518  return 0;
519  }
520 
521  QgsPointV2 segmentPt;
522  QgsVertexId vertexAfter;
523  bool leftOfBool;
524 
525  double sqrDist = d->geometry->closestSegment( QgsPointV2( point.x(), point.y() ), segmentPt, vertexAfter, &leftOfBool, epsilon );
526 
527  minDistPoint.setX( segmentPt.x() );
528  minDistPoint.setY( segmentPt.y() );
529  afterVertex = vertexNrFromVertexId( vertexAfter );
530  if ( leftOf )
531  {
532  *leftOf = leftOfBool ? 1.0 : -1.0;
533  }
534  return sqrDist;
535 }
536 
538 {
539  detach( true );
540 
541  removeWkbGeos();
542  QgsLineStringV2* ringLine = new QgsLineStringV2();
543  QList< QgsPointV2 > ringPoints;
544  convertPointList( ring, ringPoints );
545  ringLine->setPoints( ringPoints );
546  return addRing( ringLine );
547 }
548 
550 {
551  if ( !d || !d->geometry )
552  {
553  delete ring;
554  return 1;
555  }
556 
557  detach( true );
558 
559  removeWkbGeos();
560  return QgsGeometryEditUtils::addRing( d->geometry, ring );
561 }
562 
564 {
565  if ( !d )
566  {
567  return 1;
568  }
569 
570  if ( !d->geometry )
571  {
572  detach( false );
573  switch ( geomType )
574  {
575  case QGis::Point:
576  d->geometry = new QgsMultiPointV2();
577  break;
578  case QGis::Line:
579  d->geometry = new QgsMultiLineStringV2();
580  break;
581  case QGis::Polygon:
582  d->geometry = new QgsMultiPolygonV2();
583  break;
584  default:
585  return 1;
586  }
587  }
588 
590 
591  QgsAbstractGeometryV2* partGeom = 0;
592  if ( points.size() == 1 )
593  {
594  partGeom = new QgsPointV2( points[0].x(), points[0].y() );
595  }
596  else if ( points.size() > 1 )
597  {
598  QgsLineStringV2* ringLine = new QgsLineStringV2();
599  QList< QgsPointV2 > partPoints;
600  convertPointList( points, partPoints );
601  ringLine->setPoints( partPoints );
602  partGeom = ringLine;
603  }
604  return addPart( partGeom );
605 }
606 
608 {
609  detach( true );
610  removeWkbGeos();
611  return QgsGeometryEditUtils::addPart( d->geometry, part );
612 }
613 
614 int QgsGeometry::addPart( const QgsGeometry *newPart )
615 {
616  if ( !d || !d->geometry || !newPart || !newPart->d || !newPart->d->geometry )
617  {
618  return 1;
619  }
620 
621  return addPart( newPart->d->geometry->clone() );
622 }
623 
624 int QgsGeometry::addPart( GEOSGeometry *newPart )
625 {
626  if ( !d || !d->geometry || !newPart )
627  {
628  return 1;
629  }
630 
631  detach( true );
632 
633  QgsAbstractGeometryV2* geom = QgsGeos::fromGeos( newPart );
634  removeWkbGeos();
635  return QgsGeometryEditUtils::addPart( d->geometry, geom );
636 }
637 
638 int QgsGeometry::translate( double dx, double dy )
639 {
640  if ( !d || !d->geometry )
641  {
642  return 1;
643  }
644 
645  detach( true );
646 
648  removeWkbGeos();
649  return 0;
650 }
651 
652 int QgsGeometry::rotate( double rotation, const QgsPoint& center )
653 {
654  if ( !d || !d->geometry )
655  {
656  return 1;
657  }
658 
659  detach( true );
660 
661  QTransform t = QTransform::fromTranslate( center.x(), center.y() );
662  t.rotate( -rotation );
663  t.translate( -center.x(), -center.y() );
664  d->geometry->transform( t );
665  removeWkbGeos();
666  return 0;
667 }
668 
669 int QgsGeometry::splitGeometry( const QList<QgsPoint>& splitLine, QList<QgsGeometry*>& newGeometries, bool topological, QList<QgsPoint> &topologyTestPoints )
670 {
671  if ( !d || !d->geometry )
672  {
673  return 0;
674  }
675 
677  QgsLineStringV2 splitLineString;
678  QList<QgsPointV2> splitLinePointsV2;
679  convertPointList( splitLine, splitLinePointsV2 );
680  splitLineString.setPoints( splitLinePointsV2 );
682 
683  QgsGeos geos( d->geometry );
684  int result = geos.splitGeometry( splitLineString, newGeoms, topological, tp );
685 
686  if ( result == 0 )
687  {
688  detach( false );
689  d->geometry = newGeoms.at( 0 );
690 
691  newGeometries.clear();
692  for ( int i = 1; i < newGeoms.size(); ++i )
693  {
694  newGeometries.push_back( new QgsGeometry( newGeoms.at( i ) ) );
695  }
696  }
697 
698  convertPointList( tp, topologyTestPoints );
699  removeWkbGeos();
700  return result;
701 }
702 
704 int QgsGeometry::reshapeGeometry( const QList<QgsPoint>& reshapeWithLine )
705 {
706  if ( !d || !d->geometry )
707  {
708  return 0;
709  }
710 
711  QList<QgsPointV2> reshapeLine;
712  convertPointList( reshapeWithLine, reshapeLine );
713  QgsLineStringV2 reshapeLineString;
714  reshapeLineString.setPoints( reshapeLine );
715 
716  QgsGeos geos( d->geometry );
717  int errorCode = 0;
718  QgsAbstractGeometryV2* geom = geos.reshapeGeometry( reshapeLineString, &errorCode );
719  if ( errorCode == 0 && geom )
720  {
721  detach( false );
722  delete d->geometry;
723  d->geometry = geom;
724  return 0;
725  }
726  removeWkbGeos();
727  return errorCode;
728 }
729 
731 {
732  if ( !d || !d->geometry || !other->d || !other->d->geometry )
733  {
734  return 0;
735  }
736 
737  QgsGeos geos( d->geometry );
738 
739  QgsAbstractGeometryV2* diffGeom = geos.intersection( *( other->geometry() ) );
740  if ( !diffGeom )
741  {
742  return 1;
743  }
744 
745  detach( false );
746 
747  delete d->geometry;
748  d->geometry = diffGeom;
749  removeWkbGeos();
750  return 0;
751 }
752 
754 {
755  if ( d && d->geometry )
756  {
757  return d->geometry->boundingBox();
758  }
759  return QgsRectangle();
760 }
761 
762 bool QgsGeometry::intersects( const QgsRectangle& r ) const
763 {
764  QgsGeometry* g = fromRect( r );
765  bool res = intersects( g );
766  delete g;
767  return res;
768 }
769 
770 bool QgsGeometry::intersects( const QgsGeometry* geometry ) const
771 {
772  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
773  {
774  return false;
775  }
776 
777  QgsGeos geos( d->geometry );
778  return geos.intersects( *( geometry->d->geometry ) );
779 }
780 
781 bool QgsGeometry::contains( const QgsPoint* p ) const
782 {
783  if ( !d || !d->geometry || !p )
784  {
785  return false;
786  }
787 
788  QgsPointV2 pt( p->x(), p->y() );
789  QgsGeos geos( d->geometry );
790  return geos.contains( pt );
791 }
792 
793 bool QgsGeometry::contains( const QgsGeometry* geometry ) const
794 {
795  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
796  {
797  return false;
798  }
799 
800  QgsGeos geos( d->geometry );
801  return geos.contains( *( geometry->d->geometry ) );
802 }
803 
804 bool QgsGeometry::disjoint( const QgsGeometry* geometry ) const
805 {
806  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
807  {
808  return false;
809  }
810 
811  QgsGeos geos( d->geometry );
812  return geos.disjoint( *( geometry->d->geometry ) );
813 }
814 
815 bool QgsGeometry::equals( const QgsGeometry* geometry ) const
816 {
817  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
818  {
819  return false;
820  }
821 
822  QgsGeos geos( d->geometry );
823  return geos.isEqual( *( geometry->d->geometry ) );
824 }
825 
826 bool QgsGeometry::touches( const QgsGeometry* geometry ) const
827 {
828  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
829  {
830  return false;
831  }
832 
833  QgsGeos geos( d->geometry );
834  return geos.touches( *( geometry->d->geometry ) );
835 }
836 
837 bool QgsGeometry::overlaps( const QgsGeometry* geometry ) const
838 {
839  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
840  {
841  return false;
842  }
843 
844  QgsGeos geos( d->geometry );
845  return geos.overlaps( *( geometry->d->geometry ) );
846 }
847 
848 bool QgsGeometry::within( const QgsGeometry* geometry ) const
849 {
850  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
851  {
852  return false;
853  }
854 
855  QgsGeos geos( d->geometry );
856  return geos.within( *( geometry->d->geometry ) );
857 }
858 
859 bool QgsGeometry::crosses( const QgsGeometry* geometry ) const
860 {
861  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
862  {
863  return false;
864  }
865 
866  QgsGeos geos( d->geometry );
867  return geos.crosses( *( geometry->d->geometry ) );
868 }
869 
870 QString QgsGeometry::exportToWkt( const int &precision ) const
871 {
872  if ( !d || !d->geometry )
873  {
874  return QString();
875  }
876  return d->geometry->asWkt( precision );
877 }
878 
879 QString QgsGeometry::exportToGeoJSON( const int &precision ) const
880 {
881  if ( !d || !d->geometry )
882  {
883  return QString();
884  }
885  return d->geometry->asJSON( precision );
886 }
887 
888 QgsGeometry* QgsGeometry::convertToType( QGis::GeometryType destType, bool destMultipart ) const
889 {
890  switch ( destType )
891  {
892  case QGis::Point:
893  return convertToPoint( destMultipart );
894 
895  case QGis::Line:
896  return convertToLine( destMultipart );
897 
898  case QGis::Polygon:
899  return convertToPolygon( destMultipart );
900 
901  default:
902  return 0;
903  }
904 }
905 
907 {
908  if ( !d || !d->geometry )
909  {
910  return false;
911  }
912 
913  if ( isMultipart() ) //already multitype, no need to convert
914  {
915  return true;
916  }
917 
918  QgsGeometryCollectionV2* multiGeom = dynamic_cast<QgsGeometryCollectionV2*>
920  if ( !multiGeom )
921  {
922  return false;
923  }
924 
925  detach( true );
926  multiGeom->addGeometry( d->geometry );
927  d->geometry = multiGeom;
928  removeWkbGeos();
929  return true;
930 }
931 
933 {
934  if ( !d || !d->geometry || d->geometry->geometryType() != "Point" )
935  {
936  return QgsPoint();
937  }
938  QgsPointV2* pt = dynamic_cast<QgsPointV2*>( d->geometry );
939  if ( !pt )
940  {
941  return QgsPoint();
942  }
943 
944  return QgsPoint( pt->x(), pt->y() );
945 }
946 
948 {
949  QgsPolyline polyLine;
950  if ( !d || !d->geometry )
951  {
952  return polyLine;
953  }
954 
955  bool doSegmentation = ( d->geometry->geometryType() == "CompoundCurve" || d->geometry->geometryType() == "CircularString" );
956  QgsLineStringV2* line = 0;
957  if ( doSegmentation )
958  {
959  QgsCurveV2* curve = dynamic_cast<QgsCurveV2*>( d->geometry );
960  if ( !curve )
961  {
962  return polyLine;
963  }
964  line = curve->curveToLine();
965  }
966  else
967  {
968  line = dynamic_cast<QgsLineStringV2*>( d->geometry );
969  if ( !line )
970  {
971  return polyLine;
972  }
973  }
974 
975  int nVertices = line->numPoints();
976  polyLine.resize( nVertices );
977  for ( int i = 0; i < nVertices; ++i )
978  {
979  QgsPointV2 pt = line->pointN( i );
980  polyLine[i].setX( pt.x() );
981  polyLine[i].setY( pt.y() );
982  }
983 
984  if ( doSegmentation )
985  {
986  delete line;
987  }
988 
989  return polyLine;
990 }
991 
993 {
994  bool doSegmentation = ( d->geometry->geometryType() == "CurvePolygon" );
995 
996  QgsPolygonV2* p = 0;
997  if ( doSegmentation )
998  {
999  QgsCurvePolygonV2* curvePoly = dynamic_cast<QgsCurvePolygonV2*>( d->geometry );
1000  if ( !curvePoly )
1001  {
1002  return QgsPolygon();
1003  }
1004  p = curvePoly->toPolygon();
1005  }
1006  else
1007  {
1008  p = dynamic_cast<QgsPolygonV2*>( d->geometry );
1009  }
1010 
1011  if ( !p )
1012  {
1013  return QgsPolygon();
1014  }
1015 
1016  QgsPolygon polygon;
1017  convertPolygon( *p, polygon );
1018 
1019  if ( doSegmentation )
1020  {
1021  delete p;
1022  }
1023  return polygon;
1024 }
1025 
1027 {
1028  if ( !d || !d->geometry || d->geometry->geometryType() != "MultiPoint" )
1029  {
1030  return QgsMultiPoint();
1031  }
1032 
1033  const QgsMultiPointV2* mp = dynamic_cast<QgsMultiPointV2*>( d->geometry );
1034  if ( !mp )
1035  {
1036  return QgsMultiPoint();
1037  }
1038 
1039  int nPoints = mp->numGeometries();
1040  QgsMultiPoint multiPoint( nPoints );
1041  for ( int i = 0; i < nPoints; ++i )
1042  {
1043  const QgsPointV2* pt = static_cast<const QgsPointV2*>( mp->geometryN( i ) );
1044  multiPoint[i].setX( pt->x() );
1045  multiPoint[i].setY( pt->y() );
1046  }
1047  return multiPoint;
1048 }
1049 
1051 {
1052  if ( !d || !d->geometry )
1053  {
1054  return QgsMultiPolyline();
1055  }
1056 
1057  QgsGeometryCollectionV2* geomCollection = dynamic_cast<QgsGeometryCollectionV2*>( d->geometry );
1058  if ( !geomCollection )
1059  {
1060  return QgsMultiPolyline();
1061  }
1062 
1063  int nLines = geomCollection->numGeometries();
1064  if ( nLines < 1 )
1065  {
1066  return QgsMultiPolyline();
1067  }
1068 
1069  QgsMultiPolyline mpl;
1070  for ( int i = 0; i < nLines; ++i )
1071  {
1072  bool deleteLine = false;
1073  const QgsLineStringV2* line = dynamic_cast<const QgsLineStringV2*>( geomCollection->geometryN( i ) );
1074  if ( !line )
1075  {
1076  const QgsCurveV2* curve = dynamic_cast<const QgsCurveV2*>( geomCollection->geometryN( i ) );
1077  if ( !curve )
1078  {
1079  continue;
1080  }
1081  deleteLine = true;
1082  line = curve->curveToLine();
1083  }
1084 
1085  QList< QgsPointV2 > lineCoords;
1086  line->points( lineCoords );
1087  QgsPolyline polyLine;
1088  convertToPolyline( lineCoords, polyLine );
1089  mpl.append( polyLine );
1090 
1091  if ( deleteLine )
1092  {
1093  delete line;
1094  }
1095  }
1096  return mpl;
1097 }
1098 
1100 {
1101  if ( !d || !d->geometry )
1102  {
1103  return QgsMultiPolygon();
1104  }
1105 
1106  QgsGeometryCollectionV2* geomCollection = dynamic_cast<QgsGeometryCollectionV2*>( d->geometry );
1107  if ( !geomCollection )
1108  {
1109  return QgsMultiPolygon();
1110  }
1111 
1112  int nPolygons = geomCollection->numGeometries();
1113  if ( nPolygons < 1 )
1114  {
1115  return QgsMultiPolygon();
1116  }
1117 
1118  QgsMultiPolygon mp;
1119  for ( int i = 0; i < nPolygons; ++i )
1120  {
1121  const QgsPolygonV2* polygon = dynamic_cast<const QgsPolygonV2*>( geomCollection->geometryN( i ) );
1122  if ( !polygon )
1123  {
1124  const QgsCurvePolygonV2* cPolygon = dynamic_cast<const QgsCurvePolygonV2*>( geomCollection->geometryN( i ) );
1125  if ( cPolygon )
1126  {
1127  polygon = cPolygon->toPolygon();
1128  }
1129  else
1130  {
1131  continue;
1132  }
1133  }
1134 
1135  QgsPolygon poly;
1136  convertPolygon( *polygon, poly );
1137  mp.append( poly );
1138  }
1139  return mp;
1140 }
1141 
1142 double QgsGeometry::area() const
1143 {
1144  if ( !d || !d->geometry )
1145  {
1146  return -1.0;
1147  }
1148  QgsGeos g( d->geometry );
1149 
1150 #if 0
1151  //debug: compare geos area with calculation in QGIS
1152  double geosArea = g.area();
1153  double qgisArea = 0;
1154  QgsSurfaceV2* surface = dynamic_cast<QgsSurfaceV2*>( d->geometry );
1155  if ( surface )
1156  {
1157  qgisArea = surface->area();
1158  }
1159 #endif
1160 
1161  return g.area();
1162 }
1163 
1164 double QgsGeometry::length() const
1165 {
1166  if ( !d || !d->geometry )
1167  {
1168  return -1.0;
1169  }
1170  QgsGeos g( d->geometry );
1171  return g.length();
1172 }
1173 
1174 double QgsGeometry::distance( const QgsGeometry& geom ) const
1175 {
1176  if ( !d || !d->geometry || !geom.d || !geom.d->geometry )
1177  {
1178  return -1.0;
1179  }
1180 
1181  QgsGeos g( d->geometry );
1182  return g.distance( *( geom.d->geometry ) );
1183 }
1184 
1185 QgsGeometry* QgsGeometry::buffer( double distance, int segments ) const
1186 {
1187  if ( !d || !d->geometry )
1188  {
1189  return 0;
1190  }
1191 
1192  QgsGeos g( d->geometry );
1193  QgsAbstractGeometryV2* geom = g.buffer( distance, segments );
1194  if ( !geom )
1195  {
1196  return 0;
1197  }
1198  return new QgsGeometry( geom );
1199 }
1200 
1201 QgsGeometry* QgsGeometry::buffer( double distance, int segments, int endCapStyle, int joinStyle, double mitreLimit ) const
1202 {
1203  if ( !d || !d->geometry )
1204  {
1205  return 0;
1206  }
1207 
1208  QgsGeos g( d->geometry );
1209  QgsAbstractGeometryV2* geom = g.buffer( distance, segments, endCapStyle, joinStyle, mitreLimit );
1210  if ( !geom )
1211  {
1212  return 0;
1213  }
1214  return new QgsGeometry( geom );
1215 }
1216 
1217 QgsGeometry* QgsGeometry::offsetCurve( double distance, int segments, int joinStyle, double mitreLimit ) const
1218 {
1219  if ( !d || !d->geometry )
1220  {
1221  return 0;
1222  }
1223 
1224  QgsGeos geos( d->geometry );
1225  QgsAbstractGeometryV2* offsetGeom = geos.offsetCurve( distance, segments, joinStyle, mitreLimit );
1226  if ( !offsetGeom )
1227  {
1228  return 0;
1229  }
1230  return new QgsGeometry( offsetGeom );
1231 }
1232 
1233 QgsGeometry* QgsGeometry::simplify( double tolerance ) const
1234 {
1235  if ( !d || !d->geometry )
1236  {
1237  return 0;
1238  }
1239 
1240  QgsGeos geos( d->geometry );
1241  QgsAbstractGeometryV2* simplifiedGeom = geos.simplify( tolerance );
1242  if ( !simplifiedGeom )
1243  {
1244  return 0;
1245  }
1246  return new QgsGeometry( simplifiedGeom );
1247 }
1248 
1250 {
1251  if ( !d || !d->geometry )
1252  {
1253  return 0;
1254  }
1255 
1256  QgsGeos geos( d->geometry );
1258  bool ok = geos.centroid( centroid );
1259  if ( !ok )
1260  {
1261  return 0;
1262  }
1263  return new QgsGeometry( centroid.clone() );
1264 }
1265 
1267 {
1268  if ( !d || !d->geometry )
1269  {
1270  return 0;
1271  }
1272 
1273  QgsGeos geos( d->geometry );
1274  QgsPointV2 pt;
1275  bool ok = geos.pointOnSurface( pt );
1276  if ( !ok )
1277  {
1278  return 0;
1279  }
1280  return new QgsGeometry( pt.clone() );
1281 }
1282 
1284 {
1285  if ( !d || !d->geometry )
1286  {
1287  return 0;
1288  }
1289  QgsGeos geos( d->geometry );
1290  QgsAbstractGeometryV2* cHull = geos.convexHull();
1291  if ( !cHull )
1292  {
1293  return 0;
1294  }
1295  return new QgsGeometry( cHull );
1296 }
1297 
1298 QgsGeometry* QgsGeometry::interpolate( double distance ) const
1299 {
1300  if ( !d || !d->geometry )
1301  {
1302  return 0;
1303  }
1304  QgsGeos geos( d->geometry );
1305  QgsAbstractGeometryV2* result = geos.interpolate( distance );
1306  if ( !result )
1307  {
1308  return 0;
1309  }
1310  return new QgsGeometry( result );
1311 }
1312 
1314 {
1315  if ( !d || !d->geometry || !geometry->d || !geometry->d->geometry )
1316  {
1317  return 0;
1318  }
1319 
1320  QgsGeos geos( d->geometry );
1321 
1322  QgsAbstractGeometryV2* resultGeom = geos.intersection( *( geometry->d->geometry ) );
1323  return new QgsGeometry( resultGeom );
1324 }
1325 
1327 {
1328  if ( !d || !d->geometry || !geometry->d || !geometry->d->geometry )
1329  {
1330  return 0;
1331  }
1332 
1333  QgsGeos geos( d->geometry );
1334 
1335  QgsAbstractGeometryV2* resultGeom = geos.combine( *( geometry->d->geometry ) );
1336  if ( !resultGeom )
1337  {
1338  return 0;
1339  }
1340  return new QgsGeometry( resultGeom );
1341 }
1342 
1344 {
1345  if ( !d || !d->geometry || !geometry->d || !geometry->d->geometry )
1346  {
1347  return 0;
1348  }
1349 
1350  QgsGeos geos( d->geometry );
1351 
1352  QgsAbstractGeometryV2* resultGeom = geos.difference( *( geometry->d->geometry ) );
1353  if ( !resultGeom )
1354  {
1355  return 0;
1356  }
1357  return new QgsGeometry( resultGeom );
1358 }
1359 
1361 {
1362  if ( !d || !d->geometry || !geometry->d || !geometry->d->geometry )
1363  {
1364  return 0;
1365  }
1366 
1367  QgsGeos geos( d->geometry );
1368 
1369  QgsAbstractGeometryV2* resultGeom = geos.symDifference( *( geometry->d->geometry ) );
1370  if ( !resultGeom )
1371  {
1372  return 0;
1373  }
1374  return new QgsGeometry( resultGeom );
1375 }
1376 
1378 {
1379  QList<QgsGeometry*> geometryList;
1380  if ( !d || !d->geometry )
1381  {
1382  return geometryList;
1383  }
1384 
1385  QgsGeometryCollectionV2* gc = dynamic_cast<QgsGeometryCollectionV2*>( d->geometry );
1386  if ( gc )
1387  {
1388  int numGeom = gc->numGeometries();
1389  for ( int i = 0; i < numGeom; ++i )
1390  {
1391  geometryList.append( new QgsGeometry( gc->geometryN( i )->clone() ) );
1392  }
1393  }
1394  else //a singlepart geometry
1395  {
1396  geometryList.append( new QgsGeometry( d->geometry->clone() ) );
1397  }
1398 
1399  return geometryList;
1400 }
1401 
1403 {
1404  QgsPoint point = asPoint();
1405  return point.toQPointF();
1406 }
1407 
1409 {
1410  QPolygonF result;
1411  QgsPolyline polyline;
1413  if ( type == QGis::WKBLineString || type == QGis::WKBLineString25D )
1414  {
1415  polyline = asPolyline();
1416  }
1417  else if ( type == QGis::WKBPolygon || type == QGis::WKBPolygon25D )
1418  {
1419  QgsPolygon polygon = asPolygon();
1420  if ( polygon.size() < 1 )
1421  return result;
1422  polyline = polygon.at( 0 );
1423  }
1424  else
1425  {
1426  return result;
1427  }
1428 
1429  QgsPolyline::const_iterator lineIt = polyline.constBegin();
1430  for ( ; lineIt != polyline.constEnd(); ++lineIt )
1431  {
1432  result << lineIt->toQPointF();
1433  }
1434  return result;
1435 }
1436 
1437 bool QgsGeometry::deleteRing( int ringNum, int partNum )
1438 {
1439  if ( !d || !d->geometry )
1440  {
1441  return false;
1442  }
1443 
1444  detach( true );
1445 
1446  return QgsGeometryEditUtils::deleteRing( d->geometry, ringNum, partNum );
1447 }
1448 
1449 bool QgsGeometry::deletePart( int partNum )
1450 {
1451  if ( !d || !d->geometry )
1452  {
1453  return false;
1454  }
1455 
1456  if ( !isMultipart() && partNum < 1 )
1457  {
1458  setGeometry( 0 );
1459  return true;
1460  }
1461 
1462  detach( true );
1463  bool ok = QgsGeometryEditUtils::deletePart( d->geometry, partNum );
1464  removeWkbGeos();
1465  return ok;
1466 }
1467 
1469 {
1470  if ( !d || !d->geometry )
1471  {
1472  return 1;
1473  }
1474 
1475  QgsAbstractGeometryV2* diffGeom = QgsGeometryEditUtils::avoidIntersections( *( d->geometry ), ignoreFeatures );
1476  if ( diffGeom )
1477  {
1478  detach( false );
1479  d->geometry = diffGeom;
1480  removeWkbGeos();
1481  }
1482  return 0;
1483 }
1484 
1486 {
1488 }
1489 
1491 {
1492  if ( !d || !d->geometry )
1493  {
1494  return false;
1495  }
1496 
1497  QgsGeos geos( d->geometry );
1498  return geos.isValid();
1499 }
1500 
1502 {
1503  if ( !d || !d->geometry || !g.d || !g.d->geometry )
1504  {
1505  return false;
1506  }
1507 
1508  QgsGeos geos( d->geometry );
1509  return geos.isEqual( *( g.d->geometry ) );
1510 }
1511 
1513 {
1514  if ( !d || !d->geometry )
1515  {
1516  return false;
1517  }
1518 
1519  QgsGeos geos( d->geometry );
1520  return geos.isEmpty();
1521 }
1522 
1524 {
1525  QgsGeos geos( 0 );
1526 
1528  QList<QgsGeometry*>::const_iterator it = geometryList.constBegin();
1529  for ( ; it != geometryList.constEnd(); ++it )
1530  {
1531  if ( *it )
1532  {
1533  geomV2List.append(( *it )->geometry() );
1534  }
1535  }
1536 
1537  QgsAbstractGeometryV2* geom = geos.combine( geomV2List );
1538  return new QgsGeometry( geom );
1539 }
1540 
1542 {
1543  if ( !d || !d->geometry || !requiresConversionToStraightSegments() )
1544  {
1545  return;
1546  }
1547 
1548  QgsAbstractGeometryV2* straightGeom = d->geometry->segmentize();
1549  detach( false );
1550 
1551  d->geometry = straightGeom;
1552  removeWkbGeos();
1553 }
1554 
1556 {
1557  if ( !d || !d->geometry )
1558  {
1559  return false;
1560  }
1561 
1562  return d->geometry->hasCurvedSegments();
1563 }
1564 
1566 {
1567  if ( !d || !d->geometry )
1568  {
1569  return 1;
1570  }
1571 
1572  detach();
1573  d->geometry->transform( ct );
1574  removeWkbGeos();
1575  return 0;
1576 }
1577 
1579 {
1580  if ( !d || !d->geometry )
1581  {
1582  return 1;
1583  }
1584 
1585  detach();
1586  d->geometry->transform( ct );
1587  removeWkbGeos();
1588  return 0;
1589 }
1590 
1592 {
1593  if ( d && d->geometry )
1594  {
1595  detach();
1596  d->geometry->transform( mtp.transform() );
1597  }
1598 }
1599 
1600 #if 0
1601 void QgsGeometry::clip( const QgsRectangle& rect )
1602 {
1603  if ( d && d->geometry )
1604  {
1605  detach();
1606  d->geometry->clip( rect );
1607  removeWkbGeos();
1608  }
1609 }
1610 #endif
1611 
1612 void QgsGeometry::draw( QPainter& p ) const
1613 {
1614  if ( d && d->geometry )
1615  {
1616  d->geometry->draw( p );
1617  }
1618 }
1619 
1621 {
1622  if ( !d || !d->geometry )
1623  {
1624  return false;
1625  }
1626 
1628  d->geometry->coordinateSequence( coords );
1629 
1630  int vertexCount = 0;
1631  for ( int part = 0; part < coords.size(); ++part )
1632  {
1633  const QList< QList< QgsPointV2 > >& featureCoords = coords.at( part );
1634  for ( int ring = 0; ring < featureCoords.size(); ++ring )
1635  {
1636  const QList< QgsPointV2 >& ringCoords = featureCoords.at( ring );
1637  for ( int vertex = 0; vertex < ringCoords.size(); ++vertex )
1638  {
1639  if ( vertexCount == nr )
1640  {
1641  id.part = part;
1642  id.ring = ring;
1643  id.vertex = vertex;
1644  return true;
1645  }
1646  ++vertexCount;
1647  }
1648  }
1649  }
1650  return false;
1651 }
1652 
1654 {
1655  if ( !d || !d->geometry )
1656  {
1657  return false;
1658  }
1659 
1661  d->geometry->coordinateSequence( coords );
1662 
1663  int vertexCount = 0;
1664  for ( int part = 0; part < coords.size(); ++part )
1665  {
1666  const QList< QList< QgsPointV2 > >& featureCoords = coords.at( part );
1667  for ( int ring = 0; ring < featureCoords.size(); ++ring )
1668  {
1669  const QList< QgsPointV2 >& ringCoords = featureCoords.at( ring );
1670  for ( int vertex = 0; vertex < ringCoords.size(); ++vertex )
1671  {
1672  if ( vertex == id.vertex && ring == id.ring && part == id.part )
1673  {
1674  return vertexCount;
1675  }
1676  ++vertexCount;
1677  }
1678  }
1679  }
1680  return -1;
1681 }
1682 
1684 {
1685  output.clear();
1687  for ( ; it != input.constEnd(); ++it )
1688  {
1689  output.append( QgsPointV2( it->x(), it->y() ) );
1690  }
1691 }
1692 
1694 {
1695  output.clear();
1697  for ( ; it != input.constEnd(); ++it )
1698  {
1699  output.append( QgsPoint( it->x(), it->y() ) );
1700  }
1701 }
1702 
1703 void QgsGeometry::convertToPolyline( const QList<QgsPointV2>& input, QgsPolyline& output )
1704 {
1705  output.clear();
1706  output.resize( input.size() );
1707 
1708  for ( int i = 0; i < input.size(); ++i )
1709  {
1710  const QgsPointV2& pt = input.at( i );
1711  output[i].setX( pt.x() );
1712  output[i].setY( pt.y() );
1713  }
1714 }
1715 
1716 void QgsGeometry::convertPolygon( const QgsPolygonV2& input, QgsPolygon& output )
1717 {
1718  output.clear();
1720  input.coordinateSequence( coord );
1721  if ( coord.size() < 1 )
1722  {
1723  return;
1724  }
1725 
1726  const QList< QList< QgsPointV2 > >& rings = coord[0];
1727  output.resize( rings.size() );
1728  for ( int i = 0; i < rings.size(); ++i )
1729  {
1730  convertToPolyline( rings[i], output[i] );
1731  }
1732 }
1733 
1734 GEOSContextHandle_t QgsGeometry::getGEOSHandler()
1735 {
1736  return QgsGeos::getGEOSHandler();
1737 }
1738 
1740 {
1741  return new QgsGeometry( new QgsPointV2( point.x(), point.y() ) );
1742 }
1743 
1745 {
1746  if ( polygon.isClosed() )
1747  {
1749  }
1750  else
1751  {
1753  }
1754 }
1755 
1757 {
1758  QgsPolygon result;
1759  result << createPolylineFromQPolygonF( polygon );
1760  return result;
1761 }
1762 
1764 {
1765  QgsPolyline result;
1766  QPolygonF::const_iterator it = polygon.constBegin();
1767  for ( ; it != polygon.constEnd(); ++it )
1768  {
1769  result.append( QgsPoint( *it ) );
1770  }
1771  return result;
1772 }
1773 
1774 bool QgsGeometry::compare( const QgsPolyline &p1, const QgsPolyline &p2, double epsilon )
1775 {
1776  if ( p1.count() != p2.count() )
1777  return false;
1778 
1779  for ( int i = 0; i < p1.count(); ++i )
1780  {
1781  if ( !p1.at( i ).compare( p2.at( i ), epsilon ) )
1782  return false;
1783  }
1784  return true;
1785 }
1786 
1787 bool QgsGeometry::compare( const QgsPolygon &p1, const QgsPolygon &p2, double epsilon )
1788 {
1789  if ( p1.count() != p2.count() )
1790  return false;
1791 
1792  for ( int i = 0; i < p1.count(); ++i )
1793  {
1794  if ( !QgsGeometry::compare( p1.at( i ), p2.at( i ), epsilon ) )
1795  return false;
1796  }
1797  return true;
1798 }
1799 
1800 
1801 bool QgsGeometry::compare( const QgsMultiPolygon &p1, const QgsMultiPolygon &p2, double epsilon )
1802 {
1803  if ( p1.count() != p2.count() )
1804  return false;
1805 
1806  for ( int i = 0; i < p1.count(); ++i )
1807  {
1808  if ( !QgsGeometry::compare( p1.at( i ), p2.at( i ), epsilon ) )
1809  return false;
1810  }
1811  return true;
1812 }
1813 
1814 QgsGeometry* QgsGeometry::smooth( const unsigned int iterations, const double offset ) const
1815 {
1816  switch ( wkbType() )
1817  {
1818  case QGis::WKBPoint:
1819  case QGis::WKBPoint25D:
1820  case QGis::WKBMultiPoint:
1822  //can't smooth a point based geometry
1823  return new QgsGeometry( *this );
1824 
1825  case QGis::WKBLineString:
1827  {
1828  QgsPolyline line = asPolyline();
1829  return QgsGeometry::fromPolyline( smoothLine( line, iterations, offset ) );
1830  }
1831 
1834  {
1835  QgsMultiPolyline multiline = asMultiPolyline();
1836  QgsMultiPolyline resultMultiline;
1837  QgsMultiPolyline::const_iterator lineIt = multiline.constBegin();
1838  for ( ; lineIt != multiline.constEnd(); ++lineIt )
1839  {
1840  resultMultiline << smoothLine( *lineIt, iterations, offset );
1841  }
1842  return QgsGeometry::fromMultiPolyline( resultMultiline );
1843  }
1844 
1845  case QGis::WKBPolygon:
1846  case QGis::WKBPolygon25D:
1847  {
1848  QgsPolygon poly = asPolygon();
1849  return QgsGeometry::fromPolygon( smoothPolygon( poly, iterations, offset ) );
1850  }
1851 
1852  case QGis::WKBMultiPolygon:
1854  {
1855  QgsMultiPolygon multipoly = asMultiPolygon();
1856  QgsMultiPolygon resultMultipoly;
1857  QgsMultiPolygon::const_iterator polyIt = multipoly.constBegin();
1858  for ( ; polyIt != multipoly.constEnd(); ++polyIt )
1859  {
1860  resultMultipoly << smoothPolygon( *polyIt, iterations, offset );
1861  }
1862  return QgsGeometry::fromMultiPolygon( resultMultipoly );
1863  }
1864  break;
1865 
1866  case QGis::WKBUnknown:
1867  default:
1868  return new QgsGeometry( *this );
1869  }
1870 }
1871 
1872 inline QgsPoint interpolatePointOnLine( const QgsPoint& p1, const QgsPoint& p2, const double offset )
1873 {
1874  double deltaX = p2.x() - p1.x();
1875  double deltaY = p2.y() - p1.y();
1876  return QgsPoint( p1.x() + deltaX * offset, p1.y() + deltaY * offset );
1877 }
1878 
1879 QgsPolyline QgsGeometry::smoothLine( const QgsPolyline& polyline, const unsigned int iterations, const double offset ) const
1880 {
1881  QgsPolyline result = polyline;
1882  for ( unsigned int iteration = 0; iteration < iterations; ++iteration )
1883  {
1884  QgsPolyline outputLine = QgsPolyline();
1885  for ( int i = 0; i < result.count() - 1; i++ )
1886  {
1887  const QgsPoint& p1 = result.at( i );
1888  const QgsPoint& p2 = result.at( i + 1 );
1889  outputLine << ( i == 0 ? result.at( i ) : interpolatePointOnLine( p1, p2, offset ) );
1890  outputLine << ( i == result.count() - 2 ? result.at( i + 1 ) : interpolatePointOnLine( p1, p2, 1.0 - offset ) );
1891  }
1892  result = outputLine;
1893  }
1894  return result;
1895 }
1896 
1897 QgsPolygon QgsGeometry::smoothPolygon( const QgsPolygon& polygon, const unsigned int iterations, const double offset ) const
1898 {
1899  QgsPolygon resultPoly;
1900  QgsPolygon::const_iterator ringIt = polygon.constBegin();
1901  for ( ; ringIt != polygon.constEnd(); ++ringIt )
1902  {
1903  QgsPolyline resultRing = *ringIt;
1904  for ( unsigned int iteration = 0; iteration < iterations; ++iteration )
1905  {
1906  QgsPolyline outputRing = QgsPolyline();
1907  for ( int i = 0; i < resultRing.count() - 1; ++i )
1908  {
1909  const QgsPoint& p1 = resultRing.at( i );
1910  const QgsPoint& p2 = resultRing.at( i + 1 );
1911  outputRing << interpolatePointOnLine( p1, p2, offset );
1912  outputRing << interpolatePointOnLine( p1, p2, 1.0 - offset );
1913  }
1914  //close polygon
1915  outputRing << outputRing.at( 0 );
1916 
1917  resultRing = outputRing;
1918  }
1919  resultPoly << resultRing;
1920  }
1921  return resultPoly;
1922 }
1923 
1924 QgsGeometry* QgsGeometry::convertToPoint( bool destMultipart ) const
1925 {
1926  switch ( type() )
1927  {
1928  case QGis::Point:
1929  {
1930  bool srcIsMultipart = isMultipart();
1931 
1932  if (( destMultipart && srcIsMultipart ) ||
1933  ( !destMultipart && !srcIsMultipart ) )
1934  {
1935  // return a copy of the same geom
1936  return new QgsGeometry( *this );
1937  }
1938  if ( destMultipart )
1939  {
1940  // layer is multipart => make a multipoint with a single point
1941  return fromMultiPoint( QgsMultiPoint() << asPoint() );
1942  }
1943  else
1944  {
1945  // destination is singlepart => make a single part if possible
1946  QgsMultiPoint multiPoint = asMultiPoint();
1947  if ( multiPoint.count() == 1 )
1948  {
1949  return fromPoint( multiPoint[0] );
1950  }
1951  }
1952  return 0;
1953  }
1954 
1955  case QGis::Line:
1956  {
1957  // only possible if destination is multipart
1958  if ( !destMultipart )
1959  return 0;
1960 
1961  // input geometry is multipart
1962  if ( isMultipart() )
1963  {
1964  QgsMultiPolyline multiLine = asMultiPolyline();
1965  QgsMultiPoint multiPoint;
1966  for ( QgsMultiPolyline::const_iterator multiLineIt = multiLine.constBegin(); multiLineIt != multiLine.constEnd(); ++multiLineIt )
1967  for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt )
1968  multiPoint << *lineIt;
1969  return fromMultiPoint( multiPoint );
1970  }
1971  // input geometry is not multipart: copy directly the line into a multipoint
1972  else
1973  {
1974  QgsPolyline line = asPolyline();
1975  if ( !line.isEmpty() )
1976  return fromMultiPoint( line );
1977  }
1978  return 0;
1979  }
1980 
1981  case QGis::Polygon:
1982  {
1983  // can only transform if destination is multipoint
1984  if ( !destMultipart )
1985  return 0;
1986 
1987  // input geometry is multipart: make a multipoint from multipolygon
1988  if ( isMultipart() )
1989  {
1990  QgsMultiPolygon multiPolygon = asMultiPolygon();
1991  QgsMultiPoint multiPoint;
1992  for ( QgsMultiPolygon::const_iterator polygonIt = multiPolygon.constBegin(); polygonIt != multiPolygon.constEnd(); ++polygonIt )
1993  for ( QgsMultiPolyline::const_iterator multiLineIt = ( *polygonIt ).constBegin(); multiLineIt != ( *polygonIt ).constEnd(); ++multiLineIt )
1994  for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt )
1995  multiPoint << *lineIt;
1996  return fromMultiPoint( multiPoint );
1997  }
1998  // input geometry is not multipart: make a multipoint from polygon
1999  else
2000  {
2001  QgsPolygon polygon = asPolygon();
2002  QgsMultiPoint multiPoint;
2003  for ( QgsMultiPolyline::const_iterator multiLineIt = polygon.constBegin(); multiLineIt != polygon.constEnd(); ++multiLineIt )
2004  for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt )
2005  multiPoint << *lineIt;
2006  return fromMultiPoint( multiPoint );
2007  }
2008  }
2009 
2010  default:
2011  return 0;
2012  }
2013 }
2014 
2015 QgsGeometry* QgsGeometry::convertToLine( bool destMultipart ) const
2016 {
2017  switch ( type() )
2018  {
2019  case QGis::Point:
2020  {
2021  if ( !isMultipart() )
2022  return 0;
2023 
2024  QgsMultiPoint multiPoint = asMultiPoint();
2025  if ( multiPoint.count() < 2 )
2026  return 0;
2027 
2028  if ( destMultipart )
2029  return fromMultiPolyline( QgsMultiPolyline() << multiPoint );
2030  else
2031  return fromPolyline( multiPoint );
2032  }
2033 
2034  case QGis::Line:
2035  {
2036  bool srcIsMultipart = isMultipart();
2037 
2038  if (( destMultipart && srcIsMultipart ) ||
2039  ( !destMultipart && ! srcIsMultipart ) )
2040  {
2041  // return a copy of the same geom
2042  return new QgsGeometry( *this );
2043  }
2044  if ( destMultipart )
2045  {
2046  // destination is multipart => makes a multipoint with a single line
2047  QgsPolyline line = asPolyline();
2048  if ( !line.isEmpty() )
2049  return fromMultiPolyline( QgsMultiPolyline() << line );
2050  }
2051  else
2052  {
2053  // destination is singlepart => make a single part if possible
2054  QgsMultiPolyline multiLine = asMultiPolyline();
2055  if ( multiLine.count() == 1 )
2056  return fromPolyline( multiLine[0] );
2057  }
2058  return 0;
2059  }
2060 
2061  case QGis::Polygon:
2062  {
2063  // input geometry is multipolygon
2064  if ( isMultipart() )
2065  {
2066  QgsMultiPolygon multiPolygon = asMultiPolygon();
2067  QgsMultiPolyline multiLine;
2068  for ( QgsMultiPolygon::const_iterator polygonIt = multiPolygon.constBegin(); polygonIt != multiPolygon.constEnd(); ++polygonIt )
2069  for ( QgsMultiPolyline::const_iterator multiLineIt = ( *polygonIt ).constBegin(); multiLineIt != ( *polygonIt ).constEnd(); ++multiLineIt )
2070  multiLine << *multiLineIt;
2071 
2072  if ( destMultipart )
2073  {
2074  // destination is multipart
2075  return fromMultiPolyline( multiLine );
2076  }
2077  else if ( multiLine.count() == 1 )
2078  {
2079  // destination is singlepart => make a single part if possible
2080  return fromPolyline( multiLine[0] );
2081  }
2082  }
2083  // input geometry is single polygon
2084  else
2085  {
2086  QgsPolygon polygon = asPolygon();
2087  // if polygon has rings
2088  if ( polygon.count() > 1 )
2089  {
2090  // cannot fit a polygon with rings in a single line layer
2091  // TODO: would it be better to remove rings?
2092  if ( destMultipart )
2093  {
2094  QgsPolygon polygon = asPolygon();
2095  QgsMultiPolyline multiLine;
2096  for ( QgsMultiPolyline::const_iterator multiLineIt = polygon.constBegin(); multiLineIt != polygon.constEnd(); ++multiLineIt )
2097  multiLine << *multiLineIt;
2098  return fromMultiPolyline( multiLine );
2099  }
2100  }
2101  // no rings
2102  else if ( polygon.count() == 1 )
2103  {
2104  if ( destMultipart )
2105  {
2106  return fromMultiPolyline( polygon );
2107  }
2108  else
2109  {
2110  return fromPolyline( polygon[0] );
2111  }
2112  }
2113  }
2114  return 0;
2115  }
2116 
2117  default:
2118  return 0;
2119  }
2120 }
2121 
2122 QgsGeometry* QgsGeometry::convertToPolygon( bool destMultipart ) const
2123 {
2124  switch ( type() )
2125  {
2126  case QGis::Point:
2127  {
2128  if ( !isMultipart() )
2129  return 0;
2130 
2131  QgsMultiPoint multiPoint = asMultiPoint();
2132  if ( multiPoint.count() < 3 )
2133  return 0;
2134 
2135  if ( multiPoint.last() != multiPoint.first() )
2136  multiPoint << multiPoint.first();
2137 
2138  QgsPolygon polygon = QgsPolygon() << multiPoint;
2139  if ( destMultipart )
2140  return fromMultiPolygon( QgsMultiPolygon() << polygon );
2141  else
2142  return fromPolygon( polygon );
2143  }
2144 
2145  case QGis::Line:
2146  {
2147  // input geometry is multiline
2148  if ( isMultipart() )
2149  {
2150  QgsMultiPolyline multiLine = asMultiPolyline();
2151  QgsMultiPolygon multiPolygon;
2152  for ( QgsMultiPolyline::iterator multiLineIt = multiLine.begin(); multiLineIt != multiLine.end(); ++multiLineIt )
2153  {
2154  // do not create polygon for a 1 segment line
2155  if (( *multiLineIt ).count() < 3 )
2156  return 0;
2157  if (( *multiLineIt ).count() == 3 && ( *multiLineIt ).first() == ( *multiLineIt ).last() )
2158  return 0;
2159 
2160  // add closing node
2161  if (( *multiLineIt ).first() != ( *multiLineIt ).last() )
2162  *multiLineIt << ( *multiLineIt ).first();
2163  multiPolygon << ( QgsPolygon() << *multiLineIt );
2164  }
2165  // check that polygons were inserted
2166  if ( !multiPolygon.isEmpty() )
2167  {
2168  if ( destMultipart )
2169  {
2170  return fromMultiPolygon( multiPolygon );
2171  }
2172  else if ( multiPolygon.count() == 1 )
2173  {
2174  // destination is singlepart => make a single part if possible
2175  return fromPolygon( multiPolygon[0] );
2176  }
2177  }
2178  }
2179  // input geometry is single line
2180  else
2181  {
2182  QgsPolyline line = asPolyline();
2183 
2184  // do not create polygon for a 1 segment line
2185  if ( line.count() < 3 )
2186  return 0;
2187  if ( line.count() == 3 && line.first() == line.last() )
2188  return 0;
2189 
2190  // add closing node
2191  if ( line.first() != line.last() )
2192  line << line.first();
2193 
2194  // destination is multipart
2195  if ( destMultipart )
2196  {
2197  return fromMultiPolygon( QgsMultiPolygon() << ( QgsPolygon() << line ) );
2198  }
2199  else
2200  {
2201  return fromPolygon( QgsPolygon() << line );
2202  }
2203  }
2204  return 0;
2205  }
2206 
2207  case QGis::Polygon:
2208  {
2209  bool srcIsMultipart = isMultipart();
2210 
2211  if (( destMultipart && srcIsMultipart ) ||
2212  ( !destMultipart && ! srcIsMultipart ) )
2213  {
2214  // return a copy of the same geom
2215  return new QgsGeometry( *this );
2216  }
2217  if ( destMultipart )
2218  {
2219  // destination is multipart => makes a multipoint with a single polygon
2220  QgsPolygon polygon = asPolygon();
2221  if ( !polygon.isEmpty() )
2222  return fromMultiPolygon( QgsMultiPolygon() << polygon );
2223  }
2224  else
2225  {
2226  QgsMultiPolygon multiPolygon = asMultiPolygon();
2227  if ( multiPolygon.count() == 1 )
2228  {
2229  // destination is singlepart => make a single part if possible
2230  return fromPolygon( multiPolygon[0] );
2231  }
2232  }
2233  return 0;
2234  }
2235 
2236  default:
2237  return 0;
2238  }
2239 }
2240 
2242 {
2243  return new QgsGeos( geometry );
2244 }
2245 
2247 {
2248  QByteArray byteArray = QByteArray::fromRawData(( char * )geometry.asWkb(), geometry.wkbSize() ); // does not copy data and does not take ownership
2249  out << byteArray;
2250  return out;
2251 }
2252 
2254 {
2255  QByteArray byteArray;
2256  in >> byteArray;
2257  if ( byteArray.isEmpty() )
2258  {
2259  geometry.setGeometry( 0 );
2260  return in;
2261  }
2262 
2263  char *data = new char[byteArray.size()];
2264  memcpy( data, byteArray.data(), byteArray.size() );
2265  geometry.fromWkb(( unsigned char* )data, byteArray.size() );
2266  return in;
2267 }
2268 
2269 
2270 
QTransform fromTranslate(qreal dx, qreal dy)
QgsPolyline smoothLine(const QgsPolyline &polyline, const unsigned int iterations=1, const double offset=0.25) const
Smooths a polyline using the Chaikin algorithm.
QgsAbstractGeometryV2 * reshapeGeometry(const QgsLineStringV2 &reshapeWithLine, int *errorCode) const
Definition: qgsgeos.cpp:1482
static QgsGeometry * fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
QgsGeometry * simplify(double tolerance) const
Returns a simplified version of this geometry using a specified tolerance value.
QgsAbstractGeometryV2 * difference(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:136
void clear()
QgsWKBTypes::Type wkbType() const
Returns the WKB type of the geometry.
bool isEqual(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:1290
A rectangle specified with double values.
Definition: qgsrectangle.h:35
bool isValid() const override
Definition: qgsgeos.cpp:1276
static bool isMultiType(Type type)
Definition: qgswkbtypes.cpp:75
QgsPointV2 pointN(int i) const
const QgsAbstractGeometryV2 * geometry() const
Returns the underlying geometry store.
QgsGeometry * convexHull() const
Returns the smallest convex polygon that contains all the points in the geometry. ...
QDataStream & operator<<(QDataStream &out, const QgsGeometry &geometry)
Writes the geometry to stream out.
QgsGeometry * symDifference(const QgsGeometry *geometry) const
Returns a Geometry representing the points making up this Geometry that do not make up other...
QgsAbstractGeometryV2 * interpolate(double distance) const override
Definition: qgsgeos.cpp:1189
static Type multiType(Type type)
Definition: qgswkbtypes.cpp:36
int reshapeGeometry(const QList< QgsPoint > &reshapeWithLine)
Replaces a part of this geometry with another line.
void append(const T &value)
double x() const
Definition: qgspointv2.h:41
QPolygonF asQPolygonF() const
Return contents of the geometry as a QPolygonF.
iterator begin()
void push_back(const T &value)
QgsGeometry * difference(const QgsGeometry *geometry) const
Returns a geometry representing the points making up this geometry that do not make up other...
double distance(const QgsGeometry &geom) const
Returns the minimum distanace between this geometry and another geometry, using GEOS.
size_t wkbSize() const
Returns the size of the WKB in asWkb().
QgsAbstractGeometryV2 * convexHull() const override
Definition: qgsgeos.cpp:1259
void points(QList< QgsPointV2 > &pt) const override
Returns a list of points within the curve.
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:192
typedef iterator
virtual bool moveVertex(const QgsVertexId &position, const QgsPointV2 &newPos)=0
Moves a vertex within the geometry.
QgsMultiPolyline asMultiPolyline() const
Return contents of the geometry as a multi linestring if wkbType is WKBMultiLineString, otherwise an empty list.
QVector< QgsPoint > QgsPolyline
Polyline is represented as a vector of points.
Definition: qgsgeometry.h:43
QPointF asQPointF() const
Return contents of the geometry as a QPointF if wkbType is WKBPoint, otherwise returns a null QPointF...
QgsPolygon asPolygon() const
Return contents of the geometry as a polygon if wkbType is WKBPolygon, otherwise an empty list...
const_iterator constEnd() const
QList< QgsGeometry * > asGeometryCollection() const
Return contents of the geometry as a list of geometries.
QgsPoint transform(const QgsPoint &p) const
Transform the point from map (world) coordinates to device coordinates.
const T & at(int i) const
T & last()
QgsAbstractGeometryV2 * simplify(double tolerance) const override
Definition: qgsgeos.cpp:1174
virtual QString asJSON(int precision=17) const =0
Returns a GeoJSON representation of the geometry.
void setGeometry(QgsAbstractGeometryV2 *geometry)
Sets the underlying geometry store.
QgsRectangle boundingBox() const
Returns the bounding box of this feature.
int makeDifference(const QgsGeometry *other)
Changes this geometry such that it does not intersect the other geometry.
bool moveVertex(double x, double y, int atVertex)
Moves the vertex at the given position number and item (first number is index 0) to the given coordin...
QGis::GeometryType type() const
Returns type of the geometry as a QGis::GeometryType.
static QgsAbstractGeometryV2 * fromPolygon(const QgsPolygon &polygon)
Construct geometry from a polygon.
Abstract base class for all geometries.
bool crosses(const QgsGeometry *geometry) const
Test for if geometry crosses another (uses GEOS)
bool ref()
void adjacentVertices(int atVertex, int &beforeVertex, int &afterVertex) const
Returns the indexes of the vertices before and after the given vertex index.
double length() const override
Definition: qgsgeos.cpp:250
QgsGeometry * pointOnSurface() const
Returns a point within a geometry.
int addPart(const QList< QgsPoint > &points, QGis::GeometryType geomType=QGis::UnknownGeometry)
Adds a new island polygon to a multipolygon feature.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:75
static QgsAbstractGeometryV2 * fromGeos(const GEOSGeometry *geos)
Definition: qgsgeos.cpp:746
double distance(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:175
static QgsPointV2 closestVertex(const QgsAbstractGeometryV2 &geom, const QgsPointV2 &pt, QgsVertexId &id)
Returns the closest vertex to a geometry for a specified point.
QByteArray fromRawData(const char *data, int size)
GeometryType
Definition: qgis.h:155
QgsGeometry()
Constructor.
Definition: qgsgeometry.cpp:64
T & first()
Multi point geometry collection.
WkbType
Used for symbology operations.
Definition: qgis.h:53
static QgsAbstractGeometryV2 * fromPolyline(const QgsPolyline &polyline)
Construct geometry from a polyline.
static QgsAbstractGeometryV2 * fromPoint(const QgsPoint &point)
Construct geometry from a point.
static QgsAbstractGeometryV2 * fromMultiPolygon(const QgsMultiPolygon &multipoly)
Construct geometry from a multipolygon.
bool insertVertex(double x, double y, int beforeVertex)
Insert a new vertex before the given vertex index, ring and item (first number is index 0) If the req...
bool pointOnSurface(QgsPointV2 &pt) const override
Definition: qgsgeos.cpp:1230
QgsPointV2 vertexAt(const QgsVertexId &id) const
Returns the point corresponding to a specified vertex id.
bool within(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:213
QgsGeometry & operator=(QgsGeometry const &rhs)
Assignments will prompt a deep copy of the object.
Definition: qgsgeometry.cpp:91
Multi line string geometry collection.
static QgsPolyline createPolylineFromQPolygonF(const QPolygonF &polygon)
Creates a QgsPolyline from a QPolygonF.
virtual void coordinateSequence(QList< QList< QList< QgsPointV2 > > > &coord) const override
Retrieves the sequence of geometries, rings and nodes.
static int addPart(QgsAbstractGeometryV2 *geom, QgsAbstractGeometryV2 *part)
Adds part to multi type geometry (taking ownership)
double x() const
Get the x value of the point.
Definition: qgspoint.h:126
bool deleteRing(int ringNum, int partNum=0)
Delete a ring in polygon or multipolygon.
bool contains(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:223
const GEOSGeometry * asGeos() const
Returns a geos geometry.
static GEOSContextHandle_t getGEOSHandler()
Definition: qgsgeos.cpp:2020
int size() const
virtual bool insertVertex(const QgsVertexId &position, const QgsPointV2 &vertex)=0
Inserts a vertex into the geometry.
QgsMultiPolygon asMultiPolygon() const
Return contents of the geometry as a multi polygon if wkbType is WKBMultiPolygon, otherwise an empty ...
double y() const
Definition: qgspointv2.h:42
static QgsAbstractGeometryV2 * geomFromWkt(const QString &text)
Construct geometry from a WKT string.
bool deletePart(int partNum)
Delete part identified by the part number.
bool isGeosEmpty() const
Check if the geometry is empty using GEOS.
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:34
Polygon geometry type.
Definition: qgspolygonv2.h:29
bool crosses(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:208
int splitGeometry(const QList< QgsPoint > &splitLine, QList< QgsGeometry * > &newGeometries, bool topological, QList< QgsPoint > &topologyTestPoints)
Splits this geometry according to a given line.
void clear()
int vertexNrFromVertexId(const QgsVertexId &i) const
Returns the vertex number corresponding to a vertex idd.
bool contains(const QgsPoint *p) const
Test for containment of a point (uses GEOS)
QTransform & translate(qreal dx, qreal dy)
static QgsAbstractGeometryV2 * fromMultiPoint(const QgsMultiPoint &multipoint)
Construct geometry from a multipoint.
qreal x() const
qreal y() const
void append(const T &value)
static void adjacentVertices(const QgsAbstractGeometryV2 &geom, const QgsVertexId &atVertex, QgsVertexId &beforeVertex, QgsVertexId &afterVertex)
Returns vertices adjacent to a specified vertex within a geometry.
void resize(int size)
static double sqrDistance2D(const QgsPointV2 &pt1, const QgsPointV2 &pt2)
Returns the squared 2D distance between two points.
int splitGeometry(const QgsLineStringV2 &splitLine, QList< QgsAbstractGeometryV2 * > &newGeometries, bool topological, QList< QgsPointV2 > &topologyTestPoints) const override
Splits this geometry according to a given line.
Definition: qgsgeos.cpp:266
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:197
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:182
Utility class for identifying a unique vertex within a geometry.
virtual QgsAbstractGeometryV2 * clone() const override
Clones the geometry by performing a deep copy.
Definition: qgspointv2.cpp:51
Line string geometry type.
QgsPoint interpolatePointOnLine(const QgsPoint &p1, const QgsPoint &p2, const double offset)
static void convertPointList(const QList< QgsPoint > &input, QList< QgsPointV2 > &output)
bool overlaps(const QgsGeometry *geometry) const
Test for if geometry overlaps another (uses GEOS)
static GeometryType geometryType(Type type)
Definition: qgswkbtypes.cpp:99
Point geometry type.
Definition: qgspointv2.h:29
bool deleteVertex(int atVertex)
Deletes the vertex at the given position number and item (first number is index 0) Returns false if a...
QgsPolygon smoothPolygon(const QgsPolygon &polygon, const unsigned int iterations=1, const double offset=0.25) const
Smooths a polygon using the Chaikin algorithm.
QgsPoint closestVertex(const QgsPoint &point, int &atVertex, int &beforeVertex, int &afterVertex, double &sqrDist) const
Returns the vertex closest to the given point, the corresponding vertex index, squared distance snap ...
QgsGeometry * interpolate(double distance) const
int avoidIntersections(QMap< QgsVectorLayer *, QSet< QgsFeatureId > > ignoreFeatures=(QMap< QgsVectorLayer *, QSet< QgsFeatureId > >()))
Modifies geometry to avoid intersections with the layers specified in project properties.
static bool compare(const QgsPolyline &p1, const QgsPolyline &p2, double epsilon=4 *DBL_EPSILON)
Compares two polylines for equality within a specified tolerance.
QVector< QgsPolygon > QgsMultiPolygon
A collection of QgsPolygons that share a common collection of attributes.
Definition: qgsgeometry.h:58
QVector< QgsPoint > QgsMultiPoint
A collection of QgsPoints that share a common collection of attributes.
Definition: qgsgeometry.h:52
void fromGeos(GEOSGeometry *geos)
Set the geometry, feeding in a geometry in GEOS format.
virtual bool hasCurvedSegments() const
Returns true if the geometry contains curved segments.
virtual unsigned char * asWkb(int &binarySize) const =0
Returns a WKB representation of the geometry.
virtual QgsPolygonV2 * toPolygon() const
virtual void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform)=0
Transforms the geometry using a coordinate transform.
QGis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
QgsAbstractGeometryV2 * intersection(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:131
double closestSegmentWithContext(const QgsPoint &point, QgsPoint &minDistPoint, int &afterVertex, double *leftOf=0, double epsilon=DEFAULT_SEGMENT_EPSILON) const
Searches for the closest segment of geometry to the given point.
QVector< QgsPolyline > QgsPolygon
Polygon: first item of the list is outer ring, inner rings (if any) start from second item...
Definition: qgsgeometry.h:49
QgsGeometry * centroid() const
Returns the center of mass of a geometry.
void validateGeometry(QList< Error > &errors)
Validate geometry and produce a list of geometry errors.
void convertToStraightSegment()
Converts the geometry to straight line segments, if it is a curved geometry type. ...
static QgsAbstractGeometryV2 * geomFromWkbType(QgsWKBTypes::Type t)
Return empty geometry from wkb type.
Does vector analysis using the geos library and handles import, export, exception handling*...
Definition: qgsgeos.h:29
bool deref()
QgsGeometry * buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
A class to represent a point.
Definition: qgspoint.h:63
bool isClosed() const
static QgsGeometry * fromPoint(const QgsPoint &point)
Creates a new geometry from a QgsPoint object.
int translate(double dx, double dy)
Translate this geometry by dx, dy.
void draw(QPainter &p) const
Draws the geometry onto a QPainter.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometryV2 *geometry)
Creates and returns a new geometry engine.
void setX(double x)
Sets the x value of the point.
Definition: qgspoint.h:103
virtual QString geometryType() const =0
Returns a unique string representing the geometry type.
void setY(double y)
Sets the y value of the point.
Definition: qgspoint.h:111
QgsAbstractGeometryV2 * symDifference(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:170
static void validateGeometry(const QgsGeometry *g, QList< QgsGeometry::Error > &errors)
Validate geometry and produce a list of geometry errors.
double length() const
Returns the length of geometry using GEOS.
QVector< QgsPolyline > QgsMultiPolyline
A collection of QgsPolylines that share a common collection of attributes.
Definition: qgsgeometry.h:55
virtual QgsAbstractGeometryV2 * segmentize() const
Returns a version of the geometry without curves.
static QgsAbstractGeometryV2 * geomFromWkb(const unsigned char *wkb)
Construct geometry from a WKB string.
static QgsGeometry * fromMultiPolyline(const QgsMultiPolyline &multiline)
Creates a new geometry from a QgsMultiPolyline object.
static QgsGeometry * fromQPointF(const QPointF &point)
Construct geometry from a QPointF.
static bool deletePart(QgsAbstractGeometryV2 *geom, int partNum)
Deletes a part from a geometry.
QTransform & rotate(qreal angle, Qt::Axis axis)
bool isGeosEqual(const QgsGeometry &) const
Compares the geometry with another geometry using GEOS.
QgsGeometry * intersection(const QgsGeometry *geometry) const
Returns a geometry representing the points shared by this geometry and other.
bool vertexIdFromVertexNr(int nr, QgsVertexId &id) const
Calculates the vertex ID from a vertex number.
QgsGeometry * combine(const QgsGeometry *geometry) const
Returns a geometry representing all the points in this geometry and other (a union geometry operation...
static bool deleteRing(QgsAbstractGeometryV2 *geom, int ringNum, int partNum=0)
Deletes a ring from a geometry.
QgsPolyline asPolyline() const
Return contents of the geometry as a polyline if wkbType is WKBLineString, otherwise an empty list...
static QgsAbstractGeometryV2 * avoidIntersections(const QgsAbstractGeometryV2 &geom, QMap< QgsVectorLayer *, QSet< QgsFeatureId > > ignoreFeatures=(QMap< QgsVectorLayer *, QSet< QgsFeatureId > >()))
Alters a geometry so that it avoids intersections with features from all open vector layers...
virtual bool deleteVertex(const QgsVertexId &position)=0
Deletes a vertex within the geometry.
int numGeometries() const
Returns the number of geometries within the collection.
static QgsPolygon createPolygonFromQPolygonF(const QPolygonF &polygon)
Creates a QgsPolygon from a QPolygonF.
const T & at(int i) const
virtual QgsLineStringV2 * curveToLine() const =0
Returns a new line string geometry corresponding to a segmentized approximation of the curve...
const_iterator constBegin() const
QgsAbstractGeometryV2 * offsetCurve(double distance, int segments, int joinStyle, double mitreLimit) const override
Definition: qgsgeos.cpp:1466
bool intersects(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:198
static GEOSGeometry * asGeos(const QgsAbstractGeometryV2 *geom)
Definition: qgsgeos.cpp:934
bool convertToMultiType()
Converts single type geometry into multitype geometry e.g.
void setPoints(const QList< QgsPointV2 > &points)
static GEOSContextHandle_t getGEOSHandler()
Return GEOS context handle.
void mapToPixel(const QgsMapToPixel &mtp)
Transforms the geometry from map units to pixels in place.
QString exportToGeoJSON(const int &precision=17) const
Exports the geometry to GeoJSON.
QgsGeometry * offsetCurve(double distance, int segments, int joinStyle, double mitreLimit) const
Returns an offset line at a given distance and side from an input line.
bool isEmpty() const
bool centroid(QgsPointV2 &pt) const override
Definition: qgsgeos.cpp:1204
void fromWkb(unsigned char *wkb, size_t length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length...
QgsMultiPoint asMultiPoint() const
Return contents of the geometry as a multi point if wkbType is WKBMultiPoint, otherwise an empty list...
bool equals(const QgsGeometry *geometry) const
Test for if geometry equals another (uses GEOS)
const unsigned char * mWkb
Definition: qgsgeometry.cpp:59
int rotate(double rotation, const QgsPoint &center)
Rotate this geometry around the Z axis.
QgsAbstractGeometryV2 * combine(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:141
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
bool overlaps(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:218
virtual bool addGeometry(QgsAbstractGeometryV2 *g)
Adds a geometry and takes ownership.
virtual double area() const
Returns the area of the geometry.
int count(const T &value) const
bool within(const QgsGeometry *geometry) const
Test for if geometry is within another (uses GEOS)
virtual void coordinateSequence(QList< QList< QList< QgsPointV2 > > > &coord) const =0
Retrieves the sequence of geometries, rings and nodes.
Class for doing transforms between two map coordinate systems.
virtual QString asWkt(int precision=17) const =0
Returns a WKT representation of the geometry.
const QgsAbstractGeometryV2 * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
static QgsGeometry * fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
bool requiresConversionToStraightSegments() const
Returns true if the geometry is a curved geometry type which requires conversion to display as straig...
int transform(const QgsCoordinateTransform &ct)
Transform this geometry as described by CoordinateTransform ct.
static QgsGeometry * fromMultiPoint(const QgsMultiPoint &multipoint)
Creates a new geometry from a QgsMultiPoint object.
static QgsAbstractGeometryV2 * fromMultiPolyline(const QgsMultiPolyline &multiline)
Construct geometry from a multipolyline.
static QgsGeometry * fromPolyline(const QgsPolyline &polyline)
Creates a new geometry from a QgsPolyline object.
static QgsGeometry * fromWkt(QString wkt)
Creates a new geometry from a WKT string.
double y() const
Get the y value of the point.
Definition: qgspoint.h:134
static int addRing(QgsAbstractGeometryV2 *geom, QgsCurveV2 *ring)
Adds interior ring (taking ownership).
static QgsGeometry * unaryUnion(const QList< QgsGeometry * > &geometryList)
Compute the unary union on a list of geometries.
Multi polygon geometry collection.
Contains geometry relation and modification algorithms.
bool disjoint(const QgsGeometry *geometry) const
Test for if geometry is disjoint of another (uses GEOS)
virtual void draw(QPainter &p) const =0
Draws the geometry using the specified QPainter.
bool isEmpty() const
Returns true if the geometry is empty (ie, contains no underlying geometry accessible via geometry)...
static QgsGeometry * fromMultiPolygon(const QgsMultiPolygon &multipoly)
Creates a new geometry from a QgsMultiPolygon.
QgsAbstractGeometryV2 * buffer(double distance, int segments) const override
Definition: qgsgeos.cpp:1136
typedef const_iterator
GEOSGeometry * mGeos
Definition: qgsgeometry.cpp:61
static QgsGeometry * fromPolygon(const QgsPolygon &polygon)
Creates a new geometry from a QgsPolygon.
~QgsGeometry()
Destructor.
Definition: qgsgeometry.cpp:68
bool touches(const QgsGeometry *geometry) const
Test for if geometry touch another (uses GEOS)
double ANALYSIS_EXPORT leftOf(Point3D *thepoint, Point3D *p1, Point3D *p2)
Returns whether 'thepoint' is left or right of the line from 'p1' to 'p2'.
Curve polygon geometry type.
int addRing(const QList< QgsPoint > &ring)
Adds a new ring to this geometry.
const_iterator constEnd() const
const_iterator constBegin() const
QgsRectangle boundingBox() const
Returns the minimal bounding box for the geometry.
virtual QgsAbstractGeometryV2 * clone() const =0
Clones the geometry by performing a deep copy.
Abstract base class for curved geometry type.
Definition: qgscurvev2.h:32
QgsGeometry * smooth(const unsigned int iterations=1, const double offset=0.25) const
Smooths a geometry by rounding off corners using the Chaikin algorithm.
QgsPoint asPoint() const
Return contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
int size() const
QgsGeometry * convertToType(QGis::GeometryType destType, bool destMultipart=false) const
Try to convert the geometry to the requested type.
bool intersects(const QgsRectangle &r) const
Test for intersection with a rectangle (uses GEOS)
Represents a vector layer which manages a vector based data sets.
virtual double closestSegment(const QgsPointV2 &pt, QgsPointV2 &segmentPt, QgsVertexId &vertexAfter, bool *leftOf, double epsilon) const =0
Searches for the closest segment of the geometry to a given point.
bool isGeosValid() const
Checks validity of the geometry using GEOS.
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:187
double closestVertexWithContext(const QgsPoint &point, int &atVertex) const
Searches for the closest vertex in this geometry to the given point.
iterator end()
bool touches(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:203
QString exportToWkt(const int &precision=17) const
Exports the geometry to WKT.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
bool isEmpty() const override
Definition: qgsgeos.cpp:1311
double area() const
Returns the area of the geometry using GEOS.
bool disjoint(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:228
QgsAbstractGeometryV2 * geometry
Definition: qgsgeometry.cpp:58
int numPoints() const override
Returns the number of points in the curve.
double area() const override
Definition: qgsgeos.cpp:233
QDataStream & operator>>(QDataStream &in, QgsGeometry &geometry)
Reads a geometry from stream in into geometry.
double sqrDistToVertexAt(QgsPoint &point, int atVertex) const
Returns the squared cartesian distance between the given point to the given vertex index (vertex at t...
QPointF toQPointF() const
Converts a point to a QPointF.
Definition: qgspoint.cpp:121