mirror of
https://github.com/qgis/QGIS.git
synced 2025-06-21 00:03:03 -04:00
Feature fixer: multi part to single part
This commit is contained in:
parent
29fe9cca41
commit
7b162b535f
@ -40,7 +40,8 @@ from qgis.core import (Qgis,
|
||||
QgsFeature,
|
||||
QgsExpression,
|
||||
QgsWkbTypes,
|
||||
QgsGeometry)
|
||||
QgsGeometry,
|
||||
QgsVectorLayerUtils)
|
||||
from processing.gui.Postprocessing import handleAlgorithmResults
|
||||
from processing.tools import dataobjects
|
||||
from qgis.utils import iface
|
||||
@ -69,55 +70,74 @@ def execute(alg, parameters, context=None, feedback=None):
|
||||
return False, {}
|
||||
|
||||
|
||||
def make_features_compatible(new_features, input_layer, old_feature=None):
|
||||
def make_features_compatible(new_features, input_layer, context):
|
||||
"""Try to make the new features compatible with old features by:
|
||||
|
||||
- converting single to multi part
|
||||
- dropping additional attributes
|
||||
- adding back M/Z values
|
||||
- drop Z/M
|
||||
- convert multi part to single part
|
||||
|
||||
:param new_features: new features
|
||||
:type new_features: list of QgsFeatures
|
||||
:param input_layer: input layer
|
||||
:type input_layer: QgsVectorLayer
|
||||
:param context: processing context
|
||||
:type context: QgsProcessingContext
|
||||
:return: modified features
|
||||
:rtype: list of QgsFeatures
|
||||
"""
|
||||
|
||||
input_wkb_type = input_layer.wkbType()
|
||||
result_features = []
|
||||
for new_f in new_features:
|
||||
if new_f.geometry().wkbType() != input_layer.wkbType():
|
||||
# Single -> Multi
|
||||
if (QgsWkbTypes.isMultiType(input_layer.wkbType()) and not
|
||||
new_f.geometry().isMultipart()):
|
||||
new_geom = new_f.geometry()
|
||||
new_geom.convertToMultiType()
|
||||
new_f.setGeometry(new_geom)
|
||||
# Drop Z/M
|
||||
if (new_f.geometry().constGet().is3D() and not QgsWkbTypes.hasZ(input_layer.wkbType())):
|
||||
new_geom = new_f.geometry()
|
||||
new_geom.get().dropZValue()
|
||||
new_f.setGeometry(new_geom)
|
||||
if (new_f.geometry().constGet().isMeasure() and not QgsWkbTypes.hasM(input_layer.wkbType())):
|
||||
new_geom = new_f.geometry()
|
||||
new_geom.get().dropMValue()
|
||||
new_f.setGeometry(new_geom)
|
||||
# Add Z/M back (set it to 0)
|
||||
if (old_feature is not None and not new_f.geometry().constGet().is3D() and QgsWkbTypes.hasZ(input_layer.wkbType())):
|
||||
new_geom = new_f.geometry()
|
||||
new_geom.get().addZValue(0.0)
|
||||
new_f.setGeometry(new_geom)
|
||||
if (old_feature is not None and not new_f.geometry().constGet().isMeasure() and QgsWkbTypes.hasM(input_layer.wkbType())):
|
||||
new_geom = new_f.geometry()
|
||||
new_geom.get().addMValue(0.0)
|
||||
new_f.setGeometry(new_geom)
|
||||
|
||||
# Fix attributes
|
||||
if len(new_f.attributes()) > len(input_layer.fields()):
|
||||
f = QgsFeature(input_layer.fields())
|
||||
f.setGeometry(new_f.geometry())
|
||||
f.setAttributes(new_f.attributes()[:len(input_layer.fields())])
|
||||
new_f = f
|
||||
result_features.append(new_f)
|
||||
# Fix geometry
|
||||
if new_f.geometry().wkbType() != input_wkb_type:
|
||||
# Single -> Multi
|
||||
if (QgsWkbTypes.isMultiType(input_wkb_type) and not
|
||||
new_f.geometry().isMultipart()):
|
||||
new_geom = new_f.geometry()
|
||||
new_geom.convertToMultiType()
|
||||
new_f.setGeometry(new_geom)
|
||||
# Drop Z/M
|
||||
if (new_f.geometry().constGet().is3D() and not QgsWkbTypes.hasZ(input_wkb_type)):
|
||||
new_geom = new_f.geometry()
|
||||
new_geom.get().dropZValue()
|
||||
new_f.setGeometry(new_geom)
|
||||
if (new_f.geometry().constGet().isMeasure() and not QgsWkbTypes.hasM(input_wkb_type)):
|
||||
new_geom = new_f.geometry()
|
||||
new_geom.get().dropMValue()
|
||||
new_f.setGeometry(new_geom)
|
||||
# Add Z/M back (set it to 0)
|
||||
if (not new_f.geometry().constGet().is3D() and QgsWkbTypes.hasZ(input_wkb_type)):
|
||||
new_geom = new_f.geometry()
|
||||
new_geom.get().addZValue(0.0)
|
||||
new_f.setGeometry(new_geom)
|
||||
if (not new_f.geometry().constGet().isMeasure() and QgsWkbTypes.hasM(input_wkb_type)):
|
||||
new_geom = new_f.geometry()
|
||||
new_geom.get().addMValue(0.0)
|
||||
new_f.setGeometry(new_geom)
|
||||
# Multi -> Single
|
||||
if (not QgsWkbTypes.isMultiType(input_wkb_type) and
|
||||
new_f.geometry().isMultipart()):
|
||||
g = new_f.geometry()
|
||||
g2 = g.constGet()
|
||||
for i in range(g2.partCount()):
|
||||
# Clone or crash!
|
||||
g4 = QgsGeometry(g2.geometryN(i).clone())
|
||||
f = QgsVectorLayerUtils.createFeature(input_layer, g4, {i: new_f.attribute(i) for i in range(new_f.fields().count())})
|
||||
result_features.append(f)
|
||||
else:
|
||||
result_features.append(new_f)
|
||||
else:
|
||||
result_features.append(new_f)
|
||||
return result_features
|
||||
|
||||
|
||||
@ -176,7 +196,7 @@ def execute_in_place_run(alg, active_layer, parameters, context=None, feedback=N
|
||||
feature_iterator = active_layer.getFeatures(QgsFeatureRequest(active_layer.selectedFeatureIds())) if parameters['INPUT'].selectedFeaturesOnly else active_layer.getFeatures()
|
||||
for f in feature_iterator:
|
||||
new_features = alg.processFeature(f, context, feedback)
|
||||
new_features = make_features_compatible(new_features, active_layer, f)
|
||||
new_features = make_features_compatible(new_features, active_layer, context)
|
||||
if len(new_features) == 0:
|
||||
active_layer.deleteFeature(f.id())
|
||||
elif len(new_features) == 1:
|
||||
@ -200,30 +220,32 @@ def execute_in_place_run(alg, active_layer, parameters, context=None, feedback=N
|
||||
else: # Traditional 'run' with delete and add features cycle
|
||||
results, ok = alg.run(parameters, context, feedback)
|
||||
|
||||
result_layer = QgsProcessingUtils.mapLayerFromString(results['OUTPUT'], context)
|
||||
# TODO: check if features have changed before delete/add cycle
|
||||
active_layer.deleteFeatures(active_layer.selectedFeatureIds())
|
||||
new_features = []
|
||||
for f in result_layer.getFeatures():
|
||||
new_features.append(make_features_compatible([f], active_layer))
|
||||
if ok:
|
||||
result_layer = QgsProcessingUtils.mapLayerFromString(results['OUTPUT'], context)
|
||||
# TODO: check if features have changed before delete/add cycle
|
||||
active_layer.deleteFeatures(active_layer.selectedFeatureIds())
|
||||
new_features = []
|
||||
for f in result_layer.getFeatures():
|
||||
new_features.extend(make_features_compatible([f], active_layer, context))
|
||||
|
||||
# Get the new ids
|
||||
old_ids = set([f.id() for f in active_layer.getFeatures(req)])
|
||||
active_layer.addFeatures(new_features)
|
||||
new_ids = set([f.id() for f in active_layer.getFeatures(req)])
|
||||
new_feature_ids += list(new_ids - old_ids)
|
||||
# Get the new ids
|
||||
old_ids = set([f.id() for f in active_layer.getFeatures(req)])
|
||||
active_layer.addFeatures(new_features)
|
||||
new_ids = set([f.id() for f in active_layer.getFeatures(req)])
|
||||
new_feature_ids += list(new_ids - old_ids)
|
||||
|
||||
active_layer.endEditCommand()
|
||||
|
||||
if ok and new_feature_ids:
|
||||
active_layer.selectByIds(new_feature_ids)
|
||||
elif not ok:
|
||||
active_layer.rollback()
|
||||
active_layer.rollBack()
|
||||
|
||||
return ok, results
|
||||
|
||||
except QgsProcessingException as e:
|
||||
active_layer.endEditCommand()
|
||||
active_layer.rollBack()
|
||||
if raise_exceptions:
|
||||
raise e
|
||||
QgsMessageLog.logMessage(str(sys.exc_info()[0]), 'Processing', Qgis.Critical)
|
||||
|
@ -25,6 +25,11 @@ from qgis.analysis import QgsNativeAlgorithms
|
||||
start_app()
|
||||
|
||||
|
||||
class ConsoleFeedBack(QgsProcessingFeedback):
|
||||
def reportError(self, error, fatalError=False):
|
||||
print(error)
|
||||
|
||||
|
||||
class TestQgsProcessingInPlace(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
@ -70,6 +75,109 @@ class TestQgsProcessingInPlace(unittest.TestCase):
|
||||
|
||||
QgsProject.instance().addMapLayers([cls.vl, cls.multipoly_vl])
|
||||
|
||||
def _make_compatible_tester(self, feature_wkt, layer_wkb_name, attrs=[1]):
|
||||
fields = QgsFields()
|
||||
wkb_type = getattr(QgsWkbTypes, layer_wkb_name)
|
||||
fields.append(QgsField('int_f', QVariant.Int))
|
||||
layer = QgsMemoryProviderUtils.createMemoryLayer(
|
||||
'%s_layer' % layer_wkb_name, fields, wkb_type, QgsCoordinateReferenceSystem(4326))
|
||||
self.assertTrue(layer.isValid())
|
||||
self.assertEqual(layer.wkbType(), wkb_type)
|
||||
layer.startEditing()
|
||||
|
||||
f = QgsFeature(layer.fields())
|
||||
f.setAttributes(attrs)
|
||||
f.setGeometry(QgsGeometry.fromWkt(feature_wkt))
|
||||
self.assertTrue(f.isValid())
|
||||
|
||||
context = QgsProcessingContext()
|
||||
context.setProject(QgsProject.instance())
|
||||
|
||||
# Fix it!
|
||||
new_features = make_features_compatible([f], layer, context)
|
||||
|
||||
for new_f in new_features:
|
||||
self.assertEqual(new_f.geometry().wkbType(), wkb_type)
|
||||
|
||||
self.assertTrue(layer.addFeatures(new_features), "Fail: %s - %s - %s" % (feature_wkt, attrs, layer_wkb_name))
|
||||
return layer, new_features
|
||||
|
||||
def test_make_features_compatible(self):
|
||||
"""Test fixer function"""
|
||||
# Test failure
|
||||
with self.assertRaises(AssertionError):
|
||||
self._make_compatible_tester('LineString (1 1, 2 2, 3 3)', 'Point')
|
||||
self._make_compatible_tester('Point(1 1)', 'Point')
|
||||
self._make_compatible_tester('Point(1 1)', 'Point', [1, 'nope'])
|
||||
self._make_compatible_tester('Point z (1 1 3)', 'Point')
|
||||
self._make_compatible_tester('Point z (1 1 3)', 'PointZ')
|
||||
|
||||
# Adding Z back
|
||||
l, f = self._make_compatible_tester('Point (1 1)', 'PointZ')
|
||||
self.assertEqual(f[0].geometry().get().z(), 0)
|
||||
|
||||
# Adding M back
|
||||
l, f = self._make_compatible_tester('Point (1 1)', 'PointM')
|
||||
self.assertEqual(f[0].geometry().get().m(), 0)
|
||||
|
||||
self._make_compatible_tester('Point m (1 1 3)', 'Point')
|
||||
self._make_compatible_tester('Point(1 3)', 'MultiPoint')
|
||||
self._make_compatible_tester('MultiPoint((1 3), (2 2))', 'MultiPoint')
|
||||
|
||||
self._make_compatible_tester('Polygon((1 1, 2 2, 3 3, 1 1))', 'Polygon')
|
||||
self._make_compatible_tester('Polygon((1 1, 2 2, 3 3, 1 1)', 'Polygon', [1, 'nope'])
|
||||
self._make_compatible_tester('Polygon z ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'Polygon')
|
||||
self._make_compatible_tester('Polygon z ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'PolygonZ')
|
||||
|
||||
# Adding Z back
|
||||
l, f = self._make_compatible_tester('Polygon ((1 1, 2 2, 3 3, 1 1))', 'PolygonZ')
|
||||
g = f[0].geometry()
|
||||
g2 = g.get()
|
||||
for v in g2.vertices():
|
||||
self.assertEqual(v.z(), 0)
|
||||
|
||||
# Adding M back
|
||||
l, f = self._make_compatible_tester('Polygon ((1 1, 2 2, 3 3, 1 1))', 'PolygonM')
|
||||
g = f[0].geometry()
|
||||
g2 = g.get()
|
||||
for v in g2.vertices():
|
||||
self.assertEqual(v.m(), 0)
|
||||
|
||||
self._make_compatible_tester('Polygon m ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'Polygon')
|
||||
self._make_compatible_tester('Polygon m ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'PolygonM')
|
||||
self._make_compatible_tester('Polygon((1 1, 2 2, 3 3, 1 1))', 'MultiPolygon')
|
||||
self._make_compatible_tester('MultiPolygon(((1 1, 2 2, 3 3, 1 1)), ((1 1, 2 2, 3 3, 1 1)))', 'MultiPolygon')
|
||||
|
||||
self._make_compatible_tester('LineString((1 1, 2 2, 3 3, 1 1))', 'LineString')
|
||||
self._make_compatible_tester('LineString((1 1, 2 2, 3 3, 1 1)', 'LineString', [1, 'nope'])
|
||||
self._make_compatible_tester('LineString z ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'LineString')
|
||||
self._make_compatible_tester('LineString z ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'LineStringZ')
|
||||
self._make_compatible_tester('LineString m ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'LineString')
|
||||
self._make_compatible_tester('LineString m ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'LineStringM')
|
||||
|
||||
# Adding Z back
|
||||
l, f = self._make_compatible_tester('LineString (1 1, 2 2, 3 3, 1 1))', 'LineStringZ')
|
||||
g = f[0].geometry()
|
||||
g2 = g.get()
|
||||
for v in g2.vertices():
|
||||
self.assertEqual(v.z(), 0)
|
||||
|
||||
# Adding M back
|
||||
l, f = self._make_compatible_tester('LineString (1 1, 2 2, 3 3, 1 1))', 'LineStringM')
|
||||
g = f[0].geometry()
|
||||
g2 = g.get()
|
||||
for v in g2.vertices():
|
||||
self.assertEqual(v.m(), 0)
|
||||
|
||||
self._make_compatible_tester('LineString(1 1, 2 2, 3 3, 1 1)', 'MultiLineString')
|
||||
self._make_compatible_tester('MultiLineString((1 1, 2 2, 3 3, 1 1), (1 1, 2 2, 3 3, 1 1))', 'MultiLineString')
|
||||
|
||||
# Test Multi -> Single
|
||||
l, f = self._make_compatible_tester('MultiLineString((1 1, 2 2, 3 3, 1 1), (10 1, 20 2, 30 3, 10 1))', 'LineString')
|
||||
self.assertEqual(len(f), 2)
|
||||
self.assertEqual(f[0].geometry().asWkt(), 'LineString (1 1, 2 2, 3 3, 1 1)')
|
||||
self.assertEqual(f[1].geometry().asWkt(), 'LineString (10 1, 20 2, 30 3, 10 1)')
|
||||
|
||||
def _alg_tester(self, alg_name, input_layer, parameters):
|
||||
|
||||
alg = self.registry.createAlgorithmById(alg_name)
|
||||
@ -86,7 +194,7 @@ class TestQgsProcessingInPlace(unittest.TestCase):
|
||||
|
||||
context = QgsProcessingContext()
|
||||
context.setProject(QgsProject.instance())
|
||||
feedback = QgsProcessingFeedback()
|
||||
feedback = ConsoleFeedBack()
|
||||
|
||||
input_layer.rollBack()
|
||||
with self.assertRaises(QgsProcessingException) as cm:
|
||||
@ -220,115 +328,51 @@ class TestQgsProcessingInPlace(unittest.TestCase):
|
||||
# Check selected
|
||||
self.assertEqual(self.vl.selectedFeatureIds(), [1])
|
||||
|
||||
def _make_compatible_tester(self, feature_wkt, layer_wkb_name, attrs=[1], old_feature=None):
|
||||
fields = QgsFields()
|
||||
wkb_type = getattr(QgsWkbTypes, layer_wkb_name)
|
||||
fields.append(QgsField('int_f', QVariant.Int))
|
||||
layer = QgsMemoryProviderUtils.createMemoryLayer(
|
||||
'%s_layer' % layer_wkb_name, fields, wkb_type, QgsCoordinateReferenceSystem(4326))
|
||||
self.assertTrue(layer.isValid())
|
||||
self.assertEqual(layer.wkbType(), wkb_type)
|
||||
layer.startEditing()
|
||||
def test_clip(self):
|
||||
|
||||
f = QgsFeature(layer.fields())
|
||||
f.setAttributes(attrs)
|
||||
f.setGeometry(QgsGeometry.fromWkt(feature_wkt))
|
||||
mask_layer = QgsMemoryProviderUtils.createMemoryLayer(
|
||||
'mask_layer', self.vl.fields(), QgsWkbTypes.Polygon, QgsCoordinateReferenceSystem(4326))
|
||||
self.assertTrue(mask_layer.isValid())
|
||||
self.assertTrue(mask_layer.startEditing())
|
||||
f = QgsFeature(mask_layer.fields())
|
||||
f.setAttributes([1])
|
||||
f.setGeometry(QgsGeometry.fromWkt('POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))'))
|
||||
self.assertTrue(f.isValid())
|
||||
f2 = QgsFeature(mask_layer.fields())
|
||||
f2.setAttributes([1])
|
||||
f2.setGeometry(QgsGeometry.fromWkt('POLYGON((1.1 1.1, 1.1 2.1, 2.1 2.1, 2.1 1.1, 1.1 1.1))'))
|
||||
self.assertTrue(f2.isValid())
|
||||
self.assertTrue(mask_layer.addFeatures([f, f2]))
|
||||
mask_layer.commitChanges()
|
||||
mask_layer.rollBack()
|
||||
|
||||
# Fix it!
|
||||
new_features = make_features_compatible([f], layer, old_feature)
|
||||
clip_layer = QgsMemoryProviderUtils.createMemoryLayer(
|
||||
'clip_layer', self.vl.fields(), QgsWkbTypes.LineString, QgsCoordinateReferenceSystem(4326))
|
||||
self.assertTrue(clip_layer.isValid())
|
||||
self.assertTrue(clip_layer.startEditing())
|
||||
f = QgsFeature(clip_layer.fields())
|
||||
f.setAttributes([1])
|
||||
f.setGeometry(QgsGeometry.fromWkt('LINESTRING(-1 -1, 3 3)'))
|
||||
self.assertTrue(f.isValid())
|
||||
self.assertTrue(clip_layer.addFeatures([f]))
|
||||
self.assertEqual(clip_layer.featureCount(), 1)
|
||||
clip_layer.commitChanges()
|
||||
clip_layer.selectAll()
|
||||
clip_layer.rollBack()
|
||||
|
||||
self.assertEqual(f.geometry().wkbType(), wkb_type)
|
||||
self.assertTrue(layer.addFeatures(new_features), "Fail: %s - %s - %s" % (feature_wkt, attrs, layer_wkb_name))
|
||||
return layer, new_features[0]
|
||||
QgsProject.instance().addMapLayers([clip_layer, mask_layer])
|
||||
|
||||
def test_make_features_compatible(self):
|
||||
"""Test fixer function"""
|
||||
# Test failure
|
||||
with self.assertRaises(AssertionError):
|
||||
self._make_compatible_tester('LineString (1 1, 2 2, 3 3)', 'Point')
|
||||
self._make_compatible_tester('Point(1 1)', 'Point')
|
||||
self._make_compatible_tester('Point(1 1)', 'Point', [1, 'nope'])
|
||||
self._make_compatible_tester('Point z (1 1 3)', 'Point')
|
||||
self._make_compatible_tester('Point z (1 1 3)', 'PointZ')
|
||||
old_features, new_features = self._alg_tester(
|
||||
'native:clip',
|
||||
clip_layer,
|
||||
{
|
||||
'OVERLAY': mask_layer.id(),
|
||||
}
|
||||
)
|
||||
|
||||
# Adding Z back
|
||||
old_feature = QgsFeature(self.vl.fields())
|
||||
old_feature.setAttributes([1])
|
||||
old_feature.setGeometry(QgsGeometry.fromWkt('Point z (1 1 3)'))
|
||||
l, f = self._make_compatible_tester('Point (1 1)', 'PointZ', old_feature=old_feature)
|
||||
self.assertEqual(f.geometry().get().z(), 0)
|
||||
|
||||
# Adding M back
|
||||
old_feature = QgsFeature(self.vl.fields())
|
||||
old_feature.setAttributes([1])
|
||||
old_feature.setGeometry(QgsGeometry.fromWkt('Point m (1 1 3)'))
|
||||
l, f = self._make_compatible_tester('Point (1 1)', 'PointM', old_feature=old_feature)
|
||||
self.assertEqual(f.geometry().get().m(), 0)
|
||||
|
||||
self._make_compatible_tester('Point m (1 1 3)', 'Point')
|
||||
self._make_compatible_tester('Point(1 3)', 'MultiPoint')
|
||||
self._make_compatible_tester('MultiPoint((1 3), (2 2))', 'MultiPoint')
|
||||
|
||||
self._make_compatible_tester('Polygon((1 1, 2 2, 3 3, 1 1))', 'Polygon')
|
||||
self._make_compatible_tester('Polygon((1 1, 2 2, 3 3, 1 1)', 'Polygon', [1, 'nope'])
|
||||
self._make_compatible_tester('Polygon z ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'Polygon')
|
||||
self._make_compatible_tester('Polygon z ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'PolygonZ')
|
||||
|
||||
# Adding Z back
|
||||
old_feature = QgsFeature(self.vl.fields())
|
||||
old_feature.setAttributes([1])
|
||||
old_feature.setGeometry(QgsGeometry.fromWkt('Polygon z ((1 1 1, 2 2 2, 3 3 3 , 1 1 1))'))
|
||||
l, f = self._make_compatible_tester('Polygon ((1 1, 2 2, 3 3, 1 1))', 'PolygonZ', old_feature=old_feature)
|
||||
g = f.geometry()
|
||||
g2 = g.get()
|
||||
for v in g2.vertices():
|
||||
self.assertEqual(v.z(), 0)
|
||||
|
||||
# Adding M back
|
||||
old_feature = QgsFeature(self.vl.fields())
|
||||
old_feature.setAttributes([1])
|
||||
old_feature.setGeometry(QgsGeometry.fromWkt('Polygon m ((1 1 1, 2 2 2, 3 3 3 , 1 1 1))'))
|
||||
l, f = self._make_compatible_tester('Polygon ((1 1, 2 2, 3 3, 1 1))', 'PolygonM', old_feature=old_feature)
|
||||
g = f.geometry()
|
||||
g2 = g.get()
|
||||
for v in g2.vertices():
|
||||
self.assertEqual(v.m(), 0)
|
||||
|
||||
self._make_compatible_tester('Polygon m ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'Polygon')
|
||||
self._make_compatible_tester('Polygon m ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'PolygonM')
|
||||
self._make_compatible_tester('Polygon((1 1, 2 2, 3 3, 1 1))', 'MultiPolygon')
|
||||
self._make_compatible_tester('MultiPolygon(((1 1, 2 2, 3 3, 1 1)), ((1 1, 2 2, 3 3, 1 1)))', 'MultiPolygon')
|
||||
|
||||
self._make_compatible_tester('LineString((1 1, 2 2, 3 3, 1 1))', 'LineString')
|
||||
self._make_compatible_tester('LineString((1 1, 2 2, 3 3, 1 1)', 'LineString', [1, 'nope'])
|
||||
self._make_compatible_tester('LineString z ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'LineString')
|
||||
self._make_compatible_tester('LineString z ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'LineStringZ')
|
||||
self._make_compatible_tester('LineString m ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'LineString')
|
||||
self._make_compatible_tester('LineString m ((1 1 1, 2 2 2, 3 3 3, 1 1 1))', 'LineStringM')
|
||||
|
||||
# Adding Z back
|
||||
old_feature = QgsFeature(self.vl.fields())
|
||||
old_feature.setAttributes([1])
|
||||
old_feature.setGeometry(QgsGeometry.fromWkt('LineString z ((1 1 1, 2 2 2, 3 3 3 , 1 1 1))'))
|
||||
l, f = self._make_compatible_tester('LineString ((1 1, 2 2, 3 3, 1 1))', 'LineStringZ', old_feature=old_feature)
|
||||
g = f.geometry()
|
||||
g2 = g.get()
|
||||
for v in g2.vertices():
|
||||
self.assertEqual(v.z(), 0)
|
||||
|
||||
# Adding M back
|
||||
old_feature = QgsFeature(self.vl.fields())
|
||||
old_feature.setAttributes([1])
|
||||
old_feature.setGeometry(QgsGeometry.fromWkt('LineString m ((1 1 1, 2 2 2, 3 3 3 , 1 1 1))'))
|
||||
l, f = self._make_compatible_tester('LineString ((1 1, 2 2, 3 3, 1 1))', 'LineStringM', old_feature=old_feature)
|
||||
g = f.geometry()
|
||||
g2 = g.get()
|
||||
for v in g2.vertices():
|
||||
self.assertEqual(v.m(), 0)
|
||||
|
||||
self._make_compatible_tester('LineString((1 1, 2 2, 3 3, 1 1))', 'MultiLineString')
|
||||
self._make_compatible_tester('MultiLineString(((1 1, 2 2, 3 3, 1 1)), ((1 1, 2 2, 3 3, 1 1)))', 'MultiLineString')
|
||||
self.assertEqual(len(new_features), 2)
|
||||
self.assertEqual(new_features[0].geometry().asWkt(), 'LineString (0 0, 1 1)')
|
||||
self.assertEqual(new_features[0].attributes(), [1])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
Loading…
x
Reference in New Issue
Block a user