Skip to content

Commit 6a3cd82

Browse files
authoredMay 13, 2019
Merge pull request #9908 from raymondnijssen/roundextent
Round values in ExtentFromLayer processing algorithm
2 parents 84a9891 + 6e62c02 commit 6a3cd82

File tree

5 files changed

+163
-2
lines changed

5 files changed

+163
-2
lines changed
 

‎python/plugins/processing/algs/help/qgis.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ qgis:polygoncentroids: >
334334
NOTE: This algorithm is deprecated and the generic "centroids" algorithm (which works for line and multi geometry layers) should be used instead.
335335

336336
qgis:polygonfromlayerextent: >
337-
This algorithm takes a map layer and generates a new vector layer with the minimum bounding box (rectangle with N-S orientation) that covers the input layer.
337+
This algorithm takes a map layer and generates a new vector layer with the minimum bounding box (rectangle polygon with N-S orientation) that covers the input layer. Optionally, the extent can be enlarged to a rounded value.
338338

339339
qgis:polygonize: >
340340
This algorithm takes a lines layer and creates a polygon layer, with polygons generated from the lines in the input layer.

‎python/plugins/processing/algs/qgis/ExtentFromLayer.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
__revision__ = '$Format:%H$'
2727

2828
import os
29+
from math import floor, ceil
2930

3031
from qgis.PyQt.QtGui import QIcon
3132
from qgis.PyQt.QtCore import QVariant
@@ -39,6 +40,8 @@
3940
QgsProcessing,
4041
QgsProcessingException,
4142
QgsProcessingParameterMapLayer,
43+
QgsProcessingParameterDistance,
44+
QgsProcessingParameterDefinition,
4245
QgsProcessingParameterFeatureSink,
4346
QgsFields)
4447

@@ -51,6 +54,7 @@ class ExtentFromLayer(QgisAlgorithm):
5154

5255
INPUT = 'INPUT'
5356
BY_FEATURE = 'BY_FEATURE'
57+
ROUND_TO = 'ROUND_TO'
5458

5559
OUTPUT = 'OUTPUT'
5660

@@ -61,7 +65,7 @@ def svgIconPath(self):
6165
return QgsApplication.iconPath("/algorithms/mAlgorithmExtractLayerExtent.svg")
6266

6367
def tags(self):
64-
return self.tr('polygon,from,vector,raster,extent,envelope,bounds,bounding,boundary,layer').split(',')
68+
return self.tr('polygon,vector,raster,extent,envelope,bounds,bounding,boundary,layer,round,rounded').split(',')
6569

6670
def group(self):
6771
return self.tr('Layer tools')
@@ -74,6 +78,15 @@ def __init__(self):
7478

