[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', {}) compare = expected_result.get('compare', {})
pk = expected_result.get('pk', None) pk = expected_result.get('pk', None)
topo_equal_check = expected_result.get('topo_equal_check', False) 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: 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: else:
res = False res = False
for l in expected_lyrs: 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 res = True
break break
self.assertTrue(res, 'Could not find matching layer in expected results') self.assertTrue(res, 'Could not find matching layer in expected results')

View File

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