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