-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FEATURE][processing] New algorithm for single sided buffers
- Loading branch information
1 parent
298d047
commit 989d986
Showing
10 changed files
with
351 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
118 changes: 118 additions & 0 deletions
118
python/plugins/processing/algs/qgis/SingleSidedBuffer.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
""" | ||
*************************************************************************** | ||
SingleSidedBuffer.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 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 SingleSidedBuffer(GeoAlgorithm): | ||
|
||
INPUT_LAYER = 'INPUT_LAYER' | ||
OUTPUT_LAYER = 'OUTPUT_LAYER' | ||
DISTANCE = 'DISTANCE' | ||
SIDE = 'SIDE' | ||
SEGMENTS = 'SEGMENTS' | ||
JOIN_STYLE = 'JOIN_STYLE' | ||
MITRE_LIMIT = 'MITRE_LIMIT' | ||
|
||
def defineCharacteristics(self): | ||
self.name, self.i18n_name = self.trAlgorithm('Single sided buffer') | ||
self.group, self.i18n_group = self.trAlgorithm('Vector geometry tools') | ||
|
||
self.addParameter(ParameterVector(self.INPUT_LAYER, | ||
self.tr('Input layer'), [ParameterVector.VECTOR_TYPE_LINE])) | ||
self.addParameter(ParameterNumber(self.DISTANCE, | ||
self.tr('Distance'), default=10.0)) | ||
self.sides = [self.tr('Left'), | ||
'Right'] | ||
self.addParameter(ParameterSelection( | ||
self.SIDE, | ||
self.tr('Side'), | ||
self.sides)) | ||
|
||
self.addParameter(ParameterNumber(self.SEGMENTS, | ||
self.tr('Segments'), 1, default=8)) | ||
|
||
self.join_styles = [self.tr('Round'), | ||
'Mitre', | ||
'Bevel'] | ||
self.addParameter(ParameterSelection( | ||
self.JOIN_STYLE, | ||
self.tr('Join style'), | ||
self.join_styles)) | ||
self.addParameter(ParameterNumber(self.MITRE_LIMIT, | ||
self.tr('Mitre limit'), 1, default=2)) | ||
|
||
self.addOutput(OutputVector(self.OUTPUT_LAYER, self.tr('Single sided buffers'))) | ||
|
||
def processAlgorithm(self, progress): | ||
layer = dataobjects.getObjectFromUri( | ||
self.getParameterValue(self.INPUT_LAYER)) | ||
|
||
writer = self.getOutputFromName( | ||
self.OUTPUT_LAYER).getVectorWriter( | ||
layer.fields().toList(), | ||
QgsWkbTypes.Polygon, | ||
layer.crs()) | ||
|
||
distance = self.getParameterValue(self.DISTANCE) | ||
segments = int(self.getParameterValue(self.SEGMENTS)) | ||
join_style = self.getParameterValue(self.JOIN_STYLE) + 1 | ||
if self.getParameterValue(self.SIDE) == 0: | ||
side = QgsGeometry.SideLeft | ||
else: | ||
side = QgsGeometry.SideRight | ||
miter_limit = self.getParameterValue(self.MITRE_LIMIT) | ||
|
||
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.singleSidedBuffer(distance, segments, | ||
side, join_style, miter_limit) | ||
if not output_geometry: | ||
raise GeoAlgorithmExecutionException( | ||
self.tr('Error calculating single sided buffer')) | ||
|
||
output_feature.setGeometry(output_geometry) | ||
|
||
writer.addFeature(output_feature) | ||
progress.setPercentage(int(current * total)) | ||
|
||
del writer |
15 changes: 15 additions & 0 deletions
15
python/plugins/processing/tests/testdata/expected/single_sided_buffer_line.gfs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<GMLFeatureClassList> | ||
<GMLFeatureClass> | ||
<Name>single_sided_buffer_line</Name> | ||
<ElementPath>single_sided_buffer_line</ElementPath> | ||
<GeometryType>3</GeometryType> | ||
<SRSName>EPSG:4326</SRSName> | ||
<DatasetSpecificInfo> | ||
<FeatureCount>7</FeatureCount> | ||
<ExtentXMin>-1.00000</ExtentXMin> | ||
<ExtentXMax>11.00000</ExtentXMax> | ||
<ExtentYMin>-3.00000</ExtentYMin> | ||
<ExtentYMax>5.70711</ExtentYMax> | ||
</DatasetSpecificInfo> | ||
</GMLFeatureClass> | ||
</GMLFeatureClassList> |
48 changes: 48 additions & 0 deletions
48
python/plugins/processing/tests/testdata/expected/single_sided_buffer_line.gml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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</gml:X><gml:Y>-3</gml:Y></gml:coord> | ||
<gml:coord><gml:X>11</gml:X><gml:Y>5.707106781186548</gml:Y></gml:coord> | ||
</gml:Box> | ||
</gml:boundedBy> | ||
|
||
<gml:featureMember> | ||
<ogr:single_sided_buffer_line fid="lines.0"> | ||
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>11,5 9,3 9,2 6,2 6,3 8,3 8.01921471959677,3.195090322016128 8.076120467488714,3.38268343236509 8.168530387697455,3.555570233019602 8.292893218813452,3.707106781186547 10.292893218813452,5.707106781186548 11,5</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty> | ||
</ogr:single_sided_buffer_line> | ||
</gml:featureMember> | ||
<gml:featureMember> | ||
<ogr:single_sided_buffer_line fid="lines.1"> | ||
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>1,-1 -1,-1 -1,0 1,0 1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty> | ||
</ogr:single_sided_buffer_line> | ||
</gml:featureMember> | ||
<gml:featureMember> | ||
<ogr:single_sided_buffer_line fid="lines.2"> | ||
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>3,3 3,2 2,2 2,0 1,0 1,2 1.01921471959677,2.195090322016128 1.076120467488713,2.38268343236509 1.168530387697455,2.555570233019602 1.292893218813453,2.707106781186547 1.444429766980398,2.831469612302545 1.61731656763491,2.923879532511287 1.804909677983872,2.98078528040323 2,3 3,3</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty> | ||
</ogr:single_sided_buffer_line> | ||
</gml:featureMember> | ||
<gml:featureMember> | ||
<ogr:single_sided_buffer_line fid="lines.3"> | ||
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>5,1 3,1 3,2 5,2 5,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty> | ||
</ogr:single_sided_buffer_line> | ||
</gml:featureMember> | ||
<gml:featureMember> | ||
<ogr:single_sided_buffer_line fid="lines.4"> | ||
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>10,-3 7,-3 7,-2 10,-2 10,-3</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty> | ||
</ogr:single_sided_buffer_line> | ||
</gml:featureMember> | ||
<gml:featureMember> | ||
<ogr:single_sided_buffer_line fid="lines.5"> | ||
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>10,1 6,-3 5.292893218813452,-2.292893218813453 9.292893218813452,1.707106781186547 10,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty> | ||
</ogr:single_sided_buffer_line> | ||
</gml:featureMember> | ||
<gml:featureMember> | ||
<ogr:single_sided_buffer_line fid="lines.6"> | ||
</ogr:single_sided_buffer_line> | ||
</gml:featureMember> | ||
</ogr:FeatureCollection> |
15 changes: 15 additions & 0 deletions
15
python/plugins/processing/tests/testdata/expected/single_sided_buffer_line_mitre.gfs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<GMLFeatureClassList> | ||
<GMLFeatureClass> | ||
<Name>single_sided_buffer_line_mitre</Name> | ||
<ElementPath>single_sided_buffer_line_mitre</ElementPath> | ||
<GeometryType>3</GeometryType> | ||
<SRSName>EPSG:4326</SRSName> | ||
<DatasetSpecificInfo> | ||
<FeatureCount>7</FeatureCount> | ||
<ExtentXMin>-1.00000</ExtentXMin> | ||
<ExtentXMax>11.70711</ExtentXMax> | ||
<ExtentYMin>-4.00000</ExtentYMin> | ||
<ExtentYMax>5.00000</ExtentYMax> | ||
</DatasetSpecificInfo> | ||
</GMLFeatureClass> | ||
</GMLFeatureClassList> |
48 changes: 48 additions & 0 deletions
48
python/plugins/processing/tests/testdata/expected/single_sided_buffer_line_mitre.gml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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</gml:X><gml:Y>-4</gml:Y></gml:coord> | ||
<gml:coord><gml:X>11.70710678118655</gml:X><gml:Y>5</gml:Y></gml:coord> | ||
</gml:Box> | ||
</gml:boundedBy> | ||
|
||
<gml:featureMember> | ||
<ogr:single_sided_buffer_line_mitre fid="lines.0"> | ||
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>6,2 9,2 9,3 11,5 11.707106781186548,4.292893218813452 10.0,2.585786437626905 10,1 6,1 6,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty> | ||
</ogr:single_sided_buffer_line_mitre> | ||
</gml:featureMember> | ||
<gml:featureMember> | ||
<ogr:single_sided_buffer_line_mitre fid="lines.1"> | ||
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-1,-1 1,-1 1,-2 -1,-2 -1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty> | ||
</ogr:single_sided_buffer_line_mitre> | ||
</gml:featureMember> | ||
<gml:featureMember> | ||
<ogr:single_sided_buffer_line_mitre fid="lines.2"> | ||
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2,0 2,2 3,2 3,3 4,3 4,1 3,1 3,0 2,0</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty> | ||
</ogr:single_sided_buffer_line_mitre> | ||
</gml:featureMember> | ||
<gml:featureMember> | ||
<ogr:single_sided_buffer_line_mitre fid="lines.3"> | ||
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>3,1 5,1 5,0 3,0 3,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty> | ||
</ogr:single_sided_buffer_line_mitre> | ||
</gml:featureMember> | ||
<gml:featureMember> | ||
<ogr:single_sided_buffer_line_mitre fid="lines.4"> | ||
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>7,-3 10,-3 10,-4 7,-4 7,-3</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty> | ||
</ogr:single_sided_buffer_line_mitre> | ||
</gml:featureMember> | ||
<gml:featureMember> | ||
<ogr:single_sided_buffer_line_mitre fid="lines.5"> | ||
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>6,-3 10,1 10.707106781186548,0.292893218813453 6.707106781186548,-3.707106781186547 6,-3</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty> | ||
</ogr:single_sided_buffer_line_mitre> | ||
</gml:featureMember> | ||
<gml:featureMember> | ||
<ogr:single_sided_buffer_line_mitre fid="lines.6"> | ||
</ogr:single_sided_buffer_line_mitre> | ||
</gml:featureMember> | ||
</ogr:FeatureCollection> |
14 changes: 14 additions & 0 deletions
14
python/plugins/processing/tests/testdata/expected/single_sided_buffer_multiline_bevel.gfs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<GMLFeatureClassList> | ||
<GMLFeatureClass> | ||
<Name>single_sided_buffer_multiline_bevel</Name> | ||
<ElementPath>single_sided_buffer_multiline_bevel</ElementPath> | ||
<SRSName>EPSG:4326</SRSName> | ||
<DatasetSpecificInfo> | ||
<FeatureCount>4</FeatureCount> | ||
<ExtentXMin>-1.00000</ExtentXMin> | ||
<ExtentXMax>6.02404</ExtentXMax> | ||
<ExtentYMin>-1.00000</ExtentYMin> | ||
<ExtentYMax>5.11935</ExtentYMax> | ||
</DatasetSpecificInfo> | ||
</GMLFeatureClass> | ||
</GMLFeatureClassList> |
33 changes: 33 additions & 0 deletions
33
python/plugins/processing/tests/testdata/expected/single_sided_buffer_multiline_bevel.gml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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</gml:X><gml:Y>-1</gml:Y></gml:coord> | ||
<gml:coord><gml:X>6.024038190337471</gml:X><gml:Y>5.119353882875417</gml:Y></gml:coord> | ||
</gml:Box> | ||
</gml:boundedBy> | ||
|
||
<gml:featureMember> | ||
<ogr:single_sided_buffer_multiline_bevel fid="lines.1"> | ||
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>1,-1 -1,-1 -1,0 1,0 1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty> | ||
</ogr:single_sided_buffer_multiline_bevel> | ||
</gml:featureMember> | ||
<gml:featureMember> | ||
<ogr:single_sided_buffer_multiline_bevel fid="lines.2"> | ||
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>5,1 3,1 3,2 5,2 5,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>5,1 5.024184261036468,2.414779270633399 6.024038190337471,2.397687750474408 5.999853929301003,0.982908479841009 5,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty> | ||
</ogr:single_sided_buffer_multiline_bevel> | ||
</gml:featureMember> | ||
<gml:featureMember> | ||
<ogr:single_sided_buffer_multiline_bevel fid="lines.3"> | ||
</ogr:single_sided_buffer_multiline_bevel> | ||
</gml:featureMember> | ||
<gml:featureMember> | ||
<ogr:single_sided_buffer_multiline_bevel fid="lines.4"> | ||
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>3,3 3,2 2,2 2,0 1,0 1,2 2,3 3,3</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>5.459500959692898,4.119769673704415 2.944337811900192,4.04721689059501 2.915503652020259,5.046801099766013 5.430666799812965,5.119353882875417 5.459500959692898,4.119769673704415</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>5.58042226487524,2.946833013435702 3,3 3.020599614854323,3.999787805420657 5.601021879729563,3.946620818856359 5.58042226487524,2.946833013435702</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty> | ||
</ogr:single_sided_buffer_multiline_bevel> | ||
</gml:featureMember> | ||
</ogr:FeatureCollection> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters