QGIS API Documentation  2.10.1-Pisa
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups 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  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  d->geometry = geometry;
150 }
151 
153 {
154  return !d || !d->geometry;
155 }
156 
158 {
160  if ( !geom )
161  {
162  return 0;
163  }
164  return new QgsGeometry( geom );
165 }
166 
168 {
170  if ( geom )
171  {
172  return new QgsGeometry( geom );
173  }
174  return 0;
175 }
176 
178 {
180  if ( geom )
181  {
182  return new QgsGeometry( geom );
183  }
184  return 0;
185 }
186 
188 {
190  if ( geom )
191  {
192  return new QgsGeometry( geom );
193  }
194  return 0;
195 }
196 
198 {
200  if ( geom )
201  {
202  return new QgsGeometry( geom );
203  }
204  return 0;
205 }
206 
208 {
210  if ( geom )
211  {
212  return new QgsGeometry( geom );
213  }
214  return 0;
215 }
216 
218 {
220  if ( geom )
221  {
222  return new QgsGeometry( geom );
223  }
224  return 0;
225 }
226 
228 {
229  QgsPolyline ring;
230  ring.append( QgsPoint( rect.xMinimum(), rect.yMinimum() ) );
231  ring.append( QgsPoint( rect.xMaximum(), rect.yMinimum() ) );
232  ring.append( QgsPoint( rect.xMaximum(), rect.yMaximum() ) );
233  ring.append( QgsPoint( rect.xMinimum(), rect.yMaximum() ) );
234  ring.append( QgsPoint( rect.xMinimum(), rect.yMinimum() ) );
235 
236  QgsPolygon polygon;
237  polygon.append( ring );
238 
239  return fromPolygon( polygon );
240 }
241 
242 void QgsGeometry::fromWkb( unsigned char *wkb, size_t length )
243 {
244  Q_UNUSED( length );
245  if ( !d )
246  {
247  return;
248  }
249 
250  detach( false );
251 
252  if ( d->geometry )
253  {
254  delete d->geometry;
255  removeWkbGeos();
256  }
258  d->mWkb = wkb;
259  d->mWkbSize = length;
260 }
261 
262 const unsigned char *QgsGeometry::asWkb() const
263 {
264  if ( !d || !d->geometry )
265  {
266  return 0;
267  }
268 
269  if ( !d->mWkb )
270  {
271  d->mWkb = d->geometry->asWkb( d->mWkbSize );
272  }
273  return d->mWkb;
274 }
275 
276 size_t QgsGeometry::wkbSize() const
277 {
278  if ( !d || !d->geometry )
279  {
280  return 0;
281  }
282 
283  if ( !d->mWkb )
284  {
285  d->mWkb = d->geometry->asWkb( d->mWkbSize );
286  }
287  return d->mWkbSize;
288 }
289 
290 const GEOSGeometry* QgsGeometry::asGeos() const
291 {
292  if ( !d || !d->geometry )
293  {
294  return 0;
295  }
296 
297  if ( !d->mGeos )
298  {
299  d->mGeos = QgsGeos::asGeos( d->geometry );
300  }
301  return d->mGeos;
302 }
303 
304 
306 {
307  if ( !d || !d->geometry )
308  {
309  return QGis::WKBUnknown;
310  }
311  else
312  {
313  return ( QGis::WkbType )d->geometry->wkbType();
314  }
315 }
316 
317 
319 {
320  if ( !d || !d->geometry )
321  {
322  return QGis::UnknownGeometry;
323  }
325 }
326 
328 {
329  if ( !d || !d->geometry )
330  {
331  return false;
332  }
333  return QgsWKBTypes::isMultiType( d->geometry->wkbType() );
334 }
335 
336 void QgsGeometry::fromGeos( GEOSGeometry *geos )
337 {
338  if ( d )
339  {
340  detach( false );
341  delete d->geometry;
342  d->geometry = QgsGeos::fromGeos( geos );
343  d->mGeos = geos;
344  }
345 }
346 
347 QgsPoint QgsGeometry::closestVertex( const QgsPoint& point, int& atVertex, int& beforeVertex, int& afterVertex, double& sqrDist ) const
348 {
349  if ( !d || !d->geometry )
350  {
351  return QgsPoint( 0, 0 );
352  }
353  QgsPointV2 pt( point.x(), point.y() );
354  QgsVertexId id;
355 
356  QgsPointV2 vp = QgsGeometryUtils::closestVertex( *( d->geometry ), pt, id );
357  if ( !id.isValid() )
358  {
359  sqrDist = -1;
360  return QgsPoint( 0, 0 );
361  }
362  sqrDist = QgsGeometryUtils::sqrDistance2D( pt, vp );
363 
364  atVertex = vertexNrFromVertexId( id );
365  adjacentVertices( atVertex, beforeVertex, afterVertex );
366  return QgsPoint( vp.x(), vp.y() );
367 }
368 
369 void QgsGeometry::adjacentVertices( int atVertex, int& beforeVertex, int& afterVertex ) const
370 {
371  if ( !d || !d->geometry )
372  {
373  return;
374  }
375 
376  QgsVertexId id;
377  if ( !vertexIdFromVertexNr( atVertex, id ) )
378  {
379  beforeVertex = -1; afterVertex = -1;
380  return;
381  }
382 
383  QgsVertexId beforeVertexId, afterVertexId;
384  QgsGeometryUtils::adjacentVertices( *( d->geometry ), id, beforeVertexId, afterVertexId );
385  beforeVertex = vertexNrFromVertexId( beforeVertexId );
386  afterVertex = vertexNrFromVertexId( afterVertexId );
387 }
388 
389 bool QgsGeometry::moveVertex( double x, double y, int atVertex )
390 {
391  if ( !d || !d->geometry )
392  {
393  return false;
394  }
395 
396  QgsVertexId id;
397  if ( !vertexIdFromVertexNr( atVertex, id ) )
398  {
399  return false;
400  }
401 
402  detach( true );
403 
404  removeWkbGeos();
405  return d->geometry->moveVertex( id, QgsPointV2( x, y ) );
406 }
407 
408 bool QgsGeometry::moveVertex( const QgsPointV2& p, int atVertex )
409 {
410  if ( !d || !d->geometry )
411  {
412  return false;
413  }
414 
415  QgsVertexId id;
416  if ( !vertexIdFromVertexNr( atVertex, id ) )
417  {
418  return false;
419  }
420 
421  detach( true );
422 
423  removeWkbGeos();
424  return d->geometry->moveVertex( id, p );
425 }
426 
427 bool QgsGeometry::deleteVertex( int atVertex )
428 {
429  if ( !d || !d->geometry )
430  {
431  return false;
432  }
433 
434  QgsVertexId id;
435  if ( !vertexIdFromVertexNr( atVertex, id ) )
436  {
437  return false;
438  }
439 
440  detach( true );
441 
442  removeWkbGeos();
443  return d->geometry->deleteVertex( id );
444 }
445 
446 bool QgsGeometry::insertVertex( double x, double y, int beforeVertex )
447 {
448  if ( !d || !d->geometry )
449  {
450  return false;
451  }
452 
453  detach( true );
454 
455  QgsVertexId id;
456  if ( !vertexIdFromVertexNr( beforeVertex, id ) )
457  {
458  return false;
459  }
460 
461  removeWkbGeos();
462  return d->geometry->insertVertex( id, QgsPointV2( x, y ) );
463 }
464 
465 QgsPoint QgsGeometry::vertexAt( int atVertex ) const
466 {
467  if ( !d || !d->geometry )
468  {
469  return QgsPoint( 0, 0 );
470  }
471 
472  QgsVertexId vId;
473  ( void )vertexIdFromVertexNr( atVertex, vId );
474  if ( vId.vertex < 0 )
475  {
476  return QgsPoint( 0, 0 );
477  }
478  QgsPointV2 pt = d->geometry->vertexAt( vId );
479  return QgsPoint( pt.x(), pt.y() );
480 }
481 
482 double QgsGeometry::sqrDistToVertexAt( QgsPoint& point, int atVertex ) const
483 {
484  QgsPoint vertexPoint = vertexAt( atVertex );
485  return QgsGeometryUtils::sqrDistance2D( QgsPointV2( vertexPoint.x(), vertexPoint.y() ), QgsPointV2( point.x(), point.y() ) );
486 }
487 
488 double QgsGeometry::closestVertexWithContext( const QgsPoint& point, int& atVertex ) const
489 {
490  if ( !d || !d->geometry )
491  {
492  return 0.0;
493  }
494 
495  QgsVertexId vId;
496  QgsPointV2 pt( point.x(), point.y() );
497  QgsPointV2 closestPoint = QgsGeometryUtils::closestVertex( *( d->geometry ), pt, vId );
498  atVertex = vertexNrFromVertexId( vId );
499  return QgsGeometryUtils::sqrDistance2D( closestPoint, pt );
500 }
501 
503  const QgsPoint& point,
504  QgsPoint& minDistPoint,
505  int& afterVertex,
506  double *leftOf,
507  double epsilon ) const
508 {
509  if ( !d || !d->geometry )
510  {
511  return 0;
512  }
513 
514  QgsPointV2 segmentPt;
515  QgsVertexId vertexAfter;
516  bool leftOfBool;
517 
518  double sqrDist = d->geometry->closestSegment( QgsPointV2( point.x(), point.y() ), segmentPt, vertexAfter, &leftOfBool, epsilon );
519 
520  minDistPoint.setX( segmentPt.x() );
521  minDistPoint.setY( segmentPt.y() );
522  afterVertex = vertexNrFromVertexId( vertexAfter );
523  if ( leftOf )
524  {
525  *leftOf = leftOfBool ? 1.0 : -1.0;
526  }
527  return sqrDist;
528 }
529 
531 {
532  detach( true );
533 
534  removeWkbGeos();
535  QgsLineStringV2* ringLine = new QgsLineStringV2();
536  QList< QgsPointV2 > ringPoints;
537  convertPointList( ring, ringPoints );
538  ringLine->setPoints( ringPoints );
539  return addRing( ringLine );
540 }
541 
543 {
544  if ( !d || !d->geometry )
545  {
546  return 1;
547  }
548 
549  detach( true );
550 
551  removeWkbGeos();
552  return QgsGeometryEditUtils::addRing( d->geometry, ring );
553 }
554 
556 {
557  if ( !d )
558  {
559  return 1;
560  }
561 
562  if ( !d->geometry )
563  {
564  detach( false );
565  switch ( geomType )
566  {
567  case QGis::Point:
568  d->geometry = new QgsMultiPointV2();
569  break;
570  case QGis::Line:
571  d->geometry = new QgsMultiLineStringV2();
572  break;
573  case QGis::Polygon:
574  d->geometry = new QgsMultiPolygonV2();
575  break;
576  default:
577  return 1;
578  }
579  }
580 
582 
583  QgsAbstractGeometryV2* partGeom = 0;
584  if ( points.size() == 1 )
585  {
586  partGeom = new QgsPointV2( points[0].x(), points[0].y() );
587  }
588  else if ( points.size() > 1 )
589  {
590  QgsLineStringV2* ringLine = new QgsLineStringV2();
591  QList< QgsPointV2 > partPoints;
592  convertPointList( points, partPoints );
593  ringLine->setPoints( partPoints );
594  partGeom = ringLine;
595  }
596  return addPart( partGeom );
597 }
598 
600 {
601  detach( true );
602  removeWkbGeos();
603  return QgsGeometryEditUtils::addPart( d->geometry, part );
604 }
605 
606 int QgsGeometry::addPart( const QgsGeometry *newPart )
607 {
608  if ( !d || !d->geometry || !newPart || !newPart->d || !newPart->d->geometry )
609  {
610  return 1;
611  }
612 
613  return addPart( newPart->d->geometry->clone() );
614 }
615 
616 int QgsGeometry::addPart( GEOSGeometry *newPart )
617 {
618  if ( !d || !d->geometry || !newPart )
619  {
620  return 1;
621  }
622 
623  detach( true );
624 
625  QgsAbstractGeometryV2* geom = QgsGeos::fromGeos( newPart );
626  removeWkbGeos();
627  return QgsGeometryEditUtils::addPart( d->geometry, geom );
628 }
629 
630 int QgsGeometry::translate( double dx, double dy )
631 {
632  if ( !d || !d->geometry )
633  {
634  return 1;
635  }
636 
637  detach( true );
638 
640  removeWkbGeos();
641  return 0;
642 }
643 
644 int QgsGeometry::rotate( double rotation, const QgsPoint& center )
645 {
646  if ( !d || !d->geometry )
647  {
648  return 1;
649  }
650 
651  detach( true );
652 
653  QTransform t = QTransform::fromTranslate( center.x(), center.y() );
654  t.rotate( -rotation );
655  t.translate( -center.x(), -center.y() );
656  d->geometry->transform( t );
657  removeWkbGeos();
658  return 0;
659 }
660 
661 int QgsGeometry::splitGeometry( const QList<QgsPoint>& splitLine, QList<QgsGeometry*>& newGeometries, bool topological, QList<QgsPoint> &topologyTestPoints )
662 {
663  if ( !d || !d->geometry )
664  {
665  return 0;
666  }
667 
669  QgsLineStringV2 splitLineString;
670  QList<QgsPointV2> splitLinePointsV2;
671  convertPointList( splitLine, splitLinePointsV2 );
672  splitLineString.setPoints( splitLinePointsV2 );
674 
675  QgsGeos geos( d->geometry );
676  int result = geos.splitGeometry( splitLineString, newGeoms, topological, tp );
677 
678  if ( result == 0 )
679  {
680  detach( false );
681  d->geometry = newGeoms.at( 0 );
682 
683  newGeometries.clear();
684  for ( int i = 1; i < newGeoms.size(); ++i )
685  {
686  newGeometries.push_back( new QgsGeometry( newGeoms.at( i ) ) );
687  }
688  }
689 
690  convertPointList( tp, topologyTestPoints );
691  removeWkbGeos();
692  return result;
693 }
694 
696 int QgsGeometry::reshapeGeometry( const QList<QgsPoint>& reshapeWithLine )
697 {
698  if ( !d || !d->geometry )
699  {
700  return 0;
701  }
702 
703  QList<QgsPointV2> reshapeLine;
704  convertPointList( reshapeWithLine, reshapeLine );
705  QgsLineStringV2 reshapeLineString;
706  reshapeLineString.setPoints( reshapeLine );
707 
708  QgsGeos geos( d->geometry );
709  int errorCode = 0;
710  QgsAbstractGeometryV2* geom = geos.reshapeGeometry( reshapeLineString, &errorCode );
711  if ( errorCode == 0 && geom )
712  {
713  detach( false );
714  delete d->geometry;
715  d->geometry = geom;
716  return 0;
717  }
718  removeWkbGeos();
719  return errorCode;
720 }
721 
723 {
724  if ( !d || !d->geometry || !other->d || !other->d->geometry )
725  {
726  return 0;
727  }
728 
729  QgsGeos geos( d->geometry );
730 
731  QgsAbstractGeometryV2* diffGeom = geos.intersection( *( other->geometry() ) );
732  if ( !diffGeom )
733  {
734  return 1;
735  }
736 
737  detach( false );
738 
739  delete d->geometry;
740  d->geometry = diffGeom;
741  removeWkbGeos();
742  return 0;
743 }
744 
746 {
747  if ( d && d->geometry )
748  {
749  return d->geometry->boundingBox();
750  }
751  return QgsRectangle();
752 }
753 
754 bool QgsGeometry::intersects( const QgsRectangle& r ) const
755 {
756  QgsGeometry* g = fromRect( r );
757  bool res = intersects( g );
758  delete g;
759  return res;
760 }
761 
762 bool QgsGeometry::intersects( const QgsGeometry* geometry ) const
763 {
764  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
765  {
766  return false;
767  }
768 
769  QgsGeos geos( d->geometry );
770  return geos.intersects( *( geometry->d->geometry ) );
771 }
772 
773 bool QgsGeometry::contains( const QgsPoint* p ) const
774 {
775  if ( !d || !d->geometry || !p )
776  {
777  return false;
778  }
779 
780  QgsPointV2 pt( p->x(), p->y() );
781  QgsGeos geos( d->geometry );
782  return geos.contains( pt );
783 }
784 
785 bool QgsGeometry::contains( const QgsGeometry* geometry ) const
786 {
787  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
788  {
789  return false;
790  }
791 
792  QgsGeos geos( d->geometry );
793  return geos.contains( *( geometry->d->geometry ) );
794 }
795 
796 bool QgsGeometry::disjoint( const QgsGeometry* geometry ) const
797 {
798  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
799  {
800  return false;
801  }
802 
803  QgsGeos geos( d->geometry );
804  return geos.disjoint( *( geometry->d->geometry ) );
805 }
806 
807 bool QgsGeometry::equals( const QgsGeometry* geometry ) const
808 {
809  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
810  {
811  return false;
812  }
813 
814  QgsGeos geos( d->geometry );
815  return geos.isEqual( *( geometry->d->geometry ) );
816 }
817 
818 bool QgsGeometry::touches( const QgsGeometry* geometry ) const
819 {
820  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
821  {
822  return false;
823  }
824 
825  QgsGeos geos( d->geometry );
826  return geos.touches( *( geometry->d->geometry ) );
827 }
828 
829 bool QgsGeometry::overlaps( const QgsGeometry* geometry ) const
830 {
831  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
832  {
833  return false;
834  }
835 
836  QgsGeos geos( d->geometry );
837  return geos.overlaps( *( geometry->d->geometry ) );
838 }
839 
840 bool QgsGeometry::within( const QgsGeometry* geometry ) const
841 {
842  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
843  {
844  return false;
845  }
846 
847  QgsGeos geos( d->geometry );
848  return geos.within( *( geometry->d->geometry ) );
849 }
850 
851 bool QgsGeometry::crosses( const QgsGeometry* geometry ) const
852 {
853  if ( !d || !d->geometry || !geometry || !geometry->d || !geometry->d->geometry )
854  {
855  return false;
856  }
857 
858  QgsGeos geos( d->geometry );
859  return geos.crosses( *( geometry->d->geometry ) );
860 }
861 
862 QString QgsGeometry::exportToWkt( const int &precision ) const
863 {
864  if ( !d || !d->geometry )
865  {
866  return QString();
867  }
868  return d->geometry->asWkt( precision );
869 }
870 
871 QString QgsGeometry::exportToGeoJSON( const int &precision ) const
872 {
873  if ( !d || !d->geometry )
874  {
875  return QString();
876  }
877  return d->geometry->asJSON( precision );
878 }
879 
880 QgsGeometry* QgsGeometry::convertToType( QGis::GeometryType destType, bool destMultipart ) const
881 {
882  switch ( destType )
883  {
884  case QGis::Point:
885  return convertToPoint( destMultipart );
886 
887  case QGis::Line:
888  return convertToLine( destMultipart );
889 
890  case QGis::Polygon:
891  return convertToPolygon( destMultipart );
892 
893  default:
894  return 0;
895  }
896 }
897 
899 {
900  if ( !d || !d->geometry )
901  {
902  return false;
903  }
904 
905  if ( isMultipart() ) //already multitype, no need to convert
906  {
907  return true;
908  }
909 
910  QgsGeometryCollectionV2* multiGeom = dynamic_cast<QgsGeometryCollectionV2*>
912  if ( !multiGeom )
913  {
914  return false;
915  }
916 
917  detach( true );
918  multiGeom->addGeometry( d->geometry );
919  d->geometry = multiGeom;
920  removeWkbGeos();
921  return true;
922 }
923 
925 {
926  if ( !d || !d->geometry || d->geometry->geometryType() != "Point" )
927  {
928  return QgsPoint();
929  }
930  QgsPointV2* pt = dynamic_cast<QgsPointV2*>( d->geometry );
931  if ( !pt )
932  {
933  return QgsPoint();
934  }
935 
936  return QgsPoint( pt->x(), pt->y() );
937 }
938 
940 {
941  QgsPolyline polyLine;
942  if ( !d || !d->geometry )
943  {
944  return polyLine;
945  }
946 
947  bool doSegmentation = ( d->geometry->geometryType() == "CompoundCurve" || d->geometry->geometryType() == "CircularString" );
948  QgsLineStringV2* line = 0;
949  if ( doSegmentation )
950  {
951  QgsCurveV2* curve = dynamic_cast<QgsCurveV2*>( d->geometry );
952  if ( !curve )
953  {
954  return polyLine;
955  }
956  line = curve->curveToLine();
957  }
958  else
959  {
960  line = dynamic_cast<QgsLineStringV2*>( d->geometry );
961  if ( !line )
962  {
963  return polyLine;
964  }
965  }
966 
967  int nVertices = line->numPoints();
968  polyLine.resize( nVertices );
969  for ( int i = 0; i < nVertices; ++i )
970  {
971  QgsPointV2 pt = line->pointN( i );
972  polyLine[i].setX( pt.x() );
973  polyLine[i].setY( pt.y() );
974  }
975 
976  if ( doSegmentation )
977  {
978  delete line;
979  }
980 
981  return polyLine;
982 }
983 
985 {
986  bool doSegmentation = ( d->geometry->geometryType() == "CurvePolygon" );
987 
988  QgsPolygonV2* p = 0;
989  if ( doSegmentation )
990  {
991  QgsCurvePolygonV2* curvePoly = dynamic_cast<QgsCurvePolygonV2*>( d->geometry );
992  if ( !curvePoly )
993  {
994  return QgsPolygon();
995  }
996  p = curvePoly->toPolygon();
997  }
998  else
999  {
1000  p = dynamic_cast<QgsPolygonV2*>( d->geometry );
1001  }
1002 
1003  if ( !p )
1004  {
1005  return QgsPolygon();
1006  }
1007 
1008  QgsPolygon polygon;
1009  convertPolygon( *p, polygon );
1010 
1011  if ( doSegmentation )
1012  {
1013  delete p;
1014  }
1015  return polygon;
1016 }
1017 
1019 {
1020  if ( !d || !d->geometry || d->geometry->geometryType() != "MultiPoint" )
1021  {
1022  return QgsMultiPoint();
1023  }
1024 
1025  const QgsMultiPointV2* mp = dynamic_cast<QgsMultiPointV2*>( d->geometry );
1026  if ( !mp )
1027  {
1028  return QgsMultiPoint();
1029  }
1030 
1031  int nPoints = mp->numGeometries();
1032  QgsMultiPoint multiPoint( nPoints );
1033  for ( int i = 0; i < nPoints; ++i )
1034  {
1035  const QgsPointV2* pt = static_cast<const QgsPointV2*>( mp->geometryN( i ) );
1036  multiPoint[i].setX( pt->x() );
1037  multiPoint[i].setY( pt->y() );
1038  }
1039  return multiPoint;
1040 }
1041 
1043 {
1044  if ( !d || !d->geometry )
1045  {
1046  return QgsMultiPolyline();
1047  }
1048 
1049  QgsGeometryCollectionV2* geomCollection = dynamic_cast<QgsGeometryCollectionV2*>( d->geometry );
1050  if ( !geomCollection )
1051  {
1052  return QgsMultiPolyline();
1053  }
1054 
1055  int nLines = geomCollection->numGeometries();
1056  if ( nLines < 1 )
1057  {
1058  return QgsMultiPolyline();
1059  }
1060 
1061  QgsMultiPolyline mpl;
1062  for ( int i = 0; i < nLines; ++i )
1063  {
1064  bool deleteLine = false;
1065  const QgsLineStringV2* line = dynamic_cast<const QgsLineStringV2*>( geomCollection->geometryN( i ) );
1066  if ( !line )
1067  {
1068  const QgsCurveV2* curve = dynamic_cast<const QgsCurveV2*>( geomCollection->geometryN( i ) );
1069  if ( !curve )
1070  {
1071  continue;
1072  }
1073  deleteLine = true;
1074  line = curve->curveToLine();
1075  }
1076 
1077  QList< QgsPointV2 > lineCoords;
1078  line->points( lineCoords );
1079  QgsPolyline polyLine;
1080  convertToPolyline( lineCoords, polyLine );
1081  mpl.append( polyLine );
1082 
1083  if ( deleteLine )
1084  {
1085  delete line;
1086  }
1087  }
1088  return mpl;
1089 }
1090 
1092 {
1093  if ( !d || !d->geometry )
1094  {
1095  return QgsMultiPolygon();
1096  }
1097 
1098  QgsGeometryCollectionV2* geomCollection = dynamic_cast<QgsGeometryCollectionV2*>( d->geometry );
1099  if ( !geomCollection )
1100  {
1101  return QgsMultiPolygon();
1102  }
1103 
1104  int nPolygons = geomCollection->numGeometries();
1105  if ( nPolygons < 1 )
1106  {
1107  return QgsMultiPolygon();
1108  }
1109 
1110  QgsMultiPolygon mp;
1111  for ( int i = 0; i < nPolygons; ++i )
1112  {
1113  const QgsPolygonV2* polygon = dynamic_cast<const QgsPolygonV2*>( geomCollection->geometryN( i ) );
1114  if ( !polygon )
1115  {
1116  const QgsCurvePolygonV2* cPolygon = dynamic_cast<const QgsCurvePolygonV2*>( geomCollection->geometryN( i ) );
1117  if ( cPolygon )
1118  {
1119  polygon = cPolygon->toPolygon();
1120  }
1121  else
1122  {
1123  continue;
1124  }
1125  }
1126 
1127  QgsPolygon poly;
1128  convertPolygon( *polygon, poly );
1129  mp.append( poly );
1130  }
1131  return mp;
1132 }
1133 
1134 double QgsGeometry::area() const
1135 {
1136  if ( !d || !d->geometry )
1137  {
1138  return -1.0;
1139  }
1140  QgsGeos g( d->geometry );
1141 
1142 #if 0
1143  //debug: compare geos area with calculation in QGIS
1144  double geosArea = g.area();
1145  double qgisArea = 0;
1146  QgsSurfaceV2* surface = dynamic_cast<QgsSurfaceV2*>( d->geometry );
1147  if ( surface )
1148  {
1149  qgisArea = surface->area();
1150  }
1151 #endif
1152 
1153  return g.area();
1154 }
1155 
1156 double QgsGeometry::length() const
1157 {
1158  if ( !d || !d->geometry )
1159  {
1160  return -1.0;
1161  }
1162  QgsGeos g( d->geometry );
1163  return g.length();
1164 }
1165 
1166 double QgsGeometry::distance( const QgsGeometry& geom ) const
1167 {
1168  if ( !d || !d->geometry || !geom.d || !geom.d->geometry )
1169  {
1170  return -1.0;
1171  }
1172 
1173  QgsGeos g( d->geometry );
1174  return g.distance( *( geom.d->geometry ) );
1175 }
1176 
1177 QgsGeometry* QgsGeometry::buffer( double distance, int segments ) const
1178 {
1179  if ( !d || !d->geometry )
1180  {
1181  return 0;
1182  }
1183 
1184  QgsGeos g( d->geometry );
1185  QgsAbstractGeometryV2* geom = g.buffer( distance, segments );
1186  if ( !geom )
1187  {
1188  return 0;
1189  }
1190  return new QgsGeometry( geom );
1191 }
1192 
1193 QgsGeometry* QgsGeometry::buffer( double distance, int segments, int endCapStyle, int joinStyle, double mitreLimit ) const
1194 {
1195  if ( !d || !d->geometry )
1196  {
1197  return 0;
1198  }
1199 
1200  QgsGeos g( d->geometry );
1201  QgsAbstractGeometryV2* geom = g.buffer( distance, segments, endCapStyle, joinStyle, mitreLimit );
1202  if ( !geom )
1203  {
1204  return 0;
1205  }
1206  return new QgsGeometry( geom );
1207 }
1208 
1209 QgsGeometry* QgsGeometry::offsetCurve( double distance, int segments, int joinStyle, double mitreLimit ) const
1210 {
1211  if ( !d || !d->geometry )
1212  {
1213  return 0;
1214  }
1215 
1216  QgsGeos geos( d->geometry );
1217  QgsAbstractGeometryV2* offsetGeom = geos.offsetCurve( distance, segments, joinStyle, mitreLimit );
1218  if ( !offsetGeom )
1219  {
1220  return 0;
1221  }
1222  return new QgsGeometry( offsetGeom );
1223 }
1224 
1225 QgsGeometry* QgsGeometry::simplify( double tolerance ) const
1226 {
1227  if ( !d || !d->geometry )
1228  {
1229  return 0;
1230  }
1231 
1232  QgsGeos geos( d->geometry );
1233  QgsAbstractGeometryV2* simplifiedGeom = geos.simplify( tolerance );
1234  if ( !simplifiedGeom )
1235  {
1236  return 0;
1237  }
1238  return new QgsGeometry( simplifiedGeom );
1239 }
1240 
1242 {
1243  if ( !d || !d->geometry )
1244  {
1245  return 0;
1246  }
1247 
1248  QgsGeos geos( d->geometry );
1250  bool ok = geos.centroid( centroid );
1251  if ( !ok )
1252  {
1253  return 0;
1254  }
1255  return new QgsGeometry( centroid.clone() );
1256 }
1257 
1259 {
1260  if ( !d || !d->geometry )
1261  {
1262  return 0;
1263  }
1264 
1265  QgsGeos geos( d->geometry );
1266  QgsPointV2 pt;
1267  bool ok = geos.pointOnSurface( pt );
1268  if ( !ok )
1269  {
1270  return 0;
1271  }
1272  return new QgsGeometry( pt.clone() );
1273 }
1274 
1276 {
1277  if ( !d || !d->geometry )
1278  {
1279  return 0;
1280  }
1281  QgsGeos geos( d->geometry );
1282  QgsAbstractGeometryV2* cHull = geos.convexHull();
1283  if ( !cHull )
1284  {
1285  return 0;
1286  }
1287  return new QgsGeometry( cHull );
1288 }
1289 
1290 QgsGeometry* QgsGeometry::interpolate( double distance ) const
1291 {
1292  if ( !d || !d->geometry )
1293  {
1294  return 0;
1295  }
1296  QgsGeos geos( d->geometry );
1297  QgsAbstractGeometryV2* result = geos.interpolate( distance );
1298  if ( !result )
1299  {
1300  return 0;
1301  }
1302  return new QgsGeometry( result );
1303 }
1304 
1306 {
1307  if ( !d || !d->geometry || !geometry->d || !geometry->d->geometry )
1308  {
1309  return 0;
1310  }
1311 
1312  QgsGeos geos( d->geometry );
1313 
1314  QgsAbstractGeometryV2* resultGeom = geos.intersection( *( geometry->d->geometry ) );
1315  return new QgsGeometry( resultGeom );
1316 }
1317 
1319 {
1320  if ( !d || !d->geometry || !geometry->d || !geometry->d->geometry )
1321  {
1322  return 0;
1323  }
1324 
1325  QgsGeos geos( d->geometry );
1326 
1327  QgsAbstractGeometryV2* resultGeom = geos.combine( *( geometry->d->geometry ) );
1328  if ( !resultGeom )
1329  {
1330  return 0;
1331  }
1332  return new QgsGeometry( resultGeom );
1333 }
1334 
1336 {
1337  if ( !d || !d->geometry || !geometry->d || !geometry->d->geometry )
1338  {
1339  return 0;
1340  }
1341 
1342  QgsGeos geos( d->geometry );
1343 
1344  QgsAbstractGeometryV2* resultGeom = geos.difference( *( geometry->d->geometry ) );
1345  if ( !resultGeom )
1346  {
1347  return 0;
1348  }
1349  return new QgsGeometry( resultGeom );
1350 }
1351 
1353 {
1354  if ( !d || !d->geometry || !geometry->d || !geometry->d->geometry )
1355  {
1356  return 0;
1357  }
1358 
1359  QgsGeos geos( d->geometry );
1360 
1361  QgsAbstractGeometryV2* resultGeom = geos.symDifference( *( geometry->d->geometry ) );
1362  if ( !resultGeom )
1363  {
1364  return 0;
1365  }
1366  return new QgsGeometry( resultGeom );
1367 }
1368 
1370 {
1371  QList<QgsGeometry*> geometryList;
1372  if ( !d || !d->geometry )
1373  {
1374  return geometryList;
1375  }
1376 
1377  QgsGeometryCollectionV2* gc = dynamic_cast<QgsGeometryCollectionV2*>( d->geometry );
1378  if ( gc )
1379  {
1380  int numGeom = gc->numGeometries();
1381  for ( int i = 0; i < numGeom; ++i )
1382  {
1383  geometryList.append( new QgsGeometry( gc->geometryN( i )->clone() ) );
1384  }
1385  }
1386  else //a singlepart geometry
1387  {
1388  geometryList.append( new QgsGeometry( d->geometry->clone() ) );
1389  }
1390 
1391  return geometryList;
1392 }
1393 
1395 {
1396  QgsPoint point = asPoint();
1397  return point.toQPointF();
1398 }
1399 
1401 {
1402  QPolygonF result;
1403  QgsPolyline polyline;
1405  if ( type == QGis::WKBLineString || type == QGis::WKBLineString25D )
1406  {
1407  polyline = asPolyline();
1408  }
1409  else if ( type == QGis::WKBPolygon || type == QGis::WKBPolygon25D )
1410  {
1411  QgsPolygon polygon = asPolygon();
1412  if ( polygon.size() < 1 )
1413  return result;
1414  polyline = polygon.at( 0 );
1415  }
1416  else
1417  {
1418  return result;
1419  }
1420 
1421  QgsPolyline::const_iterator lineIt = polyline.constBegin();
1422  for ( ; lineIt != polyline.constEnd(); ++lineIt )
1423  {
1424  result << lineIt->toQPointF();
1425  }
1426  return result;
1427 }
1428 
1429 bool QgsGeometry::deleteRing( int ringNum, int partNum )
1430 {
1431  if ( !d || !d->geometry )
1432  {
1433  return false;
1434  }
1435 
1436  detach( true );
1437 
1438  return QgsGeometryEditUtils::deleteRing( d->geometry, ringNum, partNum );
1439 }
1440 
1441 bool QgsGeometry::deletePart( int partNum )
1442 {
1443  if ( !d || !d->geometry )
1444  {
1445  return false;
1446  }
1447 
1448  if ( !isMultipart() && partNum < 1 )
1449  {
1450  setGeometry( 0 );
1451  return true;
1452  }
1453 
1454  detach( true );
1455  bool ok = QgsGeometryEditUtils::deletePart( d->geometry, partNum );
1456  removeWkbGeos();
1457  return ok;
1458 }
1459 
1461 {
1462  if ( !d || !d->geometry )
1463  {
1464  return 1;
1465  }
1466 
1467  QgsAbstractGeometryV2* diffGeom = QgsGeometryEditUtils::avoidIntersections( *( d->geometry ), ignoreFeatures );
1468  if ( diffGeom )
1469  {
1470  detach( false );
1471  d->geometry = diffGeom;
1472  removeWkbGeos();
1473  }
1474  return 0;
1475 }
1476 
1478 {
1480 }
1481 
1483 {
1484  if ( !d || !d->geometry )
1485  {
1486  return false;
1487  }
1488 
1489  QgsGeos geos( d->geometry );
1490  return geos.isValid();
1491 }
1492 
1494 {
1495  if ( !d || !d->geometry || !g.d || !g.d->geometry )
1496  {
1497  return false;
1498  }
1499 
1500  QgsGeos geos( d->geometry );
1501  return geos.isEqual( *( g.d->geometry ) );
1502 }
1503 
1505 {
1506  if ( !d || !d->geometry )
1507  {
1508  return false;
1509  }
1510 
1511  QgsGeos geos( d->geometry );
1512  return geos.isEmpty();
1513 }
1514 
1516 {
1517  QgsGeos geos( 0 );
1518 
1520  QList<QgsGeometry*>::const_iterator it = geometryList.constBegin();
1521  for ( ; it != geometryList.constEnd(); ++it )
1522  {
1523  if ( *it )
1524  {
1525  geomV2List.append(( *it )->geometry() );
1526  }
1527  }
1528 
1529  QgsAbstractGeometryV2* geom = geos.combine( geomV2List );
1530  return new QgsGeometry( geom );
1531 }
1532 
1534 {
1535  if ( !d || !d->geometry || !requiresConversionToStraightSegments() )
1536  {
1537  return;
1538  }
1539 
1540  QgsAbstractGeometryV2* straightGeom = d->geometry->segmentize();
1541  detach( false );
1542 
1543  d->geometry = straightGeom;
1544  removeWkbGeos();
1545 }
1546 
1548 {
1549  if ( !d || !d->geometry )
1550  {
1551  return false;
1552  }
1553 
1554  return d->geometry->hasCurvedSegments();
1555 }
1556 
1558 {
1559  if ( !d || !d->geometry )
1560  {
1561  return 1;
1562  }
1563 
1564  detach();
1565  d->geometry->transform( ct );
1566  removeWkbGeos();
1567  return 0;
1568 }
1569 
1571 {
1572  if ( !d || !d->geometry )
1573  {
1574  return 1;
1575  }
1576 
1577  detach();
1578  d->geometry->transform( ct );
1579  removeWkbGeos();
1580  return 0;
1581 }
1582 
1584 {
1585  if ( d && d->geometry )
1586  {
1587  detach();
1588  d->geometry->transform( mtp.transform() );
1589  }
1590 }
1591 
1592 #if 0
1593 void QgsGeometry::clip( const QgsRectangle& rect )
1594 {
1595  if ( d && d->geometry )
1596  {
1597  detach();
1598  d->geometry->clip( rect );
1599  removeWkbGeos();
1600  }
1601 }
1602 #endif
1603 
1604 void QgsGeometry::draw( QPainter& p ) const
1605 {
1606  if ( d && d->geometry )
1607  {
1608  d->geometry->draw( p );
1609  }
1610 }
1611 
1613 {
1614  if ( !d || !d->geometry )
1615  {
1616  return false;
1617  }
1618 
1620  d->geometry->coordinateSequence( coords );
1621 
1622  int vertexCount = 0;
1623  for ( int part = 0; part < coords.size(); ++part )
1624  {
1625  const QList< QList< QgsPointV2 > >& featureCoords = coords.at( part );
1626  for ( int ring = 0; ring < featureCoords.size(); ++ring )
1627  {
1628  const QList< QgsPointV2 >& ringCoords = featureCoords.at( ring );
1629  for ( int vertex = 0; vertex < ringCoords.size(); ++vertex )
1630  {
1631  if ( vertexCount == nr )
1632  {
1633  id.part = part;
1634  id.ring = ring;
1635  id.vertex = vertex;
1636  return true;
1637  }
1638  ++vertexCount;
1639  }
1640  }
1641  }
1642  return false;
1643 }
1644 
1646 {
1647  if ( !d || !d->geometry )
1648  {
1649  return false;
1650  }
1651 
1653  d->geometry->coordinateSequence( coords );
1654 
1655  int vertexCount = 0;
1656  for ( int part = 0; part < coords.size(); ++part )
1657  {
1658  const QList< QList< QgsPointV2 > >& featureCoords = coords.at( part );
1659  for ( int ring = 0; ring < featureCoords.size(); ++ring )
1660  {
1661  const QList< QgsPointV2 >& ringCoords = featureCoords.at( ring );
1662  for ( int vertex = 0; vertex < ringCoords.size(); ++vertex )
1663  {
1664  if ( vertex == id.vertex && ring == id.ring && part == id.part )
1665  {
1666  return vertexCount;
1667  }
1668  ++vertexCount;
1669  }
1670  }
1671  }
1672  return -1;
1673 }
1674 
1675 void QgsGeometry::convertPointList( const QList<QgsPoint>& input, QList<QgsPointV2>& output )
1676 {
1677  output.clear();
1679  for ( ; it != input.constEnd(); ++it )
1680  {
1681  output.append( QgsPointV2( it->x(), it->y() ) );
1682  }
1683 }
1684 
1685 void QgsGeometry::convertPointList( const QList<QgsPointV2>& input, QList<QgsPoint>& output )
1686 {
1687  output.clear();
1689  for ( ; it != input.constEnd(); ++it )
1690  {
1691  output.append( QgsPoint( it->x(), it->y() ) );
1692  }
1693 }
1694 
1695 void QgsGeometry::convertToPolyline( const QList<QgsPointV2>& input, QgsPolyline& output )
1696 {
1697  output.clear();
1698  output.resize( input.size() );
1699 
1700  for ( int i = 0; i < input.size(); ++i )
1701  {
1702  const QgsPointV2& pt = input.at( i );
1703  output[i].setX( pt.x() );
1704  output[i].setY( pt.y() );
1705  }
1706 }
1707 
1708 void QgsGeometry::convertPolygon( const QgsPolygonV2& input, QgsPolygon& output )
1709 {
1710  output.clear();
1712  input.coordinateSequence( coord );
1713  if ( coord.size() < 1 )
1714  {
1715  return;
1716  }
1717 
1718  const QList< QList< QgsPointV2 > >& rings = coord[0];
1719  output.resize( rings.size() );
1720  for ( int i = 0; i < rings.size(); ++i )
1721  {
1722  convertToPolyline( rings[i], output[i] );
1723  }
1724 }
1725 
1726 GEOSContextHandle_t QgsGeometry::getGEOSHandler()
1727 {
1728  return QgsGeos::getGEOSHandler();
1729 }
1730 
1732 {
1733  return new QgsGeometry( new QgsPointV2( point.x(), point.y() ) );
1734 }
1735 
1737 {
1738  if ( polygon.isClosed() )
1739  {
1741  }
1742  else
1743  {
1745  }
1746 }
1747 
1749 {
1750  QgsPolygon result;
1751  result << createPolylineFromQPolygonF( polygon );
1752  return result;
1753 }
1754 
1756 {
1757  QgsPolyline result;
1758  QPolygonF::const_iterator it = polygon.constBegin();
1759  for ( ; it != polygon.constEnd(); ++it )
1760  {
1761  result.append( QgsPoint( *it ) );
1762  }
1763  return result;
1764 }
1765 
1766 bool QgsGeometry::compare( const QgsPolyline &p1, const QgsPolyline &p2, double epsilon )
1767 {
1768  if ( p1.count() != p2.count() )
1769  return false;
1770 
1771  for ( int i = 0; i < p1.count(); ++i )
1772  {
1773  if ( !p1.at( i ).compare( p2.at( i ), epsilon ) )
1774  return false;
1775  }
1776  return true;
1777 }
1778 
1779 bool QgsGeometry::compare( const QgsPolygon &p1, const QgsPolygon &p2, double epsilon )
1780 {
1781  if ( p1.count() != p2.count() )
1782  return false;
1783 
1784  for ( int i = 0; i < p1.count(); ++i )
1785  {
1786  if ( !QgsGeometry::compare( p1.at( i ), p2.at( i ), epsilon ) )
1787  return false;
1788  }
1789  return true;
1790 }
1791 
1792 
1793 bool QgsGeometry::compare( const QgsMultiPolygon &p1, const QgsMultiPolygon &p2, double epsilon )
1794 {
1795  if ( p1.count() != p2.count() )
1796  return false;
1797 
1798  for ( int i = 0; i < p1.count(); ++i )
1799  {
1800  if ( !QgsGeometry::compare( p1.at( i ), p2.at( i ), epsilon ) )
1801  return false;
1802  }
1803  return true;
1804 }
1805 
1806 QgsGeometry* QgsGeometry::smooth( const unsigned int iterations, const double offset ) const
1807 {
1808  switch ( wkbType() )
1809  {
1810  case QGis::WKBPoint:
1811  case QGis::WKBPoint25D:
1812  case QGis::WKBMultiPoint:
1814  //can't smooth a point based geometry
1815  return new QgsGeometry( *this );
1816 
1817  case QGis::WKBLineString:
1819  {
1820  QgsPolyline line = asPolyline();
1821  return QgsGeometry::fromPolyline( smoothLine( line, iterations, offset ) );
1822  }
1823 
1826  {
1827  QgsMultiPolyline multiline = asMultiPolyline();
1828  QgsMultiPolyline resultMultiline;
1829  QgsMultiPolyline::const_iterator lineIt = multiline.constBegin();
1830  for ( ; lineIt != multiline.constEnd(); ++lineIt )
1831  {
1832  resultMultiline << smoothLine( *lineIt, iterations, offset );
1833  }
1834  return QgsGeometry::fromMultiPolyline( resultMultiline );
1835  }
1836 
1837  case QGis::WKBPolygon:
1838  case QGis::WKBPolygon25D:
1839  {
1840  QgsPolygon poly = asPolygon();
1841  return QgsGeometry::fromPolygon( smoothPolygon( poly, iterations, offset ) );
1842  }
1843 
1844  case QGis::WKBMultiPolygon:
1846  {
1847  QgsMultiPolygon multipoly = asMultiPolygon();
1848  QgsMultiPolygon resultMultipoly;
1849  QgsMultiPolygon::const_iterator polyIt = multipoly.constBegin();
1850  for ( ; polyIt != multipoly.constEnd(); ++polyIt )
1851  {
1852  resultMultipoly << smoothPolygon( *polyIt, iterations, offset );
1853  }
1854  return QgsGeometry::fromMultiPolygon( resultMultipoly );
1855  }
1856  break;
1857 
1858  case QGis::WKBUnknown:
1859  default:
1860  return new QgsGeometry( *this );
1861  }
1862 }
1863 
1864 inline QgsPoint interpolatePointOnLine( const QgsPoint& p1, const QgsPoint& p2, const double offset )
1865 {
1866  double deltaX = p2.x() - p1.x();
1867  double deltaY = p2.y() - p1.y();
1868  return QgsPoint( p1.x() + deltaX * offset, p1.y() + deltaY * offset );
1869 }
1870 
1871 QgsPolyline QgsGeometry::smoothLine( const QgsPolyline& polyline, const unsigned int iterations, const double offset ) const
1872 {
1873  QgsPolyline result = polyline;
1874  for ( unsigned int iteration = 0; iteration < iterations; ++iteration )
1875  {
1876  QgsPolyline outputLine = QgsPolyline();
1877  for ( int i = 0; i < result.count() - 1; i++ )
1878  {
1879  const QgsPoint& p1 = result.at( i );
1880  const QgsPoint& p2 = result.at( i + 1 );
1881  outputLine << ( i == 0 ? result.at( i ) : interpolatePointOnLine( p1, p2, offset ) );
1882  outputLine << ( i == result.count() - 2 ? result.at( i + 1 ) : interpolatePointOnLine( p1, p2, 1.0 - offset ) );
1883  }
1884  result = outputLine;
1885  }
1886  return result;
1887 }
1888 
1889 QgsPolygon QgsGeometry::smoothPolygon( const QgsPolygon& polygon, const unsigned int iterations, const double offset ) const
1890 {
1891  QgsPolygon resultPoly;
1892  QgsPolygon::const_iterator ringIt = polygon.constBegin();
1893  for ( ; ringIt != polygon.constEnd(); ++ringIt )
1894  {
1895  QgsPolyline resultRing = *ringIt;
1896  for ( unsigned int iteration = 0; iteration < iterations; ++iteration )
1897  {
1898  QgsPolyline outputRing = QgsPolyline();
1899  for ( int i = 0; i < resultRing.count() - 1; ++i )
1900  {
1901  const QgsPoint& p1 = resultRing.at( i );
1902  const QgsPoint& p2 = resultRing.at( i + 1 );
1903  outputRing << interpolatePointOnLine( p1, p2, offset );
1904  outputRing << interpolatePointOnLine( p1, p2, 1.0 - offset );
1905  }
1906  //close polygon
1907  outputRing << outputRing.at( 0 );
1908 
1909  resultRing = outputRing;
1910  }
1911  resultPoly << resultRing;
1912  }
1913  return resultPoly;
1914 }
1915 
1916 QgsGeometry* QgsGeometry::convertToPoint( bool destMultipart ) const
1917 {
1918  switch ( type() )
1919  {
1920  case QGis::Point:
1921  {
1922  bool srcIsMultipart = isMultipart();
1923 
1924  if (( destMultipart && srcIsMultipart ) ||
1925  ( !destMultipart && !srcIsMultipart ) )
1926  {
1927  // return a copy of the same geom
1928  return new QgsGeometry( *this );
1929  }
1930  if ( destMultipart )
1931  {
1932  // layer is multipart => make a multipoint with a single point
1933  return fromMultiPoint( QgsMultiPoint() << asPoint() );
1934  }
1935  else
1936  {
1937  // destination is singlepart => make a single part if possible
1938  QgsMultiPoint multiPoint = asMultiPoint();
1939  if ( multiPoint.count() == 1 )
1940  {
1941  return fromPoint( multiPoint[0] );
1942  }
1943  }
1944  return 0;
1945  }
1946 
1947  case QGis::Line:
1948  {
1949  // only possible if destination is multipart
1950  if ( !destMultipart )
1951  return 0;
1952 
1953  // input geometry is multipart
1954  if ( isMultipart() )
1955  {
1956  QgsMultiPolyline multiLine = asMultiPolyline();
1957  QgsMultiPoint multiPoint;
1958  for ( QgsMultiPolyline::const_iterator multiLineIt = multiLine.constBegin(); multiLineIt != multiLine.constEnd(); ++multiLineIt )
1959  for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt )
1960  multiPoint << *lineIt;
1961  return fromMultiPoint( multiPoint );
1962  }
1963  // input geometry is not multipart: copy directly the line into a multipoint
1964  else
1965  {
1966  QgsPolyline line = asPolyline();
1967  if ( !line.isEmpty() )
1968  return fromMultiPoint( line );
1969  }
1970  return 0;
1971  }
1972 
1973  case QGis::Polygon:
1974  {
1975  // can only transform if destination is multipoint
1976  if ( !destMultipart )
1977  return 0;
1978 
1979  // input geometry is multipart: make a multipoint from multipolygon
1980  if ( isMultipart() )
1981  {
1982  QgsMultiPolygon multiPolygon = asMultiPolygon();
1983  QgsMultiPoint multiPoint;
1984  for ( QgsMultiPolygon::const_iterator polygonIt = multiPolygon.constBegin(); polygonIt != multiPolygon.constEnd(); ++polygonIt )
1985  for ( QgsMultiPolyline::const_iterator multiLineIt = ( *polygonIt ).constBegin(); multiLineIt != ( *polygonIt ).constEnd(); ++multiLineIt )
1986  for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt )
1987  multiPoint << *lineIt;
1988  return fromMultiPoint( multiPoint );
1989  }
1990  // input geometry is not multipart: make a multipoint from polygon
1991  else
1992  {
1993  QgsPolygon polygon = asPolygon();
1994  QgsMultiPoint multiPoint;
1995  for ( QgsMultiPolyline::const_iterator multiLineIt = polygon.constBegin(); multiLineIt != polygon.constEnd(); ++multiLineIt )
1996  for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt )
1997  multiPoint << *lineIt;
1998  return fromMultiPoint( multiPoint );
1999  }
2000  }
2001 
2002  default:
2003  return 0;
2004  }
2005 }
2006 
2007 QgsGeometry* QgsGeometry::convertToLine( bool destMultipart ) const
2008 {
2009  switch ( type() )
2010  {
2011  case QGis::Point:
2012  {
2013  if ( !isMultipart() )
2014  return 0;
2015 
2016  QgsMultiPoint multiPoint = asMultiPoint();
2017  if ( multiPoint.count() < 2 )
2018  return 0;
2019 
2020  if ( destMultipart )
2021  return fromMultiPolyline( QgsMultiPolyline() << multiPoint );
2022  else
2023  return fromPolyline( multiPoint );
2024  }
2025 
2026  case QGis::Line:
2027  {
2028  bool srcIsMultipart = isMultipart();
2029 
2030  if (( destMultipart && srcIsMultipart ) ||
2031  ( !destMultipart && ! srcIsMultipart ) )
2032  {
2033  // return a copy of the same geom
2034  return new QgsGeometry( *this );
2035  }
2036  if ( destMultipart )
2037  {
2038  // destination is multipart => makes a multipoint with a single line
2039  QgsPolyline line = asPolyline();
2040  if ( !line.isEmpty() )
2041  return fromMultiPolyline( QgsMultiPolyline() << line );
2042  }
2043  else
2044  {
2045  // destination is singlepart => make a single part if possible
2046  QgsMultiPolyline multiLine = asMultiPolyline();
2047  if ( multiLine.count() == 1 )
2048  return fromPolyline( multiLine[0] );
2049  }
2050  return 0;
2051  }
2052 
2053  case QGis::Polygon:
2054  {
2055  // input geometry is multipolygon
2056  if ( isMultipart() )
2057  {
2058  QgsMultiPolygon multiPolygon = asMultiPolygon();
2059  QgsMultiPolyline multiLine;
2060  for ( QgsMultiPolygon::const_iterator polygonIt = multiPolygon.constBegin(); polygonIt != multiPolygon.constEnd(); ++polygonIt )
2061  for ( QgsMultiPolyline::const_iterator multiLineIt = ( *polygonIt ).constBegin(); multiLineIt != ( *polygonIt ).constEnd(); ++multiLineIt )
2062  multiLine << *multiLineIt;
2063 
2064  if ( destMultipart )
2065  {
2066  // destination is multipart
2067  return fromMultiPolyline( multiLine );
2068  }
2069  else if ( multiLine.count() == 1 )
2070  {
2071  // destination is singlepart => make a single part if possible
2072  return fromPolyline( multiLine[0] );
2073  }
2074  }
2075  // input geometry is single polygon
2076  else
2077  {
2078  QgsPolygon polygon = asPolygon();
2079  // if polygon has rings
2080  if ( polygon.count() > 1 )
2081  {
2082  // cannot fit a polygon with rings in a single line layer
2083  // TODO: would it be better to remove rings?
2084  if ( destMultipart )
2085  {
2086  QgsPolygon polygon = asPolygon();
2087  QgsMultiPolyline multiLine;
2088  for ( QgsMultiPolyline::const_iterator multiLineIt = polygon.constBegin(); multiLineIt != polygon.constEnd(); ++multiLineIt )
2089  multiLine << *multiLineIt;
2090  return fromMultiPolyline( multiLine );
2091  }
2092  }
2093  // no rings
2094  else if ( polygon.count() == 1 )
2095  {
2096  if ( destMultipart )
2097  {
2098  return fromMultiPolyline( polygon );
2099  }
2100  else
2101  {
2102  return fromPolyline( polygon[0] );
2103  }
2104  }
2105  }
2106  return 0;
2107  }
2108 
2109  default:
2110  return 0;
2111  }
2112 }
2113 
2114 QgsGeometry* QgsGeometry::convertToPolygon( bool destMultipart ) const
2115 {
2116  switch ( type() )
2117  {
2118  case QGis::Point:
2119  {
2120  if ( !isMultipart() )
2121  return 0;
2122 
2123  QgsMultiPoint multiPoint = asMultiPoint();
2124  if ( multiPoint.count() < 3 )
2125  return 0;
2126 
2127  if ( multiPoint.last() != multiPoint.first() )
2128  multiPoint << multiPoint.first();
2129 
2130  QgsPolygon polygon = QgsPolygon() << multiPoint;
2131  if ( destMultipart )
2132  return fromMultiPolygon( QgsMultiPolygon() << polygon );
2133  else
2134  return fromPolygon( polygon );
2135  }
2136 
2137  case QGis::Line:
2138  {
2139  // input geometry is multiline
2140  if ( isMultipart() )
2141  {
2142  QgsMultiPolyline multiLine = asMultiPolyline();
2143  QgsMultiPolygon multiPolygon;
2144  for ( QgsMultiPolyline::iterator multiLineIt = multiLine.begin(); multiLineIt != multiLine.end(); ++multiLineIt )
2145  {
2146  // do not create polygon for a 1 segment line
2147  if (( *multiLineIt ).count() < 3 )
2148  return 0;
2149  if (( *multiLineIt ).count() == 3 && ( *multiLineIt ).first() == ( *multiLineIt ).last() )
2150  return 0;
2151 
2152  // add closing node
2153  if (( *multiLineIt ).first() != ( *multiLineIt ).last() )
2154  *multiLineIt << ( *multiLineIt ).first();
2155  multiPolygon << ( QgsPolygon() << *multiLineIt );
2156  }
2157  // check that polygons were inserted
2158  if ( !multiPolygon.isEmpty() )
2159  {
2160  if ( destMultipart )
2161  {
2162  return fromMultiPolygon( multiPolygon );
2163  }
2164  else if ( multiPolygon.count() == 1 )
2165  {
2166  // destination is singlepart => make a single part if possible
2167  return fromPolygon( multiPolygon[0] );
2168  }
2169  }
2170  }
2171  // input geometry is single line
2172  else
2173  {
2174  QgsPolyline line = asPolyline();
2175 
2176  // do not create polygon for a 1 segment line
2177  if ( line.count() < 3 )
2178  return 0;
2179  if ( line.count() == 3 && line.first() == line.last() )
2180  return 0;
2181 
2182  // add closing node
2183  if ( line.first() != line.last() )
2184  line << line.first();
2185 
2186  // destination is multipart
2187  if ( destMultipart )
2188  {
2189  return fromMultiPolygon( QgsMultiPolygon() << ( QgsPolygon() << line ) );
2190  }
2191  else
2192  {
2193  return fromPolygon( QgsPolygon() << line );
2194  }
2195  }
2196  return 0;
2197  }
2198 
2199  case QGis::Polygon:
2200  {
2201  bool srcIsMultipart = isMultipart();
2202 
2203  if (( destMultipart && srcIsMultipart ) ||
2204  ( !destMultipart && ! srcIsMultipart ) )
2205  {
2206  // return a copy of the same geom
2207  return new QgsGeometry( *this );
2208  }
2209  if ( destMultipart )
2210  {
2211  // destination is multipart => makes a multipoint with a single polygon
2212  QgsPolygon polygon = asPolygon();
2213  if ( !polygon.isEmpty() )
2214  return fromMultiPolygon( QgsMultiPolygon() << polygon );
2215  }
2216  else
2217  {
2218  QgsMultiPolygon multiPolygon = asMultiPolygon();
2219  if ( multiPolygon.count() == 1 )
2220  {
2221  // destination is singlepart => make a single part if possible
2222  return fromPolygon( multiPolygon[0] );
2223  }
2224  }
2225  return 0;
2226  }
2227 
2228  default:
2229  return 0;
2230  }
2231 }
2232 
2234 {
2235  return new QgsGeos( geometry );
2236 }
2237 
2239 {
2240  QByteArray byteArray = QByteArray::fromRawData(( char * )geometry.asWkb(), geometry.wkbSize() ); // does not copy data and does not take ownership
2241  out << byteArray;
2242  return out;
2243 }
2244 
2246 {
2247  QByteArray byteArray;
2248  in >> byteArray;
2249  char *data = new char[byteArray.size()];
2250  memcpy( data, byteArray.data(), byteArray.size() );
2251  geometry.fromWkb(( unsigned char* )data, byteArray.size() );
2252  return in;
2253 }
2254 
2255 
2256 
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:1518
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:172
void clear()
QgsWKBTypes::Type wkbType() const
Returns the WKB type of the geometry.
bool isEqual(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:1326
A rectangle specified with double values.
Definition: qgsrectangle.h:35
bool isValid() const override
Definition: qgsgeos.cpp:1312
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.
GeometryType
Definition: qgis.h:155
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:1225
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:1295
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:1210
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:286
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:782
double distance(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:211
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)
WkbType
Used for symbology operations.
Definition: qgis.h:53
QgsGeometry()
Constructor.
Definition: qgsgeometry.cpp:64
T & first()
Multi point geometry collection.
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:1266
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:249
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
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:259
const GEOSGeometry * asGeos() const
Returns a geos geometry.
static GEOSContextHandle_t getGEOSHandler()
Definition: qgsgeos.cpp:2056
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:244
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:302
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)
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
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:167
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)
Definition: qgspoint.h:103
virtual QString geometryType() const =0
Returns a unique string representing the geometry type.
void setY(double y)
Definition: qgspoint.h:111
QgsAbstractGeometryV2 * symDifference(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:206
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:1502
bool intersects(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:234
static GEOSGeometry * asGeos(const QgsAbstractGeometryV2 *geom)
Definition: qgsgeos.cpp:970
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:1240
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...
virtual void transform(const QgsCoordinateTransform &ct)=0
Transforms the geometry using a coordinate transform.
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:177
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
bool overlaps(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:254
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
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:1172
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:239
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:1347
double area() const
Returns the area of the geometry using GEOS.
bool disjoint(const QgsAbstractGeometryV2 &geom) const override
Definition: qgsgeos.cpp:264
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:269
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