diff --git a/python/plugins/processing/algs/qgis/GridLine.py b/python/plugins/processing/algs/qgis/GridLine.py index bcf5cabae4d..3bb87b8d9f5 100644 --- a/python/plugins/processing/algs/qgis/GridLine.py +++ b/python/plugins/processing/algs/qgis/GridLine.py @@ -39,14 +39,15 @@ from qgis.core import (QgsRectangle, QgsPoint, QgsLineString, QgsWkbTypes, + QgsProcessing, + QgsProcessingException, + QgsProcessingParameterEnum, + QgsProcessingParameterExtent, + QgsProcessingParameterNumber, + QgsProcessingParameterCrs, + QgsProcessingParameterFeatureSink, 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 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] @@ -73,19 +74,24 @@ class GridLine(QgisAlgorithm): super().__init__() def initAlgorithm(self, config=None): - self.addParameter(ParameterExtent(self.EXTENT, - self.tr('Grid extent'), optional=False)) - self.addParameter(ParameterNumber(self.HSPACING, - self.tr('Horizontal spacing'), 0.0, 1000000000.0, default=0.0001)) - self.addParameter(ParameterNumber(self.VSPACING, - self.tr('Vertical spacing'), 0.0, 1000000000.0, default=0.0001)) - self.addParameter(ParameterNumber(self.HOVERLAY, - self.tr('Horizontal overlay'), 0.0, 1000000000.0, default=0.0)) - self.addParameter(ParameterNumber(self.VOVERLAY, - self.tr('Vertical overlay'), 0.0, 1000000000.0, default=0.0)) - self.addParameter(ParameterCrs(self.CRS, 'Grid CRS', 'EPSG:4326')) + self.addParameter(QgsProcessingParameterExtent(self.EXTENT, self.tr('Grid extent'))) - self.addOutput(OutputVector(self.OUTPUT, self.tr('Grid'), datatype=[dataobjects.TYPE_VECTOR_LINE])) + 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' @@ -94,33 +100,31 @@ class GridLine(QgisAlgorithm): return self.tr('Create grid (lines)') def processAlgorithm(self, parameters, context, feedback): - 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)) + 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 = QgsRectangle(float(extent[0]), float(extent[2]), - float(extent[1]), float(extent[3])) + bbox = self.parameterAsExtent(parameters, self.EXTENT, context) + crs = self.parameterAsCrs(parameters, self.CRS, context) width = bbox.width() height = bbox.height() if hSpacing <= 0 or vSpacing <= 0: - raise GeoAlgorithmExecutionException( + raise QgsProcessingException( self.tr('Invalid grid spacing: {0}/{1}').format(hSpacing, vSpacing)) if hSpacing <= hOverlay or vSpacing <= vOverlay: - raise GeoAlgorithmExecutionException( + raise QgsProcessingException( self.tr('Invalid overlay: {0}/{1}').format(hOverlay, vOverlay)) if width < hSpacing: - raise GeoAlgorithmExecutionException( + raise QgsProcessingException( self.tr('Horizontal spacing is too small for the covered area')) if height < vSpacing: - raise GeoAlgorithmExecutionException( + raise QgsProcessingException( self.tr('Vertical spacing is too small for the covered area')) fields = QgsFields() @@ -131,7 +135,8 @@ class GridLine(QgisAlgorithm): fields.append(QgsField('id', QVariant.Int, '', 10, 0)) fields.append(QgsField('coord', QVariant.Double, '', 24, 15)) - writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.LineString, crs, context) + (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, + fields, QgsWkbTypes.LineString, crs) if hOverlay > 0: hSpace = [hSpacing - hOverlay, hOverlay] @@ -154,6 +159,9 @@ class GridLine(QgisAlgorithm): 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() @@ -165,7 +173,7 @@ class GridLine(QgisAlgorithm): y, id, y]) - writer.addFeature(feat, QgsFeatureSink.FastInsert) + sink.addFeature(feat, QgsFeatureSink.FastInsert) y = y - vSpace[count % 2] id += 1 count += 1 @@ -181,6 +189,9 @@ class GridLine(QgisAlgorithm): 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() @@ -192,11 +203,11 @@ class GridLine(QgisAlgorithm): bbox.yMinimum(), id, x]) - writer.addFeature(feat, QgsFeatureSink.FastInsert) + 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)) - del writer + return {self.OUTPUT: dest_id} diff --git a/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py b/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py index 6615f66f4c7..53397648311 100644 --- a/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py +++ b/python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py @@ -70,6 +70,7 @@ from .ExtractSpecificNodes import ExtractSpecificNodes from .FixedDistanceBuffer import FixedDistanceBuffer from .FixGeometry import FixGeometry from .GeometryByExpression import GeometryByExpression +from .GridLine import GridLine from .GridPolygon import GridPolygon from .Heatmap import Heatmap from .Hillshade import Hillshade @@ -139,7 +140,6 @@ from .ZonalStatistics import ZonalStatistics # from .ExtractByLocation import ExtractByLocation # from .SelectByLocation import SelectByLocation # from .SpatialJoin import SpatialJoin -# from .GridLine import GridLine # from .Gridify import Gridify # from .HubDistancePoints import HubDistancePoints # from .HubDistanceLines import HubDistanceLines @@ -188,7 +188,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider): # SelectByLocation(), # ExtractByLocation(), # SpatialJoin(), - # GridLine(), Gridify(), HubDistancePoints(), + # Gridify(), HubDistancePoints(), # HubDistanceLines(), HubLines(), # GeometryConvert(), FieldsCalculator(), # JoinAttributes(), @@ -240,6 +240,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider): FixedDistanceBuffer(), FixGeometry(), GeometryByExpression(), + GridLine(), GridPolygon(), Heatmap(), Hillshade(), diff --git a/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml b/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml index 1c73df8b908..64b881dd059 100644 --- a/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml +++ b/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml @@ -1795,21 +1795,21 @@ tests: name: expected/dropped_geometry.csv type: vector -# - algorithm: qgis:creategridlines -# name: Create grid (lines) -# params: -# CRS: EPSG:4326 -# EXTENT: -1,11.2,-4,6.5 -# HSPACING: 5.0 -# VSPACING: 3.0 -# results: -# OUTPUT: -# name: expected/grid_lines.gml -# type: vector -# compare: -# geometry: -# precision: 7 -# + - algorithm: qgis:creategridlines + name: Create grid (lines) + params: + CRS: EPSG:4326 + EXTENT: -1,11.2,-4,6.5 + HSPACING: 5.0 + VSPACING: 3.0 + results: + OUTPUT: + name: expected/grid_lines.gml + type: vector + compare: + geometry: + precision: 7 + - algorithm: qgis:creategridpolygon name: Create grid (rectangles) params: @@ -1858,20 +1858,20 @@ tests: geometry: precision: 7 -# - algorithm: qgis:creategridlines -# name: Create grid (lines with overlay) -# params: -# CRS: EPSG:4326 -# EXTENT: -1,11.2,-4,6.5 -# HOVERLAY: 2.0 -# HSPACING: 5.0 -# VOVERLAY: 1.0 -# VSPACING: 3.0 -# results: -# OUTPUT: -# name: expected/grid_lines_overlay.gml -# type: vector -# + - algorithm: qgis:creategridlines + name: Create grid (lines with overlay) + params: + CRS: EPSG:4326 + EXTENT: -1,11.2,-4,6.5 + HOVERLAY: 2.0 + HSPACING: 5.0 + VOVERLAY: 1.0 + VSPACING: 3.0 + results: + OUTPUT: + name: expected/grid_lines_overlay.gml + type: vector + - algorithm: qgis:creategridpolygon name: Create grid (rectangle with overlay) params: @@ -2586,21 +2586,21 @@ tests: # OUTPUT_LAYER: # name: expected/buffer_ovals.gml # type: vector -# -# - algorithm: qgis:creategridlines -# 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 -# VOVERLAY: 0.0 -# VSPACING: 0.1 -# results: -# OUTPUT: -# name: expected/create_grid_lines.gml -# type: vector -# + + - algorithm: qgis:creategridlines + 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 + VOVERLAY: 0.0 + VSPACING: 0.1 + results: + OUTPUT: + name: expected/create_grid_lines.gml + type: vector + # - algorithm: qgis:convertgeometrytype # name: polygon to centroid # params: