QGIS API Documentation  2.11.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
qgsvectorlayereditutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectorlayereditutils.cpp
3  ---------------------
4  begin : Dezember 2012
5  copyright : (C) 2012 by Martin Dobias
6  email : wonder dot sk at gmail dot com
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  ***************************************************************************/
16 
17 #include "qgsvectordataprovider.h"
18 #include "qgsgeometrycache.h"
20 #include "qgslinestringv2.h"
21 #include "qgslogger.h"
22 #include "qgspointv2.h"
23 
24 #include <limits>
25 
26 
28  : L( layer )
29 {
30 }
31 
32 bool QgsVectorLayerEditUtils::insertVertex( double x, double y, QgsFeatureId atFeatureId, int beforeVertex )
33 {
34  if ( !L->hasGeometryType() )
35  return false;
36 
37  QgsGeometry geometry;
38  if ( !cache()->geometry( atFeatureId, geometry ) )
39  {
40  // it's not in cache: let's fetch it from layer
41  QgsFeature f;
42  if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( atFeatureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.constGeometry() )
43  return false; // geometry not found
44 
45  geometry = *f.constGeometry();
46  }
47 
48  geometry.insertVertex( x, y, beforeVertex );
49 
50  L->editBuffer()->changeGeometry( atFeatureId, &geometry );
51  return true;
52 }
53 
54 
55 bool QgsVectorLayerEditUtils::moveVertex( double x, double y, QgsFeatureId atFeatureId, int atVertex )
56 {
57  QgsPointV2 p( x, y );
58  return moveVertex( p, atFeatureId, atVertex );
59 }
60 
61 bool QgsVectorLayerEditUtils::moveVertex( const QgsPointV2& p, QgsFeatureId atFeatureId, int atVertex )
62 {
63  if ( !L->hasGeometryType() )
64  return false;
65 
66  QgsGeometry geometry;
67  if ( !cache()->geometry( atFeatureId, geometry ) )
68  {
69  // it's not in cache: let's fetch it from layer
70  QgsFeature f;
71  if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( atFeatureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.constGeometry() )
72  return false; // geometry not found
73 
74  geometry = *f.constGeometry();
75  }
76 
77  geometry.moveVertex( p, atVertex );
78 
79  L->editBuffer()->changeGeometry( atFeatureId, &geometry );
80  return true;
81 }
82 
83 
84 bool QgsVectorLayerEditUtils::deleteVertex( QgsFeatureId atFeatureId, int atVertex )
85 {
86  if ( !L->hasGeometryType() )
87  return false;
88 
89  QgsGeometry geometry;
90  if ( !cache()->geometry( atFeatureId, geometry ) )
91  {
92  // it's not in cache: let's fetch it from layer
93  QgsFeature f;
94  if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( atFeatureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.constGeometry() )
95  return false; // geometry not found
96 
97  geometry = *f.constGeometry();
98  }
99 
100  if ( !geometry.deleteVertex( atVertex ) )
101  return false;
102 
103  L->editBuffer()->changeGeometry( atFeatureId, &geometry );
104  return true;
105 }
106 
108 {
109  QgsLineStringV2* ringLine = new QgsLineStringV2();
110  QList< QgsPointV2 > ringPoints;
112  for ( ; ringIt != ring.constEnd(); ++ringIt )
113  {
114  ringPoints.append( QgsPointV2( ringIt->x(), ringIt->y() ) );
115  }
116  ringLine->setPoints( ringPoints );
117  return addRing( ringLine );
118 }
119 
121 {
122  if ( !L->hasGeometryType() )
123  {
124  delete ring;
125  return 5;
126  }
127 
128  int addRingReturnCode = 5; //default: return code for 'ring not inserted'
129  QgsRectangle bBox = ring->boundingBox();
130  QgsFeatureIterator fit = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
131 
132  QgsFeature f;
133  while ( fit.nextFeature( f ) )
134  {
135  //add ring takes ownership of ring, and deletes it if there's an error
136  addRingReturnCode = f.geometry()->addRing( static_cast< QgsCurveV2* >( ring->clone() ) );
137  if ( addRingReturnCode == 0 )
138  {
139  L->editBuffer()->changeGeometry( f.id(), f.geometry() );
140 
141  //setModified( true, true );
142  break;
143  }
144  }
145 
146  delete ring;
147  return addRingReturnCode;
148 }
149 
151 {
152  if ( !L->hasGeometryType() )
153  return 6;
154 
155  QgsGeometry geometry;
156  if ( !cache()->geometry( featureId, geometry ) ) // maybe it's in cache
157  {
158  // it's not in cache: let's fetch it from layer
159  QgsFeature f;
160  if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.geometry() )
161  return 6; //geometry not found
162 
163  geometry = *f.geometry();
164  }
165 
166  int errorCode = geometry.addPart( points, L->geometryType() );
167  if ( errorCode == 0 )
168  {
169  L->editBuffer()->changeGeometry( featureId, &geometry );
170  }
171  return errorCode;
172 }
173 
175 {
176  if ( !L->hasGeometryType() )
177  return 6;
178 
179  QgsGeometry geometry;
180  if ( !cache()->geometry( featureId, geometry ) ) // maybe it's in cache
181  {
182  // it's not in cache: let's fetch it from layer
183  QgsFeature f;
184  if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.geometry() )
185  return 6; //geometry not found
186 
187  geometry = *f.geometry();
188  }
189 
190  int errorCode = geometry.addPart( ring );
191  if ( errorCode == 0 )
192  {
193  L->editBuffer()->changeGeometry( featureId, &geometry );
194  }
195  return errorCode;
196 }
197 
198 
199 int QgsVectorLayerEditUtils::translateFeature( QgsFeatureId featureId, double dx, double dy )
200 {
201  if ( !L->hasGeometryType() )
202  return 1;
203 
204  QgsGeometry geometry;
205  if ( !cache()->geometry( featureId, geometry ) ) // maybe it's in cache
206  {
207  // it's not in cache: let's fetch it from layer
208  QgsFeature f;
209  if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.constGeometry() )
210  return 1; //geometry not found
211 
212  geometry = *f.constGeometry();
213  }
214 
215  int errorCode = geometry.translate( dx, dy );
216  if ( errorCode == 0 )
217  {
218  L->editBuffer()->changeGeometry( featureId, &geometry );
219  }
220  return errorCode;
221 }
222 
223 
224 int QgsVectorLayerEditUtils::splitFeatures( const QList<QgsPoint>& splitLine, bool topologicalEditing )
225 {
226  if ( !L->hasGeometryType() )
227  return 4;
228 
229  QgsFeatureList newFeatures; //store all the newly created features
230  double xMin, yMin, xMax, yMax;
231  QgsRectangle bBox; //bounding box of the split line
232  int returnCode = 0;
233  int splitFunctionReturn; //return code of QgsGeometry::splitGeometry
234  int numberOfSplittedFeatures = 0;
235 
236  QgsFeatureIterator features;
237  const QgsFeatureIds selectedIds = L->selectedFeaturesIds();
238 
239  if ( selectedIds.size() > 0 ) //consider only the selected features if there is a selection
240  {
241  features = L->selectedFeaturesIterator();
242  }
243  else //else consider all the feature that intersect the bounding box of the split line
244  {
245  if ( boundingBoxFromPointList( splitLine, xMin, yMin, xMax, yMax ) == 0 )
246  {
247  bBox.setXMinimum( xMin ); bBox.setYMinimum( yMin );
248  bBox.setXMaximum( xMax ); bBox.setYMaximum( yMax );
249  }
250  else
251  {
252  return 1;
253  }
254 
255  if ( bBox.isEmpty() )
256  {
257  //if the bbox is a line, try to make a square out of it
258  if ( bBox.width() == 0.0 && bBox.height() > 0 )
259  {
260  bBox.setXMinimum( bBox.xMinimum() - bBox.height() / 2 );
261  bBox.setXMaximum( bBox.xMaximum() + bBox.height() / 2 );
262  }
263  else if ( bBox.height() == 0.0 && bBox.width() > 0 )
264  {
265  bBox.setYMinimum( bBox.yMinimum() - bBox.width() / 2 );
266  bBox.setYMaximum( bBox.yMaximum() + bBox.width() / 2 );
267  }
268  else
269  {
270  //If we have a single point, we still create a non-null box
271  double bufferDistance = 0.000001;
272  if ( L->crs().geographicFlag() )
273  bufferDistance = 0.00000001;
274  bBox.setXMinimum( bBox.xMinimum() - bufferDistance );
275  bBox.setXMaximum( bBox.xMaximum() + bufferDistance );
276  bBox.setYMinimum( bBox.yMinimum() - bufferDistance );
277  bBox.setYMaximum( bBox.yMaximum() + bufferDistance );
278  }
279  }
280 
281  features = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
282  }
283 
284  QgsFeature feat;
285  while ( features.nextFeature( feat ) )
286  {
287  if ( !feat.constGeometry() )
288  {
289  continue;
290  }
291  QList<QgsGeometry*> newGeometries;
292  QList<QgsPoint> topologyTestPoints;
293  QgsGeometry* newGeometry = 0;
294  splitFunctionReturn = feat.geometry()->splitGeometry( splitLine, newGeometries, topologicalEditing, topologyTestPoints );
295  if ( splitFunctionReturn == 0 )
296  {
297  //change this geometry
298  L->editBuffer()->changeGeometry( feat.id(), feat.geometry() );
299 
300  //insert new features
301  for ( int i = 0; i < newGeometries.size(); ++i )
302  {
303  newGeometry = newGeometries.at( i );
304  QgsFeature newFeature;
305  newFeature.setGeometry( newGeometry );
306 
307  //use default value where possible for primary key (e.g. autoincrement),
308  //and use the value from the original (split) feature if not primary key
309  QgsAttributes newAttributes = feat.attributes();
310  foreach ( int pkIdx, L->dataProvider()->pkAttributeIndexes() )
311  {
312  const QVariant defaultValue = L->dataProvider()->defaultValue( pkIdx );
313  if ( !defaultValue.isNull() )
314  {
315  newAttributes[ pkIdx ] = defaultValue;
316  }
317  else //try with NULL
318  {
319  newAttributes[ pkIdx ] = QVariant();
320  }
321  }
322 
323  newFeature.setAttributes( newAttributes );
324 
325  newFeatures.append( newFeature );
326  }
327 
328  if ( topologicalEditing )
329  {
330  QList<QgsPoint>::const_iterator topol_it = topologyTestPoints.constBegin();
331  for ( ; topol_it != topologyTestPoints.constEnd(); ++topol_it )
332  {
333  addTopologicalPoints( *topol_it );
334  }
335  }
336  ++numberOfSplittedFeatures;
337  }
338  else if ( splitFunctionReturn > 1 ) //1 means no split but also no error
339  {
340  returnCode = splitFunctionReturn;
341  }
342  }
343 
344  if ( numberOfSplittedFeatures == 0 && selectedIds.size() > 0 )
345  {
346  //There is a selection but no feature has been split.
347  //Maybe user forgot that only the selected features are split
348  returnCode = 4;
349  }
350 
351 
352  //now add the new features to this vectorlayer
353  L->editBuffer()->addFeatures( newFeatures );
354 
355  return returnCode;
356 }
357 
358 int QgsVectorLayerEditUtils::splitParts( const QList<QgsPoint>& splitLine, bool topologicalEditing )
359 {
360  if ( !L->hasGeometryType() )
361  return 4;
362 
363  double xMin, yMin, xMax, yMax;
364  QgsRectangle bBox; //bounding box of the split line
365  int returnCode = 0;
366  int splitFunctionReturn; //return code of QgsGeometry::splitGeometry
367  int numberOfSplittedParts = 0;
368 
369  QgsFeatureIterator fit;
370 
371  if ( L->selectedFeatureCount() > 0 ) //consider only the selected features if there is a selection
372  {
373  fit = L->selectedFeaturesIterator();
374  }
375  else //else consider all the feature that intersect the bounding box of the split line
376  {
377  if ( boundingBoxFromPointList( splitLine, xMin, yMin, xMax, yMax ) == 0 )
378  {
379  bBox.setXMinimum( xMin ); bBox.setYMinimum( yMin );
380  bBox.setXMaximum( xMax ); bBox.setYMaximum( yMax );
381  }
382  else
383  {
384  return 1;
385  }
386 
387  if ( bBox.isEmpty() )
388  {
389  //if the bbox is a line, try to make a square out of it
390  if ( bBox.width() == 0.0 && bBox.height() > 0 )
391  {
392  bBox.setXMinimum( bBox.xMinimum() - bBox.height() / 2 );
393  bBox.setXMaximum( bBox.xMaximum() + bBox.height() / 2 );
394  }
395  else if ( bBox.height() == 0.0 && bBox.width() > 0 )
396  {
397  bBox.setYMinimum( bBox.yMinimum() - bBox.width() / 2 );
398  bBox.setYMaximum( bBox.yMaximum() + bBox.width() / 2 );
399  }
400  else
401  {
402  //If we have a single point, we still create a non-null box
403  double bufferDistance = 0.000001;
404  if ( L->crs().geographicFlag() )
405  bufferDistance = 0.00000001;
406  bBox.setXMinimum( bBox.xMinimum() - bufferDistance );
407  bBox.setXMaximum( bBox.xMaximum() + bufferDistance );
408  bBox.setYMinimum( bBox.yMinimum() - bufferDistance );
409  bBox.setYMaximum( bBox.yMaximum() + bufferDistance );
410  }
411  }
412 
413  fit = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
414  }
415 
416  int addPartRet = 0;
417 
418  QgsFeature feat;
419  while ( fit.nextFeature( feat ) )
420  {
421  QList<QgsGeometry*> newGeometries;
422  QList<QgsPoint> topologyTestPoints;
423  splitFunctionReturn = feat.geometry()->splitGeometry( splitLine, newGeometries, topologicalEditing, topologyTestPoints );
424  if ( splitFunctionReturn == 0 )
425  {
426  //add new parts
427  for ( int i = 0; i < newGeometries.size(); ++i )
428  {
429  addPartRet = feat.geometry()->addPart( newGeometries.at( i ) );
430  if ( addPartRet )
431  break;
432  }
433 
434  // For test only: Exception already thrown here...
435  // feat.geometry()->asWkb();
436 
437  if ( !addPartRet )
438  {
439  L->editBuffer()->changeGeometry( feat.id(), feat.geometry() );
440  }
441  else
442  {
443  // Test addPartRet
444  switch ( addPartRet )
445  {
446  case 1:
447  QgsDebugMsg( "Not a multipolygon" );
448  break;
449 
450  case 2:
451  QgsDebugMsg( "Not a valid geometry" );
452  break;
453 
454  case 3:
455  QgsDebugMsg( "New polygon ring" );
456  break;
457  }
458  }
459  L->editBuffer()->changeGeometry( feat.id(), feat.geometry() );
460 
461  if ( topologicalEditing )
462  {
463  QList<QgsPoint>::const_iterator topol_it = topologyTestPoints.constBegin();
464  for ( ; topol_it != topologyTestPoints.constEnd(); ++topol_it )
465  {
466  addTopologicalPoints( *topol_it );
467  }
468  }
469  ++numberOfSplittedParts;
470  }
471  else if ( splitFunctionReturn > 1 ) //1 means no split but also no error
472  {
473  returnCode = splitFunctionReturn;
474  }
475 
476  qDeleteAll( newGeometries );
477  }
478 
479  if ( numberOfSplittedParts == 0 && L->selectedFeatureCount() > 0 && returnCode == 0 )
480  {
481  //There is a selection but no feature has been split.
482  //Maybe user forgot that only the selected features are split
483  returnCode = 4;
484  }
485 
486  return returnCode;
487 }
488 
489 
491 {
492  if ( !L->hasGeometryType() )
493  return 1;
494 
495  if ( !geom )
496  {
497  return 1;
498  }
499 
500  int returnVal = 0;
501 
502  QGis::WkbType wkbType = geom->wkbType();
503 
504  switch ( wkbType )
505  {
506  //line
508  case QGis::WKBLineString:
509  {
510  QgsPolyline theLine = geom->asPolyline();
511  QgsPolyline::const_iterator line_it = theLine.constBegin();
512  for ( ; line_it != theLine.constEnd(); ++line_it )
513  {
514  if ( addTopologicalPoints( *line_it ) != 0 )
515  {
516  returnVal = 2;
517  }
518  }
519  break;
520  }
521 
522  //multiline
525  {
526  QgsMultiPolyline theMultiLine = geom->asMultiPolyline();
527  QgsPolyline currentPolyline;
528 
529  for ( int i = 0; i < theMultiLine.size(); ++i )
530  {
531  QgsPolyline::const_iterator line_it = currentPolyline.constBegin();
532  for ( ; line_it != currentPolyline.constEnd(); ++line_it )
533  {
534  if ( addTopologicalPoints( *line_it ) != 0 )
535  {
536  returnVal = 2;
537  }
538  }
539  }
540  break;
541  }
542 
543  //polygon
544  case QGis::WKBPolygon25D:
545  case QGis::WKBPolygon:
546  {
547  QgsPolygon thePolygon = geom->asPolygon();
548  QgsPolyline currentRing;
549 
550  for ( int i = 0; i < thePolygon.size(); ++i )
551  {
552  currentRing = thePolygon.at( i );
553  QgsPolyline::const_iterator line_it = currentRing.constBegin();
554  for ( ; line_it != currentRing.constEnd(); ++line_it )
555  {
556  if ( addTopologicalPoints( *line_it ) != 0 )
557  {
558  returnVal = 2;
559  }
560  }
561  }
562  break;
563  }
564 
565  //multipolygon
568  {
569  QgsMultiPolygon theMultiPolygon = geom->asMultiPolygon();
570  QgsPolygon currentPolygon;
571  QgsPolyline currentRing;
572 
573  for ( int i = 0; i < theMultiPolygon.size(); ++i )
574  {
575  currentPolygon = theMultiPolygon.at( i );
576  for ( int j = 0; j < currentPolygon.size(); ++j )
577  {
578  currentRing = currentPolygon.at( j );
579  QgsPolyline::const_iterator line_it = currentRing.constBegin();
580  for ( ; line_it != currentRing.constEnd(); ++line_it )
581  {
582  if ( addTopologicalPoints( *line_it ) != 0 )
583  {
584  returnVal = 2;
585  }
586  }
587  }
588  }
589  break;
590  }
591  default:
592  break;
593  }
594  return returnVal;
595 }
596 
597 
599 {
600  if ( !L->hasGeometryType() )
601  return 1;
602 
603  QMultiMap<double, QgsSnappingResult> snapResults; //results from the snapper object
604  //we also need to snap to vertex to make sure the vertex does not already exist in this geometry
605  QMultiMap<double, QgsSnappingResult> vertexSnapResults;
606 
607  QList<QgsSnappingResult> filteredSnapResults; //we filter out the results that are on existing vertices
608 
609  //work with a tolerance because coordinate projection may introduce some rounding
610  double threshold = 0.0000001;
611  if ( L->crs().mapUnits() == QGis::Meters )
612  {
613  threshold = 0.001;
614  }
615  else if ( L->crs().mapUnits() == QGis::Feet )
616  {
617  threshold = 0.0001;
618  }
619 
620 
621  if ( L->snapWithContext( p, threshold, snapResults, QgsSnapper::SnapToSegment ) != 0 )
622  {
623  return 2;
624  }
625 
628  for ( ; snap_it != snapResults.constEnd(); ++snap_it )
629  {
630  //test if p is already a vertex of this geometry. If yes, don't insert it
631  bool vertexAlreadyExists = false;
632  if ( L->snapWithContext( p, threshold, vertexSnapResults, QgsSnapper::SnapToVertex ) != 0 )
633  {
634  continue;
635  }
636 
637  vertex_snap_it = vertexSnapResults.constBegin();
638  for ( ; vertex_snap_it != vertexSnapResults.constEnd(); ++vertex_snap_it )
639  {
640  if ( snap_it.value().snappedAtGeometry == vertex_snap_it.value().snappedAtGeometry )
641  {
642  vertexAlreadyExists = true;
643  }
644  }
645 
646  if ( !vertexAlreadyExists )
647  {
648  filteredSnapResults.push_back( *snap_it );
649  }
650  }
651  insertSegmentVerticesForSnap( filteredSnapResults );
652  return 0;
653 }
654 
655 
657 {
658  if ( !L->hasGeometryType() )
659  return 1;
660 
661  int returnval = 0;
662  QgsPoint layerPoint;
663 
665  for ( ; it != snapResults.constEnd(); ++it )
666  {
667  if ( it->snappedVertexNr == -1 ) // segment snap
668  {
669  layerPoint = it->snappedVertex;
670  if ( !insertVertex( layerPoint.x(), layerPoint.y(), it->snappedAtGeometry, it->afterVertexNr ) )
671  {
672  returnval = 3;
673  }
674  }
675  }
676  return returnval;
677 }
678 
679 
680 
681 
682 int QgsVectorLayerEditUtils::boundingBoxFromPointList( const QList<QgsPoint>& list, double& xmin, double& ymin, double& xmax, double& ymax ) const
683 {
684  if ( list.size() < 1 )
685  {
686  return 1;
687  }
688 
693 
694  for ( QList<QgsPoint>::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
695  {
696  if ( it->x() < xmin )
697  {
698  xmin = it->x();
699  }
700  if ( it->x() > xmax )
701  {
702  xmax = it->x();
703  }
704  if ( it->y() < ymin )
705  {
706  ymin = it->y();
707  }
708  if ( it->y() > ymax )
709  {
710  ymax = it->y();
711  }
712  }
713 
714  return 0;
715 }
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:51
Wrapper for iterator of features from vector data provider or vector layer.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
bool isEmpty() const
test if rectangle is empty.
int insertSegmentVerticesForSnap(const QList< QgsSnappingResult > &snapResults)
Inserts vertices to the snapped segments.
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:167
virtual bool addFeatures(QgsFeatureList &features)
Insert a copy of the given features into the layer (but does not commit it)
Use exact geometry intersection (slower) instead of bounding boxes.
void push_back(const T &value)
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:192
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
int size() const
QgsMultiPolyline asMultiPolyline() const
Return contents of the geometry as a multi linestring if wkbType is WKBMultiLineString, otherwise an empty list.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
QgsPolygon asPolygon() const
Return contents of the geometry as a polygon if wkbType is WKBPolygon, otherwise an empty list...
const_iterator constEnd() const
const_iterator constBegin() const
const T & at(int i) const
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...
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
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:95
WkbType
Used for symbology operations.
Definition: qgis.h:53
int addPart(const QList< QgsPoint > &ring, QgsFeatureId featureId)
Adds a new part polygon to a multipart feature.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:162
virtual QgsAttributeList pkAttributeIndexes()
Return list of indexes of fields that make up the primary key.
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 deleteVertex(QgsFeatureId atFeatureId, int atVertex)
Deletes a vertex from a feature.
double x() const
Get the x value of the point.
Definition: qgspoint.h:126
int size() const
int boundingBoxFromPointList(const QList< QgsPoint > &list, double &xmin, double &ymin, double &xmax, double &ymax) const
Little helper function that gives bounding box from a list of points.
QgsMultiPolygon asMultiPolygon() const
Return contents of the geometry as a multi polygon if wkbType is WKBMultiPolygon, otherwise an empty ...
double ANALYSIS_EXPORT max(double x, double y)
Returns the maximum of two doubles or the first argument if both are equal.
int splitGeometry(const QList< QgsPoint > &splitLine, QList< QgsGeometry * > &newGeometries, bool topological, QList< QgsPoint > &topologyTestPoints)
Splits this geometry according to a given line.
void setGeometry(const QgsGeometry &geom)
Set this feature's geometry from another QgsGeometry object.
Definition: qgsfeature.cpp:104
QgsVectorLayerEditBuffer * editBuffer()
Buffer with uncommitted editing operations. Only valid after editing has been turned on...
void append(const T &value)
bool isNull() const
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
const QgsFeatureIds & selectedFeaturesIds() const
Return reference to identifiers of selected features.
Line string geometry type.
QgsAttributes attributes() const
Returns the feature's attributes.
Definition: qgsfeature.cpp:90
int addTopologicalPoints(const QgsGeometry *geom)
Adds topological points for every vertex of the geometry.
int snapWithContext(const QgsPoint &startPoint, double snappingTolerance, QMultiMap< double, QgsSnappingResult > &snappingResults, QgsSnapper::SnappingType snap_to)
Snaps to segment or vertex within given tolerance.
Point geometry type.
Definition: qgspointv2.h:29
bool geometry(QgsFeatureId fid, QgsGeometry &geometry)
fetch geometry from cache, return true if successful
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:172
bool deleteVertex(int atVertex)
Deletes the vertex at the given position number and item (first number is index 0) Returns false if a...
const_iterator constEnd() const
int translateFeature(QgsFeatureId featureId, double dx, double dy)
Translates feature by dx, dy.
bool moveVertex(double x, double y, QgsFeatureId atFeatureId, int atVertex)
Moves the vertex at the given position number, ring and item (first number is index 0)...
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QList< int > QgsAttributeList
const T & value() const
QGis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
QGis::GeometryType geometryType() const
Returns point, line or polygon.
A class to represent a point.
Definition: qgspoint.h:63
int translate(double dx, double dy)
Translate this geometry by dx, dy.
QgsGeometry * geometry()
Get the geometry object associated with this feature.
Definition: qgsfeature.cpp:62
QgsFeatureIterator selectedFeaturesIterator(QgsFeatureRequest request=QgsFeatureRequest())
Get an iterator of the selected features.
QgsPolyline asPolyline() const
Return contents of the geometry as a polyline if wkbType is WKBLineString, otherwise an empty list...
bool insertVertex(double x, double y, QgsFeatureId atFeatureId, int beforeVertex)
Insert a new vertex before the given vertex number, in the given ring, item (first number is index 0)...
const T & at(int i) const
bool hasGeometryType() const
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
const_iterator constBegin() const
int addRing(const QList< QgsPoint > &ring)
Adds a ring to polygon/multipolygon features.
virtual QVariant defaultValue(int fieldId)
Returns the default value for field specified by fieldId.
void setPoints(const QList< QgsPointV2 > &points)
void setYMaximum(double y)
Set the maximum y value.
Definition: qgsrectangle.h:177
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
Definition: qgsfeature.cpp:68
qint64 QgsFeatureId
Definition: qgsfeature.h:31
double y() const
Get the y value of the point.
Definition: qgspoint.h:134
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
typedef const_iterator
int addRing(const QList< QgsPoint > &ring)
Adds a new ring to this geometry.
QgsVectorDataProvider * dataProvider()
Returns the data provider.
const_iterator constEnd() const
bool nextFeature(QgsFeature &f)
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
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:202
A vector of attributes.
Definition: qgsfeature.h:109
int size() const
Represents a vector layer which manages a vector based data sets.
bool geographicFlag() const
Get this Geographic? flag.
int splitParts(const QList< QgsPoint > &splitLine, bool topologicalEditing=false)
Splits parts cut by the given line.
int selectedFeatureCount()
The number of features that are selected in this layer.
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:187
virtual bool changeGeometry(QgsFeatureId fid, QgsGeometry *geom)
Change feature's geometry.
int splitFeatures(const QList< QgsPoint > &splitLine, bool topologicalEditing=false)
Splits features cut by the given line.
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:162
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:207
QgsVectorLayerEditUtils(QgsVectorLayer *layer)
QGis::UnitType mapUnits() const
Get the units that the projection is in.