mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-17 00:04:02 -04:00
Port split with lines to new API
Improvements: - handle transparent reprojection if layer and lines are in different CRS
This commit is contained in:
parent
516249cea7
commit
e23617a83d
@ -112,6 +112,7 @@ from .Smooth import Smooth
|
||||
from .SnapGeometries import SnapGeometriesToLayer
|
||||
from .SpatialiteExecuteSQL import SpatialiteExecuteSQL
|
||||
from .SpatialIndex import SpatialIndex
|
||||
from .SplitWithLines import SplitWithLines
|
||||
from .SumLines import SumLines
|
||||
from .SymmetricalDifference import SymmetricalDifference
|
||||
from .TextToFloat import TextToFloat
|
||||
@ -154,7 +155,6 @@ from .ZonalStatistics import ZonalStatistics
|
||||
# from .SetRasterStyle import SetRasterStyle
|
||||
# from .SelectByAttributeSum import SelectByAttributeSum
|
||||
# from .HypsometricCurves import HypsometricCurves
|
||||
# from .SplitWithLines import SplitWithLines
|
||||
# from .FieldsMapper import FieldsMapper
|
||||
# from .Datasources2Vrt import Datasources2Vrt
|
||||
# from .OrientedMinimumBoundingBox import OrientedMinimumBoundingBox
|
||||
@ -205,7 +205,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
|
||||
# PointsFromLines(), PointsToPaths(),
|
||||
# SetVectorStyle(), SetRasterStyle(),
|
||||
# HypsometricCurves(),
|
||||
# SplitWithLines(), CreateConstantRaster(),
|
||||
# CreateConstantRaster(),
|
||||
# FieldsMapper(), SelectByAttributeSum(), Datasources2Vrt(),
|
||||
# OrientedMinimumBoundingBox(),
|
||||
# DefineProjection(),
|
||||
@ -291,6 +291,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
|
||||
SnapGeometriesToLayer(),
|
||||
SpatialiteExecuteSQL(),
|
||||
SpatialIndex(),
|
||||
SplitWithLines(),
|
||||
SumLines(),
|
||||
SymmetricalDifference(),
|
||||
TextToFloat(),
|
||||
|
@ -26,26 +26,23 @@ __copyright__ = '(C) 2014, Bernhard Ströbl'
|
||||
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
from qgis.core import (QgsApplication,
|
||||
QgsFeatureRequest,
|
||||
from qgis.core import (QgsFeatureRequest,
|
||||
QgsFeature,
|
||||
QgsFeatureSink,
|
||||
QgsGeometry,
|
||||
QgsSpatialIndex,
|
||||
QgsWkbTypes,
|
||||
QgsMessageLog,
|
||||
QgsProcessingUtils)
|
||||
QgsProcessingParameterFeatureSource,
|
||||
QgsProcessing,
|
||||
QgsProcessingParameterFeatureSink)
|
||||
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 vector
|
||||
|
||||
|
||||
class SplitWithLines(QgisAlgorithm):
|
||||
|
||||
INPUT_A = 'INPUT_A'
|
||||
INPUT_B = 'INPUT_B'
|
||||
INPUT = 'INPUT'
|
||||
LINES = 'LINES'
|
||||
|
||||
OUTPUT = 'OUTPUT'
|
||||
|
||||
@ -56,12 +53,13 @@ class SplitWithLines(QgisAlgorithm):
|
||||
super().__init__()
|
||||
|
||||
def initAlgorithm(self, config=None):
|
||||
self.addParameter(ParameterVector(self.INPUT_A,
|
||||
self.tr('Input layer, single geometries only'), [dataobjects.TYPE_VECTOR_POLYGON,
|
||||
dataobjects.TYPE_VECTOR_LINE]))
|
||||
self.addParameter(ParameterVector(self.INPUT_B,
|
||||
self.tr('Split layer'), [dataobjects.TYPE_VECTOR_LINE]))
|
||||
self.addOutput(OutputVector(self.OUTPUT, self.tr('Split')))
|
||||
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
|
||||
self.tr('Input layer, single geometries only'), [QgsProcessing.TypeVectorLine,
|
||||
QgsProcessing.TypeVectorPolygon]))
|
||||
self.addParameter(QgsProcessingParameterFeatureSource(self.LINES,
|
||||
self.tr('Split layer'), [QgsProcessing.TypeVectorLine]))
|
||||
|
||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Split')))
|
||||
|
||||
def name(self):
|
||||
return 'splitwithlines'
|
||||
@ -70,34 +68,37 @@ class SplitWithLines(QgisAlgorithm):
|
||||
return self.tr('Split with lines')
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
layerA = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_A), context)
|
||||
splitLayer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_B), context)
|
||||
source = self.parameterAsSource(parameters, self.INPUT, context)
|
||||
line_source = self.parameterAsSource(parameters, self.LINES, context)
|
||||
|
||||
sameLayer = self.getParameterValue(self.INPUT_A) == self.getParameterValue(self.INPUT_B)
|
||||
fieldList = layerA.fields()
|
||||
sameLayer = parameters[self.INPUT] == parameters[self.LINES]
|
||||
|
||||
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fieldList, QgsWkbTypes.multiType(layerA.wkbType()),
|
||||
layerA.crs(), context)
|
||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||
source.fields(), QgsWkbTypes.multiType(source.wkbType()), source.sourceCrs())
|
||||
|
||||
spatialIndex = QgsSpatialIndex()
|
||||
splitGeoms = {}
|
||||
request = QgsFeatureRequest()
|
||||
request.setSubsetOfAttributes([])
|
||||
request.setDestinationCrs(source.sourceCrs())
|
||||
|
||||
for aSplitFeature in line_source.getFeatures(request):
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
for aSplitFeature in QgsProcessingUtils.getFeatures(splitLayer, context, request):
|
||||
splitGeoms[aSplitFeature.id()] = aSplitFeature.geometry()
|
||||
spatialIndex.insertFeature(aSplitFeature)
|
||||
# honor the case that user has selection on split layer and has setting "use selection"
|
||||
|
||||
outFeat = QgsFeature()
|
||||
features = QgsProcessingUtils.getFeatures(layerA, context)
|
||||
features = source.getFeatures()
|
||||
|
||||
if QgsProcessingUtils.featureCount(layerA, context) == 0:
|
||||
total = 100
|
||||
else:
|
||||
total = 100.0 / layerA.featureCount() if layerA.featureCount() else 0
|
||||
total = 100.0 / source.featureCount() if source.featureCount() else 100
|
||||
|
||||
for current, inFeatA in enumerate(features):
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
inGeom = inFeatA.geometry()
|
||||
attrsA = inFeatA.attributes()
|
||||
outFeat.setAttributes(attrsA)
|
||||
@ -141,6 +142,9 @@ class SplitWithLines(QgisAlgorithm):
|
||||
split_geom_engine.prepareGeometry()
|
||||
|
||||
while len(inGeoms) > 0:
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
inGeom = inGeoms.pop()
|
||||
|
||||
if inGeom.isNull(): # this has been encountered and created a run-time error
|
||||
@ -154,7 +158,7 @@ class SplitWithLines(QgisAlgorithm):
|
||||
try:
|
||||
result, newGeometries, topoTestPoints = inGeom.splitGeometry(splitterPList, False)
|
||||
except:
|
||||
QgsMessageLog.logMessage(self.tr('Geometry exception while splitting'), self.tr('Processing'), QgsMessageLog.WARNING)
|
||||
feedback.reportError(self.tr('Geometry exception while splitting'))
|
||||
result = 1
|
||||
|
||||
# splitGeometry: If there are several intersections
|
||||
@ -179,6 +183,9 @@ class SplitWithLines(QgisAlgorithm):
|
||||
parts = []
|
||||
|
||||
for aGeom in inGeoms:
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
passed = True
|
||||
|
||||
if QgsWkbTypes.geometryType(aGeom.wkbType()) == QgsWkbTypes.LineGeometry:
|
||||
@ -196,7 +203,7 @@ class SplitWithLines(QgisAlgorithm):
|
||||
|
||||
if len(parts) > 0:
|
||||
outFeat.setGeometry(QgsGeometry.collectGeometry(parts))
|
||||
writer.addFeature(outFeat, QgsFeatureSink.FastInsert)
|
||||
sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
|
||||
|
||||
feedback.setProgress(int(current * total))
|
||||
del writer
|
||||
return {self.OUTPUT: dest_id}
|
||||
|
@ -1716,56 +1716,56 @@ tests:
|
||||
name: expected/create_points.gml
|
||||
type: vector
|
||||
|
||||
# - algorithm: qgis:splitwithlines
|
||||
# name: Split lines with lines (new alg)
|
||||
# params:
|
||||
# INPUT_A:
|
||||
# name: lines.gml
|
||||
# type: vector
|
||||
# INPUT_B:
|
||||
# name: custom/lines2.gml
|
||||
# type: vector
|
||||
# results:
|
||||
# OUTPUT:
|
||||
# name: expected/split_lines_with_lines.gml
|
||||
# type: vector
|
||||
# compare:
|
||||
# geometry:
|
||||
# precision: 7
|
||||
#
|
||||
# - algorithm: qgis:splitwithlines
|
||||
# name: Split poly with lines
|
||||
# params:
|
||||
# INPUT_A:
|
||||
# name: polys.gml
|
||||
# type: vector
|
||||
# INPUT_B:
|
||||
# name: lines.gml
|
||||
# type: vector
|
||||
# results:
|
||||
# OUTPUT:
|
||||
# name: expected/split_polys_with_lines.gml
|
||||
# type: vector
|
||||
# compare:
|
||||
# geometry:
|
||||
# precision: 7
|
||||
#
|
||||
# - algorithm: qgis:splitwithlines
|
||||
# name: Split lines with same lines
|
||||
# params:
|
||||
# INPUT_A:
|
||||
# name: lines.gml
|
||||
# type: vector
|
||||
# INPUT_B:
|
||||
# name: lines.gml
|
||||
# type: vector
|
||||
# results:
|
||||
# OUTPUT:
|
||||
# name: expected/split_lines_with_lines_same.gml
|
||||
# type: vector
|
||||
# compare:
|
||||
# geometry:
|
||||
# precision: 7
|
||||
- algorithm: qgis:splitwithlines
|
||||
name: Split lines with lines (new alg)
|
||||
params:
|
||||
INPUT:
|
||||
name: lines.gml
|
||||
type: vector
|
||||
LINES:
|
||||
name: custom/lines2.gml
|
||||
type: vector
|
||||
results:
|
||||
OUTPUT:
|
||||
name: expected/split_lines_with_lines.gml
|
||||
type: vector
|
||||
compare:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
||||
- algorithm: qgis:splitwithlines
|
||||
name: Split poly with lines
|
||||
params:
|
||||
INPUT:
|
||||
name: polys.gml
|
||||
type: vector
|
||||
LINES:
|
||||
name: lines.gml
|
||||
type: vector
|
||||
results:
|
||||
OUTPUT:
|
||||
name: expected/split_polys_with_lines.gml
|
||||
type: vector
|
||||
compare:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
||||
- algorithm: qgis:splitwithlines
|
||||
name: Split lines with same lines
|
||||
params:
|
||||
INPUT:
|
||||
name: lines.gml
|
||||
type: vector
|
||||
LINES:
|
||||
name: lines.gml
|
||||
type: vector
|
||||
results:
|
||||
OUTPUT:
|
||||
name: expected/split_lines_with_lines_same.gml
|
||||
type: vector
|
||||
compare:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
||||
- algorithm: qgis:dropgeometries
|
||||
name: Drop geometries
|
||||
|
Loading…
x
Reference in New Issue
Block a user