Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsalgorithmextractbyextent.cpp 3 : : --------------------- 4 : : begin : April 2017 5 : : copyright : (C) 2017 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 "qgsalgorithmextractbyextent.h" 19 : : 20 : : ///@cond PRIVATE 21 : : 22 : 0 : QString QgsExtractByExtentAlgorithm::name() const 23 : : { 24 : 0 : return QStringLiteral( "extractbyextent" ); 25 : : } 26 : : 27 : 0 : QString QgsExtractByExtentAlgorithm::displayName() const 28 : : { 29 : 0 : return QObject::tr( "Extract/clip by extent" ); 30 : : } 31 : : 32 : 0 : QStringList QgsExtractByExtentAlgorithm::tags() const 33 : : { 34 : 0 : return QObject::tr( "clip,extract,intersect,intersection,mask,extent" ).split( ',' ); 35 : 0 : } 36 : : 37 : 0 : QString QgsExtractByExtentAlgorithm::group() const 38 : : { 39 : 0 : return QObject::tr( "Vector overlay" ); 40 : : } 41 : : 42 : 0 : QString QgsExtractByExtentAlgorithm::groupId() const 43 : : { 44 : 0 : return QStringLiteral( "vectoroverlay" ); 45 : : } 46 : 0 : void QgsExtractByExtentAlgorithm::initAlgorithm( const QVariantMap & ) 47 : : { 48 : 0 : addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) ); 49 : 0 : addParameter( new QgsProcessingParameterExtent( QStringLiteral( "EXTENT" ), QObject::tr( "Extent" ) ) ); 50 : 0 : addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "CLIP" ), QObject::tr( "Clip features to extent" ), false ) ); 51 : 0 : addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Extracted" ) ) ); 52 : 0 : } 53 : : 54 : 0 : QString QgsExtractByExtentAlgorithm::shortHelpString() const 55 : : { 56 : 0 : return QObject::tr( "This algorithm creates a new vector layer that only contains features which fall within a specified extent. " 57 : : "Any features which intersect the extent will be included.\n\n" 58 : : "Optionally, feature geometries can also be clipped to the extent. If this option is selected, then the output " 59 : : "geometries will automatically be converted to multi geometries to ensure uniform output geometry types." ); 60 : : } 61 : : 62 : 0 : QgsExtractByExtentAlgorithm *QgsExtractByExtentAlgorithm::createInstance() const 63 : : { 64 : 0 : return new QgsExtractByExtentAlgorithm(); 65 : : } 66 : : 67 : 0 : QVariantMap QgsExtractByExtentAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) 68 : : { 69 : 0 : std::unique_ptr< QgsFeatureSource > featureSource( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) ); 70 : 0 : if ( !featureSource ) 71 : 0 : throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) ); 72 : : 73 : 0 : if ( featureSource->hasSpatialIndex() == QgsFeatureSource::SpatialIndexNotPresent ) 74 : 0 : feedback->pushWarning( QObject::tr( "No spatial index exists for input layer, performance will be severely degraded" ) ); 75 : : 76 : 0 : QgsRectangle extent = parameterAsExtent( parameters, QStringLiteral( "EXTENT" ), context, featureSource->sourceCrs() ); 77 : 0 : bool clip = parameterAsBoolean( parameters, QStringLiteral( "CLIP" ), context ); 78 : : 79 : : // if clipping, we force multi output 80 : 0 : QgsWkbTypes::Type outType = clip ? QgsWkbTypes::multiType( featureSource->wkbType() ) : featureSource->wkbType(); 81 : : 82 : 0 : QString dest; 83 : 0 : std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, featureSource->fields(), outType, featureSource->sourceCrs() ) ); 84 : : 85 : 0 : if ( !sink ) 86 : 0 : throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) ); 87 : : 88 : 0 : QgsGeometry clipGeom = parameterAsExtentGeometry( parameters, QStringLiteral( "EXTENT" ), context, featureSource->sourceCrs() ); 89 : : 90 : 0 : double step = featureSource->featureCount() > 0 ? 100.0 / featureSource->featureCount() : 1; 91 : 0 : QgsFeatureIterator inputIt = featureSource->getFeatures( QgsFeatureRequest().setFilterRect( extent ).setFlags( QgsFeatureRequest::ExactIntersect ) ); 92 : 0 : QgsFeature f; 93 : 0 : int i = -1; 94 : 0 : while ( inputIt.nextFeature( f ) ) 95 : : { 96 : 0 : i++; 97 : 0 : if ( feedback->isCanceled() ) 98 : : { 99 : 0 : break; 100 : : } 101 : : 102 : 0 : if ( clip ) 103 : : { 104 : 0 : QgsGeometry g = f.geometry().intersection( clipGeom ); 105 : 0 : g.convertToMultiType(); 106 : 0 : f.setGeometry( g ); 107 : 0 : } 108 : : 109 : 0 : sink->addFeature( f, QgsFeatureSink::FastInsert ); 110 : 0 : feedback->setProgress( i * step ); 111 : : } 112 : : 113 : 0 : QVariantMap outputs; 114 : 0 : outputs.insert( QStringLiteral( "OUTPUT" ), dest ); 115 : 0 : return outputs; 116 : 0 : } 117 : : 118 : : ///@endcond 119 : :