25QString QgsMergeVectorAlgorithm::name()
const
27 return QStringLiteral(
"mergevectorlayers" );
30QString QgsMergeVectorAlgorithm::displayName()
const
32 return QObject::tr(
"Merge vector layers" );
35QStringList QgsMergeVectorAlgorithm::tags()
const
37 return QObject::tr(
"vector,layers,collect,merge,combine" ).split(
',' );
40QString QgsMergeVectorAlgorithm::group()
const
42 return QObject::tr(
"Vector general" );
45QString QgsMergeVectorAlgorithm::groupId()
const
47 return QStringLiteral(
"vectorgeneral" );
50void QgsMergeVectorAlgorithm::initAlgorithm(
const QVariantMap & )
53 addParameter(
new QgsProcessingParameterCrs( QStringLiteral(
"CRS" ), QObject::tr(
"Destination CRS" ), QVariant(),
true ) );
57 addParameter(
new QgsProcessingParameterBoolean( QStringLiteral(
"ADD_SOURCE_FIELDS" ), QObject::tr(
"Add source layer information (layer name and path)" ),
true ) );
60QString QgsMergeVectorAlgorithm::shortDescription()
const
62 return QObject::tr(
"Combines multiple vector layers of the same geometry type into a single one." );
65QString QgsMergeVectorAlgorithm::shortHelpString()
const
67 return QObject::tr(
"This algorithm combines multiple vector layers of the same geometry type into a single one.\n\n"
68 "The attribute table of the resulting layer will contain the fields from all input layers. "
69 "If fields with the same name but different types are found then the exported field will be automatically converted into a string type field. "
70 "Optionally, new fields storing the original layer name and source can be added.\n\n"
71 "If any input layers contain Z or M values, then the output layer will also contain these values. Similarly, "
72 "if any of the input layers are multi-part, the output layer will also be a multi-part layer.\n\n"
73 "Optionally, the destination coordinate reference system (CRS) for the merged layer can be set. If it is not set, the CRS will be "
74 "taken from the first input layer. All layers will all be reprojected to match this CRS." );
82QgsMergeVectorAlgorithm *QgsMergeVectorAlgorithm::createInstance()
const
84 return new QgsMergeVectorAlgorithm();
89 const QList<QgsMapLayer *> layers = parameterAsLayerList( parameters, QStringLiteral(
"LAYERS" ), context );
91 const bool addSourceFields = parameterAsBool( parameters, QStringLiteral(
"ADD_SOURCE_FIELDS" ), context );
94 long totalFeatureCount = 0;
99 feedback->
pushInfo( QObject::tr(
"Using specified destination CRS %1" ).arg( outputCrs.
authid() ) );
101 bool errored =
false;
114 feedback->
pushDebugInfo( QObject::tr(
"Error retrieving map layer." ) );
126 const QString layerName = vl->
name();
130 outputCrs = layerCrs;
131 feedback->
pushInfo( QObject::tr(
"Taking destination CRS %1 from layer" ).arg( outputCrs.
authid() ) );
138 throw QgsProcessingException( QObject::tr(
"All layers must have same geometry type! Encountered a %1 layer when expecting a %2 layer." )
159 outputType = layerWkbType;
169 for (
QgsField &destField : outputFields )
171 if ( destField.name().compare( sourceField.name(), Qt::CaseInsensitive ) == 0 )
174 if ( destField.type() != sourceField.type() )
176 feedback->
pushWarning( QObject::tr(
"%1 field in layer %2 has different data type than the destination layer (%3 instead of %4). "
177 "%1 field will be converted to string type." )
178 .arg( sourceField.name(), layerName, sourceField.typeName(), destField.typeName() ) );
179 destField.setType( QMetaType::Type::QString );
180 destField.setSubType( QMetaType::Type::UnknownType );
181 destField.setLength( 0 );
182 destField.setPrecision( 0 );
184 else if ( destField.type() == QMetaType::Type::QString && destField.length() < sourceField.length() )
186 feedback->
pushWarning( QObject::tr(
"%1 field in layer %2 has different field length than the destination layer (%3 vs %4). "
187 "%1 field length will be extended to match the larger of the two." )
188 .arg( sourceField.name(), layerName, QString::number( sourceField.length() ), QString::number( destField.length() ) ) );
189 destField.setLength( sourceField.length() );
191 else if ( destField.type() == QMetaType::Type::Double && destField.precision() < sourceField.precision() )
193 feedback->
pushWarning( QObject::tr(
"%1 field in layer %2 has different field precision than the destination layer (%3 vs %4). "
194 "%1 field precision will be extended to match the larger of the two." )
195 .arg( sourceField.name(), layerName, QString::number( sourceField.length() ), QString::number( destField.length() ) ) );
196 destField.setPrecision( sourceField.precision() );
203 outputFields.append( sourceField );
207 bool addLayerField =
false;
208 bool addPathField =
false;
209 if ( addSourceFields )
211 if ( outputFields.lookupField( QStringLiteral(
"layer" ) ) < 0 )
213 outputFields.append(
QgsField( QStringLiteral(
"layer" ), QMetaType::Type::QString, QString() ) );
214 addLayerField =
true;
217 if ( outputFields.lookupField( QStringLiteral(
"path" ) ) < 0 )
219 outputFields.append(
QgsField( QStringLiteral(
"path" ), QMetaType::Type::QString, QString() ) );
225 std::unique_ptr<QgsFeatureSink> sink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, dest, outputFields, outputType, outputCrs,
QgsFeatureSink::RegeneratePrimaryKey ) );
232 const double step = totalFeatureCount > 0 ? 100.0 / totalFeatureCount : 1;
245 const QString layerName = layer->name();
246 const QString layerSource = layer->publicSource();
249 feedback->
pushInfo( QObject::tr(
"Packaging layer %1/%2: %3" ).arg( layerNumber ).arg( layers.count() ).arg( layerName ) );
261 bool changed =
false;
284 for (
const QgsField &destField : outputFields )
286 if ( addLayerField && destField.name() == QLatin1String(
"layer" ) )
288 destAttributes.append( layerName );
291 else if ( addPathField && destField.name() == QLatin1String(
"path" ) )
293 destAttributes.append( layerSource );
297 QVariant destAttribute;
298 const int sourceIndex = layerFields.
lookupField( destField.name() );
299 if ( sourceIndex >= 0 )
301 destAttribute = f.
attributes().at( sourceIndex );
303 destAttributes.append( destAttribute );
320 outputs.insert( QStringLiteral(
"OUTPUT" ), dest );
@ Vector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
@ RegeneratesPrimaryKey
Algorithm always drops any existing primary keys or FID values and regenerates them in outputs.
QFlags< ProcessingAlgorithmDocumentationFlag > ProcessingAlgorithmDocumentationFlags
Flags describing algorithm behavior for documentation purposes.
WkbType
The WKB type describes the number of dimensions a geometry has.
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
bool isMeasure() const
Returns true if the geometry contains m values.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
Represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
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).
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
@ RegeneratePrimaryKey
This flag indicates, that a primary key field cannot be guaranteed to be unique and the sink should i...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
bool isCanceled() const
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
A geometry is the spatial representation of a feature.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
bool convertToMultiType()
Converts single type geometry into multitype geometry e.g.
Base class for all map layer types.
QgsCoordinateReferenceSystem crs
Contains information about the context in which a processing algorithm is executed.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
virtual void pushWarning(const QString &warning)
Pushes a warning informational message from the algorithm.
virtual void pushDebugInfo(const QString &info)
Pushes an informational message containing debugging helpers from the algorithm.
A boolean parameter for processing algorithms.
A coordinate reference system parameter for processing algorithms.
A feature sink output for processing algorithms.
A parameter for processing algorithms which accepts multiple map layers.
Represents a vector layer which manages a vector based dataset.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
Q_INVOKABLE Qgis::WkbType wkbType() const final
Returns the WKBType or WKBUnknown in case of error.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
static Qgis::GeometryType geometryType(Qgis::WkbType type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
static Q_INVOKABLE QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
static Qgis::WkbType addM(Qgis::WkbType type)
Adds the m dimension to a WKB type and returns the new type.
static Qgis::WkbType addZ(Qgis::WkbType type)
Adds the z dimension to a WKB type and returns the new type.
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static Q_INVOKABLE bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.
static Q_INVOKABLE QString geometryDisplayString(Qgis::GeometryType type)
Returns a display string for a geometry type.
static Qgis::WkbType multiType(Qgis::WkbType type)
Returns the multi type for a WKB type.
static Q_INVOKABLE bool isMultiType(Qgis::WkbType type)
Returns true if the WKB type is a multi type.