QGIS API Documentation  2.11.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups 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 "qgslogger.h"
21 
22 #include <limits>
23 
24 
26  : L( layer )
27 {
28 }
29 
30 bool QgsVectorLayerEditUtils::insertVertex( double x, double y, QgsFeatureId atFeatureId, int beforeVertex )
31 {
32  if ( !L->hasGeometryType() )
33  return false;
34 
35  QgsGeometry geometry;
36  if ( !cache()->geometry( atFeatureId, geometry ) )
37  {
38  // it's not in cache: let's fetch it from layer
39  QgsFeature f;
40  if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( atFeatureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.constGeometry() )
41  return false; // geometry not found
42 
43  geometry = *f.constGeometry();
44  }
45 
46  geometry.insertVertex( x, y, beforeVertex );
47 
48  L->editBuffer()->changeGeometry( atFeatureId, &geometry );
49  return true;
50 }
51 
52 
53 bool QgsVectorLayerEditUtils::moveVertex( double x, double y, QgsFeatureId atFeatureId, int atVertex )
54 {
55  QgsPointV2 p( x, y );
56  return moveVertex( p, atFeatureId, atVertex );
57 }
58 
59 bool QgsVectorLayerEditUtils::moveVertex( const QgsPointV2& p, QgsFeatureId atFeatureId, int atVertex )
60 {
61  if ( !L->hasGeometryType() )
62  return false;
63 
64  QgsGeometry geometry;
65  if ( !cache()->geometry( atFeatureId, geometry ) )
66  {
67  // it's not in cache: let's fetch it from layer
68  QgsFeature f;
69  if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( atFeatureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.constGeometry() )
70  return false; // geometry not found
71 
72  geometry = *f.constGeometry();
73  }
74 
75  geometry.moveVertex( p, atVertex );
76 
77  L->editBuffer()->changeGeometry( atFeatureId, &geometry );
78  return true;
79 }
80 
81 
82 bool QgsVectorLayerEditUtils::deleteVertex( QgsFeatureId atFeatureId, int atVertex )
83 {
84  if ( !L->hasGeometryType() )
85  return false;
86 
87  QgsGeometry geometry;
88  if ( !cache()->geometry( atFeatureId, geometry ) )
89  {
90  // it's not in cache: let's fetch it from layer
91  QgsFeature f;
92  if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( atFeatureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.constGeometry() )
93  return false; // geometry not found
94 
95  geometry = *f.constGeometry();
96  }
97 
98  if ( !geometry.deleteVertex( atVertex ) )
99  return false;
100 
101  L->editBuffer()->changeGeometry( atFeatureId, &geometry );
102  return true;
103 }
104 
105 
107 {
108  if ( !L->hasGeometryType() )
109  return 5;
110 
111  int addRingReturnCode = 5; //default: return code for 'ring not inserted'
112  double xMin, yMin, xMax, yMax;
113  QgsRectangle bBox;
114 
115  if ( boundingBoxFromPointList( ring, xMin, yMin, xMax, yMax ) == 0 )
116  {
117  bBox.setXMinimum( xMin ); bBox.setYMinimum( yMin );
118  bBox.setXMaximum( xMax ); bBox.setYMaximum( yMax );
119  }
120  else
121  {
122  return 3; //ring not valid
123  }
124 
125  QgsFeatureIterator fit = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
126 
127  QgsFeature f;
128  while ( fit.nextFeature( f ) )
129  {
130  addRingReturnCode = f.geometry()->addRing( ring );
131  if ( addRingReturnCode == 0 )
132  {
133  L->editBuffer()->changeGeometry( f.id(), f.geometry() );
134 
135  //setModified( true, true );
136  break;
137  }
138  }
139 
140  return addRingReturnCode;
141 }
142 
143 
145 {
146  if ( !L->hasGeometryType() )
147  return 6;
148 
149  QgsGeometry geometry;
150  if ( !cache()->geometry( featureId, geometry ) ) // maybe it's in cache
151  {
152  // it's not in cache: let's fetch it from layer
153  QgsFeature f;
154  if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.constGeometry() )
155  return 6; //geometry not found
156 
157  geometry = *f.constGeometry();
158  }
159 
160  int errorCode = geometry.addPart( points, L->geometryType() );
161  if ( errorCode == 0 )
162  {
163  L->editBuffer()->changeGeometry( featureId, &geometry );
164  }
165  return errorCode;
166 }
167 
168 
169 
170 int QgsVectorLayerEditUtils::translateFeature( QgsFeatureId featureId, double dx, double dy )
171 {
172  if ( !L->hasGeometryType() )
173  return 1;
174 
175  QgsGeometry geometry;
176  if ( !cache()->geometry( featureId, geometry ) ) // maybe it's in cache
177  {
178  // it's not in cache: let's fetch it from layer
179  QgsFeature f;
180  if ( !L->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.constGeometry() )
181  return 1; //geometry not found
182 
183  geometry = *f.constGeometry();
184  }
185 
186  int errorCode = geometry.translate( dx, dy );
187  if ( errorCode == 0 )
188  {
189  L->editBuffer()->changeGeometry( featureId, &geometry );
190  }
191  return errorCode;
192 }
193 
194 
195 int QgsVectorLayerEditUtils::splitFeatures( const QList<QgsPoint>& splitLine, bool topologicalEditing )
196 {
197  if ( !L->hasGeometryType() )
198  return 4;
199 
200  QgsFeatureList newFeatures; //store all the newly created features
201  double xMin, yMin, xMax, yMax;
202  QgsRectangle bBox; //bounding box of the split line
203  int returnCode = 0;
204  int splitFunctionReturn; //return code of QgsGeometry::splitGeometry
205  int numberOfSplittedFeatures = 0;
206 
207  QgsFeatureIterator features;
208  const QgsFeatureIds selectedIds = L->selectedFeaturesIds();
209 
210  if ( selectedIds.size() > 0 ) //consider only the selected features if there is a selection
211  {
212  features = L->selectedFeaturesIterator();
213  }
214  else //else consider all the feature that intersect the bounding box of the split line
215  {
216  if ( boundingBoxFromPointList( splitLine, xMin, yMin, xMax, yMax ) == 0 )
217  {
218  bBox.setXMinimum( xMin ); bBox.setYMinimum( yMin );
219  bBox.setXMaximum( xMax ); bBox.setYMaximum( yMax );
220  }
221  else
222  {
223  return 1;
224  }
225 
226  if ( bBox.isEmpty() )
227  {
228  //if the bbox is a line, try to make a square out of it
229  if ( bBox.width() == 0.0 && bBox.height() > 0 )
230  {
231  bBox.setXMinimum( bBox.xMinimum() - bBox.height() / 2 );
232  bBox.setXMaximum( bBox.xMaximum() + bBox.height() / 2 );
233  }
234  else if ( bBox.height() == 0.0 && bBox.width() > 0 )
235  {
236  bBox.setYMinimum( bBox.yMinimum() - bBox.width() / 2 );
237  bBox.setYMaximum( bBox.yMaximum() + bBox.width() / 2 );
238  }
239  else
240  {
241  //If we have a single point, we still create a non-null box
242  double bufferDistance = 0.000001;
243  if ( L->crs().geographicFlag() )
244  bufferDistance = 0.00000001;
245  bBox.setXMinimum( bBox.xMinimum() - bufferDistance );
246  bBox.setXMaximum( bBox.xMaximum() + bufferDistance );
247  bBox.setYMinimum( bBox.yMinimum() - bufferDistance );
248  bBox.setYMaximum( bBox.yMaximum() + bufferDistance );
249  }
250  }
251 
252  features = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
253  }
254 
255  QgsFeature feat;
256  while ( features.nextFeature( feat ) )
257  {
258  if ( !feat.constGeometry() )
259  {
260  continue;
261  }
262  QList<QgsGeometry*> newGeometries;
263  QList<QgsPoint> topologyTestPoints;
264  QgsGeometry* newGeometry = 0;
265  splitFunctionReturn = feat.geometry()->splitGeometry( splitLine, newGeometries, topologicalEditing, topologyTestPoints );
266  if ( splitFunctionReturn == 0 )
267  {
268  //change this geometry
269  L->editBuffer()->changeGeometry( feat.id(), feat.geometry() );
270 
271  //insert new features
272  for ( int i = 0; i < newGeometries.size(); ++i )
273  {
274  newGeometry = newGeometries.at( i );
275  QgsFeature newFeature;
276  newFeature.setGeometry( newGeometry );
277 
278  //use default value where possible for primary key (e.g. autoincrement),
279  //and use the value from the original (split) feature if not primary key
280  QgsAttributes newAttributes = feat.attributes();
281  foreach ( int pkIdx, L->dataProvider()->pkAttributeIndexes() )
282  {
283  const QVariant defaultValue = L->dataProvider()->defaultValue( pkIdx );
284  if ( !defaultValue.isNull() )
285  {
286  newAttributes[ pkIdx ] = defaultValue;
287  }
288  else //try with NULL
289  {
290  newAttributes[ pkIdx ] = QVariant();
291  }
292  }
293 
294  newFeature.setAttributes( newAttributes );
295 
296  newFeatures.append( newFeature );
297  }
298 
299  if ( topologicalEditing )
300  {
301  QList<QgsPoint>::const_iterator topol_it = topologyTestPoints.constBegin();
302  for ( ; topol_it != topologyTestPoints.constEnd(); ++topol_it )
303  {
304  addTopologicalPoints( *topol_it );
305  }
306  }
307  ++numberOfSplittedFeatures;
308  }
309  else if ( splitFunctionReturn > 1 ) //1 means no split but also no error
310  {
311  returnCode = splitFunctionReturn;
312  }
313  }
314 
315  if ( numberOfSplittedFeatures == 0 && selectedIds.size() > 0 )
316  {
317  //There is a selection but no feature has been split.
318  //Maybe user forgot that only the selected features are split
319  returnCode = 4;
320  }
321 
322 
323  //now add the new features to this vectorlayer
324  L->editBuffer()->addFeatures( newFeatures );
325 
326  return returnCode;
327 }
328 
329 int QgsVectorLayerEditUtils::splitParts( const QList<QgsPoint>& splitLine, bool topologicalEditing )
330 {
331  if ( !L->hasGeometryType() )
332  return 4;
333 
334  double xMin, yMin, xMax, yMax;
335  QgsRectangle bBox; //bounding box of the split line
336  int returnCode = 0;
337  int splitFunctionReturn; //return code of QgsGeometry::splitGeometry
338  int numberOfSplittedParts = 0;
339 
340  QgsFeatureIterator fit;
341 
342  if ( L->selectedFeatureCount() > 0 ) //consider only the selected features if there is a selection
343  {
344  fit = L->selectedFeaturesIterator();
345  }
346  else //else consider all the feature that intersect the bounding box of the split line
347  {
348  if ( boundingBoxFromPointList( splitLine, xMin, yMin, xMax, yMax ) == 0 )
349  {
350  bBox.setXMinimum( xMin ); bBox.setYMinimum( yMin );
351  bBox.setXMaximum( xMax ); bBox.setYMaximum( yMax );
352  }
353  else
354  {
355  return 1;
356  }
357 
358  if ( bBox.isEmpty() )
359  {
360  //if the bbox is a line, try to make a square out of it
361  if ( bBox.width() == 0.0 && bBox.height() > 0 )
362  {
363  bBox.setXMinimum( bBox.xMinimum() - bBox.height() / 2 );
364  bBox.setXMaximum( bBox.xMaximum() + bBox.height() / 2 );
365  }
366  else if ( bBox.height() == 0.0 && bBox.width() > 0 )
367  {
368  bBox.setYMinimum( bBox.yMinimum() - bBox.width() / 2 );
369  bBox.setYMaximum( bBox.yMaximum() + bBox.width() / 2 );
370  }
371  else
372  {
373  //If we have a single point, we still create a non-null box
374  double bufferDistance = 0.000001;
375  if ( L->crs().geographicFlag() )
376  bufferDistance = 0.00000001;
377  bBox.setXMinimum( bBox.xMinimum() - bufferDistance );
378  bBox.setXMaximum( bBox.xMaximum() + bufferDistance );
379  bBox.setYMinimum( bBox.yMinimum() - bufferDistance );
380  bBox.setYMaximum( bBox.yMaximum() + bufferDistance );
381  }
382  }
383 
384  fit = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
385  }
386 
387  int addPartRet = 0;
388 
389  QgsFeature feat;
390  while ( fit.nextFeature( feat ) )
391  {
392  QList<QgsGeometry*> newGeometries;
393  QList<QgsPoint> topologyTestPoints;
394  splitFunctionReturn = feat.geometry()->splitGeometry( splitLine, newGeometries, topologicalEditing, topologyTestPoints );
395  if ( splitFunctionReturn == 0 )
396  {
397  //add new parts
398  for ( int i = 0; i < newGeometries.size(); ++i )
399  {
400  addPartRet = feat.geometry()->addPart( newGeometries.at( i ) );
401  if ( addPartRet )
402  break;
403  }
404 
405  // For test only: Exception already thrown here...
406  // feat.geometry()->asWkb();
407 
408  if ( !addPartRet )
409  {
410  L->editBuffer()->changeGeometry( feat.id(), feat.geometry() );
411  }
412  else
413  {
414  // Test addPartRet
415  switch ( addPartRet )
416  {
417  case 1:
418  QgsDebugMsg( "Not a multipolygon" );
419  break;
420 
421  case 2:
422  QgsDebugMsg( "Not a valid geometry" );
423  break;
424 
425  case 3:
426  QgsDebugMsg( "New polygon ring" );
427  break;
428  }
429  }
430  L->editBuffer()->changeGeometry( feat.id(), feat.geometry() );
431 
432  if ( topologicalEditing )
433  {
434  QList<QgsPoint>::const_iterator topol_it = topologyTestPoints.constBegin();
435  for ( ; topol_it != topologyTestPoints.constEnd(); ++topol_it )
436  {
437  addTopologicalPoints( *topol_it );
438  }
439  }
440  ++numberOfSplittedParts;
441  }
442  else if ( splitFunctionReturn > 1 ) //1 means no split but also no error
443  {
444  returnCode = splitFunctionReturn;
445  }
446 
447  qDeleteAll( newGeometries );
448  }
449 
450  if ( numberOfSplittedParts == 0 && L->selectedFeatureCount() > 0 && returnCode == 0 )
451  {
452  //There is a selection but no feature has been split.
453  //Maybe user forgot that only the selected features are split
454  returnCode = 4;
455  }
456 
457  return returnCode;
458 }
459 
460 
462 {
463  if ( !L->hasGeometryType() )
464  return 1;
465 
466  if ( !geom )
467  {
468  return 1;
469  }
470 
471  int returnVal = 0;
472 
473  QGis::WkbType wkbType = geom->wkbType();
474 
475  switch ( wkbType )
476  {
477  //line
479  case QGis::WKBLineString:
480  {
481  QgsPolyline theLine = geom->asPolyline();
482  QgsPolyline::const_iterator line_it = theLine.constBegin();
483  for ( ; line_it != theLine.constEnd(); ++line_it )
484  {
485  if ( addTopologicalPoints( *line_it ) != 0 )
486  {
487  returnVal = 2;
488  }
489  }
490  break;
491  }
492 
493  //multiline
496  {
497  QgsMultiPolyline theMultiLine = geom->asMultiPolyline();
498  QgsPolyline currentPolyline;
499 
500  for ( int i = 0; i < theMultiLine.size(); ++i )
501  {
502  QgsPolyline::const_iterator line_it = currentPolyline.constBegin();
503  for ( ; line_it != currentPolyline.constEnd(); ++line_it )
504  {
505  if ( addTopologicalPoints( *line_it ) != 0 )
506  {
507  returnVal = 2;
508  }
509  }
510  }
511  break;
512  }
513 
514  //polygon
515  case QGis::WKBPolygon25D:
516  case QGis::WKBPolygon:
517  {
518  QgsPolygon thePolygon = geom->asPolygon();
519  QgsPolyline currentRing;
520 
521  for ( int i = 0; i < thePolygon.size(); ++i )
522  {
523  currentRing = thePolygon.at( i );
524  QgsPolyline::const_iterator line_it = currentRing.constBegin();
525  for ( ; line_it != currentRing.constEnd(); ++line_it )
526  {
527  if ( addTopologicalPoints( *line_it ) != 0 )
528  {
529  returnVal = 2;
530  }
531  }
532  }
533  break;
534  }
535 
536  //multipolygon
539  {
540  QgsMultiPolygon theMultiPolygon = geom->asMultiPolygon();
541  QgsPolygon currentPolygon;
542  QgsPolyline currentRing;
543 
544  for ( int i = 0; i < theMultiPolygon.size(); ++i )
545  {
546  currentPolygon = theMultiPolygon.at( i );
547  for ( int j = 0; j < currentPolygon.size(); ++j )
548  {
549  currentRing = currentPolygon.at( j );
550  QgsPolyline::const_iterator line_it = currentRing.constBegin();
551  for ( ; line_it != currentRing.constEnd(); ++line_it )
552  {
553  if ( addTopologicalPoints( *line_it ) != 0 )
554  {
555  returnVal = 2;
556  }
557  }
558  }
559  }
560  break;
561  }
562  default:
563  break;
564  }
565  return returnVal;
566 }
567 
568 
570 {
571  if ( !L->hasGeometryType() )
572  return 1;
573 
574  QMultiMap<double, QgsSnappingResult> snapResults; //results from the snapper object
575  //we also need to snap to vertex to make sure the vertex does not already exist in this geometry
576  QMultiMap<double, QgsSnappingResult> vertexSnapResults;
577 
578  QList<QgsSnappingResult> filteredSnapResults; //we filter out the results that are on existing vertices
579 
580  //work with a tolerance because coordinate projection may introduce some rounding
581  double threshold = 0.0000001;
582  if ( L->crs().mapUnits() == QGis::Meters )
583  {
584  threshold = 0.001;
585  }
586  else if ( L->crs().mapUnits() == QGis::Feet )
587  {
588  threshold = 0.0001;
589  }
590 
591 
592  if ( L->snapWithContext( p, threshold, snapResults, QgsSnapper::SnapToSegment ) != 0 )
593  {
594  return 2;
595  }
596 
599  for ( ; snap_it != snapResults.constEnd(); ++snap_it )
600  {
601  //test if p is already a vertex of this geometry. If yes, don't insert it
602  bool vertexAlreadyExists = false;
603  if ( L->snapWithContext( p, threshold, vertexSnapResults, QgsSnapper::SnapToVertex ) != 0 )
604  {
605  continue;
606  }
607 
608  vertex_snap_it = vertexSnapResults.constBegin();
609  for ( ; vertex_snap_it != vertexSnapResults.constEnd(); ++vertex_snap_it )
610  {
611  if ( snap_it.value().snappedAtGeometry == vertex_snap_it.value().snappedAtGeometry )
612  {
613  vertexAlreadyExists = true;
614  }
615  }
616 
617  if ( !vertexAlreadyExists )
618  {
619  filteredSnapResults.push_back( *snap_it );
620  }
621  }
622  insertSegmentVerticesForSnap( filteredSnapResults );
623  return 0;
624 }
625 
626 
628 {
629  if ( !L->hasGeometryType() )
630  return 1;
631 
632  int returnval = 0;
633  QgsPoint layerPoint;
634 
636  for ( ; it != snapResults.constEnd(); ++it )
637  {
638  if ( it->snappedVertexNr == -1 ) // segment snap
639  {
640  layerPoint = it->snappedVertex;
641  if ( !insertVertex( layerPoint.x(), layerPoint.y(), it->snappedAtGeometry, it->afterVertexNr ) )
642  {
643  returnval = 3;
644  }
645  }
646  }
647  return returnval;
648 }
649 
650 
651 
652 
653 int QgsVectorLayerEditUtils::boundingBoxFromPointList( const QList<QgsPoint>& list, double& xmin, double& ymin, double& xmax, double& ymax ) const
654 {
655  if ( list.size() < 1 )
656  {
657  return 1;
658  }
659 
664 
665  for ( QList<QgsPoint>::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
666  {
667  if ( it->x() < xmin )
668  {
669  xmin = it->x();
670  }
671  if ( it->x() > xmax )
672  {
673  xmax = it->x();
674  }
675  if ( it->y() < ymin )
676  {
677  ymin = it->y();
678  }
679  if ( it->y() > ymax )
680  {
681  ymax = it->y();
682  }
683  }
684 
685  return 0;
686 }
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
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.
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 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
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
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.
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)