Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsalgorithmtranslate.cpp 3 : : --------------------- 4 : : begin : November 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 "qgsalgorithmtranslate.h" 19 : : #include "qgsvectorlayer.h" 20 : : 21 : : ///@cond PRIVATE 22 : : 23 : 0 : QString QgsTranslateAlgorithm::name() const 24 : : { 25 : 0 : return QStringLiteral( "translategeometry" ); 26 : : } 27 : : 28 : 0 : QString QgsTranslateAlgorithm::displayName() const 29 : : { 30 : 0 : return QObject::tr( "Translate" ); 31 : : } 32 : : 33 : 0 : QStringList QgsTranslateAlgorithm::tags() const 34 : : { 35 : 0 : return QObject::tr( "move,shift,transform,z,m,values,add" ).split( ',' ); 36 : 0 : } 37 : : 38 : 0 : QString QgsTranslateAlgorithm::group() const 39 : : { 40 : 0 : return QObject::tr( "Vector geometry" ); 41 : : } 42 : : 43 : 0 : QString QgsTranslateAlgorithm::groupId() const 44 : : { 45 : 0 : return QStringLiteral( "vectorgeometry" ); 46 : : } 47 : : 48 : 0 : QString QgsTranslateAlgorithm::outputName() const 49 : : { 50 : 0 : return QObject::tr( "Translated" ); 51 : : } 52 : : 53 : 0 : QString QgsTranslateAlgorithm::shortHelpString() const 54 : : { 55 : 0 : return QObject::tr( "This algorithm moves the geometries within a layer, by offsetting them with a specified x and y displacement." ) 56 : 0 : + QStringLiteral( "\n\n" ) 57 : 0 : + QObject::tr( "Z and M values present in the geometry can also be translated." ); 58 : 0 : } 59 : : 60 : 0 : QgsTranslateAlgorithm *QgsTranslateAlgorithm::createInstance() const 61 : : { 62 : 0 : return new QgsTranslateAlgorithm(); 63 : 0 : } 64 : : 65 : 0 : void QgsTranslateAlgorithm::initParameters( const QVariantMap & ) 66 : : { 67 : 0 : std::unique_ptr< QgsProcessingParameterDistance > xOffset = std::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "DELTA_X" ), 68 : 0 : QObject::tr( "Offset distance (x-axis)" ), 69 : 0 : 0.0, QStringLiteral( "INPUT" ) ); 70 : 0 : xOffset->setIsDynamic( true ); 71 : 0 : xOffset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "DELTA_X" ), QObject::tr( "Offset distance (x-axis)" ), QgsPropertyDefinition::Double ) ); 72 : 0 : xOffset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) ); 73 : 0 : addParameter( xOffset.release() ); 74 : : 75 : 0 : std::unique_ptr< QgsProcessingParameterDistance > yOffset = std::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "DELTA_Y" ), 76 : 0 : QObject::tr( "Offset distance (y-axis)" ), 77 : 0 : 0.0, QStringLiteral( "INPUT" ) ); 78 : 0 : yOffset->setIsDynamic( true ); 79 : 0 : yOffset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "DELTA_Y" ), QObject::tr( "Offset distance (y-axis)" ), QgsPropertyDefinition::Double ) ); 80 : 0 : yOffset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) ); 81 : 0 : addParameter( yOffset.release() ); 82 : : 83 : 0 : std::unique_ptr< QgsProcessingParameterNumber > zOffset = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "DELTA_Z" ), 84 : 0 : QObject::tr( "Offset distance (z-axis)" ), QgsProcessingParameterNumber::Double, 85 : 0 : 0.0 ); 86 : 0 : zOffset->setIsDynamic( true ); 87 : 0 : zOffset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "DELTA_Z" ), QObject::tr( "Offset distance (z-axis)" ), QgsPropertyDefinition::Double ) ); 88 : 0 : zOffset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) ); 89 : 0 : addParameter( zOffset.release() ); 90 : : 91 : 0 : std::unique_ptr< QgsProcessingParameterNumber > mOffset = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "DELTA_M" ), 92 : 0 : QObject::tr( "Offset distance (m values)" ), QgsProcessingParameterNumber::Double, 93 : 0 : 0.0 ); 94 : 0 : mOffset->setIsDynamic( true ); 95 : 0 : mOffset->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "DELTA_M" ), QObject::tr( "Offset distance (m values)" ), QgsPropertyDefinition::Double ) ); 96 : 0 : mOffset->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) ); 97 : 0 : addParameter( mOffset.release() ); 98 : 0 : } 99 : : 100 : 0 : bool QgsTranslateAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) 101 : : { 102 : 0 : mDeltaX = parameterAsDouble( parameters, QStringLiteral( "DELTA_X" ), context ); 103 : 0 : mDynamicDeltaX = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "DELTA_X" ) ); 104 : 0 : if ( mDynamicDeltaX ) 105 : 0 : mDeltaXProperty = parameters.value( QStringLiteral( "DELTA_X" ) ).value< QgsProperty >(); 106 : : 107 : 0 : mDeltaY = parameterAsDouble( parameters, QStringLiteral( "DELTA_Y" ), context ); 108 : 0 : mDynamicDeltaY = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "DELTA_Y" ) ); 109 : 0 : if ( mDynamicDeltaY ) 110 : 0 : mDeltaYProperty = parameters.value( QStringLiteral( "DELTA_Y" ) ).value< QgsProperty >(); 111 : : 112 : 0 : mDeltaZ = parameterAsDouble( parameters, QStringLiteral( "DELTA_Z" ), context ); 113 : 0 : mDynamicDeltaZ = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "DELTA_Z" ) ); 114 : 0 : if ( mDynamicDeltaZ ) 115 : 0 : mDeltaZProperty = parameters.value( QStringLiteral( "DELTA_Z" ) ).value< QgsProperty >(); 116 : : 117 : 0 : mDeltaM = parameterAsDouble( parameters, QStringLiteral( "DELTA_M" ), context ); 118 : 0 : mDynamicDeltaM = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "DELTA_M" ) ); 119 : 0 : if ( mDynamicDeltaM ) 120 : 0 : mDeltaMProperty = parameters.value( QStringLiteral( "DELTA_M" ) ).value< QgsProperty >(); 121 : : 122 : 0 : return true; 123 : 0 : } 124 : : 125 : 0 : QgsFeatureList QgsTranslateAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * ) 126 : : { 127 : 0 : QgsFeature f = feature; 128 : 0 : if ( f.hasGeometry() ) 129 : : { 130 : 0 : QgsGeometry geometry = f.geometry(); 131 : : 132 : 0 : double deltaX = mDeltaX; 133 : 0 : if ( mDynamicDeltaX ) 134 : 0 : deltaX = mDeltaXProperty.valueAsDouble( context.expressionContext(), deltaX ); 135 : 0 : double deltaY = mDeltaY; 136 : 0 : if ( mDynamicDeltaY ) 137 : 0 : deltaY = mDeltaYProperty.valueAsDouble( context.expressionContext(), deltaY ); 138 : 0 : double deltaZ = mDeltaZ; 139 : 0 : if ( mDynamicDeltaZ ) 140 : 0 : deltaZ = mDeltaZProperty.valueAsDouble( context.expressionContext(), deltaZ ); 141 : 0 : double deltaM = mDeltaM; 142 : 0 : if ( mDynamicDeltaM ) 143 : 0 : deltaM = mDeltaMProperty.valueAsDouble( context.expressionContext(), deltaM ); 144 : : 145 : 0 : if ( deltaZ != 0.0 && !geometry.constGet()->is3D() ) 146 : 0 : geometry.get()->addZValue( 0 ); 147 : 0 : if ( deltaM != 0.0 && !geometry.constGet()->isMeasure() ) 148 : 0 : geometry.get()->addMValue( 0 ); 149 : : 150 : 0 : geometry.translate( deltaX, deltaY, deltaZ, deltaM ); 151 : 0 : f.setGeometry( geometry ); 152 : 0 : } 153 : 0 : return QgsFeatureList() << f; 154 : 0 : } 155 : : 156 : 0 : QgsWkbTypes::Type QgsTranslateAlgorithm::outputWkbType( QgsWkbTypes::Type inputWkbType ) const 157 : : { 158 : 0 : QgsWkbTypes::Type wkb = inputWkbType; 159 : 0 : if ( mDeltaZ != 0.0 ) 160 : 0 : wkb = QgsWkbTypes::addZ( wkb ); 161 : 0 : if ( mDeltaM != 0.0 ) 162 : 0 : wkb = QgsWkbTypes::addM( wkb ); 163 : 0 : return wkb; 164 : : } 165 : : 166 : : 167 : 0 : bool QgsTranslateAlgorithm::supportInPlaceEdit( const QgsMapLayer *l ) const 168 : : { 169 : 0 : const QgsVectorLayer *layer = qobject_cast< const QgsVectorLayer * >( l ); 170 : 0 : if ( !layer ) 171 : 0 : return false; 172 : : 173 : 0 : if ( ! QgsProcessingFeatureBasedAlgorithm::supportInPlaceEdit( layer ) ) 174 : 0 : return false; 175 : : 176 : : // Check if we can drop Z/M and still have some work done 177 : 0 : if ( mDeltaX != 0.0 || mDeltaY != 0.0 ) 178 : 0 : return true; 179 : : 180 : : // If the type differs there is no sense in executing the algorithm and drop the result 181 : 0 : QgsWkbTypes::Type inPlaceWkbType = layer->wkbType(); 182 : 0 : return inPlaceWkbType == outputWkbType( inPlaceWkbType ); 183 : 0 : } 184 : : ///@endcond 185 : : 186 : :