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