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

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :                          qgsbookmarkalgorithms.cpp
       3                 :            :                          ---------------------
       4                 :            :     begin                : September 2019
       5                 :            :     copyright            : (C) 2019 by Nyall Dawson
       6                 :            :     email                : nyall dot dawson 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 "qgsbookmarkalgorithms.h"
      19                 :            : #include "qgsapplication.h"
      20                 :            : 
      21                 :            : ///@cond PRIVATE
      22                 :            : 
      23                 :            : //
      24                 :            : // QgsBookmarksToLayerAlgorithm
      25                 :            : //
      26                 :            : 
      27                 :          0 : void QgsBookmarksToLayerAlgorithm::initAlgorithm( const QVariantMap & )
      28                 :            : {
      29                 :          0 :   std::unique_ptr< QgsProcessingParameterEnum > sourceParam = std::make_unique<QgsProcessingParameterEnum >( QStringLiteral( "SOURCE" ), QObject::tr( "Bookmark source" ), QStringList() <<
      30                 :          0 :       QObject::tr( "Project bookmarks" ) << QObject::tr( "User bookmarks" ), true, QVariantList() << 0 << 1 );
      31                 :          0 :   QVariantMap wrapperMetadata;
      32                 :          0 :   wrapperMetadata.insert( QStringLiteral( "useCheckBoxes" ), true );
      33                 :          0 :   QVariantMap metadata;
      34                 :          0 :   metadata.insert( QStringLiteral( "widget_wrapper" ), wrapperMetadata );
      35                 :          0 :   sourceParam->setMetadata( metadata );
      36                 :          0 :   addParameter( sourceParam.release() );
      37                 :          0 :   addParameter( new QgsProcessingParameterCrs( QStringLiteral( "CRS" ), QObject::tr( "Output CRS" ), QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) ) ) );
      38                 :          0 :   addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Output" ), QgsProcessing::TypeVectorPolygon ) );
      39                 :          0 : }
      40                 :            : 
      41                 :          0 : QString QgsBookmarksToLayerAlgorithm::name() const
      42                 :            : {
      43                 :          0 :   return QStringLiteral( "bookmarkstolayer" );
      44                 :            : }
      45                 :            : 
      46                 :          0 : QString QgsBookmarksToLayerAlgorithm::displayName() const
      47                 :            : {
      48                 :          0 :   return QObject::tr( "Convert spatial bookmarks to layer" );
      49                 :            : }
      50                 :            : 
      51                 :          0 : QStringList QgsBookmarksToLayerAlgorithm::tags() const
      52                 :            : {
      53                 :          0 :   return QObject::tr( "save,extract" ).split( ',' );
      54                 :          0 : }
      55                 :            : 
      56                 :          0 : QString QgsBookmarksToLayerAlgorithm::group() const
      57                 :            : {
      58                 :          0 :   return QObject::tr( "Vector general" );
      59                 :            : }
      60                 :            : 
      61                 :          0 : QString QgsBookmarksToLayerAlgorithm::groupId() const
      62                 :            : {
      63                 :          0 :   return QStringLiteral( "vectorgeneral" );
      64                 :            : }
      65                 :            : 
      66                 :          0 : QString QgsBookmarksToLayerAlgorithm::shortHelpString() const
      67                 :            : {
      68                 :          0 :   return QObject::tr( "This algorithm creates a new layer containing polygon features for stored spatial bookmarks.\n\n"
      69                 :            :                       "The export can be filtered to only bookmarks belonging to the current project, to all user bookmarks, or a combination of both." );
      70                 :            : }
      71                 :            : 
      72                 :          0 : QString QgsBookmarksToLayerAlgorithm::shortDescription() const
      73                 :            : {
      74                 :          0 :   return QObject::tr( "Converts stored spatial bookmarks to a polygon layer." );
      75                 :            : }
      76                 :            : 
      77                 :          0 : QIcon QgsBookmarksToLayerAlgorithm::icon() const
      78                 :            : {
      79                 :          0 :   return QgsApplication::getThemeIcon( QStringLiteral( "mActionShowBookmarks.svg" ) );
      80                 :          0 : }
      81                 :            : 
      82                 :          0 : QString QgsBookmarksToLayerAlgorithm::svgIconPath() const
      83                 :            : {
      84                 :          0 :   return QgsApplication::iconPath( QStringLiteral( "mActionShowBookmarks.svg" ) );
      85                 :          0 : }
      86                 :            : 
      87                 :          0 : QgsBookmarksToLayerAlgorithm *QgsBookmarksToLayerAlgorithm::createInstance() const
      88                 :            : {
      89                 :          0 :   return new QgsBookmarksToLayerAlgorithm();
      90                 :            : }
      91                 :            : 
      92                 :          0 : bool QgsBookmarksToLayerAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
      93                 :            : {
      94                 :          0 :   QList< int > sources = parameterAsEnums( parameters, QStringLiteral( "SOURCE" ), context );
      95                 :          0 :   if ( sources.contains( 0 ) )
      96                 :            :   {
      97                 :          0 :     if ( !context.project() )
      98                 :          0 :       throw QgsProcessingException( QObject::tr( "No project is available for bookmark extraction" ) );
      99                 :          0 :     mBookmarks.append( context.project()->bookmarkManager()->bookmarks() );
     100                 :          0 :   }
     101                 :          0 :   if ( sources.contains( 1 ) )
     102                 :          0 :     mBookmarks.append( QgsApplication::bookmarkManager()->bookmarks() );
     103                 :            : 
     104                 :            :   return true;
     105                 :          0 : }
     106                 :            : 
     107                 :          0 : QVariantMap QgsBookmarksToLayerAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
     108                 :            : {
     109                 :          0 :   const QgsCoordinateReferenceSystem crs = parameterAsCrs( parameters, QStringLiteral( "CRS" ), context );
     110                 :          0 :   QgsFields fields;
     111                 :          0 :   fields.append( QgsField( QStringLiteral( "name" ), QVariant::String ) );
     112                 :          0 :   fields.append( QgsField( QStringLiteral( "group" ), QVariant::String ) );
     113                 :          0 :   QString dest;
     114                 :          0 :   std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, QgsWkbTypes::Polygon, crs ) );
     115                 :          0 :   if ( !sink )
     116                 :          0 :     throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
     117                 :            : 
     118                 :          0 :   int count = mBookmarks.count();
     119                 :          0 :   int current = 0;
     120                 :          0 :   double step = count > 0 ? 100.0 / count : 1;
     121                 :            : 
     122                 :          0 :   for ( const QgsBookmark &b : std::as_const( mBookmarks ) )
     123                 :            :   {
     124                 :          0 :     if ( feedback->isCanceled() )
     125                 :            :     {
     126                 :          0 :       break;
     127                 :            :     }
     128                 :            : 
     129                 :          0 :     QgsFeature feat;
     130                 :          0 :     feat.setAttributes( QgsAttributes() << b.name() << b.group() );
     131                 :            : 
     132                 :          0 :     QgsGeometry geom = QgsGeometry::fromRect( b.extent() );
     133                 :          0 :     if ( b.extent().crs() != crs )
     134                 :            :     {
     135                 :          0 :       QgsCoordinateTransform xform( b.extent().crs(), crs, context.transformContext() );
     136                 :          0 :       geom = geom.densifyByCount( 20 );
     137                 :            :       try
     138                 :            :       {
     139                 :          0 :         geom.transform( xform );
     140                 :          0 :       }
     141                 :            :       catch ( QgsCsException & )
     142                 :            :       {
     143                 :          0 :         feedback->reportError( QObject::tr( "Could not reproject bookmark %1 to destination CRS" ).arg( b.name() ) );
     144                 :          0 :         feedback->setProgress( current++ * step );
     145                 :            :         continue;
     146                 :          0 :       }
     147                 :          0 :     }
     148                 :            : 
     149                 :          0 :     feat.setGeometry( geom );
     150                 :            : 
     151                 :          0 :     sink->addFeature( feat, QgsFeatureSink::FastInsert );
     152                 :            : 
     153                 :          0 :     feedback->setProgress( current++ * step );
     154                 :          0 :   }
     155                 :            : 
     156                 :          0 :   QVariantMap outputs;
     157                 :          0 :   outputs.insert( QStringLiteral( "OUTPUT" ), dest );
     158                 :          0 :   return outputs;
     159                 :          0 : }
     160                 :            : 
     161                 :            : 
     162                 :            : //
     163                 :            : // QgsLayerToBookmarksAlgorithm
     164                 :            : //
     165                 :            : 
     166                 :          0 : void QgsLayerToBookmarksAlgorithm::initAlgorithm( const QVariantMap & )
     167                 :            : {
     168                 :          0 :   addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ), QList< int >() << QgsProcessing::TypeVectorLine << QgsProcessing::TypeVectorPolygon ) );
     169                 :            : 
     170                 :          0 :   std::unique_ptr< QgsProcessingParameterEnum > sourceParam = std::make_unique<QgsProcessingParameterEnum >( QStringLiteral( "DESTINATION" ), QObject::tr( "Bookmark destination" ), QStringList() <<
     171                 :          0 :       QObject::tr( "Project bookmarks" ) << QObject::tr( "User bookmarks" ), false, 0 );
     172                 :          0 :   addParameter( sourceParam.release() );
     173                 :            : 
     174                 :          0 :   addParameter( new QgsProcessingParameterExpression( QStringLiteral( "NAME_EXPRESSION" ), QObject::tr( "Name field" ), QVariant(), QStringLiteral( "INPUT" ) ) );
     175                 :          0 :   addParameter( new QgsProcessingParameterExpression( QStringLiteral( "GROUP_EXPRESSION" ), QObject::tr( "Group field" ), QVariant(), QStringLiteral( "INPUT" ), true ) );
     176                 :            : 
     177                 :          0 :   addOutput( new QgsProcessingOutputNumber( QStringLiteral( "COUNT" ), QObject::tr( "Count of bookmarks added" ) ) );
     178                 :          0 : }
     179                 :            : 
     180                 :          0 : QString QgsLayerToBookmarksAlgorithm::name() const
     181                 :            : {
     182                 :          0 :   return QStringLiteral( "layertobookmarks" );
     183                 :            : }
     184                 :            : 
     185                 :          0 : QString QgsLayerToBookmarksAlgorithm::displayName() const
     186                 :            : {
     187                 :          0 :   return QObject::tr( "Convert layer to spatial bookmarks" );
     188                 :            : }
     189                 :            : 
     190                 :          0 : QStringList QgsLayerToBookmarksAlgorithm::tags() const
     191                 :            : {
     192                 :          0 :   return QObject::tr( "save,extract,store" ).split( ',' );
     193                 :          0 : }
     194                 :            : 
     195                 :          0 : QString QgsLayerToBookmarksAlgorithm::group() const
     196                 :            : {
     197                 :          0 :   return QObject::tr( "Vector general" );
     198                 :            : }
     199                 :            : 
     200                 :          0 : QString QgsLayerToBookmarksAlgorithm::groupId() const
     201                 :            : {
     202                 :          0 :   return QStringLiteral( "vectorgeneral" );
     203                 :            : }
     204                 :            : 
     205                 :          0 : QString QgsLayerToBookmarksAlgorithm::shortHelpString() const
     206                 :            : {
     207                 :          0 :   return QObject::tr( "This algorithm creates spatial bookmarks corresponding to the extent of features contained in a layer." );
     208                 :            : }
     209                 :            : 
     210                 :          0 : QString QgsLayerToBookmarksAlgorithm::shortDescription() const
     211                 :            : {
     212                 :          0 :   return QObject::tr( "Converts feature extents to stored spatial bookmarks." );
     213                 :            : }
     214                 :            : 
     215                 :          0 : QIcon QgsLayerToBookmarksAlgorithm::icon() const
     216                 :            : {
     217                 :          0 :   return QgsApplication::getThemeIcon( QStringLiteral( "mActionShowBookmarks.svg" ) );
     218                 :          0 : }
     219                 :            : 
     220                 :          0 : QString QgsLayerToBookmarksAlgorithm::svgIconPath() const
     221                 :            : {
     222                 :          0 :   return QgsApplication::iconPath( QStringLiteral( "mActionShowBookmarks.svg" ) );
     223                 :          0 : }
     224                 :            : 
     225                 :          0 : QgsLayerToBookmarksAlgorithm *QgsLayerToBookmarksAlgorithm::createInstance() const
     226                 :            : {
     227                 :          0 :   return new QgsLayerToBookmarksAlgorithm();
     228                 :            : }
     229                 :            : 
     230                 :          0 : QVariantMap QgsLayerToBookmarksAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
     231                 :            : {
     232                 :          0 :   mDest = parameterAsEnum( parameters, QStringLiteral( "DESTINATION" ), context );
     233                 :          0 :   std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
     234                 :          0 :   if ( !source )
     235                 :          0 :     throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
     236                 :            : 
     237                 :            : 
     238                 :          0 :   QString nameExpressionString = parameterAsExpression( parameters, QStringLiteral( "NAME_EXPRESSION" ), context );
     239                 :          0 :   QString groupExpressionString = parameterAsExpression( parameters, QStringLiteral( "GROUP_EXPRESSION" ), context );
     240                 :            : 
     241                 :          0 :   QgsExpressionContext expressionContext = context.expressionContext();
     242                 :          0 :   expressionContext.appendScope( source->createExpressionContextScope() );
     243                 :            : 
     244                 :          0 :   QgsExpression nameExpression = QgsExpression( nameExpressionString );
     245                 :          0 :   if ( !nameExpression.prepare( &expressionContext ) )
     246                 :          0 :     throw QgsProcessingException( QObject::tr( "Invalid name expression: %1" ).arg( nameExpression.parserErrorString() ) );
     247                 :            : 
     248                 :          0 :   QSet< QString > requiredColumns = nameExpression.referencedColumns();
     249                 :            : 
     250                 :          0 :   std::unique_ptr< QgsExpression > groupExpression;
     251                 :          0 :   if ( !groupExpressionString.isEmpty() )
     252                 :            :   {
     253                 :          0 :     groupExpression = std::make_unique< QgsExpression >( groupExpressionString );
     254                 :          0 :     if ( !groupExpression->prepare( &expressionContext ) )
     255                 :          0 :       throw QgsProcessingException( QObject::tr( "Invalid group expression: %1" ).arg( groupExpression->parserErrorString() ) );
     256                 :          0 :     requiredColumns.unite( groupExpression->referencedColumns() );
     257                 :          0 :   }
     258                 :            : 
     259                 :          0 :   QgsFeatureRequest req;
     260                 :          0 :   req.setSubsetOfAttributes( requiredColumns, source->fields() );
     261                 :            : 
     262                 :          0 :   double step = source->featureCount() > 0 ? 100.0 / source->featureCount() : 1;
     263                 :          0 :   QgsFeatureIterator fi = source->getFeatures( req, QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks );
     264                 :          0 :   QgsFeature f;
     265                 :          0 :   int current = 0;
     266                 :          0 :   while ( fi.nextFeature( f ) )
     267                 :            :   {
     268                 :          0 :     if ( feedback->isCanceled() )
     269                 :            :     {
     270                 :          0 :       break;
     271                 :            :     }
     272                 :            : 
     273                 :          0 :     if ( f.hasGeometry() )
     274                 :            :     {
     275                 :          0 :       const QgsReferencedRectangle extent( f.geometry().boundingBox(), source->sourceCrs() );
     276                 :          0 :       expressionContext.setFeature( f );
     277                 :          0 :       const QString name = nameExpression.evaluate( &expressionContext ).toString();
     278                 :          0 :       if ( !nameExpression.evalErrorString().isEmpty() )
     279                 :            :       {
     280                 :          0 :         feedback->reportError( QObject::tr( "Error evaluating name expression: %1" ).arg( nameExpression.evalErrorString() ) );
     281                 :          0 :         feedback->setProgress( current * step );
     282                 :          0 :         current++;
     283                 :          0 :         continue;
     284                 :            :       }
     285                 :          0 :       QString group;
     286                 :          0 :       if ( groupExpression )
     287                 :            :       {
     288                 :          0 :         group = groupExpression->evaluate( &expressionContext ).toString();
     289                 :          0 :         if ( !groupExpression->evalErrorString().isEmpty() )
     290                 :            :         {
     291                 :          0 :           feedback->reportError( QObject::tr( "Error evaluating group expression: %1" ).arg( groupExpression->evalErrorString() ) );
     292                 :          0 :           feedback->setProgress( current * step );
     293                 :          0 :           current++;
     294                 :          0 :           continue;
     295                 :            :         }
     296                 :          0 :       }
     297                 :            : 
     298                 :          0 :       QgsBookmark b;
     299                 :          0 :       b.setName( name );
     300                 :          0 :       b.setGroup( group );
     301                 :          0 :       b.setExtent( extent );
     302                 :          0 :       mBookmarks << b;
     303                 :          0 :     }
     304                 :          0 :     feedback->setProgress( current * step );
     305                 :          0 :     current++;
     306                 :            :   }
     307                 :            : 
     308                 :          0 :   return QVariantMap();
     309                 :          0 : }
     310                 :            : 
     311                 :          0 : QVariantMap QgsLayerToBookmarksAlgorithm::postProcessAlgorithm( QgsProcessingContext &context, QgsProcessingFeedback * )
     312                 :            : {
     313                 :          0 :   QgsBookmarkManager *dest = nullptr;
     314                 :          0 :   switch ( mDest )
     315                 :            :   {
     316                 :            :     case 0:
     317                 :          0 :       dest = context.project()->bookmarkManager();
     318                 :          0 :       break;
     319                 :            : 
     320                 :            :     case 1:
     321                 :          0 :       dest = QgsApplication::bookmarkManager();
     322                 :          0 :       break;
     323                 :            :   }
     324                 :            : 
     325                 :          0 :   for ( const QgsBookmark &b : std::as_const( mBookmarks ) )
     326                 :          0 :     dest->addBookmark( b );
     327                 :            : 
     328                 :          0 :   QVariantMap res;
     329                 :          0 :   res.insert( QStringLiteral( "COUNT" ), mBookmarks.size() );
     330                 :          0 :   return res;
     331                 :          0 : }
     332                 :            : 
     333                 :            : ///@endcond
     334                 :            : 
     335                 :            : 
     336                 :            : 

Generated by: LCOV version 1.14