Skip to content
Permalink
Browse files

[FEATURE][processing] New algorithm to extend lines

Allows extending linestrings by a set distance at the start
and end of the line
  • Loading branch information
nyalldawson committed Oct 30, 2016
1 parent 2b54582 commit 8dab2cd4d75f4fdf6d10e0741557915e783722ca
@@ -158,6 +158,9 @@ qgis:exportaddgeometrycolumns: >

Depending on the geometry type of the vector layer, the attributes added to the table will be different.

qgis:extendlines: >
This algorithms extends line geometries by a specified amount at the start and end of the line. Lines are extended using the bearing of the first and last segment in the line.

qgis:extractbyattribute: >
This algorithms creates a new vector layer that only contains matching features from an input layer. The criteria for adding features to the resulting layer is defined based on the values of an attribute from the input layer.

@@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-

"""
***************************************************************************
ExtendLines.py
--------------------
Date : October 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__ = 'October 2016'
__copyright__ = '(C) 2016, Nyall Dawson'

# This will get replaced with a git SHA1 when you do a git archive323

__revision__ = '$Format:%H$'


from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.core.parameters import ParameterVector, ParameterNumber
from processing.core.outputs import OutputVector
from processing.tools import dataobjects, vector


class ExtendLines(GeoAlgorithm):

INPUT_LAYER = 'INPUT_LAYER'
OUTPUT_LAYER = 'OUTPUT_LAYER'
START_DISTANCE = 'START_DISTANCE'
END_DISTANCE = 'END_DISTANCE'

def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Extend lines')
self.group, self.i18n_group = self.trAlgorithm('Vector geometry tools')

self.addParameter(ParameterVector(self.INPUT_LAYER,
self.tr('Input layer'), [dataobjects.TYPE_VECTOR_LINE]))
self.addParameter(ParameterNumber(self.START_DISTANCE,
self.tr('Start distance'), default=0.0))
self.addParameter(ParameterNumber(self.END_DISTANCE,
self.tr('End distance'), default=0.0))

self.addOutput(OutputVector(self.OUTPUT_LAYER, self.tr('Extended lines')))

def processAlgorithm(self, progress):
layer = dataobjects.getObjectFromUri(
self.getParameterValue(self.INPUT_LAYER))

writer = self.getOutputFromName(
self.OUTPUT_LAYER).getVectorWriter(
layer.fields(),
layer.wkbType(),
layer.crs())

start_distance = self.getParameterValue(self.START_DISTANCE)
end_distance = self.getParameterValue(self.END_DISTANCE)

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.extendLine(start_distance, end_distance)
if not output_geometry:
raise GeoAlgorithmExecutionException(
self.tr('Error calculating extended line'))

output_feature.setGeometry(output_geometry)

writer.addFeature(output_feature)
progress.setPercentage(int(current * total))

del writer
@@ -171,6 +171,7 @@
from .TinInterpolationAttribute import TinInterpolationAttribute
from .ZonalStatisticsQgis import ZonalStatisticsQgis
from .RemoveNullGeometry import RemoveNullGeometry
from .ExtendLines import ExtendLines

pluginPath = os.path.normpath(os.path.join(
os.path.split(os.path.dirname(__file__))[0], os.pardir))
@@ -232,7 +233,7 @@ def __init__(self):
ReliefAuto(), ZonalStatisticsQgis(),
IdwInterpolationZValue(), IdwInterpolationAttribute(),
TinInterpolationZValue(), TinInterpolationAttribute(),
RemoveNullGeometry(), ExtractByExpression()
RemoveNullGeometry(), ExtractByExpression(), ExtendLines()
]

if hasMatplotlib:
@@ -0,0 +1,15 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>extend_lines</Name>
<ElementPath>extend_lines</ElementPath>
<GeometryType>2</GeometryType>
<SRSName>EPSG:4326</SRSName>
<DatasetSpecificInfo>
<FeatureCount>7</FeatureCount>
<ExtentXMin>-1.10000</ExtentXMin>
<ExtentXMax>11.14142</ExtentXMax>
<ExtentYMin>-3.07071</ExtentYMin>
<ExtentYMax>5.14142</ExtentYMax>
</DatasetSpecificInfo>
</GMLFeatureClass>
</GMLFeatureClassList>
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>-1.1</gml:X><gml:Y>-3.070710678118655</gml:Y></gml:coord>
<gml:coord><gml:X>11.14142135623731</gml:X><gml:Y>5.141421356237309</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:extend_lines fid="lines.0">
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>5.9,2.0 9,2 9,3 11.141421356237309,5.141421356237309</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:extend_lines>
</gml:featureMember>
<gml:featureMember>
<ogr:extend_lines fid="lines.1">
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>-1.1,-1.0 1.2,-1.0</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:extend_lines>
</gml:featureMember>
<gml:featureMember>
<ogr:extend_lines fid="lines.2">
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>2.0,-0.1 2,2 3,2 3.0,3.2</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:extend_lines>
</gml:featureMember>
<gml:featureMember>
<ogr:extend_lines fid="lines.3">
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>2.9,1.0 5.2,1.0</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:extend_lines>
</gml:featureMember>
<gml:featureMember>
<ogr:extend_lines fid="lines.4">
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>6.9,-3.0 10.2,-3.0</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:extend_lines>
</gml:featureMember>
<gml:featureMember>
<ogr:extend_lines fid="lines.5">
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>5.929289321881345,-3.070710678118655 10.141421356237309,1.141421356237309</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:extend_lines>
</gml:featureMember>
<gml:featureMember>
<ogr:extend_lines fid="lines.6">
</ogr:extend_lines>
</gml:featureMember>
</ogr:FeatureCollection>
@@ -0,0 +1,15 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>extend_multilines</Name>
<ElementPath>extend_multilines</ElementPath>
<GeometryType>5</GeometryType>
<SRSName>EPSG:4326</SRSName>
<DatasetSpecificInfo>
<FeatureCount>4</FeatureCount>
<ExtentXMin>-1.20000</ExtentXMin>
<ExtentXMax>5.98034</ExtentXMax>
<ExtentYMin>-1.00000</ExtentYMin>
<ExtentYMax>4.13130</ExtentYMax>
</DatasetSpecificInfo>
</GMLFeatureClass>
</GMLFeatureClassList>
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>-1.2</gml:X><gml:Y>-1</gml:Y></gml:coord>
<gml:coord><gml:X>5.980337387043503</gml:X><gml:Y>4.131303337656388</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:extend_multilines fid="lines.1">
<ogr:geometryProperty><gml:MultiLineString srsName="EPSG:4326"><gml:lineStringMember><gml:LineString><gml:coordinates>-1.2,-1.0 1.4,-1.0</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString></ogr:geometryProperty>
</ogr:extend_multilines>
</gml:featureMember>
<gml:featureMember>
<ogr:extend_multilines fid="lines.2">
<ogr:geometryProperty><gml:MultiLineString srsName="EPSG:4326"><gml:lineStringMember><gml:LineString><gml:coordinates>2.8,1.0 5.4,1.0</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>5.027602565068266,2.614750056493599 4.993163391936403,0.600058428279599</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString></ogr:geometryProperty>
</ogr:extend_multilines>
</gml:featureMember>
<gml:featureMember>
<ogr:extend_multilines fid="lines.3">
</ogr:extend_multilines>
</gml:featureMember>
<gml:featureMember>
<ogr:extend_multilines fid="lines.4">
<ogr:geometryProperty><gml:MultiLineString srsName="EPSG:4326"><gml:lineStringMember><gml:LineString><gml:coordinates>2.0,-0.2 2,2 3,2 3.0,3.4</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>2.744420970065991,4.041450058619024 5.859334643361299,4.131303337656388</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>2.800042438915868,3.004119922970864 5.980337387043503,2.938593167493973</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString></ogr:geometryProperty>
</ogr:extend_multilines>
</gml:featureMember>
</ogr:FeatureCollection>
@@ -1225,3 +1225,30 @@ tests:
OUTPUT:
name: expected/extract_expression.gml
type: vector

- algorithm: qgis:extendlines
name: Extend lines
params:
END_DISTANCE: 0.2
INPUT_LAYER:
name: lines.gml
type: vector
START_DISTANCE: 0.1
results:
OUTPUT_LAYER:
name: expected/extend_lines.gml
type: vector


- algorithm: qgis:extendlines
name: Extend multilines
params:
END_DISTANCE: 0.4
INPUT_LAYER:
name: multilines.gml
type: vector
START_DISTANCE: 0.2
results:
OUTPUT_LAYER:
name: expected/extend_multilines.gml
type: vector

0 comments on commit 8dab2cd

Please sign in to comment.
You can’t perform that action at this time.