QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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 QgsVectorLayer::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 QgsGeometry::OperationResult 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  QgsGeometry::OperationResult addRingReturnCode = QgsGeometry::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 == 0 )
172  if ( addRingReturnCode == QgsGeometry::Success )
173  {
174  mLayer->changeGeometry( f.id(), g );
175  if ( modifiedFeatureId )
176  *modifiedFeatureId = f.id();
177 
178  //setModified( true, true );
179  break;
180  }
181  }
182 
183  delete ring;
184  return addRingReturnCode;
185 }
186 
187 QgsGeometry::OperationResult QgsVectorLayerEditUtils::addPart( const QVector<QgsPointXY> &points, QgsFeatureId featureId )
188 {
190  for ( QVector<QgsPointXY>::const_iterator it = points.constBegin(); it != points.constEnd(); ++it )
191  {
192  l << QgsPoint( *it );
193  }
194  return addPart( l, featureId );
195 }
196 
198 {
199  if ( !mLayer->isSpatial() )
200  return QgsGeometry::OperationResult::AddPartSelectedGeometryNotFound;
201 
202  QgsGeometry geometry;
203  bool firstPart = false;
204  QgsFeature f;
205  if ( !mLayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setNoAttributes() ).nextFeature( f ) )
206  return QgsGeometry::OperationResult::AddPartSelectedGeometryNotFound; //not found
207 
208  if ( !f.hasGeometry() )
209  {
210  //no existing geometry, so adding first part to null geometry
211  firstPart = true;
212  }
213  else
214  {
215  geometry = f.geometry();
216  }
217 
218  QgsGeometry::OperationResult errorCode = geometry.addPart( points, mLayer->geometryType() );
219  if ( errorCode == QgsGeometry::Success )
220  {
221  if ( firstPart && QgsWkbTypes::isSingleType( mLayer->wkbType() )
222  && mLayer->dataProvider()->doesStrictFeatureTypeCheck() )
223  {
224  //convert back to single part if required by layer
225  geometry.convertToSingleType();
226  }
227  mLayer->changeGeometry( featureId, geometry );
228  }
229  return errorCode;
230 }
231 
233 {
234  if ( !mLayer->isSpatial() )
236 
237  QgsGeometry geometry;
238  bool firstPart = false;
239  QgsFeature f;
240  if ( !mLayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setNoAttributes() ).nextFeature( f ) )
242 
243  if ( !f.hasGeometry() )
244  {
245  //no existing geometry, so adding first part to null geometry
246  firstPart = true;
247  }
248  else
249  {
250  geometry = f.geometry();
251  }
252 
253  QgsGeometry::OperationResult errorCode = geometry.addPart( ring, mLayer->geometryType() );
254  if ( errorCode == QgsGeometry::Success )
255  {
256  if ( firstPart && QgsWkbTypes::isSingleType( mLayer->wkbType() )
257  && mLayer->dataProvider()->doesStrictFeatureTypeCheck() )
258  {
259  //convert back to single part if required by layer
260  geometry.convertToSingleType();
261  }
262  mLayer->changeGeometry( featureId, geometry );
263  }
264  return errorCode;
265 }
266 
267 
268 int QgsVectorLayerEditUtils::translateFeature( QgsFeatureId featureId, double dx, double dy )
269 {
270  if ( !mLayer->isSpatial() )
271  return 1;
272 
273  QgsFeature f;
274  if ( !mLayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setNoAttributes() ).nextFeature( f ) || !f.hasGeometry() )
275  return 1; //geometry not found
276 
277  QgsGeometry geometry = f.geometry();
278 
279  int errorCode = geometry.translate( dx, dy );
280  if ( errorCode == 0 )
281  {
282  mLayer->changeGeometry( featureId, geometry );
283  }
284  return errorCode;
285 }
286 
287 QgsGeometry::OperationResult QgsVectorLayerEditUtils::splitFeatures( const QVector<QgsPointXY> &splitLine, bool topologicalEditing )
288 {
290  for ( QVector<QgsPointXY>::const_iterator it = splitLine.constBegin(); it != splitLine.constEnd(); ++it )
291  {
292  l << QgsPoint( *it );
293  }
294  return splitFeatures( l, topologicalEditing );
295 }
296 
298 {
299  if ( !mLayer->isSpatial() )
301 
302  double xMin, yMin, xMax, yMax;
303  QgsRectangle bBox; //bounding box of the split line
304  QgsGeometry::OperationResult returnCode = QgsGeometry::OperationResult::Success;
305  QgsGeometry::OperationResult splitFunctionReturn; //return code of QgsGeometry::splitGeometry
306  int numberOfSplitFeatures = 0;
307 
308  QgsFeatureIterator features;
309  const QgsFeatureIds selectedIds = mLayer->selectedFeatureIds();
310 
311  if ( !selectedIds.isEmpty() ) //consider only the selected features if there is a selection
312  {
313  features = mLayer->getSelectedFeatures();
314  }
315  else //else consider all the feature that intersect the bounding box of the split line
316  {
317  if ( boundingBoxFromPointList( splitLine, xMin, yMin, xMax, yMax ) )
318  {
319  bBox.setXMinimum( xMin );
320  bBox.setYMinimum( yMin );
321  bBox.setXMaximum( xMax );
322  bBox.setYMaximum( yMax );
323  }
324  else
325  {
326  return QgsGeometry::OperationResult::InvalidInputGeometryType;
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  //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 
358  QgsFeature feat;
359  while ( features.nextFeature( feat ) )
360  {
361  if ( !feat.hasGeometry() )
362  {
363  continue;
364  }
365  QVector<QgsGeometry> newGeometries;
366  QgsPointSequence topologyTestPoints;
367  QgsGeometry featureGeom = feat.geometry();
368  splitFunctionReturn = featureGeom.splitGeometry( splitLine, newGeometries, topologicalEditing, topologyTestPoints );
369  if ( splitFunctionReturn == QgsGeometry::OperationResult::Success )
370  {
371  //change this geometry
372  mLayer->changeGeometry( feat.id(), featureGeom );
373 
374  //insert new features
375  QgsAttributeMap attributeMap = feat.attributes().toMap();
376  for ( const QgsGeometry &geom : qgis::as_const( newGeometries ) )
377  {
378  QgsFeature f = QgsVectorLayerUtils::createFeature( mLayer, geom, attributeMap );
379  mLayer->addFeature( f );
380  }
381 
382  if ( topologicalEditing )
383  {
384  QgsPointSequence::const_iterator topol_it = topologyTestPoints.constBegin();
385  for ( ; topol_it != topologyTestPoints.constEnd(); ++topol_it )
386  {
387  addTopologicalPoints( *topol_it );
388  }
389  }
390  ++numberOfSplitFeatures;
391  }
392  else if ( splitFunctionReturn != QgsGeometry::OperationResult::Success && splitFunctionReturn != QgsGeometry::NothingHappened ) // i.e. no split but no error occurred
393  {
394  returnCode = splitFunctionReturn;
395  }
396  }
397 
398  if ( numberOfSplitFeatures == 0 && !selectedIds.isEmpty() )
399  {
400  //There is a selection but no feature has been split.
401  //Maybe user forgot that only the selected features are split
402  returnCode = QgsGeometry::OperationResult::NothingHappened;
403  }
404 
405  return returnCode;
406 }
407 
408 QgsGeometry::OperationResult QgsVectorLayerEditUtils::splitParts( const QVector<QgsPointXY> &splitLine, bool topologicalEditing )
409 {
411  for ( QVector<QgsPointXY>::const_iterator it = splitLine.constBegin(); it != splitLine.constEnd(); ++it )
412  {
413  l << QgsPoint( *it );
414  }
415  return splitParts( l, topologicalEditing );
416 }
417 
419 {
420  if ( !mLayer->isSpatial() )
422 
423  double xMin, yMin, xMax, yMax;
424  QgsRectangle bBox; //bounding box of the split line
425  QgsGeometry::OperationResult returnCode = QgsGeometry::OperationResult::Success;
426  QgsGeometry::OperationResult splitFunctionReturn; //return code of QgsGeometry::splitGeometry
427  int numberOfSplitParts = 0;
428 
429  QgsFeatureIterator fit;
430 
431  if ( mLayer->selectedFeatureCount() > 0 ) //consider only the selected features if there is a selection
432  {
433  fit = mLayer->getSelectedFeatures();
434  }
435  else //else consider all the feature that intersect the bounding box of the split line
436  {
437  if ( boundingBoxFromPointList( splitLine, xMin, yMin, xMax, yMax ) )
438  {
439  bBox.setXMinimum( xMin );
440  bBox.setYMinimum( yMin );
441  bBox.setXMaximum( xMax );
442  bBox.setYMaximum( yMax );
443  }
444  else
445  {
446  return QgsGeometry::OperationResult::InvalidInputGeometryType;
447  }
448 
449  if ( bBox.isEmpty() )
450  {
451  //if the bbox is a line, try to make a square out of it
452  if ( bBox.width() == 0.0 && bBox.height() > 0 )
453  {
454  bBox.setXMinimum( bBox.xMinimum() - bBox.height() / 2 );
455  bBox.setXMaximum( bBox.xMaximum() + bBox.height() / 2 );
456  }
457  else if ( bBox.height() == 0.0 && bBox.width() > 0 )
458  {
459  bBox.setYMinimum( bBox.yMinimum() - bBox.width() / 2 );
460  bBox.setYMaximum( bBox.yMaximum() + bBox.width() / 2 );
461  }
462  else
463  {
464  //If we have a single point, we still create a non-null box
465  double bufferDistance = 0.000001;
466  if ( mLayer->crs().isGeographic() )
467  bufferDistance = 0.00000001;
468  bBox.setXMinimum( bBox.xMinimum() - bufferDistance );
469  bBox.setXMaximum( bBox.xMaximum() + bufferDistance );
470  bBox.setYMinimum( bBox.yMinimum() - bufferDistance );
471  bBox.setYMaximum( bBox.yMaximum() + bufferDistance );
472  }
473  }
474 
475  fit = mLayer->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
476  }
477 
478  QgsFeature feat;
479  while ( fit.nextFeature( feat ) )
480  {
481  QVector<QgsGeometry> newGeometries;
482  QgsPointSequence topologyTestPoints;
483  QgsGeometry featureGeom = feat.geometry();
484  splitFunctionReturn = featureGeom.splitGeometry( splitLine, newGeometries, topologicalEditing, topologyTestPoints, false );
485 
486  if ( splitFunctionReturn == QgsGeometry::OperationResult::Success && !newGeometries.isEmpty() )
487  {
488  QgsGeometry newGeom( newGeometries.at( 0 ) );
489  newGeom.convertToMultiType();
490 
491  for ( int i = 1; i < newGeometries.size(); ++i )
492  {
493  QgsGeometry part = newGeometries.at( i );
494  part.convertToSingleType();
495  newGeom.addPart( part );
496  }
497 
498  mLayer->changeGeometry( feat.id(), newGeom );
499 
500  if ( topologicalEditing )
501  {
502  QgsPointSequence::const_iterator topol_it = topologyTestPoints.constBegin();
503  for ( ; topol_it != topologyTestPoints.constEnd(); ++topol_it )
504  {
505  addTopologicalPoints( *topol_it );
506  }
507  }
508  ++numberOfSplitParts;
509  }
510  else if ( splitFunctionReturn != QgsGeometry::OperationResult::Success && splitFunctionReturn != QgsGeometry::OperationResult::NothingHappened )
511  {
512  returnCode = splitFunctionReturn;
513  }
514  }
515 
516  if ( numberOfSplitParts == 0 && mLayer->selectedFeatureCount() > 0 && returnCode == QgsGeometry::Success )
517  {
518  //There is a selection but no feature has been split.
519  //Maybe user forgot that only the selected features are split
520  returnCode = QgsGeometry::OperationResult::NothingHappened;
521  }
522 
523  return returnCode;
524 }
525 
526 
528 {
529  if ( !mLayer->isSpatial() )
530  return 1;
531 
532  if ( geom.isNull() )
533  {
534  return 1;
535  }
536 
537  int returnVal = 0;
538 
540  while ( it != geom.vertices_end() )
541  {
542  if ( addTopologicalPoints( *it ) != 0 )
543  {
544  returnVal = 2;
545  }
546  it++;
547  }
548 
549  return returnVal;
550 }
551 
553 {
554  if ( !mLayer->isSpatial() )
555  return 1;
556 
557  double segmentSearchEpsilon = mLayer->crs().isGeographic() ? 1e-12 : 1e-8;
558 
559  //work with a tolerance because coordinate projection may introduce some rounding
560  double threshold = mLayer->geometryOptions()->geometryPrecision();
561 
562  if ( qgsDoubleNear( threshold, 0.0 ) )
563  {
564  threshold = 0.0000001;
565 
566  if ( mLayer->crs().mapUnits() == QgsUnitTypes::DistanceMeters )
567  {
568  threshold = 0.001;
569  }
570  else if ( mLayer->crs().mapUnits() == QgsUnitTypes::DistanceFeet )
571  {
572  threshold = 0.0001;
573  }
574  }
575 
576  QgsRectangle searchRect( p.x() - threshold, p.y() - threshold,
577  p.x() + threshold, p.y() + threshold );
578  double sqrSnappingTolerance = threshold * threshold;
579 
580  QgsFeature f;
582  .setFilterRect( searchRect )
584  .setNoAttributes() );
585 
586  QMap<QgsFeatureId, QgsGeometry> features;
587  QMap<QgsFeatureId, int> segments;
588 
589  while ( fit.nextFeature( f ) )
590  {
591  int afterVertex;
592  QgsPointXY snappedPoint;
593  double sqrDistSegmentSnap = f.geometry().closestSegmentWithContext( p, snappedPoint, afterVertex, nullptr, segmentSearchEpsilon );
594  if ( sqrDistSegmentSnap < sqrSnappingTolerance )
595  {
596  segments[f.id()] = afterVertex;
597  features[f.id()] = f.geometry();
598  }
599  }
600 
601  if ( segments.isEmpty() )
602  return 2;
603 
604  for ( QMap<QgsFeatureId, int>::const_iterator it = segments.constBegin(); it != segments.constEnd(); ++it )
605  {
606  QgsFeatureId fid = it.key();
607  int segmentAfterVertex = it.value();
608  QgsGeometry geom = features[fid];
609 
610  int atVertex, beforeVertex, afterVertex;
611  double sqrDistVertexSnap;
612  geom.closestVertex( p, atVertex, beforeVertex, afterVertex, sqrDistVertexSnap );
613 
614  if ( sqrDistVertexSnap < sqrSnappingTolerance )
615  continue; // the vertex already exists - do not insert it
616 
617  if ( !mLayer->insertVertex( p, fid, segmentAfterVertex ) )
618  {
619  QgsDebugMsg( QStringLiteral( "failed to insert topo point" ) );
620  }
621  }
622 
623  return 0;
624 }
625 
627 {
628  return addTopologicalPoints( QgsPoint( p ) );
629 }
630 
631 
632 bool QgsVectorLayerEditUtils::boundingBoxFromPointList( const QgsPointSequence &list, double &xmin, double &ymin, double &xmax, double &ymax ) const
633 {
634  if ( list.empty() )
635  {
636  return false;
637  }
638 
639  xmin = std::numeric_limits<double>::max();
640  xmax = -std::numeric_limits<double>::max();
641  ymin = std::numeric_limits<double>::max();
642  ymax = -std::numeric_limits<double>::max();
643 
644  for ( QgsPointSequence::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
645  {
646  if ( it->x() < xmin )
647  {
648  xmin = it->x();
649  }
650  if ( it->x() > xmax )
651  {
652  xmax = it->x();
653  }
654  if ( it->y() < ymin )
655  {
656  ymin = it->y();
657  }
658  if ( it->y() > ymax )
659  {
660  ymax = it->y();
661  }
662  }
663 
664  return true;
665 }
QgsCurve
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
QgsGeometry::Success
@ Success
Operation succeeded.
Definition: qgsgeometry.h:136
QgsVectorLayer::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
Definition: qgsvectorlayer.cpp:993
QgsMapLayer::crs
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:88
QgsGeometryOptions::geometryPrecision
double geometryPrecision() const
The precision in which geometries on this layer should be saved.
Definition: qgsgeometryoptions.cpp:40
QgsGeometry::addPart
OperationResult addPart(const QVector< QgsPointXY > &points, QgsWkbTypes::GeometryType geomType=QgsWkbTypes::UnknownGeometry)
Adds a new part to a the geometry.
Definition: qgsgeometry.cpp:687
QgsVectorLayer::wkbType
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
Definition: qgsvectorlayer.cpp:664
QgsVectorLayer::dataProvider
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
Definition: qgsvectorlayer.cpp:627
QgsVectorLayerEditUtils::splitParts
Q_DECL_DEPRECATED QgsGeometry::OperationResult splitParts(const QVector< QgsPointXY > &splitLine, bool topologicalEditing=false)
Splits parts cut by the given line.
Definition: qgsvectorlayereditutils.cpp:408
qgslinestring.h
QgsFeatureRequest::ExactIntersect
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
Definition: qgsfeaturerequest.h:109
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
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:1095
QgsRectangle::setXMinimum
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:130
qgsgeometryfactory.h
QgsGeometry::NothingHappened
@ NothingHappened
Nothing happened, without any error.
Definition: qgsgeometry.h:137
QgsRectangle::xMaximum
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
qgsfeatureiterator.h
QgsVectorLayer::geometryOptions
QgsGeometryOptions * geometryOptions() const
Configuration and logic to apply automatically on any edit happening on this layer.
Definition: qgsvectorlayer.cpp:5541
QgsGeometry::addRing
OperationResult addRing(const QVector< QgsPointXY > &ring)
Adds a new ring to this geometry.
Definition: qgsgeometry.cpp:668
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:3591
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:492
QgsGeometry::OperationResult
OperationResult
Success or failure of a geometry operation.
Definition: qgsgeometry.h:134
qgspoint.h
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:467
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsLineString
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:43
QgsGeometry::closestVertex
QgsPointXY closestVertex(const QgsPointXY &point, int &atVertex, int &beforeVertex, int &afterVertex, double &sqrDist) const
Returns the vertex closest to the given point, the corresponding vertex index, squared distance snap ...
Definition: qgsgeometry.cpp:386
QgsRectangle
Definition: qgsrectangle.h:41
QgsVectorLayerEditUtils::addTopologicalPoints
int addTopologicalPoints(const QgsGeometry &geom)
Adds topological points for every vertex of the geometry.
Definition: qgsvectorlayereditutils.cpp:527
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:536
QgsGeometry::AddPartSelectedGeometryNotFound
@ AddPartSelectedGeometryNotFound
The selected geometry cannot be found.
Definition: qgsgeometry.h:145
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:2941
QgsFeature::id
QgsFeatureId id
Definition: qgsfeature.h:68
QgsPoint::y
double y
Definition: qgspoint.h:59
QgsFeatureRequest
Definition: qgsfeaturerequest.h:75
QgsCoordinateReferenceSystem::isGeographic
bool isGeographic
Definition: qgscoordinatereferencesystem.h:211
QgsVectorLayer::EmptyGeometry
@ EmptyGeometry
Edit operation resulted in an empty geometry.
Definition: qgsvectorlayer.h:402
QgsVectorLayer::EditFailed
@ EditFailed
Edit operation failed.
Definition: qgsvectorlayer.h:403
QgsVectorLayerEditUtils::addPart
Q_DECL_DEPRECATED QgsGeometry::OperationResult addPart(const QVector< QgsPointXY > &ring, QgsFeatureId featureId)
Adds a new part polygon to a multipart feature.
Definition: qgsvectorlayereditutils.cpp:187
QgsVectorLayerEditUtils::translateFeature
int translateFeature(QgsFeatureId featureId, double dx, double dy)
Translates feature by dx, dy.
Definition: qgsvectorlayereditutils.cpp:268
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
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:315
QgsGeometry::convertToSingleType
bool convertToSingleType()
Converts multi type geometry into single type geometry e.g.
Definition: qgsgeometry.cpp:1500
QgsVectorLayer::selectedFeatureIds
const Q_INVOKABLE QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
Definition: qgsvectorlayer.cpp:3433
QgsGeometry::deleteVertex
bool deleteVertex(int atVertex)
Deletes the vertex at the given position number and item (first number is index 0)
Definition: qgsgeometry.cpp:503
qgsvectordataprovider.h
QgsAttributeMap
QMap< int, QVariant > QgsAttributeMap
Definition: qgsattributes.h:38
QgsUnitTypes::DistanceFeet
@ DistanceFeet
Imperial feet.
Definition: qgsunittypes.h:71
qgsvectorlayerutils.h
QgsRectangle::setXMaximum
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:135
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:116
QgsGeometry::isNull
bool isNull
Definition: qgsgeometry.h:125
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsAttributes::toMap
QgsAttributeMap toMap() const
Returns a QgsAttributeMap of the attribute values.
Definition: qgsattributes.cpp:21
QgsWkbTypes::isSingleType
static bool isSingleType(Type type)
Returns true if the WKB type is a single type.
Definition: qgswkbtypes.h:821
QgsGeometry::splitGeometry
Q_DECL_DEPRECATED OperationResult 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:819
QgsFeatureIds
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:34
QgsFeature::attributes
QgsAttributes attributes
Definition: qgsfeature.h:69
QgsRectangle::yMaximum
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
QgsVectorLayerUtils::createFeature
static QgsFeature createFeature(const QgsVectorLayer *layer, const QgsGeometry &geometry=QgsGeometry(), const QgsAttributeMap &attributes=QgsAttributeMap(), QgsExpressionContext *context=nullptr)
Creates a new feature ready for insertion into a layer.
Definition: qgsvectorlayerutils.cpp:475
QgsVectorLayerEditUtils::splitFeatures
Q_DECL_DEPRECATED QgsGeometry::OperationResult splitFeatures(const QVector< QgsPointXY > &splitLine, bool topologicalEditing=false)
Splits features cut by the given line.
Definition: qgsvectorlayereditutils.cpp:287
qgsvectorlayer.h
QgsPointXY
Definition: qgspointxy.h:43
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:3468
QgsCoordinateReferenceSystem::mapUnits
QgsUnitTypes::DistanceUnit mapUnits
Definition: qgscoordinatereferencesystem.h:210
QgsAbstractGeometry::vertex_iterator
Definition: qgsabstractgeometry.h:832
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:373
QgsPointSequence
QVector< QgsPoint > QgsPointSequence
Definition: qgsabstractgeometry.h:44
QgsGeometry
Definition: qgsgeometry.h:122
QgsVectorLayer
Definition: qgsvectorlayer.h:385
QgsGeometry::InvalidBaseGeometry
@ InvalidBaseGeometry
The base geometry on which the operation is done is invalid or empty.
Definition: qgsgeometry.h:138
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
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
QgsGeometry::convertToMultiType
bool convertToMultiType()
Converts single type geometry into multitype geometry e.g.
Definition: qgsgeometry.cpp:1468
QgsGeometry::translate
OperationResult 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:790
QgsCurve::boundingBox
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the geometry.
Definition: qgscurve.cpp:195
QgsRectangle::height
double height() const
Returns the height of the rectangle.
Definition: qgsrectangle.h:209
QgsRectangle::yMinimum
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
QgsVectorLayer::FetchFeatureFailed
@ FetchFeatureFailed
Unable to fetch requested feature.
Definition: qgsvectorlayer.h:404
QgsVectorLayer::InvalidLayer
@ InvalidLayer
Edit failed due to invalid layer.
Definition: qgsvectorlayer.h:405
QgsVectorLayerEditUtils::QgsVectorLayerEditUtils
QgsVectorLayerEditUtils(QgsVectorLayer *layer)
Definition: qgsvectorlayereditutils.cpp:34
QgsFeature
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:1858
QgsVectorLayerEditUtils::addRing
Q_DECL_DEPRECATED QgsGeometry::OperationResult addRing(const QVector< QgsPointXY > &ring, const QgsFeatureIds &targetFeatureIds=QgsFeatureIds(), QgsFeatureId *modifiedFeatureId=nullptr)
Adds a ring to polygon/multipolygon features.
Definition: qgsvectorlayereditutils.cpp:121
QgsVectorLayer::selectedFeatureCount
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
Definition: qgsvectorlayer.cpp:3428
QgsVectorLayer::EditResult
EditResult
Result of an edit operation.
Definition: qgsvectorlayer.h:399
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:1851
QgsVectorLayer::Success
@ Success
Edit operation was successful.
Definition: qgsvectorlayer.h:401
QgsFeatureIterator
Definition: qgsfeatureiterator.h:263
QgsVectorLayer::geometryType
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
Definition: qgsvectorlayer.cpp:659
QgsVectorLayer::addFeature
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) FINAL
Adds a single feature to the sink.
Definition: qgsvectorlayer.cpp:1011
QgsRectangle::isEmpty
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:437
qgswkbtypes.h
qgsabstractgeometry.h
QgsGeometry::AddRingNotInExistingFeature
@ AddRingNotInExistingFeature
The input ring doesn't have any existing ring to fit into.
Definition: qgsgeometry.h:151
QgsPoint::x
double x
Definition: qgspoint.h:58
QgsGeometry::set
void set(QgsAbstractGeometry *geometry)
Sets the underlying geometry store.
Definition: qgsgeometry.cpp:139
QgsRectangle::width
double width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:202
QgsRectangle::setYMinimum
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:140
qgsvectorlayereditbuffer.h
QgsRectangle::setYMaximum
void setYMaximum(double y)
Set the maximum y value.
Definition: qgsrectangle.h:145
QgsVectorLayerEditUtils::deleteVertex
QgsVectorLayer::EditResult deleteVertex(QgsFeatureId featureId, int vertex)
Deletes a vertex from a feature.
Definition: qgsvectorlayereditutils.cpp:97
QgsRectangle::xMinimum
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
QgsGeometry::closestSegmentWithContext
double closestSegmentWithContext(const QgsPointXY &point, QgsPointXY &minDistPoint, int &afterVertex, int *leftOf=nullptr, double epsilon=DEFAULT_SEGMENT_EPSILON) const
Searches for the closest segment of geometry to the given point.
Definition: qgsgeometry.cpp:644
QgsFeatureId
qint64 QgsFeatureId
Definition: qgsfeatureid.h:25