diff --git a/python/plugins/processing/algs/help/qgis.yaml b/python/plugins/processing/algs/help/qgis.yaml index a77487116aa2..81a92f8c8588 100644 --- a/python/plugins/processing/algs/help/qgis.yaml +++ b/python/plugins/processing/algs/help/qgis.yaml @@ -252,18 +252,9 @@ qgis:polygoncentroids: > NOTE: This algorithm is deprecated and the generic "centroids" algorithm (which works for line and multi geometry layers) should be used instead. -qgis:polygonize: > - This algorithm takes a lines layer and creates a polygon layer, with polygons generated from the lines in the input layer. - qgis:polygonstolines: > This algorithm takes a polygon layer and creates a line layer, with lines representing the rings of the polygons in the input layer. -qgis:spatialiteexecutesql: > - This algorithm performs a SQL database query on a SpatiaLite database. - -qgis:postgisexecutesql: > - This algorithm performs a SQL database query on a PostgreSQL database connected to QGIS. - qgis:postgisexecuteandloadsql: > This algorithm performs a SQL database query on a PostGIS database connected to QGIS and loads the query results as a new layer. @@ -360,25 +351,11 @@ qgis:setstyleforrasterlayer: > qgis:setstyleforvectorlayer: > This algorithm sets the style of a vector layer. The style must be defined in a QML file. -qgis:snapgeometries: > - This algorithm snaps the geometries in a layer. Snapping can be done either to the geometries from another layer, or to geometries within the same layer. - - A tolerance is specified in layer units to control how close vertices need to be to the reference layer geometries before they are snapped. - - Snapping occurs to both nodes and edges. Depending on the snapping behavior, either nodes or edges will be preferred. - - Vertices will be inserted or removed as required to make the geometries match the reference geometries. - qgis:splitwithlines: > This algorithm splits the lines or polygons in one layer using the lines in another layer to define the breaking points. Intersection between geometries in both layers are considered as split points. Output will contain multi geometries for split features. -qgis:splitvectorlayer: > - This algorithm takes a vector layer and an attribute and generates a set of vector layers in an output folder. Each of the layers created in that folder contains all features from the input layer with the same value for the specified attribute. - - The number of files generated is equal to the number of different values found for the specified attribute. - qgis:statisticsbycategories: > This algorithm calculates statistics of fields depending on a parent class. diff --git a/python/plugins/processing/algs/qgis/Polygonize.py b/python/plugins/processing/algs/qgis/Polygonize.py deleted file mode 100644 index 591b1c578884..000000000000 --- a/python/plugins/processing/algs/qgis/Polygonize.py +++ /dev/null @@ -1,123 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -*************************************************************************** - Polygonize.py - --------------------- - Date : March 2013 - Copyright : (C) 2013 by Piotr Pociask - Email : ppociask at o2 dot pl -*************************************************************************** -* * -* 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__ = 'Piotr Pociask' -__date__ = 'March 2013' -__copyright__ = '(C) 2013, Piotr Pociask' - -from qgis.PyQt.QtCore import QCoreApplication -from qgis.core import (QgsFields, - QgsFeature, - QgsFeatureSink, - QgsGeometry, - QgsWkbTypes, - QgsFeatureRequest, - QgsProcessing, - QgsProcessingException, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterBoolean, - QgsProcessingParameterFeatureSink) -from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm - - -class Polygonize(QgisAlgorithm): - INPUT = 'INPUT' - OUTPUT = 'OUTPUT' - KEEP_FIELDS = 'KEEP_FIELDS' - - def tags(self): - return self.tr('create,lines,polygons,convert').split(',') - - def group(self): - return self.tr('Vector geometry') - - def groupId(self): - return 'vectorgeometry' - - def __init__(self): - super().__init__() - - def initAlgorithm(self, config=None): - self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, - self.tr('Input layer'), types=[QgsProcessing.TypeVectorLine])) - self.addParameter(QgsProcessingParameterBoolean(self.KEEP_FIELDS, - self.tr('Keep table structure of line layer'), defaultValue=False, optional=True)) - self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Polygons from lines'), QgsProcessing.TypeVectorPolygon)) - - def name(self): - return 'polygonize' - - def displayName(self): - return self.tr('Polygonize') - - def processAlgorithm(self, parameters, context, feedback): - source = self.parameterAsSource(parameters, self.INPUT, context) - if source is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) - - if self.parameterAsBoolean(parameters, self.KEEP_FIELDS, context): - fields = source.fields() - else: - fields = QgsFields() - - (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, - fields, QgsWkbTypes.Polygon, source.sourceCrs()) - if sink is None: - raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT)) - - allLinesList = [] - features = source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([])) - feedback.pushInfo(QCoreApplication.translate('Polygonize', 'Processing lines…')) - total = (40.0 / source.featureCount()) if source.featureCount() else 1 - for current, inFeat in enumerate(features): - if feedback.isCanceled(): - break - - if inFeat.geometry(): - allLinesList.append(inFeat.geometry()) - feedback.setProgress(int(current * total)) - - feedback.setProgress(40) - - feedback.pushInfo(QCoreApplication.translate('Polygonize', 'Noding lines…')) - allLines = QgsGeometry.unaryUnion(allLinesList) - if feedback.isCanceled(): - return {} - - feedback.setProgress(45) - feedback.pushInfo(QCoreApplication.translate('Polygonize', 'Polygonizing…')) - polygons = QgsGeometry.polygonize([allLines]) - if polygons.isEmpty(): - feedback.reportError(self.tr('No polygons were created!')) - feedback.setProgress(50) - - if not polygons.isEmpty(): - feedback.pushInfo(QCoreApplication.translate('Polygonize', 'Saving polygons…')) - total = 50.0 / polygons.constGet().numGeometries() - for i in range(polygons.constGet().numGeometries()): - if feedback.isCanceled(): - break - - outFeat = QgsFeature() - geom = QgsGeometry(polygons.constGet().geometryN(i).clone()) - outFeat.setGeometry(geom) - sink.addFeature(outFeat, QgsFeatureSink.FastInsert) - feedback.setProgress(50 + int(current * total)) - - return {self.OUTPUT: dest_id} diff --git a/python/plugins/processing/algs/qgis/PostGISExecuteSQL.py b/python/plugins/processing/algs/qgis/PostGISExecuteSQL.py deleted file mode 100644 index 995d2a52850b..000000000000 --- a/python/plugins/processing/algs/qgis/PostGISExecuteSQL.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -*************************************************************************** - PostGISExecuteSQL.py - --------------------- - Date : October 2012 - Copyright : (C) 2012 by Victor Olaya and Carterix Geomatics - Email : volayaf 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__ = 'Victor Olaya, Carterix Geomatics' -__date__ = 'October 2012' -__copyright__ = '(C) 2012, Victor Olaya, Carterix Geomatics' - -from qgis.core import ( - QgsProcessingException, - QgsProcessingParameterString, - QgsProcessingParameterProviderConnection, - QgsProviderRegistry, - QgsProviderConnectionException -) -from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm - - -class PostGISExecuteSQL(QgisAlgorithm): - DATABASE = 'DATABASE' - SQL = 'SQL' - - def group(self): - return self.tr('Database') - - def groupId(self): - return 'database' - - def __init__(self): - super().__init__() - - def initAlgorithm(self, config=None): - db_param = QgsProcessingParameterProviderConnection( - self.DATABASE, - self.tr('Database (connection name)'), 'postgres') - self.addParameter(db_param) - self.addParameter(QgsProcessingParameterString(self.SQL, self.tr('SQL query'), multiLine=True)) - - def name(self): - return 'postgisexecutesql' - - def displayName(self): - return self.tr('PostgreSQL execute SQL') - - def shortDescription(self): - return self.tr('Executes a SQL command on a PostgreSQL database') - - def tags(self): - return self.tr('postgis,database').split(',') - - def processAlgorithm(self, parameters, context, feedback): - connection_name = self.parameterAsConnectionName(parameters, self.DATABASE, context) - - # resolve connection details to uri - try: - md = QgsProviderRegistry.instance().providerMetadata('postgres') - conn = md.createConnection(connection_name) - except QgsProviderConnectionException: - raise QgsProcessingException(self.tr('Could not retrieve connection details for {}').format(connection_name)) - - sql = self.parameterAsString(parameters, self.SQL, context).replace('\n', ' ') - try: - conn.executeSql(sql) - except QgsProviderConnectionException as e: - raise QgsProcessingException(self.tr('Error executing SQL:\n{0}').format(e)) - - return {} diff --git a/python/plugins/processing/algs/qgis/QgisAlgorithmProvider.py b/python/plugins/processing/algs/qgis/QgisAlgorithmProvider.py index a7c2d276cee5..76466d254c6c 100644 --- a/python/plugins/processing/algs/qgis/QgisAlgorithmProvider.py +++ b/python/plugins/processing/algs/qgis/QgisAlgorithmProvider.py @@ -63,8 +63,6 @@ from .PointsFromLines import PointsFromLines from .PointsToPaths import PointsToPaths from .PolarPlot import PolarPlot -from .Polygonize import Polygonize -from .PostGISExecuteSQL import PostGISExecuteSQL from .PostGISExecuteAndLoadSQL import PostGISExecuteAndLoadSQL from .RandomExtractWithinSubsets import RandomExtractWithinSubsets from .RandomPointsAlongLines import RandomPointsAlongLines @@ -82,8 +80,6 @@ from .SelectByExpression import SelectByExpression from .SetRasterStyle import SetRasterStyle from .SetVectorStyle import SetVectorStyle -from .SnapGeometries import SnapGeometriesToLayer -from .SpatialiteExecuteSQL import SpatialiteExecuteSQL from .SpatialJoinSummary import SpatialJoinSummary from .StatisticsByCategories import StatisticsByCategories from .TextToFloat import TextToFloat @@ -95,7 +91,6 @@ from .VectorLayerHistogram import VectorLayerHistogram from .VectorLayerScatterplot import VectorLayerScatterplot from .VectorLayerScatterplot3D import VectorLayerScatterplot3D -from .VectorSplit import VectorSplit from .VoronoiPolygons import VoronoiPolygons @@ -144,8 +139,6 @@ def getAlgs(self): PointsFromLines(), PointsToPaths(), PolarPlot(), - Polygonize(), - PostGISExecuteSQL(), PostGISExecuteAndLoadSQL(), RandomExtractWithinSubsets(), RandomPointsAlongLines(), @@ -163,8 +156,6 @@ def getAlgs(self): SelectByExpression(), SetRasterStyle(), SetVectorStyle(), - SnapGeometriesToLayer(), - SpatialiteExecuteSQL(), SpatialJoinSummary(), StatisticsByCategories(), TextToFloat(), @@ -177,7 +168,6 @@ def getAlgs(self): VectorLayerHistogram(), VectorLayerScatterplot(), VectorLayerScatterplot3D(), - VectorSplit(), VoronoiPolygons(), ] diff --git a/python/plugins/processing/algs/qgis/SnapGeometries.py b/python/plugins/processing/algs/qgis/SnapGeometries.py deleted file mode 100644 index 634b2fa9e65d..000000000000 --- a/python/plugins/processing/algs/qgis/SnapGeometries.py +++ /dev/null @@ -1,148 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -*************************************************************************** - SnapGeometries.py - ----------------- - Date : October 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__ = 'October 2016' -__copyright__ = '(C) 2016, Nyall Dawson' - -from qgis.analysis import (QgsGeometrySnapper, - QgsGeometrySnapperSingleSource, - QgsInternalGeometrySnapper) -from qgis.core import (QgsFeatureSink, - QgsProcessing, - QgsMapLayer, - QgsProcessingAlgorithm, - QgsProcessingException, - QgsProcessingParameterDistance, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterFeatureSink, - QgsProcessingParameterEnum) - -from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm - - -class SnapGeometriesToLayer(QgisAlgorithm): - INPUT = 'INPUT' - REFERENCE_LAYER = 'REFERENCE_LAYER' - TOLERANCE = 'TOLERANCE' - OUTPUT = 'OUTPUT' - BEHAVIOR = 'BEHAVIOR' - - def group(self): - return self.tr('Vector geometry') - - def groupId(self): - return 'vectorgeometry' - - def __init__(self): - super().__init__() - - def initAlgorithm(self, config=None): - self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Input layer'), [QgsProcessing.TypeVectorPoint, QgsProcessing.TypeVectorLine, QgsProcessing.TypeVectorPolygon])) - self.addParameter(QgsProcessingParameterFeatureSource(self.REFERENCE_LAYER, self.tr('Reference layer'), - [QgsProcessing.TypeVectorPoint, - QgsProcessing.TypeVectorLine, - QgsProcessing.TypeVectorPolygon])) - - self.addParameter(QgsProcessingParameterDistance(self.TOLERANCE, self.tr('Tolerance'), parentParameterName=self.INPUT, - minValue=0.00000001, defaultValue=10.0)) - - self.modes = [self.tr('Prefer aligning nodes, insert extra vertices where required'), - self.tr('Prefer closest point, insert extra vertices where required'), - self.tr('Prefer aligning nodes, don\'t insert new vertices'), - self.tr('Prefer closest point, don\'t insert new vertices'), - self.tr('Move end points only, prefer aligning nodes'), - self.tr('Move end points only, prefer closest point'), - self.tr('Snap end points to end points only'), - self.tr('Snap to anchor nodes (single layer only)')] - self.addParameter(QgsProcessingParameterEnum( - self.BEHAVIOR, - self.tr('Behavior'), - options=self.modes, defaultValue=0)) - - self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Snapped geometry'))) - - def name(self): - return 'snapgeometries' - - def displayName(self): - return self.tr('Snap geometries to layer') - - def flags(self): - return super().flags() | QgsProcessingAlgorithm.FlagSupportsInPlaceEdits - - def supportInPlaceEdit(self, layer): - return layer.type() == QgsMapLayer.VectorLayer - - def processAlgorithm(self, parameters, context, feedback): - source = self.parameterAsSource(parameters, self.INPUT, context) - if source is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) - - reference_source = self.parameterAsSource(parameters, self.REFERENCE_LAYER, context) - if reference_source is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.REFERENCE_LAYER)) - - tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context) - mode = self.parameterAsEnum(parameters, self.BEHAVIOR, context) - - (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, - source.fields(), source.wkbType(), source.sourceCrs()) - if sink is None: - raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT)) - - features = source.getFeatures() - total = 100.0 / source.featureCount() if source.featureCount() else 0 - - if parameters[self.INPUT] != parameters[self.REFERENCE_LAYER]: - if mode == 7: - raise QgsProcessingException(self.tr('This mode applies when the input and reference layer are the same.')) - - snapper = QgsGeometrySnapper(reference_source) - processed = 0 - for f in features: - if feedback.isCanceled(): - break - if f.hasGeometry(): - out_feature = f - out_feature.setGeometry(snapper.snapGeometry(f.geometry(), tolerance, mode)) - sink.addFeature(out_feature, QgsFeatureSink.FastInsert) - else: - sink.addFeature(f) - processed += 1 - feedback.setProgress(processed * total) - elif mode == 7: - # input layer == ref layer - modified_count = QgsGeometrySnapperSingleSource.run(source, sink, tolerance, feedback) - feedback.pushInfo(self.tr('Snapped {} geometries.').format(modified_count)) - else: - # snapping internally - snapper = QgsInternalGeometrySnapper(tolerance, mode) - processed = 0 - for f in features: - if feedback.isCanceled(): - break - - out_feature = f - out_feature.setGeometry(snapper.snapFeature(f)) - sink.addFeature(out_feature, QgsFeatureSink.FastInsert) - processed += 1 - feedback.setProgress(processed * total) - - return {self.OUTPUT: dest_id} diff --git a/python/plugins/processing/algs/qgis/SpatialiteExecuteSQL.py b/python/plugins/processing/algs/qgis/SpatialiteExecuteSQL.py deleted file mode 100644 index 9bf227fe137d..000000000000 --- a/python/plugins/processing/algs/qgis/SpatialiteExecuteSQL.py +++ /dev/null @@ -1,88 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -*************************************************************************** - SpatialiteExecuteSQL.py - --------------------- - Date : October 2016 - Copyright : (C) 2016 by Mathieu Pellerin - Email : nirvn dot asia 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__ = 'Mathieu Pellerin' -__date__ = 'October 2016' -__copyright__ = '(C) 2016, Mathieu Pellerin' - -from qgis.core import (QgsDataSourceUri, - QgsProcessing, - QgsProcessingAlgorithm, - QgsProcessingException, - QgsProcessingParameterVectorLayer, - QgsProcessingParameterString, - QgsProviderRegistry, - QgsProviderConnectionException) - -from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm - - -class SpatialiteExecuteSQL(QgisAlgorithm): - DATABASE = 'DATABASE' - SQL = 'SQL' - - def group(self): - return self.tr('Database') - - def groupId(self): - return 'database' - - def __init__(self): - super().__init__() - - def initAlgorithm(self, config=None): - self.addParameter(QgsProcessingParameterVectorLayer(self.DATABASE, self.tr('File Database'), types=[QgsProcessing.TypeVector], optional=False)) - self.addParameter(QgsProcessingParameterString(self.SQL, self.tr('SQL query'), multiLine=True)) - - def name(self): - return 'spatialiteexecutesql' - - def displayName(self): - return self.tr('SpatiaLite execute SQL') - - def shortDescription(self): - return self.tr('Executes a SQL command on a SpatiaLite database') - - def flags(self): - return super().flags() | QgsProcessingAlgorithm.FlagNoThreading - - def processAlgorithm(self, parameters, context, feedback): - database = self.parameterAsVectorLayer(parameters, self.DATABASE, context) - databaseuri = database.dataProvider().dataSourceUri() - uri = QgsDataSourceUri(databaseuri) - if uri.database() == '': - if '|layername' in databaseuri: - databaseuri = databaseuri[:databaseuri.find('|layername')] - elif '|layerid' in databaseuri: - databaseuri = databaseuri[:databaseuri.find('|layerid')] - uri = QgsDataSourceUri('dbname=\'%s\'' % (databaseuri)) - - try: - md = QgsProviderRegistry.instance().providerMetadata('spatialite') - conn = md.createConnection(uri.uri(), {}) - except QgsProviderConnectionException: - raise QgsProcessingException(self.tr('Could not connect to {}').format(uri.uri())) - - sql = self.parameterAsString(parameters, self.SQL, context).replace('\n', ' ') - try: - conn.executeSql(sql) - except QgsProviderConnectionException as e: - raise QgsProcessingException(self.tr('Error executing SQL:\n{0}').format(e)) - - return {} diff --git a/python/plugins/processing/algs/qgis/VectorSplit.py b/python/plugins/processing/algs/qgis/VectorSplit.py deleted file mode 100644 index 7984d56b0e85..000000000000 --- a/python/plugins/processing/algs/qgis/VectorSplit.py +++ /dev/null @@ -1,131 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -*************************************************************************** - VectorSplit.py - --------------------- - Date : September 2014 - Copyright : (C) 2014 by Alexander Bruy - Email : alexander dot bruy 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__ = 'Alexander Bruy' -__date__ = 'September 2014' -__copyright__ = '(C) 2014, Alexander Bruy' - -import os - -from qgis.core import (QgsApplication, - QgsProcessingUtils, - QgsFeatureSink, - QgsProcessingParameterFeatureSource, - QgsProcessingParameterField, - QgsProcessingParameterFolderDestination, - QgsProcessingException, - QgsProcessingOutputMultipleLayers, - QgsExpression, - QgsFeatureRequest, - QgsVectorFileWriter) - -from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm -from processing.tools.system import mkdir - -pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0] - - -class VectorSplit(QgisAlgorithm): - INPUT = 'INPUT' - FIELD = 'FIELD' - OUTPUT = 'OUTPUT' - OUTPUT_LAYERS = 'OUTPUT_LAYERS' - - def group(self): - return self.tr('Vector general') - - def groupId(self): - return 'vectorgeneral' - - def __init__(self): - super().__init__() - - def initAlgorithm(self, config=None): - self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, - self.tr('Input layer'))) - - self.addParameter(QgsProcessingParameterField(self.FIELD, - self.tr('Unique ID field'), None, self.INPUT)) - - self.addParameter(QgsProcessingParameterFolderDestination(self.OUTPUT, - self.tr('Output directory'))) - self.addOutput(QgsProcessingOutputMultipleLayers(self.OUTPUT_LAYERS, self.tr('Output layers'))) - - def icon(self): - return QgsApplication.getThemeIcon("/algorithms/mAlgorithmSplitLayer.svg") - - def svgIconPath(self): - return QgsApplication.iconPath("/algorithms/mAlgorithmSplitLayer.svg") - - def name(self): - return 'splitvectorlayer' - - def displayName(self): - return self.tr('Split vector layer') - - def processAlgorithm(self, parameters, context, feedback): - source = self.parameterAsSource(parameters, self.INPUT, context) - if source is None: - raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) - - fieldName = self.parameterAsString(parameters, self.FIELD, context) - directory = self.parameterAsString(parameters, self.OUTPUT, context) - - output_format = context.preferredVectorFormat() - if output_format not in QgsVectorFileWriter.supportedFormatExtensions(): - # fallback to gpkg if preferred format is not available - output_format = 'gpkg' - - mkdir(directory) - - fieldIndex = source.fields().lookupField(fieldName) - uniqueValues = source.uniqueValues(fieldIndex) - baseName = os.path.join(directory, '{0}'.format(fieldName)) - - fields = source.fields() - crs = source.sourceCrs() - geomType = source.wkbType() - - total = 100.0 / len(uniqueValues) if uniqueValues else 1 - output_layers = [] - - for current, i in enumerate(uniqueValues): - if feedback.isCanceled(): - break - fName = '{0}_{1}.{2}'.format(baseName, str(i).strip(), output_format) - feedback.pushInfo(self.tr('Creating layer: {}').format(fName)) - - sink, dest = QgsProcessingUtils.createFeatureSink(fName, context, fields, geomType, crs) - - filter = '{} = {}'.format(QgsExpression.quotedColumnRef(fieldName), QgsExpression.quotedValue(i)) - req = QgsFeatureRequest().setFilterExpression(filter) - - count = 0 - for f in source.getFeatures(req): - if feedback.isCanceled(): - break - sink.addFeature(f, QgsFeatureSink.FastInsert) - count += 1 - feedback.pushInfo(self.tr('Added {} features to layer').format(count)) - output_layers.append(fName) - del sink - - feedback.setProgress(int(current * total)) - - return {self.OUTPUT: directory, self.OUTPUT_LAYERS: output_layers} diff --git a/python/plugins/processing/tests/testdata/qgis_algorithm_tests2.yaml b/python/plugins/processing/tests/testdata/qgis_algorithm_tests2.yaml index 48d724f57e9d..adb1c5cb7943 100755 --- a/python/plugins/processing/tests/testdata/qgis_algorithm_tests2.yaml +++ b/python/plugins/processing/tests/testdata/qgis_algorithm_tests2.yaml @@ -495,9 +495,10 @@ tests: name: expected/geometry_by_expression_line.gml type: vector - - algorithm: qgis:snapgeometries + - algorithm: native:snapgeometries name: Snap lines to lines params: + BEHAVIOR: '0' INPUT: name: snap_lines.gml type: vector @@ -510,9 +511,10 @@ tests: name: expected/snap_lines_to_lines.gml type: vector - - algorithm: qgis:snapgeometries + - algorithm: native:snapgeometries name: Snap polygons to polygons params: + BEHAVIOR: '0' INPUT: name: snap_polys.gml type: vector @@ -525,9 +527,10 @@ tests: name: expected/snap_polys_to_polys.gml type: vector - - algorithm: qgis:snapgeometries + - algorithm: native:snapgeometries name: Snap points to points params: + BEHAVIOR: '0' INPUT: name: snap_points.gml type: vector @@ -540,7 +543,7 @@ tests: name: expected/snap_points_to_points.gml type: vector - - algorithm: qgis:snapgeometries + - algorithm: native:snapgeometries name: Snap points to lines (prefer nodes) params: BEHAVIOR: '0' @@ -556,7 +559,7 @@ tests: name: expected/snap_point_to_lines_prefer_nodes.gml type: vector - - algorithm: qgis:snapgeometries + - algorithm: native:snapgeometries name: Snap points to lines (prefer closest) params: BEHAVIOR: '1' @@ -572,7 +575,7 @@ tests: name: expected/snap_point_to_lines_prefer_closest.gml type: vector - - algorithm: qgis:snapgeometries + - algorithm: native:snapgeometries name: Snap internal params: BEHAVIOR: '0' @@ -588,7 +591,7 @@ tests: name: expected/snap_internal.gml type: vector - - algorithm: qgis:snapgeometries + - algorithm: native:snapgeometries name: Test Snap Geometries (to each other) params: BEHAVIOR: '7' diff --git a/python/plugins/processing/tests/testdata/qgis_algorithm_tests3.yaml b/python/plugins/processing/tests/testdata/qgis_algorithm_tests3.yaml index fee0ee171b89..a5da27ab324c 100755 --- a/python/plugins/processing/tests/testdata/qgis_algorithm_tests3.yaml +++ b/python/plugins/processing/tests/testdata/qgis_algorithm_tests3.yaml @@ -178,7 +178,7 @@ tests: name: expected/poly_ring_self_intersection_valid_ignore_self.gml type: vector - - algorithm: qgis:polygonize + - algorithm: native:polygonize name: Polygonize params: KEEP_FIELDS: false diff --git a/src/analysis/CMakeLists.txt b/src/analysis/CMakeLists.txt index 1dd5adaea7cc..deba7ee8fdbc 100644 --- a/src/analysis/CMakeLists.txt +++ b/src/analysis/CMakeLists.txt @@ -51,6 +51,9 @@ SET(QGIS_ANALYSIS_SRCS processing/qgsalgorithmdrape.cpp processing/qgsalgorithmdropgeometry.cpp processing/qgsalgorithmdropmzvalues.cpp + processing/qgsalgorithmexecutepostgisquery.cpp + processing/qgsalgorithmexecutespatialitequery.cpp + processing/qgsalgorithmexecutespatialitequeryregistered.cpp processing/qgsalgorithmexplode.cpp processing/qgsalgorithmexplodehstore.cpp processing/qgsalgorithmextendlines.cpp @@ -109,6 +112,7 @@ SET(QGIS_ANALYSIS_SRCS processing/qgsalgorithmpointsalonggeometry.cpp processing/qgsalgorithmpointslayerfromtable.cpp processing/qgsalgorithmpoleofinaccessibility.cpp + processing/qgsalgorithmpolygonize.cpp processing/qgsalgorithmprojectpointcartesian.cpp processing/qgsalgorithmpromotetomultipart.cpp processing/qgsalgorithmraiseexception.cpp @@ -151,11 +155,13 @@ SET(QGIS_ANALYSIS_SRCS processing/qgsalgorithmsinglesidedbuffer.cpp processing/qgsalgorithmslope.cpp processing/qgsalgorithmsmooth.cpp + processing/qgsalgorithmsnapgeometries.cpp processing/qgsalgorithmsnaptogrid.cpp processing/qgsalgorithmspatialindex.cpp processing/qgsalgorithmsplitfeaturesbyattributecharacter.cpp processing/qgsalgorithmsplitlineantimeridian.cpp processing/qgsalgorithmsplitlinesbylength.cpp + processing/qgsalgorithmsplitvectorlayer.cpp processing/qgsalgorithmsplitwithlines.cpp processing/qgsalgorithmstringconcatenation.cpp processing/qgsalgorithmswapxy.cpp diff --git a/src/analysis/processing/qgsalgorithmexecutepostgisquery.cpp b/src/analysis/processing/qgsalgorithmexecutepostgisquery.cpp new file mode 100644 index 000000000000..24b3d204005f --- /dev/null +++ b/src/analysis/processing/qgsalgorithmexecutepostgisquery.cpp @@ -0,0 +1,96 @@ +/*************************************************************************** + qgsalgorithmexecutepostgisquery.cpp + --------------------- + begin : May 2020 + copyright : (C) 2020 by Alexander Bruy + email : alexander dot bruy 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. * + * * + ***************************************************************************/ + +#include "qgsalgorithmexecutepostgisquery.h" +#include "qgsproviderregistry.h" +#include "qgsprovidermetadata.h" +#include "qgsabstractdatabaseproviderconnection.h" + +///@cond PRIVATE + +QString QgsExecutePostgisQueryAlgorithm::name() const +{ + return QStringLiteral( "postgisexecutesql" ); +} + +QString QgsExecutePostgisQueryAlgorithm::displayName() const +{ + return QObject::tr( "PostgreSQL execute SQL" ); +} + +QStringList QgsExecutePostgisQueryAlgorithm::tags() const +{ + return QObject::tr( "database,sql,postgresql,postgis,execute" ).split( ',' ); +} + +QString QgsExecutePostgisQueryAlgorithm::group() const +{ + return QObject::tr( "Database" ); +} + +QString QgsExecutePostgisQueryAlgorithm::groupId() const +{ + return QStringLiteral( "database" ); +} + +QString QgsExecutePostgisQueryAlgorithm::shortHelpString() const +{ + return QObject::tr( "Executes a SQL command on a PostgreSQL database." ); +} + +QgsExecutePostgisQueryAlgorithm *QgsExecutePostgisQueryAlgorithm::createInstance() const +{ + return new QgsExecutePostgisQueryAlgorithm(); +} + +void QgsExecutePostgisQueryAlgorithm::initAlgorithm( const QVariantMap & ) +{ + addParameter( new QgsProcessingParameterProviderConnection( QStringLiteral( "DATABASE" ), QObject::tr( "Database (connection name)" ), QStringLiteral( "postgres" ) ) ); + addParameter( new QgsProcessingParameterString( QStringLiteral( "SQL" ), QObject::tr( "SQL query" ), QVariant(), true ) ); +} + +QVariantMap QgsExecutePostgisQueryAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) +{ + Q_UNUSED( feedback ); + + QString connName = parameterAsConnectionName( parameters, QStringLiteral( "DATABASE" ), context ); + + std::unique_ptr conn; + try + { + std::unique_ptr md( QgsProviderRegistry::instance()->providerMetadata( QStringLiteral( "postgres" ) ) ); + conn.reset( static_cast( md->createConnection( connName ) ) ); + } + catch ( QgsProviderConnectionException & ) + { + throw QgsProcessingException( QObject::tr( "Could not retrieve connection details for %1" ).arg( connName ) ); + } + + QString sql = parameterAsString( parameters, QStringLiteral( "SQL" ), context ).replace( '\n', ' ' ); + try + { + conn->executeSql( sql ); + } + catch ( QgsProviderConnectionException &ex ) + { + throw QgsProcessingException( QObject::tr( "Error executing SQL:\n%1" ).arg( ex.what() ) ); + } + + return QVariantMap(); +} + +///@endcond diff --git a/src/analysis/processing/qgsalgorithmexecutepostgisquery.h b/src/analysis/processing/qgsalgorithmexecutepostgisquery.h new file mode 100644 index 000000000000..390d3f231a96 --- /dev/null +++ b/src/analysis/processing/qgsalgorithmexecutepostgisquery.h @@ -0,0 +1,54 @@ +/*************************************************************************** + qgsalgorithmexecutepostgisquery.h + ------------------------------ + begin : May 2020 + copyright : (C) 2020 by Alexander Bruy + email : alexander dot bruy 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. * + * * + ***************************************************************************/ + +#ifndef QGSALGORITHMEXECUTEPOSTGISQUERY_H +#define QGSALGORITHMEXECUTEPOSTGISQUERY_H + +#define SIP_NO_FILE + +#include "qgis_sip.h" +#include "qgsprocessingalgorithm.h" + +///@cond PRIVATE + +/** + * Native execute PostGIS query algorithm. + */ +class QgsExecutePostgisQueryAlgorithm : public QgsProcessingAlgorithm +{ + + public: + + QgsExecutePostgisQueryAlgorithm() = default; + void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override; + QString name() const override; + QString displayName() const override; + QStringList tags() const override; + QString group() const override; + QString groupId() const override; + QString shortHelpString() const override; + QgsExecutePostgisQueryAlgorithm *createInstance() const override SIP_FACTORY; + + protected: + + QVariantMap processAlgorithm( const QVariantMap ¶meters, + QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; +}; + +///@endcond PRIVATE + +#endif // QGSALGORITHMEXECUTEPOSTGISQUERY_H diff --git a/src/analysis/processing/qgsalgorithmexecutespatialitequery.cpp b/src/analysis/processing/qgsalgorithmexecutespatialitequery.cpp new file mode 100644 index 000000000000..ec87f5be2689 --- /dev/null +++ b/src/analysis/processing/qgsalgorithmexecutespatialitequery.cpp @@ -0,0 +1,107 @@ +/*************************************************************************** + qgsalgorithmexecutepostgisquery.cpp + --------------------- + begin : May 2020 + copyright : (C) 2020 by Alexander Bruy + email : alexander dot bruy 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. * + * * + ***************************************************************************/ + +#include "qgsalgorithmexecutespatialitequery.h" +#include "qgsproviderregistry.h" +#include "qgsprovidermetadata.h" +#include "qgsabstractdatabaseproviderconnection.h" + +///@cond PRIVATE + +QString QgsExecuteSpatialiteQueryAlgorithm::name() const +{ + return QStringLiteral( "spatialiteexecutesql" ); +} + +QString QgsExecuteSpatialiteQueryAlgorithm::displayName() const +{ + return QObject::tr( "SpatiaLite execute SQL" ); +} + +QStringList QgsExecuteSpatialiteQueryAlgorithm::tags() const +{ + return QObject::tr( "database,sql,spatialite,execute" ).split( ',' ); +} + +QString QgsExecuteSpatialiteQueryAlgorithm::group() const +{ + return QObject::tr( "Database" ); +} + +QString QgsExecuteSpatialiteQueryAlgorithm::groupId() const +{ + return QStringLiteral( "database" ); +} + +QString QgsExecuteSpatialiteQueryAlgorithm::shortHelpString() const +{ + return QObject::tr( "Executes a SQL command on a SpatiaLite database." ); +} + +QgsExecuteSpatialiteQueryAlgorithm *QgsExecuteSpatialiteQueryAlgorithm::createInstance() const +{ + return new QgsExecuteSpatialiteQueryAlgorithm(); +} + +void QgsExecuteSpatialiteQueryAlgorithm::initAlgorithm( const QVariantMap & ) +{ + addParameter( new QgsProcessingParameterVectorLayer( QStringLiteral( "DATABASE" ), QObject::tr( "Database (connection name)" ), QList< int >() << QgsProcessing::TypeVector ) ); + addParameter( new QgsProcessingParameterString( QStringLiteral( "SQL" ), QObject::tr( "SQL query" ), QVariant(), true ) ); +} + +QVariantMap QgsExecuteSpatialiteQueryAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) +{ + //Q_UNUSED( feedback ); + QgsVectorLayer *layer = parameterAsVectorLayer( parameters, QStringLiteral( "DATABASE" ), context ); + QString databaseUri = layer->dataProvider()->dataSourceUri(); + QgsDataSourceUri uri( databaseUri ); + if ( uri.database().isEmpty() ) + { + if ( databaseUri.contains( QStringLiteral( "|layername" ), Qt::CaseInsensitive ) ) + databaseUri = databaseUri.left( databaseUri.indexOf( QStringLiteral( "|layername" ) ) ); + else if ( databaseUri.contains( QStringLiteral( "|layerid" ), Qt::CaseInsensitive ) ) + databaseUri = databaseUri.left( databaseUri.indexOf( QStringLiteral( "|layerid" ) ) ); + + uri = QgsDataSourceUri( QStringLiteral( "dbname='%1'" ).arg( databaseUri ) ); + } + + feedback->pushInfo( databaseUri ); + std::unique_ptr conn; + try + { + std::unique_ptr md( QgsProviderRegistry::instance()->providerMetadata( QStringLiteral( "spatialite" ) ) ); + conn.reset( static_cast( md->createConnection( uri.uri(), QVariantMap() ) ) ); + } + catch ( QgsProviderConnectionException & ) + { + throw QgsProcessingException( QObject::tr( "Could not connect to %1" ).arg( uri.uri() ) ); + } + + QString sql = parameterAsString( parameters, QStringLiteral( "SQL" ), context ).replace( '\n', ' ' ); + try + { + conn->executeSql( sql ); + } + catch ( QgsProviderConnectionException &ex ) + { + throw QgsProcessingException( QObject::tr( "Error executing SQL:\n%1" ).arg( ex.what() ) ); + } + + return QVariantMap(); +} + +///@endcond diff --git a/src/analysis/processing/qgsalgorithmexecutespatialitequery.h b/src/analysis/processing/qgsalgorithmexecutespatialitequery.h new file mode 100644 index 000000000000..b9e205f55c64 --- /dev/null +++ b/src/analysis/processing/qgsalgorithmexecutespatialitequery.h @@ -0,0 +1,54 @@ +/*************************************************************************** + qgsalgorithmexecutespatialitequery.h + ------------------------------ + begin : May 2020 + copyright : (C) 2020 by Alexander Bruy + email : alexander dot bruy 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. * + * * + ***************************************************************************/ + +#ifndef QGSALGORITHMEXECUTESPATIALITEQUERY_H +#define QGSALGORITHMEXECUTESPATIALITEQUERY_H + +#define SIP_NO_FILE + +#include "qgis_sip.h" +#include "qgsprocessingalgorithm.h" + +///@cond PRIVATE + +/** + * Native execute PostGIS query algorithm. + */ +class QgsExecuteSpatialiteQueryAlgorithm : public QgsProcessingAlgorithm +{ + + public: + + QgsExecuteSpatialiteQueryAlgorithm() = default; + void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override; + QString name() const override; + QString displayName() const override; + QStringList tags() const override; + QString group() const override; + QString groupId() const override; + QString shortHelpString() const override; + QgsExecuteSpatialiteQueryAlgorithm *createInstance() const override SIP_FACTORY; + + protected: + + QVariantMap processAlgorithm( const QVariantMap ¶meters, + QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; +}; + +///@endcond PRIVATE + +#endif // QGSALGORITHMEXECUTESPATIALITEQUERY_H diff --git a/src/analysis/processing/qgsalgorithmexecutespatialitequeryregistered.cpp b/src/analysis/processing/qgsalgorithmexecutespatialitequeryregistered.cpp new file mode 100644 index 000000000000..4de8e2bbd7ea --- /dev/null +++ b/src/analysis/processing/qgsalgorithmexecutespatialitequeryregistered.cpp @@ -0,0 +1,96 @@ +/*************************************************************************** + qgsalgorithmexecutepostgisqueryregistered.cpp + --------------------- + begin : May 2020 + copyright : (C) 2020 by Alexander Bruy + email : alexander dot bruy 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. * + * * + ***************************************************************************/ + +#include "qgsalgorithmexecutespatialitequeryregistered.h" +#include "qgsproviderregistry.h" +#include "qgsprovidermetadata.h" +#include "qgsabstractdatabaseproviderconnection.h" + +///@cond PRIVATE + +QString QgsExecuteRegisteredSpatialiteQueryAlgorithm::name() const +{ + return QStringLiteral( "spatialiteexecutesqlregistered" ); +} + +QString QgsExecuteRegisteredSpatialiteQueryAlgorithm::displayName() const +{ + return QObject::tr( "SpatiaLite execute SQL (registered DB)" ); +} + +QStringList QgsExecuteRegisteredSpatialiteQueryAlgorithm::tags() const +{ + return QObject::tr( "database,sql,spatialite,execute" ).split( ',' ); +} + +QString QgsExecuteRegisteredSpatialiteQueryAlgorithm::group() const +{ + return QObject::tr( "Database" ); +} + +QString QgsExecuteRegisteredSpatialiteQueryAlgorithm::groupId() const +{ + return QStringLiteral( "database" ); +} + +QString QgsExecuteRegisteredSpatialiteQueryAlgorithm::shortHelpString() const +{ + return QObject::tr( "Executes a SQL command on a SpatiaLite database." ); +} + +QgsExecuteRegisteredSpatialiteQueryAlgorithm *QgsExecuteRegisteredSpatialiteQueryAlgorithm::createInstance() const +{ + return new QgsExecuteRegisteredSpatialiteQueryAlgorithm(); +} + +void QgsExecuteRegisteredSpatialiteQueryAlgorithm::initAlgorithm( const QVariantMap & ) +{ + addParameter( new QgsProcessingParameterProviderConnection( QStringLiteral( "DATABASE" ), QObject::tr( "Database (connection name)" ), QStringLiteral( "spatialite" ) ) ); + addParameter( new QgsProcessingParameterString( QStringLiteral( "SQL" ), QObject::tr( "SQL query" ), QVariant(), true ) ); +} + +QVariantMap QgsExecuteRegisteredSpatialiteQueryAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) +{ + Q_UNUSED( feedback ); + + QString connName = parameterAsConnectionName( parameters, QStringLiteral( "DATABASE" ), context ); + + std::unique_ptr conn; + try + { + std::unique_ptr md( QgsProviderRegistry::instance()->providerMetadata( QStringLiteral( "spatialite" ) ) ); + conn.reset( static_cast( md->createConnection( connName ) ) ); + } + catch ( QgsProviderConnectionException & ) + { + throw QgsProcessingException( QObject::tr( "Could not retrieve connection details for %1" ).arg( connName ) ); + } + + QString sql = parameterAsString( parameters, QStringLiteral( "SQL" ), context ).replace( '\n', ' ' ); + try + { + conn->executeSql( sql ); + } + catch ( QgsProviderConnectionException &ex ) + { + throw QgsProcessingException( QObject::tr( "Error executing SQL:\n%1" ).arg( ex.what() ) ); + } + + return QVariantMap(); +} + +///@endcond diff --git a/src/analysis/processing/qgsalgorithmexecutespatialitequeryregistered.h b/src/analysis/processing/qgsalgorithmexecutespatialitequeryregistered.h new file mode 100644 index 000000000000..005a843c6c1e --- /dev/null +++ b/src/analysis/processing/qgsalgorithmexecutespatialitequeryregistered.h @@ -0,0 +1,54 @@ +/*************************************************************************** + qgsalgorithmexecutespatialitequeryregistered.h + ------------------------------ + begin : May 2020 + copyright : (C) 2020 by Alexander Bruy + email : alexander dot bruy 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. * + * * + ***************************************************************************/ + +#ifndef QGSALGORITHMEXECUTESPATIALITEQUERYREGISTERED_H +#define QGSALGORITHMEXECUTESPATIALITEQUERYREGISTERED_H + +#define SIP_NO_FILE + +#include "qgis_sip.h" +#include "qgsprocessingalgorithm.h" + +///@cond PRIVATE + +/** + * Native execute SpoatiaLite (registered) query algorithm. + */ +class QgsExecuteRegisteredSpatialiteQueryAlgorithm : public QgsProcessingAlgorithm +{ + + public: + + QgsExecuteRegisteredSpatialiteQueryAlgorithm() = default; + void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override; + QString name() const override; + QString displayName() const override; + QStringList tags() const override; + QString group() const override; + QString groupId() const override; + QString shortHelpString() const override; + QgsExecuteRegisteredSpatialiteQueryAlgorithm *createInstance() const override SIP_FACTORY; + + protected: + + QVariantMap processAlgorithm( const QVariantMap ¶meters, + QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; +}; + +///@endcond PRIVATE + +#endif // QGSALGORITHMEXECUTESPATIALITEQUERYREGISTERED_H diff --git a/src/analysis/processing/qgsalgorithmpolygonize.cpp b/src/analysis/processing/qgsalgorithmpolygonize.cpp new file mode 100644 index 000000000000..04d3459d0887 --- /dev/null +++ b/src/analysis/processing/qgsalgorithmpolygonize.cpp @@ -0,0 +1,141 @@ +/*************************************************************************** + qgsalgorithmdpolygonize.cpp + --------------------- + begin : May 2020 + copyright : (C) 2020 by Alexander Bruy + email : alexander dot bruy 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. * + * * + ***************************************************************************/ + +#include "qgsalgorithmpolygonize.h" +#include "qgsgeometrycollection.h" + +///@cond PRIVATE + +QString QgsPolygonizeAlgorithm::name() const +{ + return QStringLiteral( "polygonize" ); +} + +QString QgsPolygonizeAlgorithm::displayName() const +{ + return QObject::tr( "Polygonize" ); +} + +QString QgsPolygonizeAlgorithm::shortHelpString() const +{ + return QObject::tr( "Creates a polygon layer from the input lines layer." ); +} + +QStringList QgsPolygonizeAlgorithm::tags() const +{ + return QObject::tr( "create,lines,polygons,convert" ).split( ',' ); +} + +QString QgsPolygonizeAlgorithm::group() const +{ + return QObject::tr( "Vector geometry" ); +} + +QString QgsPolygonizeAlgorithm::groupId() const +{ + return QStringLiteral( "vectorgeometry" ); +} + +void QgsPolygonizeAlgorithm::initAlgorithm( const QVariantMap & ) +{ + addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), + QObject::tr( "Input layer" ), QList< int >() << QgsProcessing::TypeVectorLine ) ); + addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "KEEP_FIELDS" ), + QObject::tr( "Keep fields from the input layer" ), false, true ) ); + addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), + QObject::tr( "Polygons" ), QgsProcessing::TypeVectorPolygon ) ); + addOutput( new QgsProcessingOutputNumber( QStringLiteral( "NUM_POLYGONS" ), QObject::tr( "Number of polygons" ) ) ); +} + +QgsPolygonizeAlgorithm *QgsPolygonizeAlgorithm::createInstance() const +{ + return new QgsPolygonizeAlgorithm(); +} + +QVariantMap QgsPolygonizeAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) +{ + std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) ); + if ( !source ) + throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) ); + + QgsFields fields = QgsFields(); + if ( parameterAsBoolean( parameters, QStringLiteral( "KEEP_FIELDS" ), context ) ) + fields = source->fields(); + + QString dest; + std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, QgsWkbTypes::Polygon, source->sourceCrs() ) ); + if ( !sink ) + throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) ); + + int polygonCount = 0; + + feedback->pushInfo( QObject::tr( "Collecting lines…" ) ); + int i = 0; + double step = source->featureCount() > 0 ? 40.0 / source->featureCount() : 1; + QgsFeature f; + QgsFeatureIterator features = source->getFeatures( QgsFeatureRequest().setNoAttributes() ); + QVector linesList; + linesList.reserve( source->featureCount() ); + while ( features.nextFeature( f ) ) + { + if ( feedback->isCanceled() ) + break; + + if ( f.hasGeometry() ) + linesList << f.geometry(); + + feedback->setProgress( i * step ); + } + feedback->setProgress( 40 ); + + feedback->pushInfo( QObject::tr( "Noding lines…" ) ); + QgsGeometry lines = QgsGeometry::unaryUnion( linesList ); + if ( feedback->isCanceled() ) + return QVariantMap(); + feedback->setProgress( 45 ); + + feedback->pushInfo( QObject::tr( "Polygonizing…" ) ); + QgsGeometry polygons = QgsGeometry::polygonize( QVector< QgsGeometry >() << lines ); + if ( polygons.isEmpty() ) + feedback->reportError( QObject::tr( "No polygons were created." ) ); + + feedback->setProgress( 50 ); + + if ( !polygons.isEmpty() ) + { + const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( polygons.constGet() ); + step = collection->numGeometries() > 0 ? 50.0 / collection->numGeometries() : 1; + for ( int part = 0; part < collection->numGeometries(); ++part ) + { + if ( feedback->isCanceled() ) + break; + + QgsFeature outFeat; + outFeat.setGeometry( QgsGeometry( collection->geometryN( part )->clone() ) ); + sink->addFeature( outFeat, QgsFeatureSink::FastInsert ); + feedback->setProgress( 50 + i * step ); + polygonCount += 1; + } + } + + QVariantMap outputs; + outputs.insert( QStringLiteral( "OUTPUT" ), dest ); + outputs.insert( QStringLiteral( "NUM_POLYGONS" ), polygonCount ); + return outputs; +} + +///@endcond diff --git a/src/analysis/processing/qgsalgorithmpolygonize.h b/src/analysis/processing/qgsalgorithmpolygonize.h new file mode 100644 index 000000000000..d723b6bb307e --- /dev/null +++ b/src/analysis/processing/qgsalgorithmpolygonize.h @@ -0,0 +1,54 @@ +/*************************************************************************** + qgsalgorithmpolygonize.h + --------------------- + begin : May 2020 + copyright : (C) 2020 by Alexander Bruy + email : alexander dot bruy 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. * + * * + ***************************************************************************/ + +#ifndef QGSALGORITHMPOLYGONIZE_H +#define QGSALGORITHMPOLYGONIZE_H + +#define SIP_NO_FILE + +#include "qgis_sip.h" +#include "qgsprocessingalgorithm.h" + +///@cond PRIVATE + +/** + * Native polygonize algorithm. + */ +class QgsPolygonizeAlgorithm : public QgsProcessingAlgorithm +{ + + public: + + QgsPolygonizeAlgorithm() = default; + void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override; + QString name() const override; + QString displayName() const override; + QStringList tags() const override; + QString group() const override; + QString groupId() const override; + QString shortHelpString() const override; + QgsPolygonizeAlgorithm *createInstance() const override SIP_FACTORY; + + protected: + + QVariantMap processAlgorithm( const QVariantMap ¶meters, + QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; +}; + +///@endcond PRIVATE + +#endif // QGSALGORITHMPOLYGONIZE_H diff --git a/src/analysis/processing/qgsalgorithmsnapgeometries.cpp b/src/analysis/processing/qgsalgorithmsnapgeometries.cpp new file mode 100644 index 000000000000..086f695f868f --- /dev/null +++ b/src/analysis/processing/qgsalgorithmsnapgeometries.cpp @@ -0,0 +1,195 @@ +/*************************************************************************** + qgsalgorithmsnapgeometries.cpp + --------------------- + begin : May 2020 + copyright : (C) 2020 by Alexander Bruy + email : alexander dot bruy 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. * + * * + ***************************************************************************/ + +#include "qgsalgorithmsnapgeometries.h" + +#include "qgsvectorlayer.h" +#include "vector/qgsgeometrysnapper.h" +#include "vector/qgsgeometrysnappersinglesource.h" + +///@cond PRIVATE + +QString QgsSnapGeometriesAlgorithm::name() const +{ + return QStringLiteral( "snapgeometries" ); +} + +QString QgsSnapGeometriesAlgorithm::displayName() const +{ + return QObject::tr( "Snap geometries to layer" ); +} + +QString QgsSnapGeometriesAlgorithm::shortHelpString() const +{ + return QObject::tr( "Snaps the geometries in a layer. Snapping can be done either to the geometries " + "from another layer, or to geometries within the same layer." ) + + QStringLiteral( "\n\n" ) + + QObject::tr( "A tolerance is specified in layer units to control how close vertices need " + "to be to the reference layer geometries before they are snapped." ) + + QStringLiteral( "\n\n" ) + + QObject::tr( "Snapping occurs to both nodes and edges. Depending on the snapping behavior, " + "either nodes or edges will be preferred." ) + + QStringLiteral( "\n\n" ) + + QObject::tr( "Vertices will be inserted or removed as required to make the geometries match " + "the reference geometries." ); +} + +QStringList QgsSnapGeometriesAlgorithm::tags() const +{ + return QObject::tr( "geometry,snap,tolerance" ).split( ',' ); +} + +QString QgsSnapGeometriesAlgorithm::group() const +{ + return QObject::tr( "Vector geometry" ); +} + +QString QgsSnapGeometriesAlgorithm::groupId() const +{ + return QStringLiteral( "vectorgeometry" ); +} + +QgsProcessingAlgorithm::Flags QgsSnapGeometriesAlgorithm::flags() const +{ + Flags f = QgsProcessingAlgorithm::flags(); + f |= QgsProcessingAlgorithm::FlagSupportsInPlaceEdits; + return f; +} + +bool QgsSnapGeometriesAlgorithm::supportInPlaceEdit( const QgsMapLayer *l ) const +{ + const QgsVectorLayer *layer = qobject_cast< const QgsVectorLayer * >( l ); + if ( !layer ) + return false; + + return layer->isSpatial(); +} + +void QgsSnapGeometriesAlgorithm::initAlgorithm( const QVariantMap & ) +{ + addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ), + QList< int >() << QgsProcessing::TypeVectorPoint << QgsProcessing::TypeVectorLine << QgsProcessing::TypeVectorPolygon ) ); + addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "REFERENCE_LAYER" ), QObject::tr( "Reference layer" ), + QList< int >() << QgsProcessing::TypeVectorPoint << QgsProcessing::TypeVectorLine << QgsProcessing::TypeVectorPolygon ) ); + addParameter( new QgsProcessingParameterDistance( QStringLiteral( "TOLERANCE" ), QObject::tr( "Tolerance" ), + 10.0, QStringLiteral( "INPUT" ), false, 0.00000001 ) ); + + QStringList options = QStringList() + << QObject::tr( "Prefer aligning nodes, insert extra vertices where required" ) + << QObject::tr( "Prefer closest point, insert extra vertices where required" ) + << QObject::tr( "Prefer aligning nodes, don't insert new vertices" ) + << QObject::tr( "Prefer closest point, don't insert new vertices" ) + << QObject::tr( "Move end points only, prefer aligning nodes" ) + << QObject::tr( "Move end points only, prefer closest point" ) + << QObject::tr( "Snap end points to end points only" ) + << QObject::tr( "Snap to anchor nodes (single layer only)" ); + addParameter( new QgsProcessingParameterEnum( QStringLiteral( "BEHAVIOR" ), QObject::tr( "Behavior" ), options, false, QVariantList() << 0 ) ); + addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), + QObject::tr( "Snapped geometry" ), QgsProcessing::TypeVectorPolygon ) ); +} + +QgsSnapGeometriesAlgorithm *QgsSnapGeometriesAlgorithm::createInstance() const +{ + return new QgsSnapGeometriesAlgorithm(); +} + +QVariantMap QgsSnapGeometriesAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) +{ + std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) ); + if ( !source ) + throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) ); + + std::unique_ptr< QgsProcessingFeatureSource > referenceSource( parameterAsSource( parameters, QStringLiteral( "REFERENCE_LAYER" ), context ) ); + if ( !referenceSource ) + throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "REFERENCE_LAYER" ) ) ); + + double tolerance = parameterAsDouble( parameters, QStringLiteral( "TOLERANCE" ), context ); + QgsGeometrySnapper::SnapMode mode = static_cast( parameterAsEnum( parameters, QStringLiteral( "BEHAVIOR" ), context ) ); + + QString dest; + std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, source->fields(), source->wkbType(), source->sourceCrs() ) ); + if ( !sink ) + throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) ); + + double step = source->featureCount() > 0 ? 100.0 / source->featureCount() : 1; + QgsFeatureIterator features = source->getFeatures(); + + if ( parameters.value( QStringLiteral( "INPUT" ) ) != parameters.value( QStringLiteral( "REFERENCE_LAYER" ) ) ) + { + if ( mode == 7 ) + throw QgsProcessingException( QObject::tr( "This mode applies when the input and reference layer are the same." ) ); + + QgsGeometrySnapper snapper( referenceSource.get() ); + long long processed = 0; + QgsFeature f; + while ( features.nextFeature( f ) ) + { + if ( feedback->isCanceled() ) + break; + + if ( f.hasGeometry() ) + { + QgsFeature outFeature( f ); + outFeature.setGeometry( snapper.snapGeometry( f.geometry(), tolerance, mode ) ); + sink->addFeature( outFeature, QgsFeatureSink::FastInsert ); + } + else + { + sink->addFeature( f ); + } + processed += 1; + feedback->setProgress( processed * step ); + } + } + else if ( mode == 7 ) + { + // input layer == reference layer + int modified = QgsGeometrySnapperSingleSource::run( *source, *sink, tolerance, feedback ); + feedback->pushInfo( QObject::tr( "Snapped %1 geometries." ).arg( modified ) ); + } + else + { + // snapping internally + QgsInternalGeometrySnapper snapper( tolerance, mode ); + long long processed = 0; + QgsFeature f; + while ( features.nextFeature( f ) ) + { + if ( feedback->isCanceled() ) + break; + + if ( f.hasGeometry() ) + { + QgsFeature outFeature( f ); + outFeature.setGeometry( snapper.snapFeature( f ) ); + sink->addFeature( outFeature, QgsFeatureSink::FastInsert ); + } + else + { + sink->addFeature( f ); + } + processed += 1; + feedback->setProgress( processed * step ); + } + } + + QVariantMap outputs; + outputs.insert( QStringLiteral( "OUTPUT" ), dest ); + return outputs; +} + +///@endcond diff --git a/src/analysis/processing/qgsalgorithmsnapgeometries.h b/src/analysis/processing/qgsalgorithmsnapgeometries.h new file mode 100644 index 000000000000..71beba9f62ae --- /dev/null +++ b/src/analysis/processing/qgsalgorithmsnapgeometries.h @@ -0,0 +1,56 @@ +/*************************************************************************** + qgsalgorithmsnapgeometries.h + --------------------- + begin : May 2020 + copyright : (C) 2020 by Alexander Bruy + email : alexander dot bruy 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. * + * * + ***************************************************************************/ + +#ifndef QGSALGORITHMSNAPGEOMETRIES_H +#define QGSALGORITHMSNAPGEOMETRIES_H + +#define SIP_NO_FILE + +#include "qgis_sip.h" +#include "qgsprocessingalgorithm.h" + +///@cond PRIVATE + +/** + * Native Snap geometries algorithm. + */ +class QgsSnapGeometriesAlgorithm : public QgsProcessingAlgorithm +{ + + public: + + QgsSnapGeometriesAlgorithm() = default; + void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override; + QString name() const override; + QString displayName() const override; + QStringList tags() const override; + QString group() const override; + QString groupId() const override; + QString shortHelpString() const override; + QgsProcessingAlgorithm::Flags flags() const override; + bool supportInPlaceEdit( const QgsMapLayer *layer ) const override; + QgsSnapGeometriesAlgorithm *createInstance() const override SIP_FACTORY; + + protected: + + QVariantMap processAlgorithm( const QVariantMap ¶meters, + QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; +}; + +///@endcond PRIVATE + +#endif // QGSALGORITHMSNAPGEOMETRIES_H diff --git a/src/analysis/processing/qgsalgorithmsplitvectorlayer.cpp b/src/analysis/processing/qgsalgorithmsplitvectorlayer.cpp new file mode 100644 index 000000000000..65b85793b2e6 --- /dev/null +++ b/src/analysis/processing/qgsalgorithmsplitvectorlayer.cpp @@ -0,0 +1,150 @@ +/*************************************************************************** + qgsalgorithmsplitvectorlayer.cpp + --------------------- + begin : May 2020 + copyright : (C) 2020 by Alexander Bruy + email : alexander dot bruy 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. * + * * + ***************************************************************************/ + +#include "qgsalgorithmsplitvectorlayer.h" +#include "qgsvectorfilewriter.h" + +///@cond PRIVATE + +QString QgsSplitVectorLayerAlgorithm::name() const +{ + return QStringLiteral( "splitvectorlayer" ); +} + +QString QgsSplitVectorLayerAlgorithm::displayName() const +{ + return QObject::tr( "Split vector layer" ); +} + +QStringList QgsSplitVectorLayerAlgorithm::tags() const +{ + return QObject::tr( "vector,split,field,unique" ).split( ',' ); +} + +QString QgsSplitVectorLayerAlgorithm::group() const +{ + return QObject::tr( "Vector general" ); +} + +QString QgsSplitVectorLayerAlgorithm::groupId() const +{ + return QStringLiteral( "vectorgeneral" ); +} + +QString QgsSplitVectorLayerAlgorithm::shortHelpString() const +{ + return QObject::tr( "Splits input vector layer into multiple layers by specified unique ID field." ) + + QStringLiteral( "\n\n" ) + + QObject::tr( "Each of the layers created in the output folder contains all features from " + "the input layer with the same value for the specified attribute. The number " + "of files generated is equal to the number of different values found for the " + "specified attribute." ); +} + +QgsSplitVectorLayerAlgorithm *QgsSplitVectorLayerAlgorithm::createInstance() const +{ + return new QgsSplitVectorLayerAlgorithm(); +} + +void QgsSplitVectorLayerAlgorithm::initAlgorithm( const QVariantMap & ) +{ + addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) ); + addParameter( new QgsProcessingParameterField( QStringLiteral( "FIELD" ), QObject::tr( "Unique ID field" ), + QVariant(), QStringLiteral( "INPUT" ) ) ); + + QStringList options = QgsVectorFileWriter::supportedFormatExtensions(); + auto fileTypeParam = qgis::make_unique < QgsProcessingParameterEnum >( QStringLiteral( "FILE_TYPE" ), QObject::tr( "Output file type" ), options, false, QVariantList() << 0, true ); + fileTypeParam->setFlags( QgsProcessingParameterDefinition::FlagAdvanced ); + addParameter( fileTypeParam.release() ); + + addParameter( new QgsProcessingParameterFolderDestination( QStringLiteral( "OUTPUT" ), QObject::tr( "Output directory" ) ) ); + addOutput( new QgsProcessingOutputMultipleLayers( QStringLiteral( "OUTPUT_LAYERS" ), QObject::tr( "Output layers" ) ) ); +} + +QVariantMap QgsSplitVectorLayerAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) +{ + std::unique_ptr< QgsFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) ); + if ( !source ) + throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) ); + + QString fieldName = parameterAsString( parameters, QStringLiteral( "FIELD" ), context ); + QString outputDir = parameterAsString( parameters, QStringLiteral( "OUTPUT" ), context ); + QString outputFormat; + if ( parameters.value( QStringLiteral( "FILE_TYPE" ) ).isValid() ) + { + int idx = parameterAsEnum( parameters, QStringLiteral( "FILE_TYPE" ), context ); + outputFormat = QgsVectorFileWriter::supportedFormatExtensions().at( idx ); + } + else + { + outputFormat = context.preferredVectorFormat(); + if ( !QgsVectorFileWriter::supportedFormatExtensions().contains( outputFormat, Qt::CaseInsensitive ) ) + outputFormat = QStringLiteral( "gpkg" ); + } + + if ( !QDir().mkpath( outputDir ) ) + throw QgsProcessingException( QStringLiteral( "Failed to create output directory." ) ); + + QgsFields fields = source->fields(); + QgsCoordinateReferenceSystem crs = source->sourceCrs(); + QgsWkbTypes::Type geometryType = source->wkbType(); + int fieldIndex = fields.lookupField( fieldName ); + QSet< QVariant > uniqueValues = source->uniqueValues( fieldIndex ); + QString baseName = outputDir + QDir::separator() + fieldName; + + int current = 0; + double step = uniqueValues.size() > 0 ? 100.0 / uniqueValues.size() : 1; + + int count = 0; + QgsFeature feat; + QStringList outputLayers; + std::unique_ptr< QgsFeatureSink > sink; + + for ( auto it = uniqueValues.constBegin(); it != uniqueValues.constEnd(); ++it ) + { + if ( feedback->isCanceled() ) + break; + + QString fileName = QStringLiteral( "%1_%2.%3" ).arg( baseName ).arg( current ).arg( outputFormat ); + feedback->pushInfo( QObject::tr( "Creating layer: %1" ).arg( fileName ) ); + + sink.reset( QgsProcessingUtils::createFeatureSink( fileName, context, fields, geometryType, crs ) ); + QString expr = QgsExpression::createFieldEqualityExpression( fieldName, *it ); + QgsFeatureIterator features = source->getFeatures( QgsFeatureRequest().setFilterExpression( expr ) ); + while ( features.nextFeature( feat ) ) + { + if ( feedback->isCanceled() ) + break; + + sink->addFeature( feat, QgsFeatureSink::FastInsert ); + count += 1; + } + + feedback->pushInfo( QObject::tr( "Added %1 features to layer" ).arg( count ) ); + outputLayers << fileName; + + current += 1; + feedback->setProgress( current * step ); + } + + QVariantMap outputs; + outputs.insert( QStringLiteral( "OUTPUT" ), outputDir ); + outputs.insert( QStringLiteral( "OUTPUT_LAYERS" ), outputLayers ); + return outputs; +} + +///@endcond diff --git a/src/analysis/processing/qgsalgorithmsplitvectorlayer.h b/src/analysis/processing/qgsalgorithmsplitvectorlayer.h new file mode 100644 index 000000000000..16e993672a3d --- /dev/null +++ b/src/analysis/processing/qgsalgorithmsplitvectorlayer.h @@ -0,0 +1,57 @@ +/*************************************************************************** + qgsalgorithmsplitvectorlayer.h + ------------------------------ + begin : May 2020 + copyright : (C) 2020 by Alexander Bruy + email : alexander dot bruy 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. * + * * + ***************************************************************************/ + +#ifndef QGSALGORITHMSPLITVECTORLAYER_H +#define QGSALGORITHMSPLITVECTORLAYER_H + +#define SIP_NO_FILE + +#include "qgis_sip.h" +#include "qgsapplication.h" +#include "qgsprocessingalgorithm.h" + +///@cond PRIVATE + +/** + * Native split vector layer algorithm. + */ +class QgsSplitVectorLayerAlgorithm : public QgsProcessingAlgorithm +{ + + public: + + QgsSplitVectorLayerAlgorithm() = default; + void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override; + QString name() const override; + QString displayName() const override; + QStringList tags() const override; + QString group() const override; + QString groupId() const override; + QString shortHelpString() const override; + QIcon icon() const override { return QgsApplication::getThemeIcon( QStringLiteral( "/algorithms/mAlgorithmSplitLayer.svg" ) ); } + QString svgIconPath() const override { return QgsApplication::iconPath( QStringLiteral( "/algorithms/mAlgorithmSplitLayer.svg" ) ); } + QgsSplitVectorLayerAlgorithm *createInstance() const override SIP_FACTORY; + + protected: + + QVariantMap processAlgorithm( const QVariantMap ¶meters, + QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; +}; + +///@endcond PRIVATE + +#endif // QGSALGORITHMSPLITVECTORLAYER_H diff --git a/src/analysis/processing/qgsnativealgorithms.cpp b/src/analysis/processing/qgsnativealgorithms.cpp index 396bbc5189c9..ac511cfd0aa6 100644 --- a/src/analysis/processing/qgsnativealgorithms.cpp +++ b/src/analysis/processing/qgsnativealgorithms.cpp @@ -46,6 +46,9 @@ #include "qgsalgorithmdrape.h" #include "qgsalgorithmdropgeometry.h" #include "qgsalgorithmdropmzvalues.h" +#include "qgsalgorithmexecutepostgisquery.h" +#include "qgsalgorithmexecutespatialitequery.h" +#include "qgsalgorithmexecutespatialitequeryregistered.h" #include "qgsalgorithmexplode.h" #include "qgsalgorithmexplodehstore.h" #include "qgsalgorithmextendlines.h" @@ -103,6 +106,7 @@ #include "qgsalgorithmpointsalonggeometry.h" #include "qgsalgorithmpointslayerfromtable.h" #include "qgsalgorithmpoleofinaccessibility.h" +#include "qgsalgorithmpolygonize.h" #include "qgsalgorithmprojectpointcartesian.h" #include "qgsalgorithmpromotetomultipart.h" #include "qgsalgorithmraiseexception.h" @@ -145,12 +149,14 @@ #include "qgsalgorithmsinglesidedbuffer.h" #include "qgsalgorithmslope.h" #include "qgsalgorithmsmooth.h" +#include "qgsalgorithmsnapgeometries.h" #include "qgsalgorithmsnaptogrid.h" #include "qgsalgorithmspatialindex.h" +#include "qgsalgorithmsplitfeaturesbyattributecharacter.h" #include "qgsalgorithmsplitlineantimeridian.h" #include "qgsalgorithmsplitlinesbylength.h" +#include "qgsalgorithmsplitvectorlayer.h" #include "qgsalgorithmsplitwithlines.h" -#include "qgsalgorithmsplitfeaturesbyattributecharacter.h" #include "qgsalgorithmstringconcatenation.h" #include "qgsalgorithmsubdivide.h" #include "qgsalgorithmsumlinelength.h" @@ -244,6 +250,9 @@ void QgsNativeAlgorithms::loadAlgorithms() addAlgorithm( new QgsDrapeToZAlgorithm() ); addAlgorithm( new QgsDropGeometryAlgorithm() ); addAlgorithm( new QgsDropMZValuesAlgorithm() ); + addAlgorithm( new QgsExecutePostgisQueryAlgorithm() ); + addAlgorithm( new QgsExecuteRegisteredSpatialiteQueryAlgorithm() ); + addAlgorithm( new QgsExecuteSpatialiteQueryAlgorithm() ); addAlgorithm( new QgsExplodeAlgorithm() ); addAlgorithm( new QgsExplodeHstoreAlgorithm() ); addAlgorithm( new QgsExtendLinesAlgorithm() ); @@ -310,6 +319,7 @@ void QgsNativeAlgorithms::loadAlgorithms() addAlgorithm( new QgsPointsAlongGeometryAlgorithm() ); addAlgorithm( new QgsPointsLayerFromTableAlgorithm() ); addAlgorithm( new QgsPoleOfInaccessibilityAlgorithm() ); + addAlgorithm( new QgsPolygonizeAlgorithm() ); addAlgorithm( new QgsProjectPointCartesianAlgorithm() ); addAlgorithm( new QgsPromoteToMultipartAlgorithm() ); addAlgorithm( new QgsRaiseExceptionAlgorithm() ); @@ -366,11 +376,13 @@ void QgsNativeAlgorithms::loadAlgorithms() addAlgorithm( new QgsSingleSidedBufferAlgorithm() ); addAlgorithm( new QgsSlopeAlgorithm() ); addAlgorithm( new QgsSmoothAlgorithm() ); + addAlgorithm( new QgsSnapGeometriesAlgorithm() ); addAlgorithm( new QgsSnapToGridAlgorithm() ); addAlgorithm( new QgsSpatialIndexAlgorithm() ); addAlgorithm( new QgsSplitFeaturesByAttributeCharacterAlgorithm() ); addAlgorithm( new QgsSplitGeometryAtAntimeridianAlgorithm() ); addAlgorithm( new QgsSplitLinesByLengthAlgorithm() ); + addAlgorithm( new QgsSplitVectorLayerAlgorithm() ); addAlgorithm( new QgsSplitWithLinesAlgorithm() ); addAlgorithm( new QgsStringConcatenationAlgorithm() ); addAlgorithm( new QgsStyleFromProjectAlgorithm() );