mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-27 00:04:49 -04:00
Port clip algorithm to new API
This commit is contained in:
parent
9038872200
commit
f1511a290c
@ -34,11 +34,14 @@ from qgis.core import (QgsFeature,
|
|||||||
QgsFeatureRequest,
|
QgsFeatureRequest,
|
||||||
QgsWkbTypes,
|
QgsWkbTypes,
|
||||||
QgsMessageLog,
|
QgsMessageLog,
|
||||||
QgsProcessingUtils)
|
QgsProcessingUtils,
|
||||||
|
QgsProcessingParameterFeatureSource,
|
||||||
|
QgsProcessingParameterFeatureSink,
|
||||||
|
QgsProcessingOutputVectorLayer,
|
||||||
|
QgsProcessingParameterDefinition
|
||||||
|
)
|
||||||
|
|
||||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||||
from processing.core.parameters import ParameterVector
|
|
||||||
from processing.core.outputs import OutputVector
|
|
||||||
from processing.tools import dataobjects
|
from processing.tools import dataobjects
|
||||||
|
|
||||||
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||||
@ -58,11 +61,12 @@ class Clip(QgisAlgorithm):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.addParameter(ParameterVector(Clip.INPUT,
|
|
||||||
self.tr('Input layer')))
|
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Input layer')))
|
||||||
self.addParameter(ParameterVector(Clip.OVERLAY,
|
self.addParameter(QgsProcessingParameterFeatureSource(self.OVERLAY, self.tr('Clip layer'), [QgsProcessingParameterDefinition.TypeVectorPolygon]))
|
||||||
self.tr('Clip layer'), [dataobjects.TYPE_VECTOR_POLYGON]))
|
|
||||||
self.addOutput(OutputVector(Clip.OUTPUT, self.tr('Clipped')))
|
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Clipped')))
|
||||||
|
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Clipped")))
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
return 'clip'
|
return 'clip'
|
||||||
@ -71,17 +75,17 @@ class Clip(QgisAlgorithm):
|
|||||||
return self.tr('Clip')
|
return self.tr('Clip')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
def processAlgorithm(self, parameters, context, feedback):
|
||||||
source_layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(Clip.INPUT), context)
|
|
||||||
mask_layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(Clip.OVERLAY), context)
|
|
||||||
|
|
||||||
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(source_layer.fields(),
|
feature_source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||||
QgsWkbTypes.multiType(source_layer.wkbType()),
|
mask_source = self.parameterAsSource(parameters, self.OVERLAY, context)
|
||||||
source_layer.crs(), context)
|
|
||||||
|
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||||
|
feature_source.fields(), QgsWkbTypes.multiType(feature_source.wkbType()), feature_source.sourceCrs())
|
||||||
|
|
||||||
# first build up a list of clip geometries
|
# first build up a list of clip geometries
|
||||||
clip_geoms = []
|
clip_geoms = []
|
||||||
for maskFeat in QgsProcessingUtils.getFeatures(mask_layer, context, QgsFeatureRequest().setSubsetOfAttributes([])):
|
for mask_feature in mask_source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([])):
|
||||||
clip_geoms.append(maskFeat.geometry())
|
clip_geoms.append(mask_feature.geometry())
|
||||||
|
|
||||||
# are we clipping against a single feature? if so, we can show finer progress reports
|
# are we clipping against a single feature? if so, we can show finer progress reports
|
||||||
if len(clip_geoms) > 1:
|
if len(clip_geoms) > 1:
|
||||||
@ -98,8 +102,10 @@ class Clip(QgisAlgorithm):
|
|||||||
tested_feature_ids = set()
|
tested_feature_ids = set()
|
||||||
|
|
||||||
for i, clip_geom in enumerate(clip_geoms):
|
for i, clip_geom in enumerate(clip_geoms):
|
||||||
input_features = [f for f in QgsProcessingUtils.getFeatures(source_layer, context,
|
if feedback.isCanceled():
|
||||||
QgsFeatureRequest().setFilterRect(clip_geom.boundingBox()))]
|
break
|
||||||
|
|
||||||
|
input_features = [f for f in feature_source.getFeatures(QgsFeatureRequest().setFilterRect(clip_geom.boundingBox()))]
|
||||||
|
|
||||||
if not input_features:
|
if not input_features:
|
||||||
continue
|
continue
|
||||||
@ -110,6 +116,9 @@ class Clip(QgisAlgorithm):
|
|||||||
total = 0
|
total = 0
|
||||||
|
|
||||||
for current, in_feat in enumerate(input_features):
|
for current, in_feat in enumerate(input_features):
|
||||||
|
if feedback.isCanceled():
|
||||||
|
break
|
||||||
|
|
||||||
if not in_feat.geometry():
|
if not in_feat.geometry():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -137,7 +146,7 @@ class Clip(QgisAlgorithm):
|
|||||||
out_feat = QgsFeature()
|
out_feat = QgsFeature()
|
||||||
out_feat.setGeometry(new_geom)
|
out_feat.setGeometry(new_geom)
|
||||||
out_feat.setAttributes(in_feat.attributes())
|
out_feat.setAttributes(in_feat.attributes())
|
||||||
writer.addFeature(out_feat)
|
sink.addFeature(out_feat)
|
||||||
except:
|
except:
|
||||||
QgsMessageLog.logMessage(self.tr('Feature geometry error: One or more '
|
QgsMessageLog.logMessage(self.tr('Feature geometry error: One or more '
|
||||||
'output features ignored due to '
|
'output features ignored due to '
|
||||||
@ -151,4 +160,4 @@ class Clip(QgisAlgorithm):
|
|||||||
# coarse progress report for multiple clip geometries
|
# coarse progress report for multiple clip geometries
|
||||||
feedback.setProgress(100.0 * i / len(clip_geoms))
|
feedback.setProgress(100.0 * i / len(clip_geoms))
|
||||||
|
|
||||||
del writer
|
return {self.OUTPUT: dest_id}
|
||||||
|
|||||||
@ -75,7 +75,7 @@ from .QgisAlgorithm import QgisAlgorithm
|
|||||||
# from .ConvexHull import ConvexHull
|
# from .ConvexHull import ConvexHull
|
||||||
# from .FixedDistanceBuffer import FixedDistanceBuffer
|
# from .FixedDistanceBuffer import FixedDistanceBuffer
|
||||||
# from .VariableDistanceBuffer import VariableDistanceBuffer
|
# from .VariableDistanceBuffer import VariableDistanceBuffer
|
||||||
# from .Clip import Clip
|
from .Clip import Clip
|
||||||
# from .Difference import Difference
|
# from .Difference import Difference
|
||||||
# from .Dissolve import Dissolve
|
# from .Dissolve import Dissolve
|
||||||
# from .Intersection import Intersection
|
# from .Intersection import Intersection
|
||||||
@ -210,7 +210,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
|
|||||||
# PolygonsToLines(), LinesToPolygons(), ExtractNodes(),
|
# PolygonsToLines(), LinesToPolygons(), ExtractNodes(),
|
||||||
# ConvexHull(), FixedDistanceBuffer(),
|
# ConvexHull(), FixedDistanceBuffer(),
|
||||||
# VariableDistanceBuffer(), Dissolve(), Difference(),
|
# VariableDistanceBuffer(), Dissolve(), Difference(),
|
||||||
# Intersection(), Union(), Clip(), ExtentFromLayer(),
|
# Intersection(), Union(), ExtentFromLayer(),
|
||||||
# RandomSelection(), RandomSelectionWithinSubsets(),
|
# RandomSelection(), RandomSelectionWithinSubsets(),
|
||||||
# SelectByLocation(), RandomExtract(), DeleteHoles(),
|
# SelectByLocation(), RandomExtract(), DeleteHoles(),
|
||||||
# RandomExtractWithinSubsets(), ExtractByLocation(),
|
# RandomExtractWithinSubsets(), ExtractByLocation(),
|
||||||
@ -263,7 +263,8 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
|
|||||||
Aspect(),
|
Aspect(),
|
||||||
AutoincrementalField(),
|
AutoincrementalField(),
|
||||||
Boundary(),
|
Boundary(),
|
||||||
BoundingBox()]
|
BoundingBox(),
|
||||||
|
Clip()]
|
||||||
|
|
||||||
if hasPlotly:
|
if hasPlotly:
|
||||||
# from .VectorLayerHistogram import VectorLayerHistogram
|
# from .VectorLayerHistogram import VectorLayerHistogram
|
||||||
|
|||||||
@ -25,90 +25,90 @@ tests:
|
|||||||
# name: expected/polys_deleteholes.gml
|
# name: expected/polys_deleteholes.gml
|
||||||
# type: vector
|
# type: vector
|
||||||
#
|
#
|
||||||
# - algorithm: qgis:clip
|
- algorithm: qgis:clip
|
||||||
# name: Clip lines by polygons
|
name: Clip lines by polygons
|
||||||
# params:
|
params:
|
||||||
# INPUT:
|
INPUT:
|
||||||
# name: custom/lines2.gml
|
name: custom/lines2.gml
|
||||||
# type: vector
|
type: vector
|
||||||
# OVERLAY:
|
OVERLAY:
|
||||||
# name: polys.gml
|
name: polys.gml
|
||||||
# type: vector
|
type: vector
|
||||||
# results:
|
results:
|
||||||
# OUTPUT:
|
OUTPUT:
|
||||||
# name: expected/clip_lines_by_polygon.gml
|
name: expected/clip_lines_by_polygon.gml
|
||||||
# type: vector
|
type: vector
|
||||||
#
|
|
||||||
# - algorithm: qgis:clip
|
- algorithm: qgis:clip
|
||||||
# name: Clip lines by multipolygon
|
name: Clip lines by multipolygon
|
||||||
# params:
|
params:
|
||||||
# INPUT:
|
INPUT:
|
||||||
# name: lines.gml
|
name: lines.gml
|
||||||
# type: vector
|
type: vector
|
||||||
# OVERLAY:
|
OVERLAY:
|
||||||
# name: multipolys.gml
|
name: multipolys.gml
|
||||||
# type: vector
|
type: vector
|
||||||
# results:
|
results:
|
||||||
# OUTPUT:
|
OUTPUT:
|
||||||
# name: expected/clip_lines_by_multipolygon.gml
|
name: expected/clip_lines_by_multipolygon.gml
|
||||||
# type: vector
|
type: vector
|
||||||
#
|
|
||||||
# - algorithm: qgis:clip
|
- algorithm: qgis:clip
|
||||||
# name: Clip polygons by multipolygons
|
name: Clip polygons by multipolygons
|
||||||
# params:
|
params:
|
||||||
# INPUT:
|
INPUT:
|
||||||
# name: polys.gml
|
name: polys.gml
|
||||||
# type: vector
|
type: vector
|
||||||
# OVERLAY:
|
OVERLAY:
|
||||||
# name: multipolys.gml
|
name: multipolys.gml
|
||||||
# type: vector
|
type: vector
|
||||||
# results:
|
results:
|
||||||
# OUTPUT:
|
OUTPUT:
|
||||||
# name: expected/clip_polys_by_multipolygon.gml
|
name: expected/clip_polys_by_multipolygon.gml
|
||||||
# type: vector
|
type: vector
|
||||||
#
|
|
||||||
# - algorithm: qgis:clip
|
- algorithm: qgis:clip
|
||||||
# name: Clip multipolygons by polygons
|
name: Clip multipolygons by polygons
|
||||||
# params:
|
params:
|
||||||
# INPUT:
|
INPUT:
|
||||||
# name: multipolys.gml
|
name: multipolys.gml
|
||||||
# type: vector
|
type: vector
|
||||||
# OVERLAY:
|
OVERLAY:
|
||||||
# name: polys.gml
|
name: polys.gml
|
||||||
# type: vector
|
type: vector
|
||||||
# results:
|
results:
|
||||||
# OUTPUT:
|
OUTPUT:
|
||||||
# name: expected/clip_multipolygons_by_polygons.gml
|
name: expected/clip_multipolygons_by_polygons.gml
|
||||||
# type: vector
|
type: vector
|
||||||
#
|
|
||||||
# - algorithm: qgis:clip
|
- algorithm: qgis:clip
|
||||||
# name: Clip points by polygons
|
name: Clip points by polygons
|
||||||
# params:
|
params:
|
||||||
# INPUT:
|
INPUT:
|
||||||
# name: points.gml
|
name: points.gml
|
||||||
# type: vector
|
type: vector
|
||||||
# OVERLAY:
|
OVERLAY:
|
||||||
# name: polys.gml
|
name: polys.gml
|
||||||
# type: vector
|
type: vector
|
||||||
# results:
|
results:
|
||||||
# OUTPUT:
|
OUTPUT:
|
||||||
# name: expected/clip_points_by_polygons.gml
|
name: expected/clip_points_by_polygons.gml
|
||||||
# type: vector
|
type: vector
|
||||||
#
|
|
||||||
# - algorithm: qgis:clip
|
- algorithm: qgis:clip
|
||||||
# name: Clip points by multipolygons
|
name: Clip points by multipolygons
|
||||||
# params:
|
params:
|
||||||
# INPUT:
|
INPUT:
|
||||||
# name: points.gml
|
name: points.gml
|
||||||
# type: vector
|
type: vector
|
||||||
# OVERLAY:
|
OVERLAY:
|
||||||
# name: multipolys.gml
|
name: multipolys.gml
|
||||||
# type: vector
|
type: vector
|
||||||
# results:
|
results:
|
||||||
# OUTPUT:
|
OUTPUT:
|
||||||
# name: expected/clip_points_by_multipolygons.gml
|
name: expected/clip_points_by_multipolygons.gml
|
||||||
# type: vector
|
type: vector
|
||||||
#
|
|
||||||
# # These datasets should produce a geometry collection and not a polygon only
|
# # These datasets should produce a geometry collection and not a polygon only
|
||||||
# # dataset. If the algorithm is fixed, a new test should be introduced to
|
# # dataset. If the algorithm is fixed, a new test should be introduced to
|
||||||
# # check this behavior.
|
# # check this behavior.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user