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