QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
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 "qgsvectorlayertools.h"
18
19#include "qgsfeaturerequest.h"
20#include "qgslogger.h"
21#include "qgsproject.h"
22#include "qgsvectorlayer.h"
23#include "qgsvectorlayerutils.h"
24
25#include <QString>
26
27#include "moc_qgsvectorlayertools.cpp"
28
29using namespace Qt::StringLiterals;
30
32 : QObject( nullptr )
33{}
34
35bool QgsVectorLayerTools::copyMoveFeatures( QgsVectorLayer *layer, QgsFeatureRequest &request, double dx, double dy, QString *errorMsg, const bool topologicalEditing, QgsVectorLayer *topologicalLayer, QString *childrenInfoMsg ) const
36{
37 bool res = false;
38 if ( !layer || !layer->isEditable() )
39 {
40 request = QgsFeatureRequest();
41 return false;
42 }
43
44 QgsFeatureIterator fi = layer->getFeatures( request );
45 QgsFeature f;
46
47 int browsedFeatureCount = 0;
48 int couldNotWriteCount = 0;
49 int noGeometryCount = 0;
50
51 QgsFeatureIds fidList;
53 QMap<QString, int> duplicateFeatureCount;
54 while ( fi.nextFeature( f ) )
55 {
56 browsedFeatureCount++;
57
58 if ( f.hasGeometry() )
59 {
60 QgsGeometry geom = f.geometry();
61 geom.translate( dx, dy );
62 f.setGeometry( geom );
63 }
64
65 QgsFeature newFeature;
66 if ( mProject )
67 {
68 newFeature = QgsVectorLayerUtils::duplicateFeature( layer, f, mProject, duplicateFeatureContext );
69 if ( !newFeature.isValid() )
70 {
71 couldNotWriteCount++;
72 QgsDebugError( u"Could not add new feature. Original copied feature id: %1"_s.arg( f.id() ) );
73 }
74 else
75 {
76 fidList.insert( newFeature.id() );
77 }
78
79 const auto duplicateFeatureContextLayers = duplicateFeatureContext.layers();
80 for ( QgsVectorLayer *chl : duplicateFeatureContextLayers )
81 {
82 if ( duplicateFeatureCount.contains( chl->name() ) )
83 {
84 duplicateFeatureCount[chl->name()] += duplicateFeatureContext.duplicatedFeatures( chl ).size();
85 }
86 else
87 {
88 duplicateFeatureCount[chl->name()] = duplicateFeatureContext.duplicatedFeatures( chl ).size();
89 }
90 }
91 }
92 else
93 {
94 newFeature = QgsVectorLayerUtils::createFeature( layer, f.geometry(), f.attributes().toMap() );
95 if ( !layer->addFeature( newFeature ) )
96 {
97 couldNotWriteCount++;
98 QgsDebugError( u"Could not add new feature. Original copied feature id: %1"_s.arg( f.id() ) );
99 }
100 else
101 {
102 fidList.insert( newFeature.id() );
103 }
104 }
105
106 // translate
107 if ( newFeature.hasGeometry() )
108 {
109 QgsGeometry geom = newFeature.geometry();
110 if ( topologicalEditing )
111 {
112 if ( topologicalLayer )
113 {
114 topologicalLayer->addTopologicalPoints( geom );
115 }
116 layer->addTopologicalPoints( geom );
117 }
118 }
119 else
120 {
121 noGeometryCount++;
122 }
123 }
124
125 QString childrenInfo;
126 for ( auto it = duplicateFeatureCount.constBegin(); it != duplicateFeatureCount.constEnd(); ++it )
127 {
128 childrenInfo += ( tr( "\n%n children on layer %1 duplicated", nullptr, it.value() ).arg( it.key() ) );
129 }
130
131 request = QgsFeatureRequest();
132 request.setFilterFids( fidList );
133
134 if ( childrenInfoMsg && !childrenInfo.isEmpty() )
135 {
136 childrenInfoMsg->append( childrenInfo );
137 }
138
139 if ( !couldNotWriteCount && !noGeometryCount )
140 {
141 res = true;
142 }
143 else if ( errorMsg )
144 {
145 errorMsg = new QString( tr( "Only %1 out of %2 features were copied." )
146 .arg( browsedFeatureCount - couldNotWriteCount - noGeometryCount, browsedFeatureCount ) );
147 if ( noGeometryCount )
148 {
149 errorMsg->append( " " );
150 errorMsg->append( tr( "Some features have no geometry." ) );
151 }
152 if ( couldNotWriteCount )
153 {
154 errorMsg->append( " " );
155 errorMsg->append( tr( "Some could not be created on the layer." ) );
156 }
157 }
158 return res;
159}
160
162{
163 return mForceSuppressFormPopup;
164}
165
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.
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:60
QgsAttributes attributes
Definition qgsfeature.h:69
QgsFeatureId id
Definition qgsfeature.h:68
QgsGeometry geometry
Definition qgsfeature.h:71
bool hasGeometry() const
Returns true if the feature has an associated geometry.
bool isValid() const
Returns the validity of this feature.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
A geometry is the spatial representation of a feature.
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 which 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 dataset.
bool isEditable() const final
Returns true if the provider is in editing mode.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
int addTopologicalPoints(const QgsGeometry &geom)
Adds topological points for every vertex of the geometry.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) final
Adds a single feature to the sink.
QSet< QgsFeatureId > QgsFeatureIds
#define QgsDebugError(str)
Definition qgslogger.h:59