QGIS API Documentation  2.12.0-Lyon
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( double precision ) 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, precision );
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  //maintain compatibility with < 2.10 API
442  if ( d->geometry->geometryType() == "MultiPoint" )
443  {
444  detach( true );
445  removeWkbGeos();
446  //delete geometry instead of point
447  return static_cast< QgsGeometryCollectionV2* >( d->geometry )->removeGeometry( atVertex );
448  }
449 
450  //if it is a point, set the geometry to NULL
452  {
453  detach( false );
454  delete d->geometry;
455  removeWkbGeos();
456  d->geometry = 0;
457  return true;
458  }
459 
460  QgsVertexId id;
461  if ( !vertexIdFromVertexNr( atVertex, id ) )
462  {
463  return false;
464  }
465 
466  detach( true );
467 
468  removeWkbGeos();
469  return d->geometry->deleteVertex( id );
470 }
471 
472 bool QgsGeometry::insertVertex( double x, double y, int beforeVertex )
473 {
474  if ( !d || !d->geometry )
475  {
476  return false;
477  }
478 
479  //maintain compatibility with < 2.10 API
480  if ( d->geometry->geometryType() == "MultiPoint" )
481  {
482  detach( true );
483  removeWkbGeos();
484  //insert geometry instead of point
485  return static_cast< QgsGeometryCollectionV2* >( d->geometry )->insertGeometry( new QgsPointV2( x, y ), beforeVertex );
486  }
487 
488  QgsVertexId id;
489  if ( !vertexIdFromVertexNr( beforeVertex, id ) )
490  {
491  return false;
492  }
493 
494  detach( true );
495 
496  removeWkbGeos();
497 
498  return d->geometry->insertVertex( id, QgsPointV2( x, y ) );
499 }
500 
501 QgsPoint QgsGeometry::vertexAt( int atVertex ) const
502 {
503  if ( !d || !d->geometry )
504  {
505  return QgsPoint( 0, 0 );
506  }
507 
508  QgsVertexId vId;
509  ( void )vertexIdFromVertexNr( atVertex, vId );
510  if ( vId.vertex < 0 )
511  {
512  return QgsPoint( 0, 0 );
513  }
514  QgsPointV2 pt = d->geometry->vertexAt( vId );
515  return QgsPoint( pt.x(), pt.y() );
516 }
517 
518 double QgsGeometry::sqrDistToVertexAt( QgsPoint& point, int atVertex ) const
519 {
520  QgsPoint vertexPoint = vertexAt( atVertex );
521  return QgsGeometryUtils::sqrDistance2D( QgsPointV2( vertexPoint.x(), vertexPoint.y() ), QgsPointV2( point.x(), point.y() ) );
522 }
523 
524 double QgsGeometry::closestVertexWithContext( const QgsPoint& point, int& atVertex ) const
525 {
526  if ( !d || !d->geometry )
527  {
528  return 0.0;
529  }
530 
531  QgsVertexId vId;
532  QgsPointV2 pt( point.x(), point.y() );
533  QgsPointV2 closestPoint = QgsGeometryUtils::closestVertex( *( d->geometry ), pt, vId );
534  atVertex = vertexNrFromVertexId( vId );
535  return QgsGeometryUtils::sqrDistance2D( closestPoint, pt );
536 }
537 
539  const QgsPoint& point,
540  QgsPoint& minDistPoint,
541  int& afterVertex,
542  double *leftOf,
543  double epsilon ) const
544 {
545  if ( !d || !d->geometry )
546  {
547  return 0;
548  }
549 
550  QgsPointV2 segmentPt;
551  QgsVertexId vertexAfter;
552  bool leftOfBool;
553 
554  double sqrDist = d->geometry->closestSegment( QgsPointV2( point.x(), point.y() ), segmentPt, vertexAfter, &leftOfBool, epsilon );
555 
556  minDistPoint.setX( segmentPt.x() );
557  minDistPoint.setY( segmentPt.y() );
558  afterVertex = vertexNrFromVertexId( vertexAfter );
559  if ( leftOf )
560  {
561  *leftOf = leftOfBool ? 1.0 : -1.0;
562  }
563  return sqrDist;
564 }
565 
567 {
568  detach( true );
569 
570  removeWkbGeos();
571  QgsLineStringV2* ringLine = new QgsLineStringV2();
572  QList< QgsPointV2 > ringPoints;
573  convertPointList( ring, ringPoints );
574  ringLine->setPoints( ringPoints );
575  return addRing( ringLine );
576 }
577 
579 {
580  if ( !d || !d->geometry )
581  {
582  delete ring;
583  return 1;
584  }
585 
586  detach( true );
587 
588  removeWkbGeos();
589  return QgsGeometryEditUtils::addRing( d->geometry, ring );
590 }
591 
593 {
594  QgsAbstractGeometryV2* partGeom = 0;
595  if ( points.size() == 1 )
596  {
597  partGeom = new QgsPointV2( points[0].x(), points[0].y() );
598  }
599  else if ( points.size() > 1 )
600  {
601  QgsLineStringV2* ringLine = new QgsLineStringV2();
602  QList< QgsPointV2 > partPoints;
603  convertPointList( points, partPoints );
604  ringLine->setPoints( partPoints );
605  partGeom = ringLine;
606  }
607  return addPart( partGeom, geomType );
608 }
609 
611 {
612  if ( !d )
613  {
614  return 1;
615  }
616 
617  if ( !d->geometry )
618  {
619  detach( false );
620  switch ( geomType )
621  {
622  case QGis::Point:
623  d->geometry = new QgsMultiPointV2();
624  break;
625  case QGis::Line:
626  d->geometry = new QgsMultiLineStringV2();
627  break;
628  case QGis::Polygon:
629  d->geometry = new QgsMultiPolygonV2();
630  break;
631  default:
632  return 1;
633  }
634  }
635  else
636  {
637  detach( true );
638  removeWkbGeos();
639  }
640 
642  return QgsGeometryEditUtils::addPart( d->geometry, part );
643 }
644 
645 int QgsGeometry::addPart( const QgsGeometry *newPart )
646 {
647  if ( !d || !d->geometry || !newPart || !newPart->d || !newPart->d->geometry )
648  {
649  return 1;
650  }
651 
652  return addPart( newPart->d->geometry->clone() );
653 }
654 
655 int QgsGeometry::addPart( GEOSGeometry *newPart )
656 {
657  if ( !d || !d->geometry || !newPart )
658  {
659  return 1;
660  }
661 
662  detach( true );
663 
664  QgsAbstractGeometryV2* geom = QgsGeos::fromGeos( newPart );
665  removeWkbGeos();
666  return QgsGeometryEditUtils::addPart( d->geometry, geom );
667 }
668 
669 int QgsGeometry::translate( double dx, double dy )
670 {
671  if ( !d || !d->geometry )
672  {
673  return 1;
674  }
675 
676  detach( true );
677 
679  removeWkbGeos();
680  return 0;
681 }
682 
683 int QgsGeometry::rotate( double rotation, const QgsPoint& center )
684 {
685  if ( !d || !d->geometry )
686  {
687  return 1;
688  }
689 
690  detach( true );
691 
692  QTransform t = QTransform::fromTranslate( center.x(), center.y() );
693  t.rotate( -rotation );
694  t.translate( -center.x(), -center.y() );
695  d->geometry->transform( t );
696  removeWkbGeos();
697  return 0;
698 }
699 
700 int QgsGeometry::splitGeometry( const QList<QgsPoint>& splitLine, QList<QgsGeometry*>& newGeometries, bool topological, QList<QgsPoint> &topologyTestPoints )
701 {
702  if ( !d || !d->geometry )
703  {
704  return 0;
705  }
706 
708  QgsLineStringV2 splitLineString;
709  QList<QgsPointV2> splitLinePointsV2;
710  convertPointList( splitLine, splitLinePointsV2 );
711  splitLineString.setPoints( splitLinePointsV2 );
713 
714  QgsGeos geos( d->geometry );
715  int result = geos.splitGeometry( splitLineString, newGeoms, topological, tp );
716 
717  if ( result == 0 )
718  {
719  detach( false );
720  d->geometry = newGeoms.at( 0 );
721 
722  newGeometries.clear();
723  for ( int i = 1; i < newGeoms.size(); ++i )
724  {
725  newGeometries.push_back( new QgsGeometry( newGeoms.at( i ) ) );
726  }
727  }
728 
729  convertPointList( tp, topologyTestPoints );
730  removeWkbGeos();
731  return result;
732 }
733 
735 int QgsGeometry::reshapeGeometry( const QList<QgsPoint>& reshapeWithLine )
736 {
737  if ( !d || !d->geometry )
738  {
739  return 0;
740  }
741 
742  QList<QgsPointV2> reshapeLine;
743  convertPointList( reshapeWithLine, reshapeLine );
744  QgsLineStringV2 reshapeLineString;
745  reshapeLineString.setPoints( reshapeLine );
746 
747  QgsGeos geos( d->geometry );
748  int errorCode = 0;
749  QgsAbstractGeometryV2* geom = geos.reshapeGeometry( reshapeLineString, &errorCode );
750  if ( errorCode == 0 && geom )
751  {
752  detach( false );
753  delete d->geometry;
754  d->geometry = geom;
755  removeWkbGeos();
756  return 0;
757  }
758  return errorCode;
759 }
760 
762 {
763  if ( !d || !d->geometry || !other->d || !other->d->geometry )
764  {
765  return 0;
766  }
767 
768  QgsGeos geos( d->geometry );
769 
770  QgsAbstractGeometryV2* diffGeom = geos.intersection( *( other->geometry() ) );
771  if ( !diffGeom )
772  {
773  return 1;
774  }
775 
776  detach( false );
777 
778  delete d->geometry;
779  d->geometry = diffGeom;
780  removeWkbGeos();
781  return 0;
782 }
783 
785 {
786  if ( d && d->geometry )
787  {
788  return d->geometry->boundingBox();
789  }
790  return QgsRectangle();
791 }
792 
793 bool QgsGeometry::intersects( const QgsRectangle& r ) const
794 {
795  QgsGeometry* g = fromRect( r );
796  bool res = intersects( g );
797  delete g;
798  return res;
799 }
800 
801 bool QgsGeometry::intersects( const QgsGeometry* geometry ) const
802 {
803  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
804  {
805  return false;
806  }
807 
808  QgsGeos geos( d->geometry );
809  return geos.intersects( *( geometry->d->geometry ) );
810 }
811 
812 bool QgsGeometry::contains( const QgsPoint* p ) const
813 {
814  if ( !d || !d->geometry || !p )
815  {
816  return false;
817  }
818 
819  QgsPointV2 pt( p->x(), p->y() );
820  QgsGeos geos( d->geometry );
821  return geos.contains( pt );
822 }
823 
824 bool QgsGeometry::contains( const QgsGeometry* geometry ) const
825 {
826  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
827  {
828  return false;
829  }
830 
831  QgsGeos geos( d->geometry );
832  return geos.contains( *( geometry->d->geometry ) );
833 }
834 
835 bool QgsGeometry::disjoint( const QgsGeometry* geometry ) const
836 {
837  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
838  {
839  return false;
840  }
841 
842  QgsGeos geos( d->geometry );
843  return geos.disjoint( *( geometry->d->geometry ) );
844 }
845 
846 bool QgsGeometry::equals( const QgsGeometry* geometry ) const
847 {
848  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
849  {
850  return false;
851  }
852 
853  QgsGeos geos( d->geometry );
854  return geos.isEqual( *( geometry->d->geometry ) );
855 }
856 
857 bool QgsGeometry::touches( const QgsGeometry* geometry ) const
858 {
859  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
860  {
861  return false;
862  }
863 
864  QgsGeos geos( d->geometry );
865  return geos.touches( *( geometry->d->geometry ) );
866 }
867 
868 bool QgsGeometry::overlaps( const QgsGeometry* geometry ) const
869 {
870  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
871  {
872  return false;
873  }
874 
875  QgsGeos geos( d->geometry );
876  return geos.overlaps( *( geometry->d->geometry ) );
877 }
878 
879 bool QgsGeometry::within( const QgsGeometry* geometry ) const
880 {
881  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
882  {
883  return false;
884  }
885 
886  QgsGeos geos( d->geometry );
887  return geos.within( *( geometry->d->geometry ) );
888 }
889 
890 bool QgsGeometry::crosses( const QgsGeometry* geometry ) const
891 {
892  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
893  {
894  return false;
895  }
896 
897  QgsGeos geos( d->geometry );
898  return geos.crosses( *( geometry->d->geometry ) );
899 }
900 
901 QString QgsGeometry::exportToWkt( const int &precision ) const
902 {
903  if ( !d || !d->geometry )
904  {
905  return QString();
906  }
907  return d->geometry->asWkt( precision );
908 }
909 
910 QString QgsGeometry::exportToGeoJSON( const int &precision ) const
911 {
912  if ( !d || !d->geometry )
913  {
914  return QString();
915  }
916  return d->geometry->asJSON( precision );
917 }
918 
919 QgsGeometry* QgsGeometry::convertToType( QGis::GeometryType destType, bool destMultipart ) const
920 {
921  switch ( destType )
922  {
923  case QGis::Point:
924  return convertToPoint( destMultipart );
925 
926  case QGis::Line:
927  return convertToLine( destMultipart );
928 
929  case QGis::Polygon:
930  return convertToPolygon( destMultipart );
931 
932  default:
933  return 0;
934  }
935 }
936 
938 {
939  if ( !d || !d->geometry )
940  {
941  return false;
942  }
943 
944  if ( isMultipart() ) //already multitype, no need to convert
945  {
946  return true;
947  }
948 
949  QgsGeometryCollectionV2* multiGeom = dynamic_cast<QgsGeometryCollectionV2*>
951  if ( !multiGeom )
952  {
953  return false;
954  }
955 
956  detach( true );
957  multiGeom->addGeometry( d->geometry );
958  d->geometry = multiGeom;
959  removeWkbGeos();
960  return true;
961 }
962 
964 {
965  if ( !d || !d->geometry )
966  {
967  return false;
968  }
969 
970  if ( !isMultipart() ) //already single part, no need to convert
971  {
972  return true;
973  }
974 
975  QgsGeometryCollectionV2* multiGeom = dynamic_cast<QgsGeometryCollectionV2*>( d->geometry );
976  if ( !multiGeom || multiGeom->partCount() < 1 )
977  return false;
978 
979  QgsAbstractGeometryV2* firstPart = multiGeom->geometryN( 0 )->clone();
980  detach( false );
981 
982  d->geometry = firstPart;
983  removeWkbGeos();
984  return true;
985 }
986 
988 {
989  if ( !d || !d->geometry || d->geometry->geometryType() != "Point" )
990  {
991  return QgsPoint();
992  }
993  QgsPointV2* pt = dynamic_cast<QgsPointV2*>( d->geometry );
994  if ( !pt )
995  {
996  return QgsPoint();
997  }
998 
999  return QgsPoint( pt->x(), pt->y() );
1000 }
1001 
1003 {
1004  QgsPolyline polyLine;
1005  if ( !d || !d->geometry )
1006  {
1007  return polyLine;
1008  }
1009 
1010  bool doSegmentation = ( d->geometry->geometryType() == "CompoundCurve" || d->geometry->geometryType() == "CircularString" );
1011  QgsLineStringV2* line = 0;
1012  if ( doSegmentation )
1013  {
1014  QgsCurveV2* curve = dynamic_cast<QgsCurveV2*>( d->geometry );
1015  if ( !curve )
1016  {
1017  return polyLine;
1018  }
1019  line = curve->curveToLine();
1020  }
1021  else
1022  {
1023  line = dynamic_cast<QgsLineStringV2*>( d->geometry );
1024  if ( !line )
1025  {
1026  return polyLine;
1027  }
1028  }
1029 
1030  int nVertices = line->numPoints();
1031  polyLine.resize( nVertices );
1032  for ( int i = 0; i < nVertices; ++i )
1033  {
1034  QgsPointV2 pt = line->pointN( i );
1035  polyLine[i].setX( pt.x() );
1036  polyLine[i].setY( pt.y() );
1037  }
1038 
1039  if ( doSegmentation )
1040  {
1041  delete line;
1042  }
1043 
1044  return polyLine;
1045 }
1046 
1048 {
1049  bool doSegmentation = ( d->geometry->geometryType() == "CurvePolygon" );
1050 
1051  QgsPolygonV2* p = 0;
1052  if ( doSegmentation )
1053  {
1054  QgsCurvePolygonV2* curvePoly = dynamic_cast<QgsCurvePolygonV2*>( d->geometry );
1055  if ( !curvePoly )
1056  {
1057  return QgsPolygon();
1058  }
1059  p = curvePoly->toPolygon();
1060  }
1061  else
1062  {
1063  p = dynamic_cast<QgsPolygonV2*>( d->geometry );
1064  }
1065 
1066  if ( !p )
1067  {
1068  return QgsPolygon();
1069  }
1070 
1071  QgsPolygon polygon;
1072  convertPolygon( *p, polygon );
1073 
1074  if ( doSegmentation )
1075  {
1076  delete p;
1077  }
1078  return polygon;
1079 }
1080 
1082 {
1083  if ( !d || !d->geometry || d->geometry->geometryType() != "MultiPoint" )
1084  {
1085  return QgsMultiPoint();
1086  }
1087 
1088  const QgsMultiPointV2* mp = dynamic_cast<QgsMultiPointV2*>( d->geometry );
1089  if ( !mp )
1090  {
1091  return QgsMultiPoint();
1092  }
1093 
1094  int nPoints = mp->numGeometries();
1095  QgsMultiPoint multiPoint( nPoints );
1096  for ( int i = 0; i < nPoints; ++i )
1097  {
1098  const QgsPointV2* pt = static_cast<const QgsPointV2*>( mp->geometryN( i ) );
1099  multiPoint[i].setX( pt->x() );
1100  multiPoint[i].setY( pt->y() );
1101  }
1102  return multiPoint;
1103 }
1104 
1106 {
1107  if ( !d || !d->geometry )
1108  {
1109  return QgsMultiPolyline();
1110  }
1111 
1112  QgsGeometryCollectionV2* geomCollection = dynamic_cast<QgsGeometryCollectionV2*>( d->geometry );
1113  if ( !geomCollection )
1114  {
1115  return QgsMultiPolyline();
1116  }
1117 
1118  int nLines = geomCollection->numGeometries();
1119  if ( nLines < 1 )
1120  {
1121  return QgsMultiPolyline();
1122  }
1123 
1124  QgsMultiPolyline mpl;
1125  for ( int i = 0; i < nLines; ++i )
1126  {
1127  bool deleteLine = false;
1128  const QgsLineStringV2* line = dynamic_cast<const QgsLineStringV2*>( geomCollection->geometryN( i ) );
1129  if ( !line )
1130  {
1131  const QgsCurveV2* curve = dynamic_cast<const QgsCurveV2*>( geomCollection->geometryN( i ) );
1132  if ( !curve )
1133  {
1134  continue;
1135  }
1136  deleteLine = true;
1137  line = curve->curveToLine();
1138  }
1139 
1140  QList< QgsPointV2 > lineCoords;
1141  line->points( lineCoords );
1142  QgsPolyline polyLine;
1143  convertToPolyline( lineCoords, polyLine );
1144  mpl.append( polyLine );
1145 
1146  if ( deleteLine )
1147  {
1148  delete line;
1149  }
1150  }
1151  return mpl;
1152 }
1153 
1155 {
1156  if ( !d || !d->geometry )
1157  {
1158  return QgsMultiPolygon();
1159  }
1160 
1161  QgsGeometryCollectionV2* geomCollection = dynamic_cast<QgsGeometryCollectionV2*>( d->geometry );
1162  if ( !geomCollection )
1163  {
1164  return QgsMultiPolygon();
1165  }
1166 
1167  int nPolygons = geomCollection->numGeometries();
1168  if ( nPolygons < 1 )
1169  {
1170  return QgsMultiPolygon();
1171  }
1172 
1173  QgsMultiPolygon mp;
1174  for ( int i = 0; i < nPolygons; ++i )
1175  {
1176  const QgsPolygonV2* polygon = dynamic_cast<const QgsPolygonV2*>( geomCollection->geometryN( i ) );
1177  if ( !polygon )
1178  {
1179  const QgsCurvePolygonV2* cPolygon = dynamic_cast<const QgsCurvePolygonV2*>( geomCollection->geometryN( i ) );
1180  if ( cPolygon )
1181  {
1182  polygon = cPolygon->toPolygon();
1183  }
1184  else
1185  {
1186  continue;
1187  }
1188  }
1189 
1190  QgsPolygon poly;
1191  convertPolygon( *polygon, poly );
1192  mp.append( poly );
1193  }
1194  return mp;
1195 }
1196 
1197 double QgsGeometry::area() const
1198 {
1199  if ( !d || !d->geometry )
1200  {
1201  return -1.0;
1202  }
1203  QgsGeos g( d->geometry );
1204 
1205 #if 0
1206  //debug: compare geos area with calculation in QGIS
1207  double geosArea = g.area();
1208  double qgisArea = 0;
1209  QgsSurfaceV2* surface = dynamic_cast<QgsSurfaceV2*>( d->geometry );
1210  if ( surface )
1211  {
1212  qgisArea = surface->area();
1213  }
1214 #endif
1215 
1216  return g.area();
1217 }
1218 
1219 double QgsGeometry::length() const
1220 {
1221  if ( !d || !d->geometry )
1222  {
1223  return -1.0;
1224  }
1225  QgsGeos g( d->geometry );
1226  return g.length();
1227 }
1228 
1229 double QgsGeometry::distance( const QgsGeometry& geom ) const
1230 {
1231  if ( !d || !d->geometry || !geom.d || !geom.d->geometry )
1232  {
1233  return -1.0;
1234  }
1235 
1236  QgsGeos g( d->geometry );
1237  return g.distance( *( geom.d->geometry ) );
1238 }
1239 
1240 QgsGeometry* QgsGeometry::buffer( double distance, int segments ) const
1241 {
1242  if ( !d || !d->geometry )
1243  {
1244  return 0;
1245  }
1246 
1247  QgsGeos g( d->geometry );
1248  QgsAbstractGeometryV2* geom = g.buffer( distance, segments );
1249  if ( !geom )
1250  {
1251  return 0;
1252  }
1253  return new QgsGeometry( geom );
1254 }
1255 
1256 QgsGeometry* QgsGeometry::buffer( double distance, int segments, int endCapStyle, int joinStyle, double mitreLimit ) const
1257 {
1258  if ( !d || !d->geometry )
1259  {
1260  return 0;
1261  }
1262 
1263  QgsGeos g( d->geometry );
1264  QgsAbstractGeometryV2* geom = g.buffer( distance, segments, endCapStyle, joinStyle, mitreLimit );
1265  if ( !geom )
1266  {
1267  return 0;
1268  }
1269  return new QgsGeometry( geom );
1270 }
1271 
1272 QgsGeometry* QgsGeometry::offsetCurve( double distance, int segments, int joinStyle, double mitreLimit ) const
1273 {
1274  if ( !d || !d->geometry )
1275  {
1276  return 0;
1277  }
1278 
1279  QgsGeos geos( d->geometry );
1280  QgsAbstractGeometryV2* offsetGeom = geos.offsetCurve( distance, segments, joinStyle, mitreLimit );
1281  if ( !offsetGeom )
1282  {
1283  return 0;
1284  }
1285  return new QgsGeometry( offsetGeom );
1286 }
1287 
1288 QgsGeometry* QgsGeometry::simplify( double tolerance ) const
1289 {
1290  if ( !d || !d->geometry )
1291  {
1292  return 0;
1293  }
1294 
1295  QgsGeos geos( d->geometry );
1296  QgsAbstractGeometryV2* simplifiedGeom = geos.simplify( tolerance );
1297  if ( !simplifiedGeom )
1298  {
1299  return 0;
1300  }
1301  return new QgsGeometry( simplifiedGeom );
1302 }
1303 
1305 {
1306  if ( !d || !d->geometry )
1307  {
1308  return 0;
1309  }
1310 
1311  QgsGeos geos( d->geometry );
1313  bool ok = geos.centroid( centroid );
1314  if ( !ok )
1315  {
1316  return 0;
1317  }
1318  return new QgsGeometry( centroid.clone() );
1319 }
1320 
1322 {
1323  if ( !d || !d->geometry )
1324  {
1325  return 0;
1326  }
1327 
1328  QgsGeos geos( d->geometry );
1329  QgsPointV2 pt;
1330  bool ok = geos.pointOnSurface( pt );
1331  if ( !ok )
1332  {
1333  return 0;
1334  }
1335  return new QgsGeometry( pt.clone() );
1336 }
1337 
1339 {
1340  if ( !d || !d->geometry )
1341  {
1342  return 0;
1343  }
1344  QgsGeos geos( d->geometry );
1345  QgsAbstractGeometryV2* cHull = geos.convexHull();
1346  if ( !cHull )
1347  {
1348  return 0;
1349  }
1350  return new QgsGeometry( cHull );
1351 }
1352 
1353 QgsGeometry* QgsGeometry::interpolate( double distance ) const
1354 {
1355  if ( !d || !d->geometry )
1356  {
1357  return 0;
1358  }
1359  QgsGeos geos( d->geometry );
1360  QgsAbstractGeometryV2* result = geos.interpolate( distance );
1361  if ( !result )
1362  {
1363  return 0;
1364  }
1365  return new QgsGeometry( result );
1366 }
1367 
1369 {
1370  if ( !d || !d->geometry || !geometry->d || !geometry->d->geometry )
1371  {
1372  return 0;
1373  }
1374 
1375  QgsGeos geos( d->geometry );
1376 
1377  QgsAbstractGeometryV2* resultGeom = geos.intersection( *( geometry->d->geometry ) );
1378  return new QgsGeometry( resultGeom );
1379 }
1380 
1382 {
1383  if ( !d || !d->geometry || !geometry->d || !geometry->d->geometry )
1384  {
1385  return 0;
1386  }
1387 
1388  QgsGeos geos( d->geometry );
1389 
1390  QgsAbstractGeometryV2* resultGeom = geos.combine( *( geometry->d->geometry ) );
1391  if ( !resultGeom )
1392  {
1393  return 0;
1394  }
1395  return new QgsGeometry( resultGeom );
1396 }
1397 
1399 {
1400  if ( !d || !d->geometry || !geometry->d || !geometry->d->geometry )
1401  {
1402  return 0;
1403  }
1404 
1405  QgsGeos geos( d->geometry );
1406 
1407  QgsAbstractGeometryV2* resultGeom = geos.difference( *( geometry->d->geometry ) );
1408  if ( !resultGeom )
1409  {
1410  return 0;
1411  }
1412  return new QgsGeometry( resultGeom );
1413 }
1414 
1416 {
1417  if ( !d || !d->geometry || !geometry->d || !geometry->d->geometry )
1418  {
1419  return 0;
1420  }
1421 
1422  QgsGeos geos( d->geometry );
1423 
1424  QgsAbstractGeometryV2* resultGeom = geos.symDifference( *( geometry->d->geometry ) );
1425  if ( !resultGeom )
1426  {
1427  return 0;
1428  }
1429  return new QgsGeometry( resultGeom );
1430 }
1431 
1433 {
1434  QList<QgsGeometry*> geometryList;
1435  if ( !d || !d->geometry )
1436  {
1437  return geometryList;
1438  }
1439 
1440  QgsGeometryCollectionV2* gc = dynamic_cast<QgsGeometryCollectionV2*>( d->geometry );
1441  if ( gc )
1442  {
1443  int numGeom = gc->numGeometries();
1444  geometryList.reserve( numGeom );
1445  for ( int i = 0; i < numGeom; ++i )
1446  {
1447  geometryList.append( new QgsGeometry( gc->geometryN( i )->clone() ) );
1448  }
1449  }
1450  else //a singlepart geometry
1451  {
1452  geometryList.append( new QgsGeometry( d->geometry->clone() ) );
1453  }
1454 
1455  return geometryList;
1456 }
1457 
1459 {
1460  QgsPoint point = asPoint();
1461  return point.toQPointF();
1462 }
1463 
1465 {
1466  QPolygonF result;
1467  QgsPolyline polyline;
1469  if ( type == QGis::WKBLineString || type == QGis::WKBLineString25D )
1470  {
1471  polyline = asPolyline();
1472  }
1473  else if ( type == QGis::WKBPolygon || type == QGis::WKBPolygon25D )
1474  {
1475  QgsPolygon polygon = asPolygon();
1476  if ( polygon.size() < 1 )
1477  return result;
1478  polyline = polygon.at( 0 );
1479  }
1480  else
1481  {
1482  return result;
1483  }
1484 
1485  QgsPolyline::const_iterator lineIt = polyline.constBegin();
1486  for ( ; lineIt != polyline.constEnd(); ++lineIt )
1487  {
1488  result << lineIt->toQPointF();
1489  }
1490  return result;
1491 }
1492 
1493 bool QgsGeometry::deleteRing( int ringNum, int partNum )
1494 {
1495  if ( !d || !d->geometry )
1496  {
1497  return false;
1498  }
1499 
1500  detach( true );
1501 
1502  return QgsGeometryEditUtils::deleteRing( d->geometry, ringNum, partNum );
1503 }
1504 
1505 bool QgsGeometry::deletePart( int partNum )
1506 {
1507  if ( !d || !d->geometry )
1508  {
1509  return false;
1510  }
1511 
1512  if ( !isMultipart() && partNum < 1 )
1513  {
1514  setGeometry( 0 );
1515  return true;
1516  }
1517 
1518  detach( true );
1519  bool ok = QgsGeometryEditUtils::deletePart( d->geometry, partNum );
1520  removeWkbGeos();
1521  return ok;
1522 }
1523 
1525 {
1526  if ( !d || !d->geometry )
1527  {
1528  return 1;
1529  }
1530 
1531  QgsAbstractGeometryV2* diffGeom = QgsGeometryEditUtils::avoidIntersections( *( d->geometry ), ignoreFeatures );
1532  if ( diffGeom )
1533  {
1534  detach( false );
1535  d->geometry = diffGeom;
1536  removeWkbGeos();
1537  }
1538  return 0;
1539 }
1540 
1542 {
1544 }
1545 
1547 {
1548  if ( !d || !d->geometry )
1549  {
1550  return false;
1551  }
1552 
1553  QgsGeos geos( d->geometry );
1554  return geos.isValid();
1555 }
1556 
1558 {
1559  if ( !d || !d->geometry || !g.d || !g.d->geometry )
1560  {
1561  return false;
1562  }
1563 
1564  QgsGeos geos( d->geometry );
1565  return geos.isEqual( *( g.d->geometry ) );
1566 }
1567 
1569 {
1570  if ( !d || !d->geometry )
1571  {
1572  return false;
1573  }
1574 
1575  QgsGeos geos( d->geometry );
1576  return geos.isEmpty();
1577 }
1578 
1580 {
1581  QgsGeos geos( 0 );
1582 
1584  QList<QgsGeometry*>::const_iterator it = geometryList.constBegin();
1585  for ( ; it != geometryList.constEnd(); ++it )
1586  {
1587  if ( *it )
1588  {
1589  geomV2List.append(( *it )->geometry() );
1590  }
1591  }
1592 
1593  QgsAbstractGeometryV2* geom = geos.combine( geomV2List );
1594  return new QgsGeometry( geom );
1595 }
1596 
1598 {
1599  if ( !d || !d->geometry || !requiresConversionToStraightSegments() )
1600  {
1601  return;
1602  }
1603 
1604  QgsAbstractGeometryV2* straightGeom = d->geometry->segmentize();
1605  detach( false );
1606 
1607  d->geometry = straightGeom;
1608  removeWkbGeos();
1609 }
1610 
1612 {
1613  if ( !d || !d->geometry )
1614  {
1615  return false;
1616  }
1617 
1618  return d->geometry->hasCurvedSegments();
1619 }
1620 
1622 {
1623  if ( !d || !d->geometry )
1624  {
1625  return 1;
1626  }
1627 
1628  detach();
1629  d->geometry->transform( ct );
1630  removeWkbGeos();
1631  return 0;
1632 }
1633 
1635 {
1636  if ( !d || !d->geometry )
1637  {
1638  return 1;
1639  }
1640 
1641  detach();
1642  d->geometry->transform( ct );
1643  removeWkbGeos();
1644  return 0;
1645 }
1646 
1648 {
1649  if ( d && d->geometry )
1650  {
1651  detach();
1652  d->geometry->transform( mtp.transform() );
1653  }
1654 }
1655 
1656 #if 0
1657 void QgsGeometry::clip( const QgsRectangle& rect )
1658 {
1659  if ( d && d->geometry )
1660  {
1661  detach();
1662  d->geometry->clip( rect );
1663  removeWkbGeos();
1664  }
1665 }
1666 #endif
1667 
1668 void QgsGeometry::draw( QPainter& p ) const
1669 {
1670  if ( d && d->geometry )
1671  {
1672  d->geometry->draw( p );
1673  }
1674 }
1675 
1677 {
1678  if ( !d || !d->geometry )
1679  {
1680  return false;
1681  }
1682 
1684  d->geometry->coordinateSequence( coords );
1685 
1686  int vertexCount = 0;
1687  for ( int part = 0; part < coords.size(); ++part )
1688  {
1689  const QList< QList< QgsPointV2 > >& featureCoords = coords.at( part );
1690  for ( int ring = 0; ring < featureCoords.size(); ++ring )
1691  {
1692  const QList< QgsPointV2 >& ringCoords = featureCoords.at( ring );
1693  for ( int vertex = 0; vertex < ringCoords.size(); ++vertex )
1694  {
1695  if ( vertexCount == nr )
1696  {
1697  id.part = part;
1698  id.ring = ring;
1699  id.vertex = vertex;
1700  return true;
1701  }
1702  ++vertexCount;
1703  }
1704  }
1705  }
1706  return false;
1707 }
1708 
1710 {
1711  if ( !d || !d->geometry )
1712  {
1713  return -1;
1714  }
1715 
1717  d->geometry->coordinateSequence( coords );
1718 
1719  int vertexCount = 0;
1720  for ( int part = 0; part < coords.size(); ++part )
1721  {
1722  const QList< QList< QgsPointV2 > >& featureCoords = coords.at( part );
1723  for ( int ring = 0; ring < featureCoords.size(); ++ring )
1724  {
1725  const QList< QgsPointV2 >& ringCoords = featureCoords.at( ring );
1726  for ( int vertex = 0; vertex < ringCoords.size(); ++vertex )
1727  {
1728  if ( vertex == id.vertex && ring == id.ring && part == id.part )
1729  {
1730  return vertexCount;
1731  }
1732  ++vertexCount;
1733  }
1734  }
1735  }
1736  return -1;
1737 }
1738 
1740 {
1741  output.clear();
1743  for ( ; it != input.constEnd(); ++it )
1744  {
1745  output.append( QgsPointV2( it->x(), it->y() ) );
1746  }
1747 }
1748 
1750 {
1751  output.clear();
1753  for ( ; it != input.constEnd(); ++it )
1754  {
1755  output.append( QgsPoint( it->x(), it->y() ) );
1756  }
1757 }
1758 
1759 void QgsGeometry::convertToPolyline( const QList<QgsPointV2>& input, QgsPolyline& output )
1760 {
1761  output.clear();
1762  output.resize( input.size() );
1763 
1764  for ( int i = 0; i < input.size(); ++i )
1765  {
1766  const QgsPointV2& pt = input.at( i );
1767  output[i].setX( pt.x() );
1768  output[i].setY( pt.y() );
1769  }
1770 }
1771 
1772 void QgsGeometry::convertPolygon( const QgsPolygonV2& input, QgsPolygon& output )
1773 {
1774  output.clear();
1776  input.coordinateSequence( coord );
1777  if ( coord.size() < 1 )
1778  {
1779  return;
1780  }
1781 
1782  const QList< QList< QgsPointV2 > >& rings = coord[0];
1783  output.resize( rings.size() );
1784  for ( int i = 0; i < rings.size(); ++i )
1785  {
1786  convertToPolyline( rings[i], output[i] );
1787  }
1788 }
1789 
1790 GEOSContextHandle_t QgsGeometry::getGEOSHandler()
1791 {
1792  return QgsGeos::getGEOSHandler();
1793 }
1794 
1796 {
1797  return new QgsGeometry( new QgsPointV2( point.x(), point.y() ) );
1798 }
1799 
1801 {
1802  if ( polygon.isClosed() )
1803  {
1805  }
1806  else
1807  {
1809  }
1810 }
1811 
1813 {
1814  QgsPolygon result;
1815  result << createPolylineFromQPolygonF( polygon );
1816  return result;
1817 }
1818 
1820 {
1821  QgsPolyline result;
1822  QPolygonF::const_iterator it = polygon.constBegin();
1823  for ( ; it != polygon.constEnd(); ++it )
1824  {
1825  result.append( QgsPoint( *it ) );
1826  }
1827  return result;
1828 }
1829 
1830 bool QgsGeometry::compare( const QgsPolyline &p1, const QgsPolyline &p2, double epsilon )
1831 {
1832  if ( p1.count() != p2.count() )
1833  return false;
1834 
1835  for ( int i = 0; i < p1.count(); ++i )
1836  {
1837  if ( !p1.at( i ).compare( p2.at( i ), epsilon ) )
1838  return false;
1839  }
1840  return true;
1841 }
1842 
1843 bool QgsGeometry::compare( const QgsPolygon &p1, const QgsPolygon &p2, double epsilon )
1844 {
1845  if ( p1.count() != p2.count() )
1846  return false;
1847 
1848  for ( int i = 0; i < p1.count(); ++i )
1849  {
1850  if ( !QgsGeometry::compare( p1.at( i ), p2.at( i ), epsilon ) )
1851  return false;
1852  }
1853  return true;
1854 }
1855 
1856 
1857 bool QgsGeometry::compare( const QgsMultiPolygon &p1, const QgsMultiPolygon &p2, double epsilon )
1858 {
1859  if ( p1.count() != p2.count() )
1860  return false;
1861 
1862  for ( int i = 0; i < p1.count(); ++i )
1863  {
1864  if ( !QgsGeometry::compare( p1.at( i ), p2.at( i ), epsilon ) )
1865  return false;
1866  }
1867  return true;
1868 }
1869 
1870 QgsGeometry* QgsGeometry::smooth( const unsigned int iterations, const double offset ) const
1871 {
1872  switch ( wkbType() )
1873  {
1874  case QGis::WKBPoint:
1875  case QGis::WKBPoint25D:
1876  case QGis::WKBMultiPoint:
1878  //can't smooth a point based geometry
1879  return new QgsGeometry( *this );
1880 
1881  case QGis::WKBLineString:
1883  {
1884  QgsPolyline line = asPolyline();
1885  return QgsGeometry::fromPolyline( smoothLine( line, iterations, offset ) );
1886  }
1887 
1890  {
1891  QgsMultiPolyline multiline = asMultiPolyline();
1892  QgsMultiPolyline resultMultiline;
1893  QgsMultiPolyline::const_iterator lineIt = multiline.constBegin();
1894  for ( ; lineIt != multiline.constEnd(); ++lineIt )
1895  {
1896  resultMultiline << smoothLine( *lineIt, iterations, offset );
1897  }
1898  return QgsGeometry::fromMultiPolyline( resultMultiline );
1899  }
1900 
1901  case QGis::WKBPolygon:
1902  case QGis::WKBPolygon25D:
1903  {
1904  QgsPolygon poly = asPolygon();
1905  return QgsGeometry::fromPolygon( smoothPolygon( poly, iterations, offset ) );
1906  }
1907 
1908  case QGis::WKBMultiPolygon:
1910  {
1911  QgsMultiPolygon multipoly = asMultiPolygon();
1912  QgsMultiPolygon resultMultipoly;
1913  QgsMultiPolygon::const_iterator polyIt = multipoly.constBegin();
1914  for ( ; polyIt != multipoly.constEnd(); ++polyIt )
1915  {
1916  resultMultipoly << smoothPolygon( *polyIt, iterations, offset );
1917  }
1918  return QgsGeometry::fromMultiPolygon( resultMultipoly );
1919  }
1920  break;
1921 
1922  case QGis::WKBUnknown:
1923  default:
1924  return new QgsGeometry( *this );
1925  }
1926 }
1927 
1928 inline QgsPoint interpolatePointOnLine( const QgsPoint& p1, const QgsPoint& p2, const double offset )
1929 {
1930  double deltaX = p2.x() - p1.x();
1931  double deltaY = p2.y() - p1.y();
1932  return QgsPoint( p1.x() + deltaX * offset, p1.y() + deltaY * offset );
1933 }
1934 
1935 QgsPolyline QgsGeometry::smoothLine( const QgsPolyline& polyline, const unsigned int iterations, const double offset ) const
1936 {
1937  QgsPolyline result = polyline;
1938  for ( unsigned int iteration = 0; iteration < iterations; ++iteration )
1939  {
1940  QgsPolyline outputLine = QgsPolyline();
1941  outputLine.reserve( 2 * ( result.count() - 1 ) );
1942  for ( int i = 0; i < result.count() - 1; i++ )
1943  {
1944  const QgsPoint& p1 = result.at( i );
1945  const QgsPoint& p2 = result.at( i + 1 );
1946  outputLine << ( i == 0 ? result.at( i ) : interpolatePointOnLine( p1, p2, offset ) );
1947  outputLine << ( i == result.count() - 2 ? result.at( i + 1 ) : interpolatePointOnLine( p1, p2, 1.0 - offset ) );
1948  }
1949  result = outputLine;
1950  }
1951  return result;
1952 }
1953 
1954 QgsPolygon QgsGeometry::smoothPolygon( const QgsPolygon& polygon, const unsigned int iterations, const double offset ) const
1955 {
1956  QgsPolygon resultPoly;
1957  QgsPolygon::const_iterator ringIt = polygon.constBegin();
1958  for ( ; ringIt != polygon.constEnd(); ++ringIt )
1959  {
1960  QgsPolyline resultRing = *ringIt;
1961  for ( unsigned int iteration = 0; iteration < iterations; ++iteration )
1962  {
1963  QgsPolyline outputRing = QgsPolyline();
1964  outputRing.reserve( 2 * ( resultRing.count() - 1 ) + 1 );
1965  for ( int i = 0; i < resultRing.count() - 1; ++i )
1966  {
1967  const QgsPoint& p1 = resultRing.at( i );
1968  const QgsPoint& p2 = resultRing.at( i + 1 );
1969  outputRing << interpolatePointOnLine( p1, p2, offset );
1970  outputRing << interpolatePointOnLine( p1, p2, 1.0 - offset );
1971  }
1972  //close polygon
1973  outputRing << outputRing.at( 0 );
1974 
1975  resultRing = outputRing;
1976  }
1977  resultPoly << resultRing;
1978  }
1979  return resultPoly;
1980 }
1981 
1982 QgsGeometry* QgsGeometry::convertToPoint( bool destMultipart ) const
1983 {
1984  switch ( type() )
1985  {
1986  case QGis::Point:
1987  {
1988  bool srcIsMultipart = isMultipart();
1989 
1990  if (( destMultipart && srcIsMultipart ) ||
1991  ( !destMultipart && !srcIsMultipart ) )
1992  {
1993  // return a copy of the same geom
1994  return new QgsGeometry( *this );
1995  }
1996  if ( destMultipart )
1997  {
1998  // layer is multipart => make a multipoint with a single point
1999  return fromMultiPoint( QgsMultiPoint() << asPoint() );
2000  }
2001  else
2002  {
2003  // destination is singlepart => make a single part if possible
2004  QgsMultiPoint multiPoint = asMultiPoint();
2005  if ( multiPoint.count() == 1 )
2006  {
2007  return fromPoint( multiPoint[0] );
2008  }
2009  }
2010  return 0;
2011  }
2012 
2013  case QGis::Line:
2014  {
2015  // only possible if destination is multipart
2016  if ( !destMultipart )
2017  return 0;
2018 
2019  // input geometry is multipart
2020  if ( isMultipart() )
2021  {
2022  QgsMultiPolyline multiLine = asMultiPolyline();
2023  QgsMultiPoint multiPoint;
2024  for ( QgsMultiPolyline::const_iterator multiLineIt = multiLine.constBegin(); multiLineIt != multiLine.constEnd(); ++multiLineIt )
2025  for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt )
2026  multiPoint << *lineIt;
2027  return fromMultiPoint( multiPoint );
2028  }
2029  // input geometry is not multipart: copy directly the line into a multipoint
2030  else
2031  {
2032  QgsPolyline line = asPolyline();
2033  if ( !line.isEmpty() )
2034  return fromMultiPoint( line );
2035  }
2036  return 0;
2037  }
2038 
2039  case QGis::Polygon:
2040  {
2041  // can only transform if destination is multipoint
2042  if ( !destMultipart )
2043  return 0;
2044 
2045  // input geometry is multipart: make a multipoint from multipolygon
2046  if ( isMultipart() )
2047  {
2048  QgsMultiPolygon multiPolygon = asMultiPolygon();
2049  QgsMultiPoint multiPoint;
2050  for ( QgsMultiPolygon::const_iterator polygonIt = multiPolygon.constBegin(); polygonIt != multiPolygon.constEnd(); ++polygonIt )
2051  for ( QgsMultiPolyline::const_iterator multiLineIt = ( *polygonIt ).constBegin(); multiLineIt != ( *polygonIt ).constEnd(); ++multiLineIt )
2052  for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt )
2053  multiPoint << *lineIt;
2054  return fromMultiPoint( multiPoint );
2055  }
2056  // input geometry is not multipart: make a multipoint from polygon
2057  else
2058  {
2059  QgsPolygon polygon = asPolygon();
2060  QgsMultiPoint multiPoint;
2061  for ( QgsMultiPolyline::const_iterator multiLineIt = polygon.constBegin(); multiLineIt != polygon.constEnd(); ++multiLineIt )
2062  for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt )
2063  multiPoint << *lineIt;
2064  return fromMultiPoint( multiPoint );
2065  }
2066  }
2067 
2068  default:
2069  return 0;
2070  }
2071 }
2072 
2073 QgsGeometry* QgsGeometry::convertToLine( bool destMultipart ) const
2074 {
2075  switch ( type() )
2076  {
2077  case QGis::Point:
2078  {
2079  if ( !isMultipart() )
2080  return 0;
2081 
2082  QgsMultiPoint multiPoint = asMultiPoint();
2083  if ( multiPoint.count() < 2 )
2084  return 0;
2085 
2086  if ( destMultipart )
2087  return fromMultiPolyline( QgsMultiPolyline() << multiPoint );
2088  else
2089  return fromPolyline( multiPoint );
2090  }
2091 
2092  case QGis::Line:
2093  {
2094  bool srcIsMultipart = isMultipart();
2095 
2096  if (( destMultipart && srcIsMultipart ) ||
2097  ( !destMultipart && ! srcIsMultipart ) )
2098  {
2099  // return a copy of the same geom
2100  return new QgsGeometry( *this );
2101  }
2102  if ( destMultipart )
2103  {
2104  // destination is multipart => makes a multipoint with a single line
2105  QgsPolyline line = asPolyline();
2106  if ( !line.isEmpty() )
2107  return fromMultiPolyline( QgsMultiPolyline() << line );
2108  }
2109  else
2110  {
2111  // destination is singlepart => make a single part if possible
2112  QgsMultiPolyline multiLine = asMultiPolyline();
2113  if ( multiLine.count() == 1 )
2114  return fromPolyline( multiLine[0] );
2115  }
2116  return 0;
2117  }
2118 
2119  case QGis::Polygon:
2120  {
2121  // input geometry is multipolygon
2122  if ( isMultipart() )
2123  {
2124  QgsMultiPolygon multiPolygon = asMultiPolygon();
2125  QgsMultiPolyline multiLine;
2126  for ( QgsMultiPolygon::const_iterator polygonIt = multiPolygon.constBegin(); polygonIt != multiPolygon.constEnd(); ++polygonIt )
2127  for ( QgsMultiPolyline::const_iterator multiLineIt = ( *polygonIt ).constBegin(); multiLineIt != ( *polygonIt ).constEnd(); ++multiLineIt )
2128  multiLine << *multiLineIt;
2129 
2130  if ( destMultipart )
2131  {
2132  // destination is multipart
2133  return fromMultiPolyline( multiLine );
2134  }
2135  else if ( multiLine.count() == 1 )
2136  {
2137  // destination is singlepart => make a single part if possible
2138  return fromPolyline( multiLine[0] );
2139  }
2140  }
2141  // input geometry is single polygon
2142  else
2143  {
2144  QgsPolygon polygon = asPolygon();
2145  // if polygon has rings
2146  if ( polygon.count() > 1 )
2147  {
2148  // cannot fit a polygon with rings in a single line layer
2149  // TODO: would it be better to remove rings?
2150  if ( destMultipart )
2151  {
2152  QgsPolygon polygon = asPolygon();
2153  QgsMultiPolyline multiLine;
2154  for ( QgsMultiPolyline::const_iterator multiLineIt = polygon.constBegin(); multiLineIt != polygon.constEnd(); ++multiLineIt )
2155  multiLine << *multiLineIt;
2156  return fromMultiPolyline( multiLine );
2157  }
2158  }
2159  // no rings
2160  else if ( polygon.count() == 1 )
2161  {
2162  if ( destMultipart )
2163  {
2164  return fromMultiPolyline( polygon );
2165  }
2166  else
2167  {
2168  return fromPolyline( polygon[0] );
2169  }
2170  }
2171  }
2172  return 0;
2173  }
2174 
2175  default:
2176  return 0;
2177  }
2178 }
2179 
2180 QgsGeometry* QgsGeometry::convertToPolygon( bool destMultipart ) const
2181 {
2182  switch ( type() )
2183  {
2184  case QGis::Point:
2185  {
2186  if ( !isMultipart() )
2187  return 0;
2188 
2189  QgsMultiPoint multiPoint = asMultiPoint();
2190  if ( multiPoint.count() < 3 )
2191  return 0;
2192 
2193  if ( multiPoint.last() != multiPoint.first() )
2194  multiPoint << multiPoint.first();
2195 
2196  QgsPolygon polygon = QgsPolygon() << multiPoint;
2197  if ( destMultipart )
2198  return fromMultiPolygon( QgsMultiPolygon() << polygon );
2199  else
2200  return fromPolygon( polygon );
2201  }
2202 
2203  case QGis::Line:
2204  {
2205  // input geometry is multiline
2206  if ( isMultipart() )
2207  {
2208  QgsMultiPolyline multiLine = asMultiPolyline();
2209  QgsMultiPolygon multiPolygon;
2210  for ( QgsMultiPolyline::iterator multiLineIt = multiLine.begin(); multiLineIt != multiLine.end(); ++multiLineIt )
2211  {
2212  // do not create polygon for a 1 segment line
2213  if (( *multiLineIt ).count() < 3 )
2214  return 0;
2215  if (( *multiLineIt ).count() == 3 && ( *multiLineIt ).first() == ( *multiLineIt ).last() )
2216  return 0;
2217 
2218  // add closing node
2219  if (( *multiLineIt ).first() != ( *multiLineIt ).last() )
2220  *multiLineIt << ( *multiLineIt ).first();
2221  multiPolygon << ( QgsPolygon() << *multiLineIt );
2222  }
2223  // check that polygons were inserted
2224  if ( !multiPolygon.isEmpty() )
2225  {
2226  if ( destMultipart )
2227  {
2228  return fromMultiPolygon( multiPolygon );
2229  }
2230  else if ( multiPolygon.count() == 1 )
2231  {
2232  // destination is singlepart => make a single part if possible
2233  return fromPolygon( multiPolygon[0] );
2234  }
2235  }
2236  }
2237  // input geometry is single line
2238  else
2239  {
2240  QgsPolyline line = asPolyline();
2241 
2242  // do not create polygon for a 1 segment line
2243  if ( line.count() < 3 )
2244  return 0;
2245  if ( line.count() == 3 && line.first() == line.last() )
2246  return 0;
2247 
2248  // add closing node
2249  if ( line.first() != line.last() )
2250  line << line.first();
2251 
2252  // destination is multipart
2253  if ( destMultipart )
2254  {
2255  return fromMultiPolygon( QgsMultiPolygon() << ( QgsPolygon() << line ) );
2256  }
2257  else
2258  {
2259  return fromPolygon( QgsPolygon() << line );
2260  }
2261  }
2262  return 0;
2263  }
2264 
2265  case QGis::Polygon:
2266  {
2267  bool srcIsMultipart = isMultipart();
2268 
2269  if (( destMultipart && srcIsMultipart ) ||
2270  ( !destMultipart && ! srcIsMultipart ) )
2271  {
2272  // return a copy of the same geom
2273  return new QgsGeometry( *this );
2274  }
2275  if ( destMultipart )
2276  {
2277  // destination is multipart => makes a multipoint with a single polygon
2278  QgsPolygon polygon = asPolygon();
2279  if ( !polygon.isEmpty() )
2280  return fromMultiPolygon( QgsMultiPolygon() << polygon );
2281  }
2282  else
2283  {
2284  QgsMultiPolygon multiPolygon = asMultiPolygon();
2285  if ( multiPolygon.count() == 1 )
2286  {
2287  // destination is singlepart => make a single part if possible
2288  return fromPolygon( multiPolygon[0] );
2289  }
2290  }
2291  return 0;
2292  }
2293 
2294  default:
2295  return 0;
2296  }
2297 }
2298 
2300 {
2301  return new QgsGeos( geometry );
2302 }
2303 
2305 {
2306  QByteArray byteArray = QByteArray::fromRawData(( char * )geometry.asWkb(), geometry.wkbSize() ); // does not copy data and does not take ownership
2307  out << byteArray;
2308  return out;
2309 }
2310 
2312 {
2313  QByteArray byteArray;
2314  in >> byteArray;
2315  if ( byteArray.isEmpty() )
2316  {
2317  geometry.setGeometry( 0 );
2318  return in;
2319  }
2320 
2321  char *data = new char[byteArray.size()];
2322  memcpy( data, byteArray.data(), byteArray.size() );
2323  geometry.fromWkb(( unsigned char* )data, byteArray.size() );
2324  return in;
2325 }
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.
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.
void clear()
QgsWKBTypes::Type wkbType() const
Returns the WKB type of the geometry.
double length(QString *errorMsg=0) const override
Definition: qgsgeos.cpp:316
A rectangle specified with double values.
Definition: qgsrectangle.h:35
static bool isMultiType(Type type)
Definition: qgswkbtypes.cpp:75
QgsPointV2 pointN(int i) const
bool intersects(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:230
QgsGeometry * convexHull() const
Returns the smallest convex polygon that contains all the points in the geometry. ...
QgsAbstractGeometryV2 * interpolate(double distance, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:1269
QDataStream & operator<<(QDataStream &out, const QgsGeometry &geometry)
Writes the geometry to stream out.
bool crosses(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:240
QgsGeometry * symDifference(const QgsGeometry *geometry) const
Returns a Geometry representing the points making up this Geometry that do not make up other...
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:42
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().
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:196
typedef iterator
static bool compare(const QgsPolyline &p1, const QgsPolyline &p2, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compares two polylines for equality within a specified tolerance.
virtual bool moveVertex(const QgsVertexId &position, const QgsPointV2 &newPos)=0
Moves a vertex within the geometry.
QgsAbstractGeometryV2 * geometry() const
Returns the underlying geometry store.
void reserve(int alloc)
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:44
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
bool centroid(QgsPointV2 &pt, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:1284
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()
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.
QgsGeometry * pointOnSurface() const
Returns a point within a geometry.
int addPart(const QList< QgsPoint > &points, QGis::GeometryType geomType=QGis::UnknownGeometry)
Adds a new part to a the geometry.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:76
static QgsAbstractGeometryV2 * fromGeos(const GEOSGeometry *geos)
Create a geometry from a GEOSGeometry.
Definition: qgsgeos.cpp:815
bool pointOnSurface(QgsPointV2 &pt, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:1325
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:104
QgsGeometry()
Constructor.
Definition: qgsgeometry.cpp:64
T & first()
Multi point geometry collection.
WkbType
Used for symbology operations.
Definition: qgis.h:56
bool disjoint(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:260
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 contains(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:255
QgsAbstractGeometryV2 * symDifference(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:200
QgsGeometry & operator=(QgsGeometry const &rhs)
Assignments will prompt a deep copy of the object.
Definition: qgsgeometry.cpp:91
double area(QString *errorMsg=0) const override
Definition: qgsgeos.cpp:299
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.
static GEOSContextHandle_t getGEOSHandler()
Definition: qgsgeos.cpp:2147
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:43
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
int splitGeometry(const QList< QgsPoint > &splitLine, QList< QgsGeometry * > &newGeometries, bool topological, QList< QgsPoint > &topologyTestPoints)
Splits this geometry according to a given line.
void clear()
static Type flatType(Type type)
Definition: qgswkbtypes.cpp:46
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)
int avoidIntersections(const QMap< QgsVectorLayer *, QSet< QgsFeatureId > > &ignoreFeatures=(QMap< QgsVectorLayer *, QSet< QgsFeatureId > >()))
Modifies geometry to avoid intersections with the layers specified in project properties.
bool overlaps(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:250
static double sqrDistance2D(const QgsPointV2 &pt1, const QgsPointV2 &pt2)
Returns the squared 2D distance between two points.
bool convertToSingleType()
Converts multi type geometry into single type geometry e.g.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:201
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:186
Utility class for identifying a unique vertex within a geometry.
Line string geometry type.
QgsPoint interpolatePointOnLine(const QgsPoint &p1, const QgsPoint &p2, const double offset)
QgsAbstractGeometryV2 * combine(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:171
static void convertPointList(const QList< QgsPoint > &input, QList< QgsPointV2 > &output)
Upgrades a point list from QgsPoint to QgsPointV2.
bool overlaps(const QgsGeometry *geometry) const
Test for if geometry overlaps another (uses GEOS)
int splitGeometry(const QgsLineStringV2 &splitLine, QList< QgsAbstractGeometryV2 * > &newGeometries, bool topological, QList< QgsPointV2 > &topologyTestPoints, QString *errorMsg=0) const override
Splits this geometry according to a given line.
Definition: qgsgeos.cpp:332
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
QVector< QgsPolygon > QgsMultiPolygon
A collection of QgsPolygons that share a common collection of attributes.
Definition: qgsgeometry.h:59
QVector< QgsPoint > QgsMultiPoint
A collection of QgsPoints that share a common collection of attributes.
Definition: qgsgeometry.h:53
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 QgsPointV2 * clone() const override
Clones the geometry by performing a deep copy.
Definition: qgspointv2.cpp:56
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.)
virtual int partCount() const override
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:50
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.
const GEOSGeometry * asGeos(double precision=0) const
Returns a geos geometry.
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.
void reserve(int size)
QgsAbstractGeometryV2 * reshapeGeometry(const QgsLineStringV2 &reshapeWithLine, int *errorCode, QString *errorMsg=0) const
Definition: qgsgeos.cpp:1608
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometryV2 *geometry)
Creates and returns a new geometry engine.
static GEOSGeometry * asGeos(const QgsAbstractGeometryV2 *geom, double precision=0)
Definition: qgsgeos.cpp:1004
void setX(double x)
Sets the x value of the point.
Definition: qgspoint.h:103
virtual QgsPointV2 vertexAt(const QgsVertexId &id) const =0
Returns the point corresponding to a specified vertex id.
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
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:56
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.
QgsAbstractGeometryV2 * difference(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:166
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.
QgsAbstractGeometryV2 * convexHull(QString *errorMsg=0) const override
Definition: qgsgeos.cpp:1354
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.
QgsAbstractGeometryV2 * simplify(double tolerance, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:1254
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
QgsAbstractGeometryV2 * buffer(double distance, int segments, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:1216
virtual QgsLineStringV2 * curveToLine() const =0
Returns a new line string geometry corresponding to a segmentized approximation of the curve...
const_iterator constBegin() const
QgsAbstractGeometryV2 * intersection(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:161
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.
bool within(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:245
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
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.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
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.
bool isEqual(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:1385
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.
bool isEmpty(QString *errorMsg=0) const override
Definition: qgsgeos.cpp:1405
static QgsGeometry * fromMultiPoint(const QgsMultiPoint &multipoint)
Creates a new geometry from a QgsMultiPoint object.
QgsAbstractGeometryV2 * offsetCurve(double distance, int segments, int joinStyle, double mitreLimit, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:1592
static QgsAbstractGeometryV2 * fromMultiPolyline(const QgsMultiPolyline &multiline)
Construct geometry from a multipolyline.
bool touches(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:235
static QgsGeometry * fromPolyline(const QgsPolyline &polyline)
Creates a new geometry from a QgsPolyline object.
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).
double distance(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
Definition: qgsgeos.cpp:205
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.
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.
static QgsGeometry * fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
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:191
double closestVertexWithContext(const QgsPoint &point, int &atVertex) const
Searches for the closest vertex in this geometry to the given point.
bool isValid(QString *errorMsg=0) const override
Definition: qgsgeos.cpp:1371
iterator end()
QString exportToWkt(const int &precision=17) const
Exports the geometry to WKT.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
double area() const
Returns the area of the geometry using GEOS.
QgsAbstractGeometryV2 * geometry
Definition: qgsgeometry.cpp:58
int numPoints() const override
Returns the number of points in the curve.
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