26using namespace Qt::StringLiterals;
30QString QgsExplodeHstoreAlgorithm::name()
const
32 return u
"explodehstorefield"_s;
35QString QgsExplodeHstoreAlgorithm::displayName()
const
37 return QObject::tr(
"Explode HStore Field" );
40QStringList QgsExplodeHstoreAlgorithm::tags()
const
42 return QObject::tr(
"field,explode,hstore,osm,openstreetmap" ).split(
',' );
45QString QgsExplodeHstoreAlgorithm::group()
const
47 return QObject::tr(
"Vector table" );
50QString QgsExplodeHstoreAlgorithm::groupId()
const
52 return u
"vectortable"_s;
55QString QgsExplodeHstoreAlgorithm::shortHelpString()
const
57 return QObject::tr(
"This algorithm creates a copy of the input layer and adds a new field for every unique key in the HStore field.\n"
58 "The expected field list is an optional comma separated list. By default, all unique keys are added. If this list is specified, only these fields are added and the HStore field is updated." );
61QString QgsExplodeHstoreAlgorithm::shortDescription()
const
63 return QObject::tr(
"Creates a copy of the input layer and adds a new field for every unique key in the HStore field." );
68 return new QgsExplodeHstoreAlgorithm();
71void QgsExplodeHstoreAlgorithm::initAlgorithm(
const QVariantMap & )
75 addParameter(
new QgsProcessingParameterString( u
"EXPECTED_FIELDS"_s, QObject::tr(
"Expected list of fields separated by a comma" ), QVariant(),
false,
true ) );
81 std::unique_ptr<QgsProcessingFeatureSource> source( parameterAsSource( parameters, u
"INPUT"_s, context ) );
84 int attrSourceCount = source->fields().count();
86 QString fieldName = parameterAsString( parameters, u
"FIELD"_s, context );
87 int fieldIndex = source->fields().lookupField( fieldName );
91 QStringList expectedFields;
92 QString fieldList = parameterAsString( parameters, u
"EXPECTED_FIELDS"_s, context );
93 if ( !fieldList.trimmed().isEmpty() )
95 expectedFields = fieldList.split(
',' );
98 QList<QString> fieldsToAdd;
99 QHash<QgsFeatureId, QVariantMap> hstoreFeatures;
100 QList<QgsFeature> features;
102 double step = source->featureCount() > 0 ? 50.0 / source->featureCount() : 1;
112 double progress = i * step;
113 if ( progress >= 50 )
119 for (
auto key = currentHStore.keyBegin(); key != currentHStore.keyEnd(); key++ )
121 if ( expectedFields.isEmpty() && !fieldsToAdd.contains( *key ) )
122 fieldsToAdd.insert( 0, *key );
124 hstoreFeatures.insert( feat.
id(), currentHStore );
125 features.append( feat );
128 if ( !expectedFields.isEmpty() )
130 fieldsToAdd = expectedFields;
134 for (
const QString &fieldName : fieldsToAdd )
136 hstoreFields.
append(
QgsField( fieldName, QMetaType::Type::QString ) );
142 std::unique_ptr<QgsFeatureSink> sink( parameterAsSink( parameters, u
"OUTPUT"_s, context, sinkId, outFields, source->wkbType(), source->sourceCrs() ) );
147 int attrCount = attrSourceCount + fieldsToAdd.count();
149 step = !features.empty() ? 50.0 / features.count() : 1;
151 for (
const QgsFeature &feat : std::as_const( features ) )
162 for (
int i = 0; i < fieldIndicesInput.count(); ++i )
163 outAttributes[i] = attrs[fieldIndicesInput[i]];
165 QVariantMap currentHStore = hstoreFeatures.take( feat.
id() );
168 for (
int i = 0; i < fieldsToAdd.count(); ++i )
170 current = fieldsToAdd.at( i );
171 if ( currentHStore.contains( current ) )
173 outAttributes[attrSourceCount + i] = currentHStore.take( current );
177 if ( !expectedFields.isEmpty() )
191 outputs.insert( u
"OUTPUT"_s, sinkId );
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.
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
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.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
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.
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
A geometry is the spatial representation of a feature.
static QString build(const QVariantMap &map)
Build a hstore-formatted string from a QVariantMap.
static QVariantMap parse(const QString &string)
Returns a QVariantMap object containing the key and values from a hstore-formatted string.
Abstract base class for processing algorithms.
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
A feature sink output for processing algorithms.
An input feature source (such as vector layers) parameter for processing algorithms.
A vector layer or feature source field parameter for processing algorithms.
A string parameter for processing algorithms.
static QList< int > fieldNamesToIndices(const QStringList &fieldNames, const QgsFields &fields)
Returns a list of field indices parsed from the given list of field names.
static QgsFields combineFields(const QgsFields &fieldsA, const QgsFields &fieldsB, const QString &fieldsBPrefix=QString())
Combines two field lists, avoiding duplicate field names (in a case-insensitive manner).