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