[processing] Add option to ignore part order when comparing geometries to expected results

This commit is contained in:
Nyall Dawson 2021-02-04 16:08:00 +10:00
parent f3fab9e9a9
commit 846d1fe0e6
2 changed files with 22 additions and 10 deletions

View File

@ -340,13 +340,19 @@ class AlgorithmsTest(object):
compare = expected_result.get('compare', {})
pk = expected_result.get('pk', None)
topo_equal_check = expected_result.get('topo_equal_check', False)
ignore_part_order = expected_result.get('ignore_part_order', False)
geom_config = {
'topo_equal_check': topo_equal_check,
'ignore_part_order': ignore_part_order
}
if len(expected_lyrs) == 1:
self.assertLayersEqual(expected_lyrs[0], result_lyr, compare=compare, pk=pk, geometry={'topo_equal_check': topo_equal_check})
self.assertLayersEqual(expected_lyrs[0], result_lyr, compare=compare, pk=pk, geometry=geom_config)
else:
res = False
for l in expected_lyrs:
if self.checkLayersEqual(l, result_lyr, compare=compare, pk=pk, geometry={'topo_equal_check': topo_equal_check}):
if self.checkLayersEqual(l, result_lyr, compare=compare, pk=pk, geometry=geom_config):
res = True
break
self.assertTrue(res, 'Could not find matching layer in expected results')

View File

@ -116,6 +116,11 @@ class TestCase(_TestCase):
except KeyError:
topo_equal_check = False
try:
ignore_part_order = compare['geometry']['ignore_part_order']
except KeyError:
ignore_part_order = False
try:
unordered = compare['unordered']
except KeyError:
@ -128,7 +133,7 @@ class TestCase(_TestCase):
for feat_expected in features_expected:
if self.checkGeometriesEqual(feat.geometry(), feat_expected.geometry(),
feat.id(), feat_expected.id(),
False, precision, topo_equal_check) and \
False, precision, topo_equal_check, ignore_part_order) and \
self.checkAttributesEqual(feat, feat_expected, layer_expected.fields(), False, compare):
feat_expected_equal = feat_expected
break
@ -181,7 +186,7 @@ class TestCase(_TestCase):
feats[1].geometry(),
feats[0].id(),
feats[1].id(),
use_asserts, precision, topo_equal_check)
use_asserts, precision, topo_equal_check, ignore_part_order)
if not eq and not use_asserts:
return False
@ -217,20 +222,21 @@ class TestCase(_TestCase):
_check_dirs_equal_recursive(dc)
def assertGeometriesEqual(self, geom0, geom1, geom0_id='geometry 1', geom1_id='geometry 2', precision=14, topo_equal_check=False):
self.checkGeometriesEqual(geom0, geom1, geom0_id, geom1_id, use_asserts=True, precision=precision, topo_equal_check=topo_equal_check)
def assertGeometriesEqual(self, geom0, geom1, geom0_id='geometry 1', geom1_id='geometry 2', precision=14, topo_equal_check=False, ignore_part_order=False):
self.checkGeometriesEqual(geom0, geom1, geom0_id, geom1_id, use_asserts=True, precision=precision, topo_equal_check=topo_equal_check, ignore_part_order=ignore_part_order)
def checkGeometriesEqual(self, geom0, geom1, geom0_id, geom1_id, use_asserts=False, precision=14, topo_equal_check=False):
def checkGeometriesEqual(self, geom0, geom1, geom0_id, geom1_id, use_asserts=False, precision=14, topo_equal_check=False, ignore_part_order=False):
""" Checks whether two geometries are the same - using either a strict check of coordinates (up to given precision)
or by using topological equality (where e.g. a polygon with clockwise is equal to a polygon with counter-clockwise
order of vertices)
.. versionadded:: 3.2
"""
if not geom0.isNull() and not geom1.isNull():
if topo_equal_check:
equal = geom0.constGet().asWkt(precision) == geom1.constGet().asWkt(precision)
if not equal and topo_equal_check:
equal = geom0.isGeosEqual(geom1)
else:
equal = geom0.constGet().asWkt(precision) == geom1.constGet().asWkt(precision)
if not equal and ignore_part_order and geom0.isMultipart():
equal = sorted([p.asWkt(precision) for p in geom0.constParts()]) == sorted([p.asWkt(precision) for p in geom1.constParts()])
elif geom0.isNull() and geom1.isNull():
equal = True
else: