LCOV - code coverage report
Current view: top level - analysis/processing - qgsalgorithmexplodehstore.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 0 103 0.0 %
Date: 2021-03-26 12:19:53 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :                          qgsalgorithmexplodehstore.h
       3                 :            :                          ---------------------
       4                 :            :     begin                : September 2018
       5                 :            :     copyright            : (C) 2018 by Etienne Trimaille
       6                 :            :     email                : etienne dot trimaille at gmail dot com
       7                 :            :  ***************************************************************************/
       8                 :            : 
       9                 :            : /***************************************************************************
      10                 :            :  *                                                                         *
      11                 :            :  *   This program is free software; you can redistribute it and/or modify  *
      12                 :            :  *   it under the terms of the GNU General Public License as published by  *
      13                 :            :  *   the Free Software Foundation; either version 2 of the License, or     *
      14                 :            :  *   (at your option) any later version.                                   *
      15                 :            :  *                                                                         *
      16                 :            :  ***************************************************************************/
      17                 :            : 
      18                 :            : #include "qgis.h"
      19                 :            : #include "qgsalgorithmexplodehstore.h"
      20                 :            : #include "qgshstoreutils.h"
      21                 :            : #include "qgsprocessingutils.h"
      22                 :            : 
      23                 :            : ///@cond PRIVATE
      24                 :            : 
      25                 :          0 : QString QgsExplodeHstoreAlgorithm::name() const
      26                 :            : {
      27                 :          0 :   return QStringLiteral( "explodehstorefield" );
      28                 :            : }
      29                 :            : 
      30                 :          0 : QString QgsExplodeHstoreAlgorithm::displayName() const
      31                 :            : {
      32                 :          0 :   return QObject::tr( "Explode HStore Field" );
      33                 :            : }
      34                 :            : 
      35                 :          0 : QStringList QgsExplodeHstoreAlgorithm::tags() const
      36                 :            : {
      37                 :          0 :   return QObject::tr( "field,explode,hstore,osm,openstreetmap" ).split( ',' );
      38                 :          0 : }
      39                 :            : 
      40                 :          0 : QString QgsExplodeHstoreAlgorithm::group() const
      41                 :            : {
      42                 :          0 :   return QObject::tr( "Vector table" );
      43                 :            : }
      44                 :            : 
      45                 :          0 : QString QgsExplodeHstoreAlgorithm::groupId() const
      46                 :            : {
      47                 :          0 :   return QStringLiteral( "vectortable" );
      48                 :            : }
      49                 :            : 
      50                 :          0 : QString QgsExplodeHstoreAlgorithm::shortHelpString() const
      51                 :            : {
      52                 :          0 :   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." );
      54                 :            : }
      55                 :            : 
      56                 :          0 : QgsProcessingAlgorithm *QgsExplodeHstoreAlgorithm::createInstance() const
      57                 :            : {
      58                 :          0 :   return new QgsExplodeHstoreAlgorithm();
      59                 :            : }
      60                 :            : 
      61                 :          0 : void QgsExplodeHstoreAlgorithm::initAlgorithm( const QVariantMap & )
      62                 :            : {
      63                 :          0 :   addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ),
      64                 :          0 :                 QObject::tr( "Input layer" ) ) );
      65                 :          0 :   addParameter( new QgsProcessingParameterField( QStringLiteral( "FIELD" ),
      66                 :          0 :                 QObject::tr( "HStore field" ), QVariant(), QStringLiteral( "INPUT" ) ) );
      67                 :          0 :   addParameter( new QgsProcessingParameterString( QStringLiteral( "EXPECTED_FIELDS" ), QObject::tr( "Expected list of fields separated by a comma" ), QVariant(), false, true ) );
      68                 :          0 :   addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Exploded" ) ) );
      69                 :          0 : }
      70                 :            : 
      71                 :          0 : QVariantMap QgsExplodeHstoreAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
      72                 :            : {
      73                 :          0 :   std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
      74                 :          0 :   if ( !source )
      75                 :          0 :     throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
      76                 :          0 :   int attrSourceCount = source->fields().count();
      77                 :            : 
      78                 :          0 :   QString fieldName = parameterAsString( parameters, QStringLiteral( "FIELD" ), context );
      79                 :          0 :   int fieldIndex = source->fields().lookupField( fieldName );
      80                 :          0 :   if ( fieldIndex < 0 )
      81                 :          0 :     throw QgsProcessingException( QObject::tr( "Invalid HStore field" ) );
      82                 :            : 
      83                 :          0 :   QStringList expectedFields;
      84                 :          0 :   QString fieldList = parameterAsString( parameters, QStringLiteral( "EXPECTED_FIELDS" ), context );
      85                 :          0 :   if ( ! fieldList.trimmed().isEmpty() )
      86                 :            :   {
      87                 :          0 :     expectedFields = fieldList.split( ',' );
      88                 :          0 :   }
      89                 :            : 
      90                 :          0 :   QList<QString> fieldsToAdd;
      91                 :          0 :   QHash<QgsFeatureId, QVariantMap> hstoreFeatures;
      92                 :          0 :   QList<QgsFeature> features;
      93                 :            : 
      94                 :          0 :   double step = source->featureCount() > 0 ? 50.0 / source->featureCount() : 1;
      95                 :          0 :   int i = 0;
      96                 :          0 :   QgsFeatureIterator featIterator = source->getFeatures( );
      97                 :          0 :   QgsFeature feat;
      98                 :          0 :   while ( featIterator.nextFeature( feat ) )
      99                 :            :   {
     100                 :          0 :     i++;
     101                 :          0 :     if ( feedback->isCanceled() )
     102                 :          0 :       break;
     103                 :            : 
     104                 :          0 :     double progress = i * step;
     105                 :          0 :     if ( progress >= 50 )
     106                 :          0 :       feedback->setProgress( 50.0 );
     107                 :            :     else
     108                 :          0 :       feedback->setProgress( progress );
     109                 :            : 
     110                 :          0 :     QVariantMap currentHStore = QgsHstoreUtils::parse( feat.attribute( fieldName ).toString() );
     111                 :          0 :     for ( const QString &key : currentHStore.keys() )
     112                 :            :     {
     113                 :          0 :       if ( expectedFields.isEmpty() && ! fieldsToAdd.contains( key ) )
     114                 :          0 :         fieldsToAdd.insert( 0, key );
     115                 :            :     }
     116                 :          0 :     hstoreFeatures.insert( feat.id(), currentHStore );
     117                 :          0 :     features.append( feat );
     118                 :          0 :   }
     119                 :            : 
     120                 :          0 :   if ( ! expectedFields.isEmpty() )
     121                 :            :   {
     122                 :          0 :     fieldsToAdd = expectedFields;
     123                 :          0 :   }
     124                 :            : 
     125                 :          0 :   QgsFields hstoreFields;
     126                 :          0 :   for ( const QString &fieldName : fieldsToAdd )
     127                 :            :   {
     128                 :          0 :     hstoreFields.append( QgsField( fieldName, QVariant::String ) );
     129                 :            :   }
     130                 :            : 
     131                 :          0 :   QgsFields outFields = QgsProcessingUtils::combineFields( source->fields(), hstoreFields );
     132                 :            : 
     133                 :          0 :   QString sinkId;
     134                 :          0 :   std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, sinkId, outFields, source->wkbType(), source->sourceCrs() ) );
     135                 :          0 :   if ( !sink )
     136                 :          0 :     throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
     137                 :            : 
     138                 :          0 :   QList<int> fieldIndicesInput = QgsProcessingUtils::fieldNamesToIndices( QStringList(), source->fields() );
     139                 :          0 :   int attrCount = attrSourceCount + fieldsToAdd.count();
     140                 :          0 :   QgsFeature outFeature;
     141                 :          0 :   step = !features.empty() ? 50.0 / features.count() : 1;
     142                 :          0 :   i = 0;
     143                 :          0 :   for ( const QgsFeature &feat : std::as_const( features ) )
     144                 :            :   {
     145                 :          0 :     i++;
     146                 :          0 :     if ( feedback->isCanceled() )
     147                 :          0 :       break;
     148                 :            : 
     149                 :          0 :     feedback->setProgress( i * step + 50.0 );
     150                 :            : 
     151                 :          0 :     QgsAttributes outAttributes( attrCount );
     152                 :            : 
     153                 :          0 :     const QgsAttributes attrs( feat.attributes() );
     154                 :          0 :     for ( int i = 0; i < fieldIndicesInput.count(); ++i )
     155                 :          0 :       outAttributes[i] = attrs[fieldIndicesInput[i]];
     156                 :            : 
     157                 :          0 :     QVariantMap currentHStore = hstoreFeatures.take( feat.id() );
     158                 :            : 
     159                 :          0 :     QString current;
     160                 :          0 :     for ( int i = 0; i < fieldsToAdd.count(); ++i )
     161                 :            :     {
     162                 :          0 :       current = fieldsToAdd.at( i );
     163                 :          0 :       if ( currentHStore.contains( current ) )
     164                 :            :       {
     165                 :          0 :         outAttributes[attrSourceCount + i] = currentHStore.take( current );
     166                 :          0 :       }
     167                 :          0 :     }
     168                 :            : 
     169                 :          0 :     if ( ! expectedFields.isEmpty() )
     170                 :            :     {
     171                 :          0 :       outAttributes[fieldIndex] = QgsHstoreUtils::build( currentHStore );
     172                 :          0 :     }
     173                 :            : 
     174                 :          0 :     outFeature.setGeometry( QgsGeometry( feat.geometry() ) );
     175                 :          0 :     outFeature.setAttributes( outAttributes );
     176                 :          0 :     sink->addFeature( outFeature, QgsFeatureSink::FastInsert );
     177                 :          0 :   }
     178                 :            : 
     179                 :          0 :   QVariantMap outputs;
     180                 :          0 :   outputs.insert( QStringLiteral( "OUTPUT" ), sinkId );
     181                 :          0 :   return outputs;
     182                 :          0 : }
     183                 :            : 
     184                 :            : ///@endcond

Generated by: LCOV version 1.14