QGIS API Documentation 3.99.0-Master (21b3aa880ba)
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 "moc_qgsvectorlayertools.cpp"
26
28 : QObject( nullptr )
29{}
30
31bool QgsVectorLayerTools::copyMoveFeatures( QgsVectorLayer *layer, QgsFeatureRequest &request, double dx, double dy, QString *errorMsg, const bool topologicalEditing, QgsVectorLayer *topologicalLayer, QString *childrenInfoMsg ) const
32{
33 bool res = false;
34 if ( !layer || !layer->isEditable() )
35 {
36 return false;
37 }
38
39 QgsFeatureIterator fi = layer->getFeatures( request );
40 QgsFeature f;
41
42 int browsedFeatureCount = 0;
43 int couldNotWriteCount = 0;
44 int noGeometryCount = 0;
45
46 QgsFeatureIds fidList;
48 QMap<QString, int> duplicateFeatureCount;
49 while ( fi.nextFeature( f ) )
50 {
51 browsedFeatureCount++;
52
53 if ( f.hasGeometry() )
54 {
55 QgsGeometry geom = f.geometry();
56 geom.translate( dx, dy );
57 f.setGeometry( geom );
58 }
59
60 QgsFeature newFeature;
61 if ( mProject )
62 {
63 newFeature = QgsVectorLayerUtils::duplicateFeature( layer, f, mProject, duplicateFeatureContext );
64 if ( !newFeature.isValid() )
65 {
66 couldNotWriteCount++;
67 QgsDebugError( QStringLiteral( "Could not add new feature. Original copied feature id: %1" ).arg( f.id() ) );
68 }
69 else
70 {
71 fidList.insert( newFeature.id() );
72 }
73
74 const auto duplicateFeatureContextLayers = duplicateFeatureContext.layers();
75 for ( QgsVectorLayer *chl : duplicateFeatureContextLayers )
76 {
77 if ( duplicateFeatureCount.contains( chl->name() ) )
78 {
79 duplicateFeatureCount[chl->name()] += duplicateFeatureContext.duplicatedFeatures( chl ).size();
80 }
81 else
82 {
83 duplicateFeatureCount[chl->name()] = duplicateFeatureContext.duplicatedFeatures( chl ).size();
84 }
85 }
86 }
87 else
88 {
89 newFeature = QgsVectorLayerUtils::createFeature( layer, f.geometry(), f.attributes().toMap() );
90 if ( !layer->addFeature( newFeature ) )
91 {
92 couldNotWriteCount++;
93 QgsDebugError( QStringLiteral( "Could not add new feature. Original copied feature id: %1" ).arg( f.id() ) );
94 }
95 else
96 {
97 fidList.insert( newFeature.id() );
98 }
99 }
100
101 // translate
102 if ( newFeature.hasGeometry() )
103 {
104 QgsGeometry geom = newFeature.geometry();
105 if ( topologicalEditing )
106 {
107 if ( topologicalLayer )
108 {
109 topologicalLayer->addTopologicalPoints( geom );
110 }
111 layer->addTopologicalPoints( geom );
112 }
113 }
114 else
115 {
116 noGeometryCount++;
117 }
118 }
119
120 QString childrenInfo;
121 for ( auto it = duplicateFeatureCount.constBegin(); it != duplicateFeatureCount.constEnd(); ++it )
122 {
123 childrenInfo += ( tr( "\n%n children on layer %1 duplicated", nullptr, it.value() ).arg( it.key() ) );
124 }
125
126 request = QgsFeatureRequest();
127 request.setFilterFids( fidList );
128
129 if ( childrenInfoMsg && !childrenInfo.isEmpty() )
130 {
131 childrenInfoMsg->append( childrenInfo );
132 }
133
134 if ( !couldNotWriteCount && !noGeometryCount )
135 {
136 res = true;
137 }
138 else if ( errorMsg )
139 {
140 errorMsg = new QString( tr( "Only %1 out of %2 features were copied." )
141 .arg( browsedFeatureCount - couldNotWriteCount - noGeometryCount, browsedFeatureCount ) );
142 if ( noGeometryCount )
143 {
144 errorMsg->append( " " );
145 errorMsg->append( tr( "Some features have no geometry." ) );
146 }
147 if ( couldNotWriteCount )
148 {
149 errorMsg->append( " " );
150 errorMsg->append( tr( "Some could not be created on the layer." ) );
151 }
152 }
153 return res;
154}
155
157{
158 return mForceSuppressFormPopup;
159}
160
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:58
QgsAttributes attributes
Definition qgsfeature.h:67
QgsFeatureId id
Definition qgsfeature.h:66
QgsGeometry geometry
Definition qgsfeature.h:69
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:57