diff --git a/python/plugins/processing/algs/help/qgis.yaml b/python/plugins/processing/algs/help/qgis.yaml index 3a3c2c2af5b..f325ebe7279 100644 --- a/python/plugins/processing/algs/help/qgis.yaml +++ b/python/plugins/processing/algs/help/qgis.yaml @@ -452,6 +452,9 @@ qgis:symmetricaldifference: > qgis:texttofloat: > This algorithm modifies the type of a given attribute in a vector layer, converting a text attribute containing numeric strings into a numeric attribute. +qgis:translate: > + This algorithm moves the geometries within a layer, by offsetting them with a specified x and y displacement. + qgis:union: > This algorithm creates a layer containing all the features from both input layers. In the case of polygon layers, separate features are created for overlapping and non-overlapping features. The attribute table of the union layer contains attribute values from the respective input layer for non-overlapping features, and attribute values from both input layers for overlapping features. diff --git a/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py b/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py index 65eead8cf72..a4e88ad1f1e 100644 --- a/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py +++ b/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py @@ -152,6 +152,7 @@ from .Boundary import Boundary from .PointOnSurface import PointOnSurface from .OffsetLine import OffsetLine from .PolygonCentroids import PolygonCentroids +from .Translate import Translate pluginPath = os.path.normpath(os.path.join( os.path.split(os.path.dirname(__file__))[0], os.pardir)) @@ -205,7 +206,8 @@ class QGISAlgorithmProvider(AlgorithmProvider): RectanglesOvalsDiamondsVariable(), RectanglesOvalsDiamondsFixed(), MergeLines(), BoundingBox(), Boundary(), PointOnSurface(), - OffsetLine(), PolygonCentroids() + OffsetLine(), PolygonCentroids(), + Translate() ] if hasMatplotlib: diff --git a/python/plugins/processing/algs/qgis/Translate.py b/python/plugins/processing/algs/qgis/Translate.py new file mode 100644 index 00000000000..24061c18391 --- /dev/null +++ b/python/plugins/processing/algs/qgis/Translate.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- + +""" +*************************************************************************** + Translate.py + -------------- + Date : August 2016 + Copyright : (C) 2016 by Nyall Dawson + Email : nyall dot dawson at gmail dot com +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +*************************************************************************** +""" + +__author__ = 'Nyall Dawson' +__date__ = 'August 2016' +__copyright__ = '(C) 2016, Nyall Dawson' + +# This will get replaced with a git SHA1 when you do a git archive323 + +__revision__ = '$Format:%H$' + +import os + +from qgis.core import QgsGeometry, QgsWkbTypes + +from qgis.PyQt.QtGui import QIcon + +from processing.core.GeoAlgorithm import GeoAlgorithm +from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException +from processing.core.parameters import ParameterVector, ParameterSelection, ParameterNumber +from processing.core.outputs import OutputVector +from processing.tools import dataobjects, vector + +pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0] + + +class Translate(GeoAlgorithm): + + INPUT_LAYER = 'INPUT_LAYER' + OUTPUT_LAYER = 'OUTPUT_LAYER' + DELTA_X = 'DELTA_X' + DELTA_Y = 'DELTA_Y' + + def defineCharacteristics(self): + self.name, self.i18n_name = self.trAlgorithm('Translate geometry') + self.group, self.i18n_group = self.trAlgorithm('Vector geometry tools') + + self.addParameter(ParameterVector(self.INPUT_LAYER, + self.tr('Input layer'), [ParameterVector.VECTOR_TYPE_ANY])) + self.addParameter(ParameterNumber(self.DELTA_X, + self.tr('Offset distance (x-axis)'), default=1.0)) + self.addParameter(ParameterNumber(self.DELTA_Y, + self.tr('Offset distance (y-axis)'), default=0.0)) + + self.addOutput(OutputVector(self.OUTPUT_LAYER, self.tr('Translated'))) + + def processAlgorithm(self, progress): + layer = dataobjects.getObjectFromUri( + self.getParameterValue(self.INPUT_LAYER)) + + writer = self.getOutputFromName( + self.OUTPUT_LAYER).getVectorWriter( + layer.fields().toList(), + layer.wkbType(), + layer.crs()) + + delta_x = self.getParameterValue(self.DELTA_X) + delta_y = self.getParameterValue(self.DELTA_Y) + + features = vector.features(layer) + total = 100.0 / len(features) + + for current, input_feature in enumerate(features): + output_feature = input_feature + input_geometry = input_feature.geometry() + if input_geometry: + output_geometry = input_geometry + output_geometry.translate(delta_x, delta_y) + if not output_geometry: + raise GeoAlgorithmExecutionException( + self.tr('Error translating geometry')) + + output_feature.setGeometry(output_geometry) + + writer.addFeature(output_feature) + progress.setPercentage(int(current * total)) + + del writer diff --git a/python/plugins/processing/tests/testdata/expected/lines_translated.gfs b/python/plugins/processing/tests/testdata/expected/lines_translated.gfs new file mode 100644 index 00000000000..6c3acc3b896 --- /dev/null +++ b/python/plugins/processing/tests/testdata/expected/lines_translated.gfs @@ -0,0 +1,15 @@ + + + lines_translated + lines_translated + 2 + EPSG:4326 + + 7 + -0.90000 + 11.10000 + -3.20000 + 4.80000 + + + diff --git a/python/plugins/processing/tests/testdata/expected/lines_translated.gml b/python/plugins/processing/tests/testdata/expected/lines_translated.gml new file mode 100644 index 00000000000..23ccb44cb11 --- /dev/null +++ b/python/plugins/processing/tests/testdata/expected/lines_translated.gml @@ -0,0 +1,48 @@ + + + + + -0.9-3.2 + 11.14.8 + + + + + + 6.1,1.8 9.1,1.8 9.1,2.8 11.1,4.8 + + + + + -0.9,-1.2 1.1,-1.2 + + + + + 2.1,-0.2 2.1,1.8 3.1,1.8 3.1,2.8 + + + + + 3.1,0.8 5.1,0.8 + + + + + 7.1,-3.2 10.1,-3.2 + + + + + 6.1,-3.2 10.1,0.8 + + + + + + + diff --git a/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml b/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml index 3b9f937248c..95c67b00a21 100644 --- a/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml +++ b/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml @@ -809,3 +809,15 @@ tests: name: expected/centroid_polys.gml type: vector + - algorithm: qgis:translategeometry + name: Lines translated + params: + DELTA_X: 0.1 + DELTA_Y: -0.2 + INPUT_LAYER: + name: lines.gml + type: vector + results: + OUTPUT_LAYER: + name: expected/lines_translated.gml + type: vector