QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsvectorlayertools.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsvectorlayertools.cpp
3 ---------------------
4 begin : 09.11.2016
5 copyright : (C) 2016 by Denis Rouzaud
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 ***************************************************************************/
15
16
17#include "qgsvectorlayer.h"
18#include "qgsvectorlayertools.h"
19#include "qgsfeaturerequest.h"
20#include "qgslogger.h"
21#include "qgsvectorlayerutils.h"
22#include "qgsproject.h"
23
24
26 : QObject( nullptr )
27{}
28
29bool QgsVectorLayerTools::copyMoveFeatures( QgsVectorLayer *layer, QgsFeatureRequest &request, double dx, double dy, QString *errorMsg, const bool topologicalEditing, QgsVectorLayer *topologicalLayer, QString *childrenInfoMsg ) const
30{
31 bool res = false;
32 if ( !layer || !layer->isEditable() )
33 {
34 return false;
35 }
36
37 QgsFeatureIterator fi = layer->getFeatures( request );
38 QgsFeature f;
39
40 int browsedFeatureCount = 0;
41 int couldNotWriteCount = 0;
42 int noGeometryCount = 0;
43
44 QgsFeatureIds fidList;
46 QMap<QString, int> duplicateFeatureCount;
47 while ( fi.nextFeature( f ) )
48 {
49 browsedFeatureCount++;
50
51 if ( f.hasGeometry() )
52 {
53 QgsGeometry geom = f.geometry();
54 geom.translate( dx, dy );
55 f.setGeometry( geom );
56 }
57
58 QgsFeature newFeature;
59 if ( mProject )
60 {
61 newFeature = QgsVectorLayerUtils::duplicateFeature( layer, f, mProject, duplicateFeatureContext );
62 if ( !newFeature.isValid() )
63 {
64 couldNotWriteCount++;
65 QgsDebugError( QStringLiteral( "Could not add new feature. Original copied feature id: %1" ).arg( f.id() ) );
66 }
67 else
68 {
69 fidList.insert( newFeature.id() );
70 }
71
72 const auto duplicateFeatureContextLayers = duplicateFeatureContext.layers();
73 for ( QgsVectorLayer *chl : duplicateFeatureContextLayers )
74 {
75 if ( duplicateFeatureCount.contains( chl->name() ) )
76 {
77 duplicateFeatureCount[chl->name()] += duplicateFeatureContext.duplicatedFeatures( chl ).size();
78 }
79 else
80 {
81 duplicateFeatureCount[chl->name()] = duplicateFeatureContext.duplicatedFeatures( chl ).size();
82 }
83 }
84 }
85 else
86 {
87 newFeature = QgsVectorLayerUtils::createFeature( layer, f.geometry(), f.attributes().toMap() );
88 if ( !layer->addFeature( newFeature ) )
89 {
90 couldNotWriteCount++;
91 QgsDebugError( QStringLiteral( "Could not add new feature. Original copied feature id: %1" ).arg( f.id() ) );
92 }
93 else
94 {
95 fidList.insert( newFeature.id() );
96 }
97 }
98
99 // translate
100 if ( newFeature.hasGeometry() )
101 {
102 QgsGeometry geom = newFeature.geometry();
103 if ( topologicalEditing )
104 {
105 if ( topologicalLayer )
106 {
107 topologicalLayer->addTopologicalPoints( geom );
108 }
109 layer->addTopologicalPoints( geom );
110 }
111 }
112 else
113 {
114 noGeometryCount++;
115 }
116 }
117
118 QString childrenInfo;
119 for ( auto it = duplicateFeatureCount.constBegin(); it != duplicateFeatureCount.constEnd(); ++it )
120 {
121 childrenInfo += ( tr( "\n%n children on layer %1 duplicated", nullptr, it.value() ).arg( it.key() ) );
122 }
123
124 request = QgsFeatureRequest();
125 request.setFilterFids( fidList );
126
127 if ( childrenInfoMsg && !childrenInfo.isEmpty() )
128 {
129 childrenInfoMsg->append( childrenInfo );
130 }
131
132 if ( !couldNotWriteCount && !noGeometryCount )
133 {
134 res = true;
135 }
136 else if ( errorMsg )
137 {
138 errorMsg = new QString( tr( "Only %1 out of %2 features were copied." )
139 .arg( browsedFeatureCount - couldNotWriteCount - noGeometryCount, browsedFeatureCount ) );
140 if ( noGeometryCount )
141 {
142 errorMsg->append( " " );
143 errorMsg->append( tr( "Some features have no geometry." ) );
144 }
145 if ( couldNotWriteCount )
146 {
147 errorMsg->append( " " );
148 errorMsg->append( tr( "Some could not be created on the layer." ) );
149 }
150 }
151 return res;
152}
153
155{
156 return mForceSuppressFormPopup;
157}
158
159void QgsVectorLayerTools::setForceSuppressFormPopup( bool forceSuppressFormPopup )
160{
161 mForceSuppressFormPopup = forceSuppressFormPopup;
162}
CORE_EXPORT QgsAttributeMap toMap() const
Returns a QgsAttributeMap of the attribute values.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QgsAttributes attributes
Definition: qgsfeature.h:65
QgsGeometry geometry
Definition: qgsfeature.h:67
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:230
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:216
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:167
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:162
Qgis::GeometryOperationResult translate(double dx, double dy, double dz=0.0, double dm=0.0)
Translates this geometry by dx, dy, dz and dm.
bool forceSuppressFormPopup() const
Returns force suppress form popup status.
virtual bool copyMoveFeatures(QgsVectorLayer *layer, QgsFeatureRequest &request, double dx=0, double dy=0, QString *errorMsg=nullptr, const bool topologicalEditing=false, QgsVectorLayer *topologicalLayer=nullptr, QString *childrenInfoMsg=nullptr) const
Copy and move features with defined translation.
void setForceSuppressFormPopup(bool forceSuppressFormPopup)
Sets force suppress form popup status to forceSuppressFormPopup.
Contains mainly the QMap with QgsVectorLayer and QgsFeatureIds do list all the duplicated features.
QgsFeatureIds duplicatedFeatures(QgsVectorLayer *layer) const
Returns the duplicated features in the given layer.
QList< QgsVectorLayer * > layers() const
Returns all the layers on which features have been duplicated.
static QgsFeature duplicateFeature(QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, QgsDuplicateFeatureContext &duplicateFeatureContext, const int maxDepth=0, int depth=0, QList< QgsVectorLayer * > referencedLayersBranch=QList< QgsVectorLayer * >())
Duplicates a feature and it's children (one level deep).
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.
Represents a vector layer which manages a vector based data sets.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) FINAL
Adds a single feature to the sink.
int addTopologicalPoints(const QgsGeometry &geom)
Adds topological points for every vertex of the geometry.
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
#define QgsDebugError(str)
Definition: qgslogger.h:38