25 QString QgsExplodeHstoreAlgorithm::name()
const
27 return QStringLiteral(
"explodehstorefield" );
30 QString QgsExplodeHstoreAlgorithm::displayName()
const
32 return QObject::tr(
"Explode HStore Field" );
35 QStringList QgsExplodeHstoreAlgorithm::tags()
const
37 return QObject::tr(
"field,explode,hstore,osm,openstreetmap" ).split(
',' );
40 QString QgsExplodeHstoreAlgorithm::group()
const
42 return QObject::tr(
"Vector table" );
45 QString QgsExplodeHstoreAlgorithm::groupId()
const
47 return QStringLiteral(
"vectortable" );
50 QString QgsExplodeHstoreAlgorithm::shortHelpString()
const
52 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"
53 "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." );
58 return new QgsExplodeHstoreAlgorithm();
61 void QgsExplodeHstoreAlgorithm::initAlgorithm(
const QVariantMap & )
64 QObject::tr(
"Input layer" ) ) );
66 QObject::tr(
"HStore field" ), QVariant(), QStringLiteral(
"INPUT" ) ) );
67 addParameter(
new QgsProcessingParameterString( QStringLiteral(
"EXPECTED_FIELDS" ), QObject::tr(
"Expected list of fields separated by a comma" ), QVariant(),
false,
true ) );
73 std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral(
"INPUT" ), context ) );
76 int attrSourceCount = source->fields().count();
78 QString fieldName = parameterAsString( parameters, QStringLiteral(
"FIELD" ), context );
79 int fieldIndex = source->fields().lookupField( fieldName );
83 QStringList expectedFields;
84 QString fieldList = parameterAsString( parameters, QStringLiteral(
"EXPECTED_FIELDS" ), context );
85 if ( ! fieldList.trimmed().isEmpty() )
87 expectedFields = fieldList.split(
',' );
90 QList<QString> fieldsToAdd;
91 QHash<QgsFeatureId, QVariantMap> hstoreFeatures;
92 QList<QgsFeature> features;
94 double step = source->featureCount() > 0 ? 50.0 / source->featureCount() : 1;
104 double progress = i * step;
105 if ( progress >= 50 )
111 for (
const QString &key : currentHStore.keys() )
113 if ( expectedFields.isEmpty() && ! fieldsToAdd.contains( key ) )
114 fieldsToAdd.insert( 0, key );
116 hstoreFeatures.insert( feat.
id(), currentHStore );
117 features.append( feat );
120 if ( ! expectedFields.isEmpty() )
122 fieldsToAdd = expectedFields;
126 for (
const QString &fieldName : fieldsToAdd )
134 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, sinkId, outFields, source->wkbType(), source->sourceCrs() ) );
139 int attrCount = attrSourceCount + fieldsToAdd.count();
141 step = !features.empty() ? 50.0 / features.count() : 1;
143 for (
const QgsFeature &feat : std::as_const( features ) )
154 for (
int i = 0; i < fieldIndicesInput.count(); ++i )
155 outAttributes[i] = attrs[fieldIndicesInput[i]];
157 QVariantMap currentHStore = hstoreFeatures.take( feat.
id() );
160 for (
int i = 0; i < fieldsToAdd.count(); ++i )
162 current = fieldsToAdd.at( i );
163 if ( currentHStore.contains( current ) )
165 outAttributes[attrSourceCount + i] = currentHStore.take( current );
169 if ( ! expectedFields.isEmpty() )
181 outputs.insert( QStringLiteral(
"OUTPUT" ), sinkId );