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