mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Resurrect grid polygon algorithm
This commit is contained in:
parent
d8260b8c47
commit
ea18e8e9db
@ -37,15 +37,17 @@ from qgis.core import (QgsRectangle,
|
||||
QgsGeometry,
|
||||
QgsPointXY,
|
||||
QgsWkbTypes,
|
||||
QgsProcessingParameterEnum,
|
||||
QgsProcessingParameterExtent,
|
||||
QgsProcessingParameterNumber,
|
||||
QgsProcessingParameterCrs,
|
||||
QgsProcessingParameterFeatureSink,
|
||||
QgsProcessingOutputVectorLayer,
|
||||
QgsProcessingParameterDefinition,
|
||||
QgsFields)
|
||||
|
||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
||||
from processing.core.parameters import ParameterExtent
|
||||
from processing.core.parameters import ParameterNumber
|
||||
from processing.core.parameters import ParameterSelection
|
||||
from processing.core.parameters import ParameterCrs
|
||||
from processing.core.outputs import OutputVector
|
||||
from processing.tools import dataobjects
|
||||
|
||||
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||
@ -76,21 +78,28 @@ class GridPolygon(QgisAlgorithm):
|
||||
self.tr('Diamond (polygon)'),
|
||||
self.tr('Hexagon (polygon)')]
|
||||
|
||||
self.addParameter(ParameterSelection(self.TYPE,
|
||||
self.tr('Grid type'), self.types))
|
||||
self.addParameter(ParameterExtent(self.EXTENT,
|
||||
self.tr('Grid extent'), optional=False))
|
||||
self.addParameter(ParameterNumber(self.HSPACING,
|
||||
self.tr('Horizontal spacing'), 0.0, 1000000000.0, 0.0001))
|
||||
self.addParameter(ParameterNumber(self.VSPACING,
|
||||
self.tr('Vertical spacing'), 0.0, 1000000000.0, 0.0001))
|
||||
self.addParameter(ParameterNumber(self.HOVERLAY,
|
||||
self.tr('Horizontal overlay'), 0.0, 1000000000.0, 0.0))
|
||||
self.addParameter(ParameterNumber(self.VOVERLAY,
|
||||
self.tr('Vertical overlay'), 0.0, 1000000000.0, 0.0))
|
||||
self.addParameter(ParameterCrs(self.CRS, 'Grid CRS', 'EPSG:4326'))
|
||||
self.addParameter(QgsProcessingParameterEnum(self.TYPE,
|
||||
self.tr('Grid type'), self.types))
|
||||
|
||||
self.addOutput(OutputVector(self.OUTPUT, self.tr('Grid'), datatype=[dataobjects.TYPE_VECTOR_POLYGON]))
|
||||
self.addParameter(QgsProcessingParameterExtent(self.EXTENT, self.tr('Grid extent')))
|
||||
|
||||
self.addParameter(QgsProcessingParameterNumber(self.HSPACING,
|
||||
self.tr('Horizontal spacing'), QgsProcessingParameterNumber.Double,
|
||||
0.0001, False, 0, 1000000000.0))
|
||||
self.addParameter(QgsProcessingParameterNumber(self.VSPACING,
|
||||
self.tr('Vertical spacing'), QgsProcessingParameterNumber.Double,
|
||||
0.0001, False, 0, 1000000000.0))
|
||||
self.addParameter(QgsProcessingParameterNumber(self.HOVERLAY,
|
||||
self.tr('Horizontal overlay'), QgsProcessingParameterNumber.Double,
|
||||
0.0, False, 0, 1000000000.0))
|
||||
self.addParameter(QgsProcessingParameterNumber(self.VOVERLAY,
|
||||
self.tr('Vertical overlay'), QgsProcessingParameterNumber.Double,
|
||||
0.0, False, 0, 1000000000.0))
|
||||
|
||||
self.addParameter(QgsProcessingParameterCrs(self.CRS, 'Grid CRS', 'ProjectCrs'))
|
||||
|
||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Grid')))
|
||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Grid'), QgsProcessingParameterDefinition.TypeVectorPolygon))
|
||||
|
||||
def name(self):
|
||||
return 'creategridpolygon'
|
||||
@ -99,16 +108,15 @@ class GridPolygon(QgisAlgorithm):
|
||||
return self.tr('Create grid (polygon)')
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
idx = self.getParameterValue(self.TYPE)
|
||||
extent = self.getParameterValue(self.EXTENT).split(',')
|
||||
hSpacing = self.getParameterValue(self.HSPACING)
|
||||
vSpacing = self.getParameterValue(self.VSPACING)
|
||||
hOverlay = self.getParameterValue(self.HOVERLAY)
|
||||
vOverlay = self.getParameterValue(self.VOVERLAY)
|
||||
crs = QgsCoordinateReferenceSystem(self.getParameterValue(self.CRS))
|
||||
idx = self.parameterAsEnum(parameters, self.TYPE, context)
|
||||
|
||||
bbox = QgsRectangle(float(extent[0]), float(extent[2]),
|
||||
float(extent[1]), float(extent[3]))
|
||||
hSpacing = self.parameterAsDouble(parameters, self.HSPACING, context)
|
||||
vSpacing = self.parameterAsDouble(parameters, self.VSPACING, context)
|
||||
hOverlay = self.parameterAsDouble(parameters, self.HOVERLAY, context)
|
||||
vOverlay = self.parameterAsDouble(parameters, self.VOVERLAY, context)
|
||||
|
||||
bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
|
||||
crs = self.parameterAsCrs(parameters, self.CRS, context)
|
||||
|
||||
width = bbox.width()
|
||||
height = bbox.height()
|
||||
@ -138,21 +146,22 @@ class GridPolygon(QgisAlgorithm):
|
||||
fields.append(QgsField('bottom', QVariant.Double, '', 24, 16))
|
||||
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
|
||||
|
||||
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Polygon, crs, context)
|
||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||
fields, QgsWkbTypes.Polygon, crs)
|
||||
|
||||
if idx == 0:
|
||||
self._rectangleGrid(
|
||||
writer, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
||||
sink, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
||||
elif idx == 1:
|
||||
self._diamondGrid(
|
||||
writer, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
||||
sink, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
||||
elif idx == 2:
|
||||
self._hexagonGrid(
|
||||
writer, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
||||
sink, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
||||
|
||||
del writer
|
||||
return {self.OUTPUT: dest_id}
|
||||
|
||||
def _rectangleGrid(self, writer, width, height, originX, originY,
|
||||
def _rectangleGrid(self, sink, width, height, originX, originY,
|
||||
hSpacing, vSpacing, hOverlay, vOverlay, feedback):
|
||||
ft = QgsFeature()
|
||||
|
||||
@ -166,6 +175,9 @@ class GridPolygon(QgisAlgorithm):
|
||||
count = 0
|
||||
|
||||
for col in range(columns):
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
x1 = originX + (col * hSpacing - col * hOverlay)
|
||||
x2 = x1 + hSpacing
|
||||
|
||||
@ -182,14 +194,14 @@ class GridPolygon(QgisAlgorithm):
|
||||
|
||||
ft.setGeometry(QgsGeometry.fromPolygon([polyline]))
|
||||
ft.setAttributes([x1, y1, x2, y2, id])
|
||||
writer.addFeature(ft)
|
||||
sink.addFeature(ft)
|
||||
|
||||
id += 1
|
||||
count += 1
|
||||
if int(math.fmod(count, count_update)) == 0:
|
||||
feedback.setProgress(int(count / cells * 100))
|
||||
|
||||
def _diamondGrid(self, writer, width, height, originX, originY,
|
||||
def _diamondGrid(self, sink, width, height, originX, originY,
|
||||
hSpacing, vSpacing, hOverlay, vOverlay, feedback):
|
||||
ft = QgsFeature()
|
||||
|
||||
@ -209,6 +221,9 @@ class GridPolygon(QgisAlgorithm):
|
||||
count = 0
|
||||
|
||||
for col in range(columns):
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
x = originX - (col * halfHOverlay)
|
||||
x1 = x + ((col + 0) * halfHSpacing)
|
||||
x2 = x + ((col + 1) * halfHSpacing)
|
||||
@ -234,13 +249,13 @@ class GridPolygon(QgisAlgorithm):
|
||||
|
||||
ft.setGeometry(QgsGeometry.fromPolygon([polyline]))
|
||||
ft.setAttributes([x1, y1, x3, y3, id])
|
||||
writer.addFeature(ft)
|
||||
sink.addFeature(ft)
|
||||
id += 1
|
||||
count += 1
|
||||
if int(math.fmod(count, count_update)) == 0:
|
||||
feedback.setProgress(int(count / cells * 100))
|
||||
|
||||
def _hexagonGrid(self, writer, width, height, originX, originY,
|
||||
def _hexagonGrid(self, sink, width, height, originX, originY,
|
||||
hSpacing, vSpacing, hOverlay, vOverlay, feedback):
|
||||
ft = QgsFeature()
|
||||
|
||||
@ -269,6 +284,9 @@ class GridPolygon(QgisAlgorithm):
|
||||
count = 0
|
||||
|
||||
for col in range(columns):
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
# (column + 1) and (row + 1) calculation is used to maintain
|
||||
# topology between adjacent shapes and avoid overlaps/holes
|
||||
# due to rounding errors
|
||||
@ -298,7 +316,7 @@ class GridPolygon(QgisAlgorithm):
|
||||
|
||||
ft.setGeometry(QgsGeometry.fromPolygon([polyline]))
|
||||
ft.setAttributes([x1, y1, x4, y3, id])
|
||||
writer.addFeature(ft)
|
||||
sink.addFeature(ft)
|
||||
id += 1
|
||||
count += 1
|
||||
if int(math.fmod(count, count_update)) == 0:
|
||||
|
@ -92,7 +92,7 @@ from .DeleteColumn import DeleteColumn
|
||||
# from .TextToFloat import TextToFloat
|
||||
# from .ExtractByAttribute import ExtractByAttribute
|
||||
# from .SelectByAttribute import SelectByAttribute
|
||||
# from .GridPolygon import GridPolygon
|
||||
from .GridPolygon import GridPolygon
|
||||
# from .GridLine import GridLine
|
||||
# from .Gridify import Gridify
|
||||
# from .HubDistancePoints import HubDistancePoints
|
||||
@ -217,7 +217,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
|
||||
# SpatialJoin(), RegularPoints(), SymmetricalDifference(),
|
||||
# VectorSplit(), VectorGridLines(), VectorGridPolygons(),
|
||||
# DeleteDuplicateGeometries(), TextToFloat(),
|
||||
# ExtractByAttribute(), SelectByAttribute(), GridPolygon(),
|
||||
# ExtractByAttribute(), SelectByAttribute(),
|
||||
# GridLine(), Gridify(), HubDistancePoints(),
|
||||
# HubDistanceLines(), HubLines(), Merge(),
|
||||
# GeometryConvert(), FieldsCalculator(),
|
||||
@ -269,7 +269,8 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
|
||||
Clip(),
|
||||
DeleteColumn(),
|
||||
ExtentFromLayer(),
|
||||
ExtractByExpression()
|
||||
ExtractByExpression(),
|
||||
GridPolygon()
|
||||
]
|
||||
|
||||
if hasPlotly:
|
||||
|
@ -515,7 +515,7 @@ class ParameterNumber(Parameter):
|
||||
|
||||
def _layerVariables(self, element, alg=None):
|
||||
variables = {}
|
||||
context = dataobjects.createContext()
|
||||
context = createContext()
|
||||
layer = QgsProcessingUtils.mapLayerFromString(element.value, context)
|
||||
if layer is not None:
|
||||
name = element.name if alg is None else "%s_%s" % (alg.name, element.name)
|
||||
|
@ -39,6 +39,7 @@ from qgis.core import (QgsProcessingUtils,
|
||||
QgsProject)
|
||||
from processing.gui.RectangleMapTool import RectangleMapTool
|
||||
from processing.core.ProcessingConfig import ProcessingConfig
|
||||
from processing.tools.dataobjects import createContext
|
||||
|
||||
pluginPath = os.path.split(os.path.dirname(__file__))[0]
|
||||
WIDGET, BASE = uic.loadUiType(
|
||||
@ -65,15 +66,14 @@ class ExtentSelectionPanel(BASE, WIDGET):
|
||||
self.tool = RectangleMapTool(canvas)
|
||||
self.tool.rectangleCreated.connect(self.updateExtent)
|
||||
|
||||
if param.default:
|
||||
tokens = param.default.split(',')
|
||||
if len(tokens) == 4:
|
||||
if param.defaultValue() is not None:
|
||||
context = createContext()
|
||||
rect = QgsProcessingParameters.parameterAsExtent(param, {param.name(): param.defaultValue()}, context)
|
||||
if not rect.isNull():
|
||||
try:
|
||||
float(tokens[0])
|
||||
float(tokens[1])
|
||||
float(tokens[2])
|
||||
float(tokens[3])
|
||||
self.leText.setText(param.default)
|
||||
s = '{},{},{},{}'.format(
|
||||
rect.xMinimum(), rect.xMaximum(), rect.yMinimum(), rect.yMaximum())
|
||||
self.leText.setText(s)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
@ -1692,54 +1692,54 @@ tests:
|
||||
# geometry:
|
||||
# precision: 7
|
||||
#
|
||||
# - algorithm: qgis:creategridpolygon
|
||||
# name: Create grid (rectangles)
|
||||
# params:
|
||||
# CRS: EPSG:4326
|
||||
# EXTENT: -1,11.2,-4,6.5
|
||||
# HSPACING: 5.0
|
||||
# TYPE: '0'
|
||||
# VSPACING: 3.0
|
||||
# results:
|
||||
# OUTPUT:
|
||||
# name: expected/grid_rectangles.gml
|
||||
# type: vector
|
||||
# compare:
|
||||
# geometry:
|
||||
# precision: 7
|
||||
#
|
||||
# - algorithm: qgis:creategridpolygon
|
||||
# name: Create grid (diamond)
|
||||
# params:
|
||||
# CRS: EPSG:4326
|
||||
# EXTENT: -1,11.2,-4,6.5
|
||||
# HSPACING: 5.0
|
||||
# TYPE: '1'
|
||||
# VSPACING: 3.0
|
||||
# results:
|
||||
# OUTPUT:
|
||||
# name: expected/grid_diamond.gml
|
||||
# type: vector
|
||||
# compare:
|
||||
# geometry:
|
||||
# precision: 7
|
||||
#
|
||||
# - algorithm: qgis:creategridpolygon
|
||||
# name: Create grid (hexagon)
|
||||
# params:
|
||||
# CRS: EPSG:4326
|
||||
# EXTENT: -1,11.2,-4,6.5
|
||||
# HSPACING: 5.0
|
||||
# TYPE: '2'
|
||||
# VSPACING: 5.0
|
||||
# results:
|
||||
# OUTPUT:
|
||||
# name: expected/grid_hexagon.gml
|
||||
# type: vector
|
||||
# compare:
|
||||
# geometry:
|
||||
# precision: 7
|
||||
#
|
||||
- algorithm: qgis:creategridpolygon
|
||||
name: Create grid (rectangles)
|
||||
params:
|
||||
CRS: EPSG:4326
|
||||
EXTENT: -1,11.2,-4,6.5
|
||||
HSPACING: 5.0
|
||||
TYPE: '0'
|
||||
VSPACING: 3.0
|
||||
results:
|
||||
OUTPUT:
|
||||
name: expected/grid_rectangles.gml
|
||||
type: vector
|
||||
compare:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
||||
- algorithm: qgis:creategridpolygon
|
||||
name: Create grid (diamond)
|
||||
params:
|
||||
CRS: EPSG:4326
|
||||
EXTENT: -1,11.2,-4,6.5
|
||||
HSPACING: 5.0
|
||||
TYPE: '1'
|
||||
VSPACING: 3.0
|
||||
results:
|
||||
OUTPUT:
|
||||
name: expected/grid_diamond.gml
|
||||
type: vector
|
||||
compare:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
||||
- algorithm: qgis:creategridpolygon
|
||||
name: Create grid (hexagon)
|
||||
params:
|
||||
CRS: EPSG:4326
|
||||
EXTENT: -1,11.2,-4,6.5
|
||||
HSPACING: 5.0
|
||||
TYPE: '2'
|
||||
VSPACING: 5.0
|
||||
results:
|
||||
OUTPUT:
|
||||
name: expected/grid_hexagon.gml
|
||||
type: vector
|
||||
compare:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
||||
# - algorithm: qgis:creategridlines
|
||||
# name: Create grid (lines with overlay)
|
||||
# params:
|
||||
@ -1754,60 +1754,60 @@ tests:
|
||||
# name: expected/grid_lines_overlay.gml
|
||||
# type: vector
|
||||
#
|
||||
# - algorithm: qgis:creategridpolygon
|
||||
# name: Create grid (rectangle with overlay)
|
||||
# params:
|
||||
# CRS: EPSG:4326
|
||||
# EXTENT: -1,11.2,-4,6.5
|
||||
# HOVERLAY: 2.0
|
||||
# HSPACING: 5.0
|
||||
# TYPE: '0'
|
||||
# VOVERLAY: 1.0
|
||||
# VSPACING: 3.0
|
||||
# results:
|
||||
# OUTPUT:
|
||||
# name: expected/grid_rectangle_overlay.gml
|
||||
# type: vector
|
||||
# compare:
|
||||
# geometry:
|
||||
# precision: 7
|
||||
#
|
||||
# - algorithm: qgis:creategridpolygon
|
||||
# name: Create grid (diamond with overlay)
|
||||
# params:
|
||||
# CRS: EPSG:4326
|
||||
# EXTENT: -1,11.2,-4,6.5
|
||||
# HOVERLAY: 2.0
|
||||
# HSPACING: 5.0
|
||||
# TYPE: '1'
|
||||
# VOVERLAY: 1.0
|
||||
# VSPACING: 3.0
|
||||
# results:
|
||||
# OUTPUT:
|
||||
# name: expected/grid_diamond_overlay.gml
|
||||
# type: vector
|
||||
# compare:
|
||||
# geometry:
|
||||
# precision: 7
|
||||
#
|
||||
# - algorithm: qgis:creategridpolygon
|
||||
# name: Create grid (hexagon with overlay)
|
||||
# params:
|
||||
# CRS: EPSG:4326
|
||||
# EXTENT: -1,11.2,-4,6.5
|
||||
# HOVERLAY: 2.0
|
||||
# HSPACING: 5.0
|
||||
# TYPE: '2'
|
||||
# VOVERLAY: 1.0
|
||||
# VSPACING: 5.0
|
||||
# results:
|
||||
# OUTPUT:
|
||||
# name: expected/grid_hexagon_overlay.gml
|
||||
# type: vector
|
||||
# compare:
|
||||
# geometry:
|
||||
# precision: 7
|
||||
#
|
||||
- algorithm: qgis:creategridpolygon
|
||||
name: Create grid (rectangle with overlay)
|
||||
params:
|
||||
CRS: EPSG:4326
|
||||
EXTENT: -1,11.2,-4,6.5
|
||||
HOVERLAY: 2.0
|
||||
HSPACING: 5.0
|
||||
TYPE: '0'
|
||||
VOVERLAY: 1.0
|
||||
VSPACING: 3.0
|
||||
results:
|
||||
OUTPUT:
|
||||
name: expected/grid_rectangle_overlay.gml
|
||||
type: vector
|
||||
compare:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
||||
- algorithm: qgis:creategridpolygon
|
||||
name: Create grid (diamond with overlay)
|
||||
params:
|
||||
CRS: EPSG:4326
|
||||
EXTENT: -1,11.2,-4,6.5
|
||||
HOVERLAY: 2.0
|
||||
HSPACING: 5.0
|
||||
TYPE: '1'
|
||||
VOVERLAY: 1.0
|
||||
VSPACING: 3.0
|
||||
results:
|
||||
OUTPUT:
|
||||
name: expected/grid_diamond_overlay.gml
|
||||
type: vector
|
||||
compare:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
||||
- algorithm: qgis:creategridpolygon
|
||||
name: Create grid (hexagon with overlay)
|
||||
params:
|
||||
CRS: EPSG:4326
|
||||
EXTENT: -1,11.2,-4,6.5
|
||||
HOVERLAY: 2.0
|
||||
HSPACING: 5.0
|
||||
TYPE: '2'
|
||||
VOVERLAY: 1.0
|
||||
VSPACING: 5.0
|
||||
results:
|
||||
OUTPUT:
|
||||
name: expected/grid_hexagon_overlay.gml
|
||||
type: vector
|
||||
compare:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
||||
# - algorithm: qgis:deleteholes
|
||||
# name: Delete holes (no min)
|
||||
# params:
|
||||
|
Loading…
x
Reference in New Issue
Block a user