7579
def initAlgorithm(self, config=None):
7680
self.addParameter(QgsProcessingParameterMapLayer(self.INPUT, self.tr('Input layer')))
81+
82+
round_to_parameter = QgsProcessingParameterDistance(self.ROUND_TO,
83+
self.tr('Round values to'),
84+
parentParameterName=self.INPUT,
85+
minValue=0,
86+
defaultValue=0)
87+
round_to_parameter.setFlags(round_to_parameter.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
88+
self.addParameter(round_to_parameter)
89+
7790
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Extent'), type=QgsProcessing.TypeVectorPolygon))
7891

7992
def name(self):
@@ -85,6 +98,8 @@ def displayName(self):
8598
def processAlgorithm(self, parameters, context, feedback):
8699
layer = self.parameterAsLayer(parameters, self.INPUT, context)
87100

101+
round_to = self.parameterAsDouble(parameters, self.ROUND_TO, context)
102+
88103
fields = QgsFields()
89104
fields.append(QgsField('MINX', QVariant.Double))
90105
fields.append(QgsField('MINY', QVariant.Double))
@@ -109,7 +124,15 @@ def processAlgorithm(self, parameters, context, feedback):
109124
pass
110125

111126
rect = layer.extent()
127+
128+
if round_to > 0:
129+
rect.setXMinimum(floor(rect.xMinimum() / round_to) * round_to)
130+
rect.setYMinimum(floor(rect.yMinimum() / round_to) * round_to)
131+
rect.setXMaximum(ceil(rect.xMaximum() / round_to) * round_to)
132+
rect.setYMaximum(ceil(rect.yMaximum() / round_to) * round_to)
133+
112134
geometry = QgsGeometry.fromRect(rect)
135+
113136
minx = rect.xMinimum()
114137
miny = rect.yMinimum()
115138
maxx = rect.xMaximum()
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<ogr:FeatureCollection
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://ogr.maptools.org/ polygon_from_extent_rounded_2.xsd"
5+
xmlns:ogr="http://ogr.maptools.org/"
6+
xmlns:gml="http://www.opengis.net/gml">
7+
<gml:boundedBy>
8+
<gml:Box>
9+
<gml:coord><gml:X>-2</gml:X><gml:Y>-4</gml:Y></gml:coord>
10+
<gml:coord><gml:X>12</gml:X><gml:Y>6</gml:Y></gml:coord>
11+
</gml:Box>
12+
</gml:boundedBy>
13+
14+
<gml:featureMember>
15+
<ogr:polygon_from_extent_rounded_2 fid="polygon_from_extent_rounded_2.0">
16+
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-2,-4 12,-4 12,6 -2,6 -2,-4</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
17+
<ogr:MINX>-2</ogr:MINX>
18+
<ogr:MINY>-4</ogr:MINY>
19+
<ogr:MAXX>12</ogr:MAXX>
20+
<ogr:MAXY>6</ogr:MAXY>
21+
<ogr:CNTX>5</ogr:CNTX>
22+
<ogr:CNTY>1</ogr:CNTY>
23+
<ogr:AREA>140</ogr:AREA>
24+
<ogr:PERIM>48</ogr:PERIM>
25+
<ogr:HEIGHT>10</ogr:HEIGHT>
26+
<ogr:WIDTH>14</ogr:WIDTH>
27+
</ogr:polygon_from_extent_rounded_2>
28+
</gml:featureMember>
29+
</ogr:FeatureCollection>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0">
3+
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>
4+
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
5+
<xs:complexType name="FeatureCollectionType">
6+
<xs:complexContent>
7+
<xs:extension base="gml:AbstractFeatureCollectionType">
8+
<xs:attribute name="lockId" type="xs:string" use="optional"/>
9+
<xs:attribute name="scope" type="xs:string" use="optional"/>
10+
</xs:extension>
11+
</xs:complexContent>
12+
</xs:complexType>
13+
<xs:element name="polygon_from_extent_rounded_2" type="ogr:polygon_from_extent_rounded_2_Type" substitutionGroup="gml:_Feature"/>
14+
<xs:complexType name="polygon_from_extent_rounded_2_Type">
15+
<xs:complexContent>
16+
<xs:extension base="gml:AbstractFeatureType">
17+
<xs:sequence>
18+
<xs:element name="geometryProperty" type="gml:PolygonPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
19+
<xs:element name="MINX" nillable="true" minOccurs="0" maxOccurs="1">
20+
<xs:simpleType>
21+
<xs:restriction base="xs:decimal">
22+
</xs:restriction>
23+
</xs:simpleType>
24+
</xs:element>
25+
<xs:element name="MINY" nillable="true" minOccurs="0" maxOccurs="1">
26+
<xs:simpleType>
27+
<xs:restriction base="xs:decimal">
28+
</xs:restriction>
29+
</xs:simpleType>
30+
</xs:element>
31+
<xs:element name="MAXX" nillable="true" minOccurs="0" maxOccurs="1">
32+
<xs:simpleType>
33+
<xs:restriction base="xs:decimal">
34+
</xs:restriction>
35+
</xs:simpleType>
36+
</xs:element>
37+
<xs:element name="MAXY" nillable="true" minOccurs="0" maxOccurs="1">
38+
<xs:simpleType>
39+
<xs:restriction base="xs:decimal">
40+
</xs:restriction>
41+
</xs:simpleType>
42+
</xs:element>
43+
<xs:element name="CNTX" nillable="true" minOccurs="0" maxOccurs="1">
44+
<xs:simpleType>
45+
<xs:restriction base="xs:decimal">
46+
</xs:restriction>
47+
</xs:simpleType>
48+
</xs:element>
49+
<xs:element name="CNTY" nillable="true" minOccurs="0" maxOccurs="1">
50+
<xs:simpleType>
51+
<xs:restriction base="xs:decimal">
52+
</xs:restriction>
53+
</xs:simpleType>
54+
</xs:element>
55+
<xs:element name="AREA" nillable="true" minOccurs="0" maxOccurs="1">
56+
<xs:simpleType>
57+
<xs:restriction base="xs:decimal">
58+
</xs:restriction>
59+
</xs:simpleType>
60+
</xs:element>
61+
<xs:element name="PERIM" nillable="true" minOccurs="0" maxOccurs="1">
62+
<xs:simpleType>
63+
<xs:restriction base="xs:decimal">
64+
</xs:restriction>
65+
</xs:simpleType>
66+
</xs:element>
67+
<xs:element name="HEIGHT" nillable="true" minOccurs="0" maxOccurs="1">
68+
<xs:simpleType>
69+
<xs:restriction base="xs:decimal">
70+
</xs:restriction>
71+
</xs:simpleType>
72+
</xs:element>
73+
<xs:element name="WIDTH" nillable="true" minOccurs="0" maxOccurs="1">
74+
<xs:simpleType>
75+
<xs:restriction base="xs:decimal">
76+
</xs:restriction>
77+
</xs:simpleType>
78+
</xs:element>
79+
</xs:sequence>
80+
</xs:extension>
81+
</xs:complexContent>
82+
</xs:complexType>
83+
</xs:schema>

‎python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,4 +1801,30 @@ tests:
18011801
name: expected/multipoint_delaunay.gml
18021802
type: vector
18031803

1804+
- algorithm: qgis:polygonfromlayerextent
1805+
name: Polygon from layer extent rounded to 0
1806+
params:
1807+
BY_FEATURE: false
1808+
INPUT:
1809+
name: polys.gml
1810+
type: vector
1811+
ROUND_TO: 0.0
1812+
results:
1813+
OUTPUT:
1814+
name: expected/polygon_from_extent.gml
1815+
type: vector
1816+
1817+
- algorithm: qgis:polygonfromlayerextent
1818+
name: Polygon from layer extent rounded to 2
1819+
params:
1820+
BY_FEATURE: false
1821+
INPUT:
1822+
name: lines.gml
1823+
type: vector
1824+
ROUND_TO: 2.0
1825+
results:
1826+
OUTPUT:
1827+
name: expected/polygon_from_extent_rounded_2.gml
1828+
type: vector
1829+
18041830
# See ../README.md for a description of the file format

0 commit comments

Comments
 (0)
Please sign in to comment.