QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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 "qgsfeatureiterator.h"
20 #include "qgslinestring.h"
21 #include "qgslogger.h"
22 #include "qgspoint.h"
23 #include "qgsgeometryfactory.h"
24 #include "qgis.h"
25 #include "qgswkbtypes.h"
26 #include "qgsvectorlayerutils.h"
27 #include "qgsvectorlayer.h"
28 #include "qgsgeometryoptions.h"
29 #include "qgsabstractgeometry.h"
30 
31 #include <limits>
32 
33 
35  : mLayer( layer )
36 {
37 }
38 
39 bool QgsVectorLayerEditUtils::insertVertex( double x, double y, QgsFeatureId atFeatureId, int beforeVertex )
40 {
41  if ( !mLayer->isSpatial() )
42  return false;
43 
44  QgsFeature f;
45  if ( !mLayer->getFeatures( QgsFeatureRequest().setFilterFid( atFeatureId ).setNoAttributes() ).nextFeature( f ) || !f.hasGeometry() )
46  return false; // geometry not found
47 
48  QgsGeometry geometry = f.geometry();
49 
50  geometry.insertVertex( x, y, beforeVertex );
51 
52  mLayer->changeGeometry( atFeatureId, geometry );
53  return true;
54 }
55 
56 bool QgsVectorLayerEditUtils::insertVertex( const QgsPoint &point, QgsFeatureId atFeatureId, int beforeVertex )
57 {
58  if ( !mLayer->isSpatial() )
59  return false;
60 
61  QgsFeature f;
62  if ( !mLayer->getFeatures( QgsFeatureRequest().setFilterFid( atFeatureId ).setNoAttributes() ).nextFeature( f ) || !f.hasGeometry() )
63  return false; // geometry not found
64 
65  QgsGeometry geometry = f.geometry();
66 
67  geometry.insertVertex( point, beforeVertex );
68 
69  mLayer->changeGeometry( atFeatureId, geometry );
70  return true;
71 }
72 
73 bool QgsVectorLayerEditUtils::moveVertex( double x, double y, QgsFeatureId atFeatureId, int atVertex )
74 {
75  QgsPoint p( x, y );
76  return moveVertex( p, atFeatureId, atVertex );
77 }
78 
79 bool QgsVectorLayerEditUtils::moveVertex( const QgsPoint &p, QgsFeatureId atFeatureId, int atVertex )
80 {
81  if ( !mLayer->isSpatial() )
82  return false;
83 
84  QgsFeature f;
85  if ( !mLayer->getFeatures( QgsFeatureRequest().setFilterFid( atFeatureId ).setNoAttributes() ).nextFeature( f ) || !f.hasGeometry() )
86  return false; // geometry not found
87 
88  QgsGeometry geometry = f.geometry();
89 
90  geometry.moveVertex( p, atVertex );
91 
92  mLayer->changeGeometry( atFeatureId, geometry );
93  return true;
94 }
95 
96 
98 {
99  if ( !mLayer->isSpatial() )
101 
102  QgsFeature f;
103  if ( !mLayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setNoAttributes() ).nextFeature( f ) || !f.hasGeometry() )
104  return Qgis::VectorEditResult::FetchFeatureFailed; // geometry not found
105 
106  QgsGeometry geometry = f.geometry();
107 
108  if ( !geometry.deleteVertex( vertex ) )
110 
111  if ( geometry.constGet() && geometry.constGet()->nCoordinates() == 0 )
112  {
113  //last vertex deleted, set geometry to null
114  geometry.set( nullptr );
115  }
116 
117  mLayer->changeGeometry( featureId, geometry );
119 }
120 
121 Qgis::GeometryOperationResult QgsVectorLayerEditUtils::addRing( const QVector<QgsPointXY> &ring, const QgsFeatureIds &targetFeatureIds, QgsFeatureId *modifiedFeatureId )
122 {
124  for ( QVector<QgsPointXY>::const_iterator it = ring.constBegin(); it != ring.constEnd(); ++it )
125  {
126  l << QgsPoint( *it );
127  }
128  return addRing( l, targetFeatureIds, modifiedFeatureId );
129 }
130 
132 {
133  QgsLineString *ringLine = new QgsLineString( ring );
134  return addRing( ringLine, targetFeatureIds, modifiedFeatureId );
135 }
136 
138 {
139  if ( !mLayer->isSpatial() )
140  {
141  delete ring;
143  }
144 
145  Qgis::GeometryOperationResult addRingReturnCode = Qgis::GeometryOperationResult::AddRingNotInExistingFeature; //default: return code for 'ring not inserted'
146  QgsFeature f;
147 
148  QgsFeatureIterator fit;
149  if ( !targetFeatureIds.isEmpty() )
150  {
151  //check only specified features
152  fit = mLayer->getFeatures( QgsFeatureRequest().setFilterFids( targetFeatureIds ) );
153  }
154  else
155  {
156  //check all intersecting features
157  QgsRectangle bBox = ring->boundingBox();
158  fit = mLayer->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
159  }
160 
161  //find first valid feature we can add the ring to
162  while ( fit.nextFeature( f ) )
163  {
164  if ( !f.hasGeometry() )
165  continue;
166 
167  //add ring takes ownership of ring, and deletes it if there's an error
168  QgsGeometry g = f.geometry();
169 
170  addRingReturnCode = g.addRing( static_cast< QgsCurve * >( ring->clone() ) );
171  if ( addRingReturnCode == Qgis::GeometryOperationResult::Success )
172  {
173  mLayer->changeGeometry( f.id(), g );
174  if ( modifiedFeatureId )
175  *modifiedFeatureId = f.id();
176 
177  //setModified( true, true );
178  break;
179  }
180  }
181 
182  delete ring;
183  return addRingReturnCode;
184 }
185 
186 Qgis::GeometryOperationResult QgsVectorLayerEditUtils::addPart( const QVector<QgsPointXY> &points, QgsFeatureId featureId )
187 {
189  for ( QVector<QgsPointXY>::const_iterator it = points.constBegin(); it != points.constEnd(); ++it )
190  {
191  l << QgsPoint( *it );
192  }
193  return addPart( l, featureId );
194 }
195 
197 {
198  if ( !mLayer->isSpatial() )
200 
201  QgsGeometry geometry;
202  bool firstPart = false;
203  QgsFeature f;
204  if ( !mLayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setNoAttributes() ).nextFeature( f ) )
206 
207  if ( !f.hasGeometry() )
208  {
209  //no existing geometry, so adding first part to null geometry
210  firstPart = true;
211  }
212  else
213  {
214  geometry = f.geometry();
215  }
216 
217  Qgis::GeometryOperationResult errorCode = geometry.addPart( points, mLayer->geometryType() );
218  if ( errorCode == Qgis::GeometryOperationResult::Success )
219  {
220  if ( firstPart && QgsWkbTypes::isSingleType( mLayer->wkbType() )
221  && mLayer->dataProvider()->doesStrictFeatureTypeCheck() )
222  {
223  //convert back to single part if required by layer
224  geometry.convertToSingleType();
225  }
226  mLayer->changeGeometry( featureId, geometry );
227  }
228  return errorCode;
229 }
230 
232 {
233  if ( !mLayer->isSpatial() )
235 
236  QgsGeometry geometry;
237  bool firstPart = false;
238  QgsFeature f;
239  if ( !mLayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setNoAttributes() ).nextFeature( f ) )
241 
242  if ( !f.hasGeometry() )
243  {
244  //no existing geometry, so adding first part to null geometry
245  firstPart = true;
246  }
247  else
248  {
249  geometry = f.geometry();
250  }
251 
252  Qgis::GeometryOperationResult errorCode = geometry.addPart( ring, mLayer->geometryType() );
253  if ( errorCode == Qgis::GeometryOperationResult::Success )
254  {
255  if ( firstPart && QgsWkbTypes::isSingleType( mLayer->wkbType() )
256  && mLayer->dataProvider()->doesStrictFeatureTypeCheck() )
257  {
258  //convert back to single part if required by layer
259  geometry.convertToSingleType();
260  }
261  mLayer->changeGeometry( featureId, geometry );
262  }
263  return errorCode;
264 }
265 
266 // TODO QGIS 4.0 -- this should return Qgis::GeometryOperationResult
267 int QgsVectorLayerEditUtils::translateFeature( QgsFeatureId featureId, double dx, double dy )
268 {
269  if ( !mLayer->isSpatial() )
270  return 1;
271 
272  QgsFeature f;
273  if ( !mLayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setNoAttributes() ).nextFeature( f ) || !f.hasGeometry() )
274  return 1; //geometry not found
275 
276  QgsGeometry geometry = f.geometry();
277 
278  Qgis::GeometryOperationResult errorCode = geometry.translate( dx, dy );
279  if ( errorCode == Qgis::GeometryOperationResult::Success )
280  {
281  mLayer->changeGeometry( featureId, geometry );
282  }
283  return errorCode == Qgis::GeometryOperationResult::Success ? 0 : 1;
284 }
285 
286 Qgis::GeometryOperationResult QgsVectorLayerEditUtils::splitFeatures( const QVector<QgsPointXY> &splitLine, bool topologicalEditing )
287 {
289  for ( QVector<QgsPointXY>::const_iterator it = splitLine.constBegin(); it != splitLine.constEnd(); ++it )
290  {
291  l << QgsPoint( *it );
292  }
293  return splitFeatures( l, topologicalEditing );
294 }
295 
297 {
298  QgsLineString lineString( splitLine );
299  QgsPointSequence topologyTestPoints;
300  bool preserveCircular = false;
301  return splitFeatures( &lineString, topologyTestPoints, preserveCircular, topologicalEditing );
302 }
303 
304 Qgis::GeometryOperationResult QgsVectorLayerEditUtils::splitFeatures( const QgsCurve *curve, QgsPointSequence &topologyTestPoints, bool preserveCircular, bool topologicalEditing )
305 {
306  if ( !mLayer->isSpatial() )
308 
309  QgsRectangle bBox; //bounding box of the split line
311  Qgis::GeometryOperationResult splitFunctionReturn; //return code of QgsGeometry::splitGeometry
312  int numberOfSplitFeatures = 0;
313 
314  QgsFeatureIterator features;
315  const QgsFeatureIds selectedIds = mLayer->selectedFeatureIds();
316 
317  // deactivate preserving circular if the curve contains only straight segments to avoid transforming Polygon to CurvePolygon
318  preserveCircular &= curve->hasCurvedSegments();
319 
320  if ( !selectedIds.isEmpty() ) //consider only the selected features if there is a selection
321  {
322  features = mLayer->getSelectedFeatures();
323  }
324  else //else consider all the feature that intersect the bounding box of the split line
325  {
326 
327  bBox = curve->boundingBox();
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  //If we have a single point, we still create a non-null box
345  double bufferDistance = 0.000001;
346  if ( mLayer->crs().isGeographic() )
347  bufferDistance = 0.00000001;
348  bBox.setXMinimum( bBox.xMinimum() - bufferDistance );
349  bBox.setXMaximum( bBox.xMaximum() + bufferDistance );
350  bBox.setYMinimum( bBox.yMinimum() - bufferDistance );
351  bBox.setYMaximum( bBox.yMaximum() + bufferDistance );
352  }
353  }
354 
355  features = mLayer->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
356  }
357 
359 
360  QgsFeature feat;
361  while ( features.nextFeature( feat ) )
362  {
363  if ( !feat.hasGeometry() )
364  {
365  continue;
366  }
367  QVector<QgsGeometry> newGeometries;
368  QgsPointSequence featureTopologyTestPoints;
369  QgsGeometry featureGeom = feat.geometry();
370  splitFunctionReturn = featureGeom.splitGeometry( curve, newGeometries, preserveCircular, topologicalEditing, featureTopologyTestPoints );
371  topologyTestPoints.append( featureTopologyTestPoints );
372  if ( splitFunctionReturn == Qgis::GeometryOperationResult::Success )
373  {
374  //change this geometry
375  mLayer->changeGeometry( feat.id(), featureGeom );
376 
377  //insert new features
378  QgsAttributeMap attributeMap = feat.attributes().toMap();
379  for ( const QgsGeometry &geom : std::as_const( newGeometries ) )
380  {
381  featuresDataToAdd << QgsVectorLayerUtils::QgsFeatureData( geom, attributeMap );
382  }
383 
384  if ( topologicalEditing )
385  {
386  QgsPointSequence::const_iterator topol_it = featureTopologyTestPoints.constBegin();
387  for ( ; topol_it != featureTopologyTestPoints.constEnd(); ++topol_it )
388  {
389  addTopologicalPoints( *topol_it );
390  }
391  }
392  ++numberOfSplitFeatures;
393  }
394  else if ( splitFunctionReturn != Qgis::GeometryOperationResult::Success && splitFunctionReturn != Qgis::GeometryOperationResult::NothingHappened ) // i.e. no split but no error occurred
395  {
396  returnCode = splitFunctionReturn;
397  }
398  }
399 
400  if ( !featuresDataToAdd.isEmpty() )
401  {
402  // finally create and add all bits of geometries cut off the original geometries
403  // (this is much faster than creating features one by one)
404  QgsFeatureList featuresListToAdd = QgsVectorLayerUtils::createFeatures( mLayer, featuresDataToAdd );
405  mLayer->addFeatures( featuresListToAdd );
406  }
407 
408  if ( numberOfSplitFeatures == 0 )
409  {
411  }
412 
413  return returnCode;
414 }
415 
416 Qgis::GeometryOperationResult QgsVectorLayerEditUtils::splitParts( const QVector<QgsPointXY> &splitLine, bool topologicalEditing )
417 {
419  for ( QVector<QgsPointXY>::const_iterator it = splitLine.constBegin(); it != splitLine.constEnd(); ++it )
420  {
421  l << QgsPoint( *it );
422  }
423  return splitParts( l, topologicalEditing );
424 }
425 
427 {
428  if ( !mLayer->isSpatial() )
430 
431  double xMin, yMin, xMax, yMax;
432  QgsRectangle bBox; //bounding box of the split line
434  Qgis::GeometryOperationResult splitFunctionReturn; //return code of QgsGeometry::splitGeometry
435  int numberOfSplitParts = 0;
436 
437  QgsFeatureIterator fit;
438 
439  if ( mLayer->selectedFeatureCount() > 0 ) //consider only the selected features if there is a selection
440  {
441  fit = mLayer->getSelectedFeatures();
442  }
443  else //else consider all the feature that intersect the bounding box of the split line
444  {
445  if ( boundingBoxFromPointList( splitLine, xMin, yMin, xMax, yMax ) )
446  {
447  bBox.setXMinimum( xMin );
448  bBox.setYMinimum( yMin );
449  bBox.setXMaximum( xMax );
450  bBox.setYMaximum( yMax );
451  }
452  else
453  {
455  }
456 
457  if ( bBox.isEmpty() )
458  {
459  //if the bbox is a line, try to make a square out of it
460  if ( bBox.width() == 0.0 && bBox.height() > 0 )
461  {
462  bBox.setXMinimum( bBox.xMinimum() - bBox.height() / 2 );
463  bBox.setXMaximum( bBox.xMaximum() + bBox.height() / 2 );
464  }
465  else if ( bBox.height() == 0.0 && bBox.width() > 0 )
466  {
467  bBox.setYMinimum( bBox.yMinimum() - bBox.width() / 2 );
468  bBox.setYMaximum( bBox.yMaximum() + bBox.width() / 2 );
469  }
470  else
471  {
472  //If we have a single point, we still create a non-null box
473  double bufferDistance = 0.000001;
474  if ( mLayer->crs().isGeographic() )
475  bufferDistance = 0.00000001;
476  bBox.setXMinimum( bBox.xMinimum() - bufferDistance );
477  bBox.setXMaximum( bBox.xMaximum() + bufferDistance );
478  bBox.setYMinimum( bBox.yMinimum() - bufferDistance );
479  bBox.setYMaximum( bBox.yMaximum() + bufferDistance );
480  }
481  }
482 
483  fit = mLayer->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
484  }
485 
486  QgsFeature feat;
487  while ( fit.nextFeature( feat ) )
488  {
489  QVector<QgsGeometry> newGeometries;
490  QgsPointSequence topologyTestPoints;
491  QgsGeometry featureGeom = feat.geometry();
492  splitFunctionReturn = featureGeom.splitGeometry( splitLine, newGeometries, topologicalEditing, topologyTestPoints, false );
493 
494  if ( splitFunctionReturn == Qgis::GeometryOperationResult::Success && !newGeometries.isEmpty() )
495  {
496  QgsGeometry newGeom( newGeometries.at( 0 ) );
497  newGeom.convertToMultiType();
498 
499  for ( int i = 1; i < newGeometries.size(); ++i )
500  {
501  QgsGeometry part = newGeometries.at( i );
502  part.convertToSingleType();
503  newGeom.addPart( part );
504  }
505 
506  mLayer->changeGeometry( feat.id(), newGeom );
507 
508  if ( topologicalEditing )
509  {
510  QgsPointSequence::const_iterator topol_it = topologyTestPoints.constBegin();
511  for ( ; topol_it != topologyTestPoints.constEnd(); ++topol_it )
512  {
513  addTopologicalPoints( *topol_it );
514  }
515  }
516  ++numberOfSplitParts;
517  }
518  else if ( splitFunctionReturn != Qgis::GeometryOperationResult::Success && splitFunctionReturn != Qgis::GeometryOperationResult::NothingHappened )
519  {
520  returnCode = splitFunctionReturn;
521  }
522  }
523 
524  if ( numberOfSplitParts == 0 && mLayer->selectedFeatureCount() > 0 && returnCode == Qgis::GeometryOperationResult::Success )
525  {
526  //There is a selection but no feature has been split.
527  //Maybe user forgot that only the selected features are split
529  }
530 
531  return returnCode;
532 }
533 
534 
536 {
537  if ( !mLayer->isSpatial() )
538  return 1;
539 
540  if ( geom.isNull() )
541  {
542  return 1;
543  }
544 
545  bool pointsAdded = false;
546 
548  while ( it != geom.vertices_end() )
549  {
550  if ( addTopologicalPoints( *it ) == 0 )
551  {
552  pointsAdded = true;
553  }
554  ++it;
555  }
556 
557  return pointsAdded ? 0 : 2;
558 }
559 
561 {
562  if ( !mLayer->isSpatial() )
563  return 1;
564 
565  double segmentSearchEpsilon = mLayer->crs().isGeographic() ? 1e-12 : 1e-8;
566 
567  //work with a tolerance because coordinate projection may introduce some rounding
568  double threshold = mLayer->geometryOptions()->geometryPrecision();
569 
570  if ( qgsDoubleNear( threshold, 0.0 ) )
571  {
572  threshold = 0.0000001;
573 
574  if ( mLayer->crs().mapUnits() == QgsUnitTypes::DistanceMeters )
575  {
576  threshold = 0.001;
577  }
578  else if ( mLayer->crs().mapUnits() == QgsUnitTypes::DistanceFeet )
579  {
580  threshold = 0.0001;
581  }
582  }
583 
584  QgsRectangle searchRect( p.x() - threshold, p.y() - threshold,
585  p.x() + threshold, p.y() + threshold );
586  double sqrSnappingTolerance = threshold * threshold;
587 
588  QgsFeature f;
590  .setFilterRect( searchRect )
592  .setNoAttributes() );
593 
594  QMap<QgsFeatureId, QgsGeometry> features;
595  QMap<QgsFeatureId, int> segments;
596 
597  while ( fit.nextFeature( f ) )
598  {
599  int afterVertex;
600  QgsPointXY snappedPoint;
601  double sqrDistSegmentSnap = f.geometry().closestSegmentWithContext( p, snappedPoint, afterVertex, nullptr, segmentSearchEpsilon );
602  if ( sqrDistSegmentSnap < sqrSnappingTolerance )
603  {
604  segments[f.id()] = afterVertex;
605  features[f.id()] = f.geometry();
606  }
607  }
608 
609  if ( segments.isEmpty() )
610  return 2;
611 
612  bool pointsAdded = false;
613  for ( QMap<QgsFeatureId, int>::const_iterator it = segments.constBegin(); it != segments.constEnd(); ++it )
614  {
615  QgsFeatureId fid = it.key();
616  int segmentAfterVertex = it.value();
617  QgsGeometry geom = features[fid];
618 
619  int atVertex, beforeVertex, afterVertex;
620  double sqrDistVertexSnap;
621  geom.closestVertex( p, atVertex, beforeVertex, afterVertex, sqrDistVertexSnap );
622 
623  if ( sqrDistVertexSnap < sqrSnappingTolerance )
624  continue; // the vertex already exists - do not insert it
625 
626  if ( !mLayer->insertVertex( p, fid, segmentAfterVertex ) )
627  {
628  QgsDebugMsg( QStringLiteral( "failed to insert topo point" ) );
629  }
630  else
631  {
632  pointsAdded = true;
633  }
634  }
635 
636  return pointsAdded ? 0 : 2;
637 }
638 
640 {
641  if ( !mLayer->isSpatial() )
642  return 1;
643 
644  if ( ps.isEmpty() )
645  {
646  return 1;
647  }
648 
649  bool pointsAdded = false;
650 
651  QgsPointSequence::const_iterator it = ps.constBegin();
652  while ( it != ps.constEnd() )
653  {
654  if ( addTopologicalPoints( *it ) == 0 )
655  {
656  pointsAdded = true;
657  }
658  ++it;
659  }
660 
661  return pointsAdded ? 0 : 2;
662 }
663 
665 {
666  return addTopologicalPoints( QgsPoint( p ) );
667 }
668 
669 
670 bool QgsVectorLayerEditUtils::boundingBoxFromPointList( const QgsPointSequence &list, double &xmin, double &ymin, double &xmax, double &ymax ) const
671 {
672  if ( list.empty() )
673  {
674  return false;
675  }
676 
677  xmin = std::numeric_limits<double>::max();
678  xmax = -std::numeric_limits<double>::max();
679  ymin = std::numeric_limits<double>::max();
680  ymax = -std::numeric_limits<double>::max();
681 
682  for ( QgsPointSequence::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
683  {
684  if ( it->x() < xmin )
685  {
686  xmin = it->x();
687  }
688  if ( it->x() > xmax )
689  {
690  xmax = it->x();
691  }
692  if ( it->y() < ymin )
693  {
694  ymin = it->y();
695  }
696  if ( it->y() > ymax )
697  {
698  ymax = it->y();
699  }
700  }
701 
702  return true;
703 }
QgsCurve
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
QgsVectorLayer::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
Definition: qgsvectorlayer.cpp:1052
QgsWkbTypes::isSingleType
static bool isSingleType(Type type) SIP_HOLDGIL
Returns true if the WKB type is a single type.
Definition: qgswkbtypes.h:852
QgsMapLayer::crs
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
QgsVectorLayer::addFeatures
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) FINAL
Adds a list of features to the sink.
Definition: qgsvectorlayer.cpp:3658
QgsGeometryOptions::geometryPrecision
double geometryPrecision() const
The precision in which geometries on this layer should be saved.
Definition: qgsgeometryoptions.cpp:38
QgsRectangle::height
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
QgsVectorLayer::wkbType
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
Definition: qgsvectorlayer.cpp:725
QgsGeometry::addPart
Qgis::GeometryOperationResult addPart(const QVector< QgsPointXY > &points, QgsWkbTypes::GeometryType geomType=QgsWkbTypes::UnknownGeometry)
Adds a new part to a the geometry.
Definition: qgsgeometry.cpp:794
QgsVectorLayer::dataProvider
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
Definition: qgsvectorlayer.cpp:676
qgslinestring.h
QgsFeatureRequest::ExactIntersect
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
Definition: qgsfeaturerequest.h:117
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:48
QgsVectorLayer::insertVertex
bool insertVertex(double x, double y, QgsFeatureId atFeatureId, int beforeVertex)
Inserts a new vertex before the given vertex number, in the given ring, item (first number is index 0...
Definition: qgsvectorlayer.cpp:1154
qgsgeometryfactory.h
QgsVectorLayerEditUtils::deleteVertex
Qgis::VectorEditResult deleteVertex(QgsFeatureId featureId, int vertex)
Deletes a vertex from a feature.
Definition: qgsvectorlayereditutils.cpp:97
qgsfeatureiterator.h
QgsRectangle::yMinimum
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
QgsVectorLayer::geometryOptions
QgsGeometryOptions * geometryOptions() const
Configuration and logic to apply automatically on any edit happening on this layer.
Definition: qgsvectorlayer.cpp:5828
Qgis::VectorEditResult::FetchFeatureFailed
@ FetchFeatureFailed
Unable to fetch requested feature.
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
qgis.h
QgsVectorLayer::isSpatial
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
Definition: qgsvectorlayer.cpp:3733
qgsvectorlayereditutils.h
QgsVectorDataProvider::doesStrictFeatureTypeCheck
virtual bool doesStrictFeatureTypeCheck() const
Returns true if the provider is strict about the type of inserted features (e.g.
Definition: qgsvectordataprovider.h:503
qgspoint.h
QgsVectorLayerUtils::QgsFeatureData
Encapsulate geometry and attributes for new features, to be passed to createFeatures.
Definition: qgsvectorlayerutils.h:100
QgsGeometry::moveVertex
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...
Definition: qgsgeometry.cpp:478
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsLineString
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:44
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsGeometry::splitGeometry
Q_DECL_DEPRECATED Qgis::GeometryOperationResult splitGeometry(const QVector< QgsPointXY > &splitLine, QVector< QgsGeometry > &newGeometries, bool topological, QVector< QgsPointXY > &topologyTestPoints, bool splitFeature=true)
Splits this geometry according to a given line.
Definition: qgsgeometry.cpp:926
QgsGeometry::closestVertex
QgsPointXY closestVertex(const QgsPointXY &point, int &closestVertexIndex, int &previousVertexIndex, int &nextVertexIndex, double &sqrDist) const
Returns the vertex closest to the given point, the corresponding vertex index, squared distance snap ...
Definition: qgsgeometry.cpp:397
Qgis::VectorEditResult::EmptyGeometry
@ EmptyGeometry
Edit operation resulted in an empty geometry.
QgsVectorLayerEditUtils::addTopologicalPoints
int addTopologicalPoints(const QgsGeometry &geom)
Adds topological points for every vertex of the geometry.
Definition: qgsvectorlayereditutils.cpp:535
QgsGeometry::insertVertex
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...
Definition: qgsgeometry.cpp:631
QgsVectorLayer::changeGeometry
bool changeGeometry(QgsFeatureId fid, QgsGeometry &geometry, bool skipDefaultValue=false)
Changes a feature's geometry within the layer's edit buffer (but does not immediately commit the chan...
Definition: qgsvectorlayer.cpp:3048
QgsRectangle::xMaximum
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
QgsFeature::id
QgsFeatureId id
Definition: qgsfeature.h:68
QgsPoint::y
double y
Definition: qgspoint.h:70
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:83
QgsCoordinateReferenceSystem::isGeographic
bool isGeographic
Definition: qgscoordinatereferencesystem.h:216
QgsGeometry::addRing
Qgis::GeometryOperationResult addRing(const QVector< QgsPointXY > &ring)
Adds a new ring to this geometry.
Definition: qgsgeometry.cpp:775
QgsVectorLayerEditUtils::translateFeature
int translateFeature(QgsFeatureId featureId, double dx, double dy)
Translates feature by dx, dy.
Definition: qgsvectorlayereditutils.cpp:267
QgsVectorLayerEditUtils::moveVertex
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),...
Definition: qgsvectorlayereditutils.cpp:73
QgsVectorLayerUtils::QgsFeaturesDataList
QList< QgsVectorLayerUtils::QgsFeatureData > QgsFeaturesDataList
Alias for list of QgsFeatureData.
Definition: qgsvectorlayerutils.h:122
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2265
QgsVectorLayerEditUtils::addRing
Q_DECL_DEPRECATED Qgis::GeometryOperationResult addRing(const QVector< QgsPointXY > &ring, const QgsFeatureIds &targetFeatureIds=QgsFeatureIds(), QgsFeatureId *modifiedFeatureId=nullptr)
Adds a ring to polygon/multipolygon features.
Definition: qgsvectorlayereditutils.cpp:121
QgsGeometry::convertToSingleType
bool convertToSingleType()
Converts multi type geometry into single type geometry e.g.
Definition: qgsgeometry.cpp:1603
QgsVectorLayer::selectedFeatureIds
const Q_INVOKABLE QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
Definition: qgsvectorlayer.cpp:3621
Qgis::VectorEditResult::InvalidLayer
@ InvalidLayer
Edit failed due to invalid layer.
Qgis::GeometryOperationResult
GeometryOperationResult
Success or failure of a geometry operation.
Definition: qgis.h:901
QgsGeometry::deleteVertex
bool deleteVertex(int atVertex)
Deletes the vertex at the given position number and item (first number is index 0)
Definition: qgsgeometry.cpp:514
qgsvectordataprovider.h
QgsFeatureList
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:882
QgsAttributeMap
QMap< int, QVariant > QgsAttributeMap
Definition: qgsattributes.h:38
QgsUnitTypes::DistanceFeet
@ DistanceFeet
Imperial feet.
Definition: qgsunittypes.h:71
QgsRectangle::setXMinimum
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
Definition: qgsrectangle.h:151
qgsvectorlayerutils.h
QgsUnitTypes::DistanceMeters
@ DistanceMeters
Meters.
Definition: qgsunittypes.h:69
QgsAbstractGeometry::nCoordinates
virtual int nCoordinates() const
Returns the number of nodes contained in the geometry.
Definition: qgsabstractgeometry.cpp:150
QgsGeometry::isNull
bool isNull
Definition: qgsgeometry.h:127
Qgis::VectorEditResult::EditFailed
@ EditFailed
Edit operation failed.
QgsAbstractGeometry::hasCurvedSegments
virtual bool hasCurvedSegments() const
Returns true if the geometry contains curved segments.
Definition: qgsabstractgeometry.cpp:385
QgsRectangle::xMinimum
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
QgsGeometry::closestSegmentWithContext
double closestSegmentWithContext(const QgsPointXY &point, QgsPointXY &minDistPoint, int &nextVertexIndex, int *leftOrRightOfSegment=nullptr, double epsilon=DEFAULT_SEGMENT_EPSILON) const
Searches for the closest segment of geometry to the given point.
Definition: qgsgeometry.cpp:751
QgsAttributes::toMap
CORE_EXPORT QgsAttributeMap toMap() const
Returns a QgsAttributeMap of the attribute values.
Definition: qgsattributes.cpp:21
Qgis::GeometryOperationResult::AddRingNotInExistingFeature
@ AddRingNotInExistingFeature
The input ring doesn't have any existing ring to fit into.
Qgis::VectorEditResult::Success
@ Success
Edit operation was successful.
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:136
QgsFeatureIds
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
QgsGeometry::translate
Qgis::GeometryOperationResult translate(double dx, double dy, double dz=0.0, double dm=0.0)
Translates this geometry by dx, dy, dz and dm.
Definition: qgsgeometry.cpp:897
QgsFeature::attributes
QgsAttributes attributes
Definition: qgsfeature.h:69
QgsRectangle::setXMaximum
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
Definition: qgsrectangle.h:156
qgsvectorlayer.h
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:58
QgsRectangle::setYMaximum
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
Definition: qgsrectangle.h:166
QgsCurve::clone
QgsCurve * clone() const override=0
Clones the geometry by performing a deep copy.
QgsVectorLayer::getSelectedFeatures
QgsFeatureIterator getSelectedFeatures(QgsFeatureRequest request=QgsFeatureRequest()) const
Returns an iterator of the selected features.
Definition: qgsvectorlayer.cpp:3642
QgsCoordinateReferenceSystem::mapUnits
QgsUnitTypes::DistanceUnit mapUnits
Definition: qgscoordinatereferencesystem.h:215
Qgis::GeometryOperationResult::InvalidBaseGeometry
@ InvalidBaseGeometry
The base geometry on which the operation is done is invalid or empty.
QgsRectangle::yMaximum
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
QgsVectorLayerEditUtils::splitFeatures
Q_DECL_DEPRECATED Qgis::GeometryOperationResult splitFeatures(const QVector< QgsPointXY > &splitLine, bool topologicalEditing=false)
Splits features cut by the given line.
Definition: qgsvectorlayereditutils.cpp:286
QgsAbstractGeometry::vertex_iterator
The vertex_iterator class provides STL-style iterator for vertices.
Definition: qgsabstractgeometry.h:924
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:399
QgsRectangle::setYMinimum
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
Definition: qgsrectangle.h:161
QgsPointSequence
QVector< QgsPoint > QgsPointSequence
Definition: qgsabstractgeometry.h:52
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:230
QgsRectangle::width
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
QgsVectorLayerEditUtils::insertVertex
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)...
Definition: qgsvectorlayereditutils.cpp:39
Qgis::GeometryOperationResult::Success
@ Success
Operation succeeded.
QgsGeometry::convertToMultiType
bool convertToMultiType()
Converts single type geometry into multitype geometry e.g.
Definition: qgsgeometry.cpp:1571
Qgis::VectorEditResult
VectorEditResult
Specifies the result of a vector layer edit operation.
Definition: qgis.h:791
QgsCurve::boundingBox
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the geometry.
Definition: qgscurve.cpp:238
QgsVectorLayerEditUtils::addPart
Q_DECL_DEPRECATED Qgis::GeometryOperationResult addPart(const QVector< QgsPointXY > &ring, QgsFeatureId featureId)
Adds a new part polygon to a multipart feature.
Definition: qgsvectorlayereditutils.cpp:186
QgsVectorLayerUtils::createFeatures
static QgsFeatureList createFeatures(const QgsVectorLayer *layer, const QgsFeaturesDataList &featuresData, QgsExpressionContext *context=nullptr)
Creates a set of new features ready for insertion into a layer.
Definition: qgsvectorlayerutils.cpp:485
QgsVectorLayerEditUtils::QgsVectorLayerEditUtils
QgsVectorLayerEditUtils(QgsVectorLayer *layer)
Definition: qgsvectorlayereditutils.cpp:34
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
qgsgeometryoptions.h
QgsGeometry::vertices_end
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
Definition: qgsgeometry.cpp:1989
QgsVectorLayer::selectedFeatureCount
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
Definition: qgsvectorlayer.cpp:3616
qgslogger.h
QgsGeometry::vertices_begin
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
Definition: qgsgeometry.cpp:1982
Qgis::GeometryOperationResult::AddPartSelectedGeometryNotFound
@ AddPartSelectedGeometryNotFound
The selected geometry cannot be found.
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:289
QgsVectorLayer::geometryType
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
Definition: qgsvectorlayer.cpp:720
Qgis::GeometryOperationResult::NothingHappened
@ NothingHappened
Nothing happened, without any error.
QgsRectangle::isEmpty
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:469
qgswkbtypes.h
Qgis::GeometryOperationResult::InvalidInputGeometryType
@ InvalidInputGeometryType
The input geometry (ring, part, split line, etc.) has not the correct geometry type.
qgsabstractgeometry.h
QgsPoint::x
double x
Definition: qgspoint.h:69
QgsGeometry::set
void set(QgsAbstractGeometry *geometry)
Sets the underlying geometry store.
Definition: qgsgeometry.cpp:147
qgsvectorlayereditbuffer.h
QgsVectorLayerEditUtils::splitParts
Q_DECL_DEPRECATED Qgis::GeometryOperationResult splitParts(const QVector< QgsPointXY > &splitLine, bool topologicalEditing=false)
Splits parts cut by the given line.
Definition: qgsvectorlayereditutils.cpp:416
QgsFeatureId
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
Definition: qgsfeatureid.h:28