mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
[needs-docs][processing] merge grid algorithms and add point grid type
This commit is contained in:
parent
c91fd5a067
commit
aaf97933c2
@ -2,7 +2,7 @@
|
||||
|
||||
"""
|
||||
***************************************************************************
|
||||
GridPolygon.py
|
||||
Grid.py
|
||||
---------------------
|
||||
Date : May 2010
|
||||
Copyright : (C) 2010 by Michael Minn
|
||||
@ -34,6 +34,8 @@ from qgis.core import (QgsField,
|
||||
QgsFeatureSink,
|
||||
QgsFeature,
|
||||
QgsGeometry,
|
||||
QgsLineString,
|
||||
QgsPoint,
|
||||
QgsPointXY,
|
||||
QgsWkbTypes,
|
||||
QgsProcessing,
|
||||
@ -50,7 +52,7 @@ from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||
|
||||
|
||||
class GridPolygon(QgisAlgorithm):
|
||||
class Grid(QgisAlgorithm):
|
||||
TYPE = 'TYPE'
|
||||
EXTENT = 'EXTENT'
|
||||
HSPACING = 'HSPACING'
|
||||
@ -64,7 +66,7 @@ class GridPolygon(QgisAlgorithm):
|
||||
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'vector_grid.png'))
|
||||
|
||||
def tags(self):
|
||||
return self.tr('grid,lines,vector,create,fishnet').split(',')
|
||||
return self.tr('grid,lines,polygons,vector,create,fishnet,diamond,hexagon').split(',')
|
||||
|
||||
def group(self):
|
||||
return self.tr('Vector creation')
|
||||
@ -76,7 +78,9 @@ class GridPolygon(QgisAlgorithm):
|
||||
super().__init__()
|
||||
|
||||
def initAlgorithm(self, config=None):
|
||||
self.types = [self.tr('Rectangle (polygon)'),
|
||||
self.types = [self.tr('Point'),
|
||||
self.tr('Line'),
|
||||
self.tr('Rectangle (polygon)'),
|
||||
self.tr('Diamond (polygon)'),
|
||||
self.tr('Hexagon (polygon)')]
|
||||
|
||||
@ -103,10 +107,10 @@ class GridPolygon(QgisAlgorithm):
|
||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Grid'), type=QgsProcessing.TypeVectorPolygon))
|
||||
|
||||
def name(self):
|
||||
return 'creategridpolygon'
|
||||
return 'creategrid'
|
||||
|
||||
def displayName(self):
|
||||
return self.tr('Create grid (polygon)')
|
||||
return self.tr('Create grid')
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
idx = self.parameterAsEnum(parameters, self.TYPE, context)
|
||||
@ -119,16 +123,11 @@ class GridPolygon(QgisAlgorithm):
|
||||
crs = self.parameterAsCrs(parameters, self.CRS, context)
|
||||
bbox = self.parameterAsExtent(parameters, self.EXTENT, context, crs)
|
||||
|
||||
width = bbox.width()
|
||||
height = bbox.height()
|
||||
originX = bbox.xMinimum()
|
||||
originY = bbox.yMaximum()
|
||||
|
||||
if hSpacing <= 0 or vSpacing <= 0:
|
||||
raise QgsProcessingException(
|
||||
self.tr('Invalid grid spacing: {0}/{1}').format(hSpacing, vSpacing))
|
||||
|
||||
if width < hSpacing:
|
||||
if bbox.width() < hSpacing:
|
||||
raise QgsProcessingException(
|
||||
self.tr('Horizontal spacing is too large for the covered area'))
|
||||
|
||||
@ -136,7 +135,7 @@ class GridPolygon(QgisAlgorithm):
|
||||
raise QgsProcessingException(
|
||||
self.tr('Invalid overlay: {0}/{1}').format(hOverlay, vOverlay))
|
||||
|
||||
if height < vSpacing:
|
||||
if bbox.height() < vSpacing:
|
||||
raise QgsProcessingException(
|
||||
self.tr('Vertical spacing is too large for the covered area'))
|
||||
|
||||
@ -147,27 +146,133 @@ class GridPolygon(QgisAlgorithm):
|
||||
fields.append(QgsField('bottom', QVariant.Double, '', 24, 16))
|
||||
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
|
||||
|
||||
if idx == 0:
|
||||
outputWkb = QgsWkbTypes.Point
|
||||
elif idx == 1:
|
||||
outputWkb = QgsWkbTypes.LineString
|
||||
else:
|
||||
outputWkb = QgsWkbTypes.Polygon
|
||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||
fields, QgsWkbTypes.Polygon, crs)
|
||||
fields, outputWkb, crs)
|
||||
|
||||
if idx == 0:
|
||||
self._rectangleGrid(
|
||||
sink, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
||||
self._pointGrid(
|
||||
sink, bbox, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
||||
elif idx == 1:
|
||||
self._diamondGrid(
|
||||
sink, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
||||
self._lineGrid(
|
||||
sink, bbox, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
||||
elif idx == 2:
|
||||
self._rectangleGrid(
|
||||
sink, bbox, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
||||
elif idx == 3:
|
||||
self._diamondGrid(
|
||||
sink, bbox, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
||||
elif idx == 4:
|
||||
self._hexagonGrid(
|
||||
sink, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
||||
sink, bbox, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
|
||||
|
||||
return {self.OUTPUT: dest_id}
|
||||
|
||||
def _rectangleGrid(self, sink, width, height, originX, originY,
|
||||
hSpacing, vSpacing, hOverlay, vOverlay, feedback):
|
||||
ft = QgsFeature()
|
||||
def _pointGrid(self, sink, bbox, hSpacing, vSpacing, hOverlay, vOverlay, feedback):
|
||||
feat = QgsFeature()
|
||||
|
||||
columns = int(math.ceil(float(width) / (hSpacing - hOverlay)))
|
||||
rows = int(math.ceil(float(height) / (vSpacing - vOverlay)))
|
||||
columns = int(math.ceil(float(bbox.width()) / (hSpacing - hOverlay)))
|
||||
rows = int(math.ceil(float(bbox.height()) / (vSpacing - vOverlay)))
|
||||
|
||||
cells = rows * columns
|
||||
count_update = cells * 0.05
|
||||
|
||||
id = 1
|
||||
count = 0
|
||||
|
||||
for col in range(columns):
|
||||
for row in range(rows):
|
||||
x = bbox.xMinimum() + (col * hSpacing - col * hOverlay)
|
||||
y = bbox.yMaximum() - (row * vSpacing - row * vOverlay)
|
||||
feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(x, y)))
|
||||
feat.setAttributes([x, y, x + hSpacing, y + vSpacing, id])
|
||||
sink.addFeature(feat, QgsFeatureSink.FastInsert)
|
||||
|
||||
id += 1
|
||||
count += 1
|
||||
if int(math.fmod(count, count_update)) == 0:
|
||||
feedback.setProgress(int(count / cells * 100))
|
||||
|
||||
def _lineGrid(self, sink, bbox, hSpacing, vSpacing, hOverlay, vOverlay, feedback):
|
||||
feat = QgsFeature()
|
||||
|
||||
if hOverlay > 0:
|
||||
hSpace = [hSpacing - hOverlay, hOverlay]
|
||||
else:
|
||||
hSpace = [hSpacing, hSpacing]
|
||||
|
||||
if vOverlay > 0:
|
||||
vSpace = [vSpacing - vOverlay, vOverlay]
|
||||
else:
|
||||
vSpace = [vSpacing, vSpacing]
|
||||
|
||||
count = 0
|
||||
id = 1
|
||||
|
||||
# latitude lines
|
||||
count_max = bbox.height() / vSpacing
|
||||
count_update = count_max * 0.10
|
||||
y = bbox.yMaximum()
|
||||
while y >= bbox.yMinimum():
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
pt1 = QgsPoint(bbox.xMinimum(), y)
|
||||
pt2 = QgsPoint(bbox.xMaximum(), y)
|
||||
line = QgsLineString([pt1, pt2])
|
||||
feat.setGeometry(QgsGeometry(line))
|
||||
feat.setAttributes([bbox.xMinimum(),
|
||||
y,
|
||||
bbox.xMaximum(),
|
||||
y,
|
||||
id,
|
||||
y])
|
||||
sink.addFeature(feat, QgsFeatureSink.FastInsert)
|
||||
y = y - vSpace[count % 2]
|
||||
id += 1
|
||||
count += 1
|
||||
if int(math.fmod(count, count_update)) == 0:
|
||||
feedback.setProgress(int(count / count_max * 50))
|
||||
|
||||
feedback.setProgress(50)
|
||||
|
||||
# longitude lines
|
||||
# counters for progressbar - update every 5%
|
||||
count = 0
|
||||
count_max = bbox.width() / hSpacing
|
||||
count_update = count_max * 0.10
|
||||
x = bbox.xMinimum()
|
||||
while x <= bbox.xMaximum():
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
pt1 = QgsPoint(x, bbox.yMaximum())
|
||||
pt2 = QgsPoint(x, bbox.yMinimum())
|
||||
line = QgsLineString([pt1, pt2])
|
||||
feat.setGeometry(QgsGeometry(line))
|
||||
feat.setAttributes([x,
|
||||
bbox.yMaximum(),
|
||||
x,
|
||||
bbox.yMinimum(),
|
||||
id,
|
||||
x])
|
||||
sink.addFeature(feat, QgsFeatureSink.FastInsert)
|
||||
x = x + hSpace[count % 2]
|
||||
id += 1
|
||||
count += 1
|
||||
if int(math.fmod(count, count_update)) == 0:
|
||||
feedback.setProgress(50 + int(count / count_max * 50))
|
||||
|
||||
def _rectangleGrid(self, sink, bbox, hSpacing, vSpacing, hOverlay, vOverlay, feedback):
|
||||
feat = QgsFeature()
|
||||
|
||||
columns = int(math.ceil(float(bbox.width()) / (hSpacing - hOverlay)))
|
||||
rows = int(math.ceil(float(bbox.height()) / (vSpacing - vOverlay)))
|
||||
|
||||
cells = rows * columns
|
||||
count_update = cells * 0.05
|
||||
@ -179,11 +284,11 @@ class GridPolygon(QgisAlgorithm):
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
x1 = originX + (col * hSpacing - col * hOverlay)
|
||||
x1 = bbox.xMinimum() + (col * hSpacing - col * hOverlay)
|
||||
x2 = x1 + hSpacing
|
||||
|
||||
for row in range(rows):
|
||||
y1 = originY - (row * vSpacing - row * vOverlay)
|
||||
y1 = bbox.yMaximum() - (row * vSpacing - row * vOverlay)
|
||||
y2 = y1 - vSpacing
|
||||
|
||||
polyline = []
|
||||
@ -193,18 +298,17 @@ class GridPolygon(QgisAlgorithm):
|
||||
polyline.append(QgsPointXY(x1, y2))
|
||||
polyline.append(QgsPointXY(x1, y1))
|
||||
|
||||
ft.setGeometry(QgsGeometry.fromPolygonXY([polyline]))
|
||||
ft.setAttributes([x1, y1, x2, y2, id])
|
||||
sink.addFeature(ft, QgsFeatureSink.FastInsert)
|
||||
feat.setGeometry(QgsGeometry.fromPolygonXY([polyline]))
|
||||
feat.setAttributes([x1, y1, x2, y2, id])
|
||||
sink.addFeature(feat, QgsFeatureSink.FastInsert)
|
||||
|
||||
id += 1
|
||||
count += 1
|
||||
if int(math.fmod(count, count_update)) == 0:
|
||||
feedback.setProgress(int(count / cells * 100))
|
||||
|
||||
def _diamondGrid(self, sink, width, height, originX, originY,
|
||||
hSpacing, vSpacing, hOverlay, vOverlay, feedback):
|
||||
ft = QgsFeature()
|
||||
def _diamondGrid(self, sink, bbox, hSpacing, vSpacing, hOverlay, vOverlay, feedback):
|
||||
feat = QgsFeature()
|
||||
|
||||
halfHSpacing = hSpacing / 2
|
||||
halfVSpacing = vSpacing / 2
|
||||
@ -212,8 +316,8 @@ class GridPolygon(QgisAlgorithm):
|
||||
halfHOverlay = hOverlay / 2
|
||||
halfVOverlay = vOverlay / 2
|
||||
|
||||
columns = int(math.ceil(float(width) / (halfHSpacing - halfHOverlay)))
|
||||
rows = int(math.ceil(float(height) / (vSpacing - halfVOverlay)))
|
||||
columns = int(math.ceil(float(bbox.width()) / (halfHSpacing - halfHOverlay)))
|
||||
rows = int(math.ceil(float(bbox.height()) / (vSpacing - halfVOverlay)))
|
||||
|
||||
cells = rows * columns
|
||||
count_update = cells * 0.05
|
||||
@ -225,13 +329,13 @@ class GridPolygon(QgisAlgorithm):
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
x = originX - (col * halfHOverlay)
|
||||
x = bbox.xMinimum() - (col * halfHOverlay)
|
||||
x1 = x + ((col + 0) * halfHSpacing)
|
||||
x2 = x + ((col + 1) * halfHSpacing)
|
||||
x3 = x + ((col + 2) * halfHSpacing)
|
||||
|
||||
for row in range(rows):
|
||||
y = originY + (row * halfVOverlay)
|
||||
y = bbox.yMaximum() + (row * halfVOverlay)
|
||||
if (col % 2) == 0:
|
||||
y1 = y - (((row * 2) + 0) * halfVSpacing)
|
||||
y2 = y - (((row * 2) + 1) * halfVSpacing)
|
||||
@ -248,17 +352,16 @@ class GridPolygon(QgisAlgorithm):
|
||||
polyline.append(QgsPointXY(x2, y3))
|
||||
polyline.append(QgsPointXY(x1, y2))
|
||||
|
||||
ft.setGeometry(QgsGeometry.fromPolygonXY([polyline]))
|
||||
ft.setAttributes([x1, y1, x3, y3, id])
|
||||
sink.addFeature(ft, QgsFeatureSink.FastInsert)
|
||||
feat.setGeometry(QgsGeometry.fromPolygonXY([polyline]))
|
||||
feat.setAttributes([x1, y1, x3, y3, id])
|
||||
sink.addFeature(feat, QgsFeatureSink.FastInsert)
|
||||
id += 1
|
||||
count += 1
|
||||
if int(math.fmod(count, count_update)) == 0:
|
||||
feedback.setProgress(int(count / cells * 100))
|
||||
|
||||
def _hexagonGrid(self, sink, width, height, originX, originY,
|
||||
hSpacing, vSpacing, hOverlay, vOverlay, feedback):
|
||||
ft = QgsFeature()
|
||||
def _hexagonGrid(self, sink, bbox, hSpacing, vSpacing, hOverlay, vOverlay, feedback):
|
||||
feat = QgsFeature()
|
||||
|
||||
# To preserve symmetry, hspacing is fixed relative to vspacing
|
||||
xVertexLo = 0.288675134594813 * vSpacing
|
||||
@ -275,8 +378,8 @@ class GridPolygon(QgisAlgorithm):
|
||||
|
||||
halfVSpacing = vSpacing / 2.0
|
||||
|
||||
columns = int(math.ceil(float(width) / hOverlay))
|
||||
rows = int(math.ceil(float(height) / (vSpacing - vOverlay)))
|
||||
columns = int(math.ceil(float(bbox.width()) / hOverlay))
|
||||
rows = int(math.ceil(float(bbox.height()) / (vSpacing - vOverlay)))
|
||||
|
||||
cells = rows * columns
|
||||
count_update = cells * 0.05
|
||||
@ -291,20 +394,20 @@ class GridPolygon(QgisAlgorithm):
|
||||
# (column + 1) and (row + 1) calculation is used to maintain
|
||||
# topology between adjacent shapes and avoid overlaps/holes
|
||||
# due to rounding errors
|
||||
x1 = originX + (col * hOverlay) # far left
|
||||
x1 = bbox.xMinimum() + (col * hOverlay) # far left
|
||||
x2 = x1 + (xVertexHi - xVertexLo) # left
|
||||
x3 = originX + (col * hOverlay) + hSpacing # right
|
||||
x3 = bbox.xMinimum() + (col * hOverlay) + hSpacing # right
|
||||
x4 = x3 + (xVertexHi - xVertexLo) # far right
|
||||
|
||||
for row in range(rows):
|
||||
if (col % 2) == 0:
|
||||
y1 = originY + (row * vOverlay) - (((row * 2) + 0) * halfVSpacing) # hi
|
||||
y2 = originY + (row * vOverlay) - (((row * 2) + 1) * halfVSpacing) # mid
|
||||
y3 = originY + (row * vOverlay) - (((row * 2) + 2) * halfVSpacing) # lo
|
||||
y1 = bbox.yMaximum() + (row * vOverlay) - (((row * 2) + 0) * halfVSpacing) # hi
|
||||
y2 = bbox.yMaximum() + (row * vOverlay) - (((row * 2) + 1) * halfVSpacing) # mid
|
||||
y3 = bbox.yMaximum() + (row * vOverlay) - (((row * 2) + 2) * halfVSpacing) # lo
|
||||
else:
|
||||
y1 = originY + (row * vOverlay) - (((row * 2) + 1) * halfVSpacing) # hi
|
||||
y2 = originY + (row * vOverlay) - (((row * 2) + 2) * halfVSpacing) # mid
|
||||
y3 = originY + (row * vOverlay) - (((row * 2) + 3) * halfVSpacing) # lo
|
||||
y1 = bbox.yMaximum() + (row * vOverlay) - (((row * 2) + 1) * halfVSpacing) # hi
|
||||
y2 = bbox.yMaximum() + (row * vOverlay) - (((row * 2) + 2) * halfVSpacing) # mid
|
||||
y3 = bbox.yMaximum() + (row * vOverlay) - (((row * 2) + 3) * halfVSpacing) # lo
|
||||
|
||||
polyline = []
|
||||
polyline.append(QgsPointXY(x1, y2))
|
||||
@ -315,9 +418,9 @@ class GridPolygon(QgisAlgorithm):
|
||||
polyline.append(QgsPointXY(x2, y3))
|
||||
polyline.append(QgsPointXY(x1, y2))
|
||||
|
||||
ft.setGeometry(QgsGeometry.fromPolygonXY([polyline]))
|
||||
ft.setAttributes([x1, y1, x4, y3, id])
|
||||
sink.addFeature(ft, QgsFeatureSink.FastInsert)
|
||||
feat.setGeometry(QgsGeometry.fromPolygonXY([polyline]))
|
||||
feat.setAttributes([x1, y1, x4, y3, id])
|
||||
sink.addFeature(feat, QgsFeatureSink.FastInsert)
|
||||
id += 1
|
||||
count += 1
|
||||
if int(math.fmod(count, count_update)) == 0:
|
@ -1,216 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
***************************************************************************
|
||||
Grid.py
|
||||
---------------------
|
||||
Date : May 2010
|
||||
Copyright : (C) 2010 by Michael Minn
|
||||
Email : pyqgis at michaelminn 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__ = 'Michael Minn'
|
||||
__date__ = 'May 2010'
|
||||
__copyright__ = '(C) 2010, Michael Minn'
|
||||
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
import os
|
||||
import math
|
||||
|
||||
from qgis.PyQt.QtGui import QIcon
|
||||
from qgis.PyQt.QtCore import QVariant
|
||||
from qgis.core import (QgsRectangle,
|
||||
QgsCoordinateReferenceSystem,
|
||||
QgsField,
|
||||
QgsFeatureSink,
|
||||
QgsFeature,
|
||||
QgsGeometry,
|
||||
QgsPoint,
|
||||
QgsLineString,
|
||||
QgsWkbTypes,
|
||||
QgsProcessing,
|
||||
QgsProcessingException,
|
||||
QgsProcessingParameterEnum,
|
||||
QgsProcessingParameterExtent,
|
||||
QgsProcessingParameterNumber,
|
||||
QgsProcessingParameterCrs,
|
||||
QgsProcessingParameterFeatureSink,
|
||||
QgsFields)
|
||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||
|
||||
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||
|
||||
|
||||
class GridLine(QgisAlgorithm):
|
||||
EXTENT = 'EXTENT'
|
||||
HSPACING = 'HSPACING'
|
||||
VSPACING = 'VSPACING'
|
||||
HOVERLAY = 'HOVERLAY'
|
||||
VOVERLAY = 'VOVERLAY'
|
||||
CRS = 'CRS'
|
||||
OUTPUT = 'OUTPUT'
|
||||
|
||||
def icon(self):
|
||||
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'vector_grid.png'))
|
||||
|
||||
def tags(self):
|
||||
return self.tr('grid,lines,vector,create,fishnet').split(',')
|
||||
|
||||
def group(self):
|
||||
return self.tr('Vector creation')
|
||||
|
||||
def groupId(self):
|
||||
return 'vectorcreation'
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def initAlgorithm(self, config=None):
|
||||
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'), type=QgsProcessing.TypeVectorLine))
|
||||
|
||||
def name(self):
|
||||
return 'creategridlines'
|
||||
|
||||
def displayName(self):
|
||||
return self.tr('Create grid (lines)')
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
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)
|
||||
|
||||
crs = self.parameterAsCrs(parameters, self.CRS, context)
|
||||
bbox = self.parameterAsExtent(parameters, self.EXTENT, context, crs)
|
||||
|
||||
width = bbox.width()
|
||||
height = bbox.height()
|
||||
|
||||
if hSpacing <= 0 or vSpacing <= 0:
|
||||
raise QgsProcessingException(
|
||||
self.tr('Invalid grid spacing: {0}/{1}').format(hSpacing, vSpacing))
|
||||
|
||||
if hSpacing <= hOverlay or vSpacing <= vOverlay:
|
||||
raise QgsProcessingException(
|
||||
self.tr('Invalid overlay: {0}/{1}').format(hOverlay, vOverlay))
|
||||
|
||||
if width < hSpacing:
|
||||
raise QgsProcessingException(
|
||||
self.tr('Horizontal spacing is too large for the covered area'))
|
||||
|
||||
if height < vSpacing:
|
||||
raise QgsProcessingException(
|
||||
self.tr('Vertical spacing is too large for the covered area'))
|
||||
|
||||
fields = QgsFields()
|
||||
fields.append(QgsField('left', QVariant.Double, '', 24, 16))
|
||||
fields.append(QgsField('top', QVariant.Double, '', 24, 16))
|
||||
fields.append(QgsField('right', QVariant.Double, '', 24, 16))
|
||||
fields.append(QgsField('bottom', QVariant.Double, '', 24, 16))
|
||||
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
|
||||
fields.append(QgsField('coord', QVariant.Double, '', 24, 15))
|
||||
|
||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||
fields, QgsWkbTypes.LineString, crs)
|
||||
|
||||
if hOverlay > 0:
|
||||
hSpace = [hSpacing - hOverlay, hOverlay]
|
||||
else:
|
||||
hSpace = [hSpacing, hSpacing]
|
||||
|
||||
if vOverlay > 0:
|
||||
vSpace = [vSpacing - vOverlay, vOverlay]
|
||||
else:
|
||||
vSpace = [vSpacing, vSpacing]
|
||||
|
||||
feat = QgsFeature()
|
||||
feat.initAttributes(len(fields))
|
||||
|
||||
count = 0
|
||||
id = 1
|
||||
|
||||
# latitude lines
|
||||
count_max = height / vSpacing
|
||||
count_update = count_max * 0.10
|
||||
y = bbox.yMaximum()
|
||||
while y >= bbox.yMinimum():
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
pt1 = QgsPoint(bbox.xMinimum(), y)
|
||||
pt2 = QgsPoint(bbox.xMaximum(), y)
|
||||
line = QgsLineString()
|
||||
line.setPoints([pt1, pt2])
|
||||
feat.setGeometry(QgsGeometry(line))
|
||||
feat.setAttributes([bbox.xMinimum(),
|
||||
y,
|
||||
bbox.xMaximum(),
|
||||
y,
|
||||
id,
|
||||
y])
|
||||
sink.addFeature(feat, QgsFeatureSink.FastInsert)
|
||||
y = y - vSpace[count % 2]
|
||||
id += 1
|
||||
count += 1
|
||||
if int(math.fmod(count, count_update)) == 0:
|
||||
feedback.setProgress(int(count / count_max * 50))
|
||||
|
||||
feedback.setProgress(50)
|
||||
|
||||
# longitude lines
|
||||
# counters for progressbar - update every 5%
|
||||
count = 0
|
||||
count_max = width / hSpacing
|
||||
count_update = count_max * 0.10
|
||||
x = bbox.xMinimum()
|
||||
while x <= bbox.xMaximum():
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
pt1 = QgsPoint(x, bbox.yMaximum())
|
||||
pt2 = QgsPoint(x, bbox.yMinimum())
|
||||
line = QgsLineString()
|
||||
line.setPoints([pt1, pt2])
|
||||
feat.setGeometry(QgsGeometry(line))
|
||||
feat.setAttributes([x,
|
||||
bbox.yMaximum(),
|
||||
x,
|
||||
bbox.yMinimum(),
|
||||
id,
|
||||
x])
|
||||
sink.addFeature(feat, QgsFeatureSink.FastInsert)
|
||||
x = x + hSpace[count % 2]
|
||||
id += 1
|
||||
count += 1
|
||||
if int(math.fmod(count, count_update)) == 0:
|
||||
feedback.setProgress(50 + int(count / count_max * 50))
|
||||
|
||||
return {self.OUTPUT: dest_id}
|
@ -70,8 +70,7 @@ from .FieldsMapper import FieldsMapper
|
||||
from .FindProjection import FindProjection
|
||||
from .GeometryConvert import GeometryConvert
|
||||
from .GeometryByExpression import GeometryByExpression
|
||||
from .GridLine import GridLine
|
||||
from .GridPolygon import GridPolygon
|
||||
from .Grid import Grid
|
||||
from .Heatmap import Heatmap
|
||||
from .Hillshade import Hillshade
|
||||
from .HubDistanceLines import HubDistanceLines
|
||||
@ -191,8 +190,7 @@ class QgisAlgorithmProvider(QgsProcessingProvider):
|
||||
FindProjection(),
|
||||
GeometryByExpression(),
|
||||
GeometryConvert(),
|
||||
GridLine(),
|
||||
GridPolygon(),
|
||||
Grid(),
|
||||
Heatmap(),
|
||||
Hillshade(),
|
||||
HubDistanceLines(),
|
||||
|
@ -37,10 +37,5 @@
|
||||
<ElementPath>id</ElementPath>
|
||||
<Type>Integer</Type>
|
||||
</PropertyDefn>
|
||||
<PropertyDefn>
|
||||
<Name>coord</Name>
|
||||
<ElementPath>coord</ElementPath>
|
||||
<Type>Real</Type>
|
||||
</PropertyDefn>
|
||||
</GMLFeatureClass>
|
||||
</GMLFeatureClassList>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -37,10 +37,5 @@
|
||||
<ElementPath>id</ElementPath>
|
||||
<Type>Integer</Type>
|
||||
</PropertyDefn>
|
||||
<PropertyDefn>
|
||||
<Name>coord</Name>
|
||||
<ElementPath>coord</ElementPath>
|
||||
<Type>Real</Type>
|
||||
</PropertyDefn>
|
||||
</GMLFeatureClass>
|
||||
</GMLFeatureClassList>
|
||||
|
@ -19,7 +19,6 @@
|
||||
<ogr:right>11.1999999999999993</ogr:right>
|
||||
<ogr:bottom>6.5000000000000000</ogr:bottom>
|
||||
<ogr:id>1</ogr:id>
|
||||
<ogr:coord>6.500000000000000</ogr:coord>
|
||||
</ogr:grid_lines>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -30,7 +29,6 @@
|
||||
<ogr:right>11.1999999999999993</ogr:right>
|
||||
<ogr:bottom>3.5000000000000000</ogr:bottom>
|
||||
<ogr:id>2</ogr:id>
|
||||
<ogr:coord>3.500000000000000</ogr:coord>
|
||||
</ogr:grid_lines>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -41,7 +39,6 @@
|
||||
<ogr:right>11.1999999999999993</ogr:right>
|
||||
<ogr:bottom>0.5000000000000000</ogr:bottom>
|
||||
<ogr:id>3</ogr:id>
|
||||
<ogr:coord>0.500000000000000</ogr:coord>
|
||||
</ogr:grid_lines>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -52,7 +49,6 @@
|
||||
<ogr:right>11.1999999999999993</ogr:right>
|
||||
<ogr:bottom>-2.5000000000000000</ogr:bottom>
|
||||
<ogr:id>4</ogr:id>
|
||||
<ogr:coord>-2.500000000000000</ogr:coord>
|
||||
</ogr:grid_lines>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -63,7 +59,6 @@
|
||||
<ogr:right>-1.0000000000000000</ogr:right>
|
||||
<ogr:bottom>-4.0000000000000000</ogr:bottom>
|
||||
<ogr:id>5</ogr:id>
|
||||
<ogr:coord>-1.000000000000000</ogr:coord>
|
||||
</ogr:grid_lines>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -74,7 +69,6 @@
|
||||
<ogr:right>4.0000000000000000</ogr:right>
|
||||
<ogr:bottom>-4.0000000000000000</ogr:bottom>
|
||||
<ogr:id>6</ogr:id>
|
||||
<ogr:coord>4.000000000000000</ogr:coord>
|
||||
</ogr:grid_lines>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -85,7 +79,6 @@
|
||||
<ogr:right>9.0000000000000000</ogr:right>
|
||||
<ogr:bottom>-4.0000000000000000</ogr:bottom>
|
||||
<ogr:id>7</ogr:id>
|
||||
<ogr:coord>9.000000000000000</ogr:coord>
|
||||
</ogr:grid_lines>
|
||||
</gml:featureMember>
|
||||
</ogr:FeatureCollection>
|
||||
|
@ -37,10 +37,5 @@
|
||||
<ElementPath>id</ElementPath>
|
||||
<Type>Integer</Type>
|
||||
</PropertyDefn>
|
||||
<PropertyDefn>
|
||||
<Name>coord</Name>
|
||||
<ElementPath>coord</ElementPath>
|
||||
<Type>Real</Type>
|
||||
</PropertyDefn>
|
||||
</GMLFeatureClass>
|
||||
</GMLFeatureClassList>
|
||||
|
@ -19,7 +19,6 @@
|
||||
<ogr:right>11.1999999999999993</ogr:right>
|
||||
<ogr:bottom>6.5000000000000000</ogr:bottom>
|
||||
<ogr:id>1</ogr:id>
|
||||
<ogr:coord>6.500000000000000</ogr:coord>
|
||||
</ogr:grid_lines_overlay>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -30,7 +29,6 @@
|
||||
<ogr:right>11.1999999999999993</ogr:right>
|
||||
<ogr:bottom>4.5000000000000000</ogr:bottom>
|
||||
<ogr:id>2</ogr:id>
|
||||
<ogr:coord>4.500000000000000</ogr:coord>
|
||||
</ogr:grid_lines_overlay>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -41,7 +39,6 @@
|
||||
<ogr:right>11.1999999999999993</ogr:right>
|
||||
<ogr:bottom>3.5000000000000000</ogr:bottom>
|
||||
<ogr:id>3</ogr:id>
|
||||
<ogr:coord>3.500000000000000</ogr:coord>
|
||||
</ogr:grid_lines_overlay>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -52,7 +49,6 @@
|
||||
<ogr:right>11.1999999999999993</ogr:right>
|
||||
<ogr:bottom>1.5000000000000000</ogr:bottom>
|
||||
<ogr:id>4</ogr:id>
|
||||
<ogr:coord>1.500000000000000</ogr:coord>
|
||||
</ogr:grid_lines_overlay>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -63,7 +59,6 @@
|
||||
<ogr:right>11.1999999999999993</ogr:right>
|
||||
<ogr:bottom>0.5000000000000000</ogr:bottom>
|
||||
<ogr:id>5</ogr:id>
|
||||
<ogr:coord>0.500000000000000</ogr:coord>
|
||||
</ogr:grid_lines_overlay>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -74,7 +69,6 @@
|
||||
<ogr:right>11.1999999999999993</ogr:right>
|
||||
<ogr:bottom>-1.5000000000000000</ogr:bottom>
|
||||
<ogr:id>6</ogr:id>
|
||||
<ogr:coord>-1.500000000000000</ogr:coord>
|
||||
</ogr:grid_lines_overlay>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -85,7 +79,6 @@
|
||||
<ogr:right>11.1999999999999993</ogr:right>
|
||||
<ogr:bottom>-2.5000000000000000</ogr:bottom>
|
||||
<ogr:id>7</ogr:id>
|
||||
<ogr:coord>-2.500000000000000</ogr:coord>
|
||||
</ogr:grid_lines_overlay>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -96,7 +89,6 @@
|
||||
<ogr:right>-1.0000000000000000</ogr:right>
|
||||
<ogr:bottom>-4.0000000000000000</ogr:bottom>
|
||||
<ogr:id>8</ogr:id>
|
||||
<ogr:coord>-1.000000000000000</ogr:coord>
|
||||
</ogr:grid_lines_overlay>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -107,7 +99,6 @@
|
||||
<ogr:right>2.0000000000000000</ogr:right>
|
||||
<ogr:bottom>-4.0000000000000000</ogr:bottom>
|
||||
<ogr:id>9</ogr:id>
|
||||
<ogr:coord>2.000000000000000</ogr:coord>
|
||||
</ogr:grid_lines_overlay>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -118,7 +109,6 @@
|
||||
<ogr:right>4.0000000000000000</ogr:right>
|
||||
<ogr:bottom>-4.0000000000000000</ogr:bottom>
|
||||
<ogr:id>10</ogr:id>
|
||||
<ogr:coord>4.000000000000000</ogr:coord>
|
||||
</ogr:grid_lines_overlay>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -129,7 +119,6 @@
|
||||
<ogr:right>7.0000000000000000</ogr:right>
|
||||
<ogr:bottom>-4.0000000000000000</ogr:bottom>
|
||||
<ogr:id>11</ogr:id>
|
||||
<ogr:coord>7.000000000000000</ogr:coord>
|
||||
</ogr:grid_lines_overlay>
|
||||
</gml:featureMember>
|
||||
<gml:featureMember>
|
||||
@ -140,7 +129,6 @@
|
||||
<ogr:right>9.0000000000000000</ogr:right>
|
||||
<ogr:bottom>-4.0000000000000000</ogr:bottom>
|
||||
<ogr:id>12</ogr:id>
|
||||
<ogr:coord>9.000000000000000</ogr:coord>
|
||||
</ogr:grid_lines_overlay>
|
||||
</gml:featureMember>
|
||||
</ogr:FeatureCollection>
|
||||
|
@ -2163,12 +2163,13 @@ tests:
|
||||
name: expected/dropped_geometry.csv
|
||||
type: vector
|
||||
|
||||
- algorithm: qgis:creategridlines
|
||||
- algorithm: qgis:creategrid
|
||||
name: Create grid (lines)
|
||||
params:
|
||||
CRS: EPSG:4326
|
||||
EXTENT: -1,11.2,-4,6.5
|
||||
HSPACING: 5.0
|
||||
TYPE: '1'
|
||||
VSPACING: 3.0
|
||||
results:
|
||||
OUTPUT:
|
||||
@ -2178,13 +2179,13 @@ tests:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
||||
- algorithm: qgis:creategridpolygon
|
||||
- algorithm: qgis:creategrid
|
||||
name: Create grid (rectangles)
|
||||
params:
|
||||
CRS: EPSG:4326
|
||||
EXTENT: -1,11.2,-4,6.5
|
||||
HSPACING: 5.0
|
||||
TYPE: '0'
|
||||
TYPE: '2'
|
||||
VSPACING: 3.0
|
||||
results:
|
||||
OUTPUT:
|
||||
@ -2194,13 +2195,13 @@ tests:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
||||
- algorithm: qgis:creategridpolygon
|
||||
- algorithm: qgis:creategrid
|
||||
name: Create grid (diamond)
|
||||
params:
|
||||
CRS: EPSG:4326
|
||||
EXTENT: -1,11.2,-4,6.5
|
||||
HSPACING: 5.0
|
||||
TYPE: '1'
|
||||
TYPE: '3'
|
||||
VSPACING: 3.0
|
||||
results:
|
||||
OUTPUT:
|
||||
@ -2210,13 +2211,13 @@ tests:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
||||
- algorithm: qgis:creategridpolygon
|
||||
- algorithm: qgis:creategrid
|
||||
name: Create grid (hexagon)
|
||||
params:
|
||||
CRS: EPSG:4326
|
||||
EXTENT: -1,11.2,-4,6.5
|
||||
HSPACING: 5.0
|
||||
TYPE: '2'
|
||||
TYPE: '4'
|
||||
VSPACING: 5.0
|
||||
results:
|
||||
OUTPUT:
|
||||
@ -2226,13 +2227,14 @@ tests:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
||||
- algorithm: qgis:creategridlines
|
||||
- algorithm: qgis:creategrid
|
||||
name: Create grid (lines 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:
|
||||
@ -2240,14 +2242,14 @@ tests:
|
||||
name: expected/grid_lines_overlay.gml
|
||||
type: vector
|
||||
|
||||
- algorithm: qgis:creategridpolygon
|
||||
- algorithm: qgis:creategrid
|
||||
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'
|
||||
TYPE: '2'
|
||||
VOVERLAY: 1.0
|
||||
VSPACING: 3.0
|
||||
results:
|
||||
@ -2258,14 +2260,14 @@ tests:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
||||
- algorithm: qgis:creategridpolygon
|
||||
- algorithm: qgis:creategrid
|
||||
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'
|
||||
TYPE: '3'
|
||||
VOVERLAY: 1.0
|
||||
VSPACING: 3.0
|
||||
results:
|
||||
@ -2276,14 +2278,14 @@ tests:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
||||
- algorithm: qgis:creategridpolygon
|
||||
- algorithm: qgis:creategrid
|
||||
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'
|
||||
TYPE: '4'
|
||||
VOVERLAY: 1.0
|
||||
VSPACING: 5.0
|
||||
results:
|
||||
@ -3362,13 +3364,14 @@ tests:
|
||||
name: expected/buffer_ovals.gml
|
||||
type: vector
|
||||
|
||||
- algorithm: qgis:creategridlines
|
||||
- algorithm: qgis:creategrid
|
||||
name: Lines grid 0.1 degree spacing
|
||||
params:
|
||||
CRS: EPSG:4326
|
||||
EXTENT: -0.10453905405405395,8.808021567567568,-2.5010055337837844,4.058021763513514
|
||||
HOVERLAY: 0.0
|
||||
HSPACING: 0.1
|
||||
TYPE: '1'
|
||||
VOVERLAY: 0.0
|
||||
VSPACING: 0.1
|
||||
results:
|
||||
|
Loading…
x
Reference in New Issue
Block a user