From 4b62d38980865fa4809bde35918b7b79d310e6cf Mon Sep 17 00:00:00 2001 From: Jiri Kozel Date: Wed, 5 May 2021 13:02:23 +0200 Subject: [PATCH 01/10] Remove unused method get_default_native_bbox --- src/layman/layer/geoserver/__init__.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/layman/layer/geoserver/__init__.py b/src/layman/layer/geoserver/__init__.py index 6659bf0b5..70829adc3 100644 --- a/src/layman/layer/geoserver/__init__.py +++ b/src/layman/layer/geoserver/__init__.py @@ -118,10 +118,6 @@ def bbox_to_native_bbox(bbox): } -def get_default_native_bbox(): - return bbox_to_native_bbox(settings.LAYMAN_DEFAULT_OUTPUT_BBOX) - - def get_layer_native_bbox(workspace, layer): db_bbox = layman_util.get_publication_info(workspace, LAYER_TYPE, layer, context={'keys': ['bounding_box']})['bounding_box'] # GeoServer is not working good with degradeted bbox From de21f3ca311ab8a846ba3c81b4284b803aec40d2 Mon Sep 17 00:00:00 2001 From: Jiri Kozel Date: Wed, 5 May 2021 13:07:30 +0200 Subject: [PATCH 02/10] Extract get_layer_bbox from get_layer_native_bbox --- src/layman/layer/geoserver/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/layman/layer/geoserver/__init__.py b/src/layman/layer/geoserver/__init__.py index 70829adc3..387646fa6 100644 --- a/src/layman/layer/geoserver/__init__.py +++ b/src/layman/layer/geoserver/__init__.py @@ -118,10 +118,14 @@ def bbox_to_native_bbox(bbox): } -def get_layer_native_bbox(workspace, layer): +def get_layer_bbox(workspace, layer): db_bbox = layman_util.get_publication_info(workspace, LAYER_TYPE, layer, context={'keys': ['bounding_box']})['bounding_box'] # GeoServer is not working good with degradeted bbox - bbox = bbox_util.ensure_bbox_with_area(db_bbox, settings.NO_AREA_BBOX_PADDING) if not bbox_util.is_empty(db_bbox) else settings.LAYMAN_DEFAULT_OUTPUT_BBOX + return bbox_util.ensure_bbox_with_area(db_bbox, settings.NO_AREA_BBOX_PADDING) if not bbox_util.is_empty(db_bbox) else settings.LAYMAN_DEFAULT_OUTPUT_BBOX + + +def get_layer_native_bbox(workspace, layer): + bbox = get_layer_bbox(workspace, layer) return bbox_to_native_bbox(bbox) From cf134efa65a1611528df51e7f51f174f6380f1da Mon Sep 17 00:00:00 2001 From: Jiri Kozel Date: Wed, 5 May 2021 13:10:14 +0200 Subject: [PATCH 03/10] Move bbox_to_native_bbox from layman to geoserver --- src/geoserver/util.py | 10 ++++++++++ src/layman/layer/geoserver/__init__.py | 14 ++------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/geoserver/util.py b/src/geoserver/util.py index 8d9c15b60..54ffcde23 100644 --- a/src/geoserver/util.py +++ b/src/geoserver/util.py @@ -792,3 +792,13 @@ def get_feature_type( ) r.raise_for_status() return r.json()['featureType'] + + +def bbox_to_native_bbox(bbox): + return { + "minx": bbox[0], + "miny": bbox[1], + "maxx": bbox[2], + "maxy": bbox[3], + "crs": "EPSG:3857", + } diff --git a/src/layman/layer/geoserver/__init__.py b/src/layman/layer/geoserver/__init__.py index 387646fa6..4da370688 100644 --- a/src/layman/layer/geoserver/__init__.py +++ b/src/layman/layer/geoserver/__init__.py @@ -7,7 +7,7 @@ from layman.http import LaymanError from layman import settings, util as layman_util from layman.common import bbox as bbox_util, geoserver as gs_common, empty_method -from layman.layer import LAYER_TYPE, db as db_source +from layman.layer import LAYER_TYPE from layman.layer.qgis import wms as qgis_wms from . import wms @@ -108,16 +108,6 @@ def set_security_rules(workspace, layer, access_rights, auth, geoserver_workspac gs_util.ensure_layer_security_roles(geoserver_workspace, layer, security_write_roles, 'w', auth) -def bbox_to_native_bbox(bbox): - return { - "minx": bbox[0], - "miny": bbox[1], - "maxx": bbox[2], - "maxy": bbox[3], - "crs": "EPSG:3857", - } - - def get_layer_bbox(workspace, layer): db_bbox = layman_util.get_publication_info(workspace, LAYER_TYPE, layer, context={'keys': ['bounding_box']})['bounding_box'] # GeoServer is not working good with degradeted bbox @@ -126,7 +116,7 @@ def get_layer_bbox(workspace, layer): def get_layer_native_bbox(workspace, layer): bbox = get_layer_bbox(workspace, layer) - return bbox_to_native_bbox(bbox) + return gs_util.bbox_to_native_bbox(bbox) def publish_layer_from_db(workspace, layername, description, title, access_rights, geoserver_workspace=None): From 0737fdcf9d1d0e6a6f26fede22d54b0ac254bf67 Mon Sep 17 00:00:00 2001 From: Jiri Kozel Date: Wed, 5 May 2021 13:14:43 +0200 Subject: [PATCH 04/10] Use bbox_to_native_bbox inside geoserver package --- src/geoserver/util.py | 4 ++-- src/layman/layer/geoserver/wfs_tasks.py | 2 +- src/layman/layer/geoserver/wms_tasks.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/geoserver/util.py b/src/geoserver/util.py index 54ffcde23..b5ab5c4b0 100644 --- a/src/geoserver/util.py +++ b/src/geoserver/util.py @@ -228,7 +228,7 @@ def patch_feature_type(geoserver_workspace, feature_type_name, *, title=None, de if description: ftype['abstract'] = description if bbox: - ftype['nativeBoundingBox'] = bbox + ftype['nativeBoundingBox'] = bbox_to_native_bbox(bbox) ftype = {k: v for k, v in ftype.items() if v is not None} body = { @@ -504,7 +504,7 @@ def patch_wms_layer(geoserver_workspace, layer, *, auth, bbox): "enabled": True, } if bbox: - wms_layer['nativeBoundingBox'] = bbox + wms_layer['nativeBoundingBox'] = bbox_to_native_bbox(bbox) wms_layer['nativeCRS'] = 'EPSG:3857' r = requests.put(urljoin(GS_REST_WORKSPACES, f'{geoserver_workspace}/wmslayers/{layer}'), diff --git a/src/layman/layer/geoserver/wfs_tasks.py b/src/layman/layer/geoserver/wfs_tasks.py index 0206cc4cf..14b6c488d 100644 --- a/src/layman/layer/geoserver/wfs_tasks.py +++ b/src/layman/layer/geoserver/wfs_tasks.py @@ -20,7 +20,7 @@ def patch_after_wfst( if self.is_aborted(): raise AbortedException - bbox = geoserver.get_layer_native_bbox(workspace, layer) + bbox = geoserver.get_layer_bbox(workspace, layer) gs_util.patch_feature_type(workspace, layer, auth=settings.LAYMAN_GS_AUTH, bbox=bbox) wfs.clear_cache(workspace) diff --git a/src/layman/layer/geoserver/wms_tasks.py b/src/layman/layer/geoserver/wms_tasks.py index ad75ba23b..2aaf4fcbb 100644 --- a/src/layman/layer/geoserver/wms_tasks.py +++ b/src/layman/layer/geoserver/wms_tasks.py @@ -20,7 +20,7 @@ def patch_after_wfst( if self.is_aborted(): raise AbortedException - bbox = geoserver.get_layer_native_bbox(workspace, layer) + bbox = geoserver.get_layer_bbox(workspace, layer) geoserver_workspace = wms.get_geoserver_workspace(workspace) style_type = layman_util.get_publication_info(workspace, LAYER_TYPE, layer, context={'keys': ['style_type'], })['style_type'] if style_type == 'sld': From ac8a44cd77d362754ce9885e1fb6128dc56dc825 Mon Sep 17 00:00:00 2001 From: Jiri Kozel Date: Wed, 5 May 2021 13:26:52 +0200 Subject: [PATCH 05/10] Update also lanLon bbox of WMS Layer on native bbox change + test --- src/geoserver/util.py | 16 +++++++++++++--- test/util.py | 13 ++++++++++--- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/geoserver/util.py b/src/geoserver/util.py index b5ab5c4b0..f833fba97 100644 --- a/src/geoserver/util.py +++ b/src/geoserver/util.py @@ -500,12 +500,11 @@ def delete_wms_layer(geoserver_workspace, layer, auth): def patch_wms_layer(geoserver_workspace, layer, *, auth, bbox): - wms_layer = { - "enabled": True, - } + wms_layer = get_wms_layer(geoserver_workspace, layer, auth=auth) if bbox: wms_layer['nativeBoundingBox'] = bbox_to_native_bbox(bbox) wms_layer['nativeCRS'] = 'EPSG:3857' + # automatically recalculates also 'latLonBoundingBox' r = requests.put(urljoin(GS_REST_WORKSPACES, f'{geoserver_workspace}/wmslayers/{layer}'), data=json.dumps({ @@ -518,6 +517,17 @@ def patch_wms_layer(geoserver_workspace, layer, *, auth, bbox): r.raise_for_status() +def get_wms_layer(geoserver_workspace, layer, *, auth): + r = requests.get(urljoin(GS_REST_WORKSPACES, + f'{geoserver_workspace}/wmslayers/{layer}'), + headers=headers_json, + auth=auth, + timeout=5, + ) + r.raise_for_status() + return r.json()['wmsLayer'] + + def ensure_workspace(geoserver_workspace, auth=None): auth = auth or GS_AUTH all_workspaces = get_all_workspaces(auth) diff --git a/test/util.py b/test/util.py index be858d775..01921df6d 100644 --- a/test/util.py +++ b/test/util.py @@ -92,6 +92,13 @@ def assert_wfs_bbox(workspace, layer, expected_bbox): def assert_wms_bbox(workspace, layer, expected_bbox): with app.app_context(): wms_get_capabilities = wms.get_wms_proxy(workspace) - wms_bboxes = wms_get_capabilities.contents[layer].crs_list - wms_bbox_3857 = next(bbox[:4] for bbox in wms_bboxes if bbox[4] == 'EPSG:3857') - assert_same_bboxes(expected_bbox, wms_bbox_3857, 0.00001) + wms_layer = wms_get_capabilities.contents[layer] + bbox_3857 = next(bbox[:4] for bbox in wms_layer.crs_list if bbox[4] == 'EPSG:3857') + assert_same_bboxes(expected_bbox, bbox_3857, 0.00001) + + with app.app_context(): + expected_bbox_4326 = bbox_util.transform(expected_bbox, 3857, 4326, ) + wgs84_bboxes = [bbox[:4] for bbox in wms_layer.crs_list if bbox[4] in ['EPSG:4326', 'CRS:84']] + wgs84_bboxes.append(wms_layer.boundingBoxWGS84) + for wgs84_bbox in wgs84_bboxes: + assert_same_bboxes(expected_bbox_4326, wgs84_bbox, 0.00001) From c7ed6b924bd977a791252722ee8de15ec079e9eb Mon Sep 17 00:00:00 2001 From: Jiri Kozel Date: Wed, 5 May 2021 13:45:00 +0200 Subject: [PATCH 06/10] micka.soap: patch_after_wfst --- src/layman/geoserver_proxy_test.py | 14 ++++++++++++++ src/layman/layer/micka/soap_tasks.py | 26 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 src/layman/layer/micka/soap_tasks.py diff --git a/src/layman/geoserver_proxy_test.py b/src/layman/geoserver_proxy_test.py index 3e4ae4825..0c624a2fe 100644 --- a/src/layman/geoserver_proxy_test.py +++ b/src/layman/geoserver_proxy_test.py @@ -8,6 +8,7 @@ from geoserver.util import get_layer_thumbnail, get_square_bbox from layman import app, settings, util as layman_util +from layman.common import bbox as bbox_util from layman.layer import db, util as layer_util from layman.layer.filesystem import thumbnail from layman.layer.geoserver import wfs as geoserver_wfs @@ -375,6 +376,19 @@ def assert_all_sources_bbox(workspace, layer, expected_bbox): test_util.assert_wfs_bbox(workspace, layer, expected_bbox) test_util.assert_wms_bbox(workspace, layer, expected_bbox) + with app.app_context(): + expected_bbox_4326 = bbox_util.transform(expected_bbox, 3857, 4326, ) + md_comparison = client_util.get_workspace_layer_metadata_comparison(workspace, layer) + csw_prefix = settings.CSW_PROXY_URL + csw_src_key = client_util.get_source_key_from_metadata_comparison(md_comparison, csw_prefix) + assert csw_src_key is not None + prop_key = 'extent' + md_props = md_comparison['metadata_properties'] + assert md_props[prop_key]['equal'] is True + assert md_props[prop_key]['equal_or_null'] is True + csw_bbox_4326 = tuple(md_props[prop_key]['values'][csw_src_key]) + test_util.assert_same_bboxes(expected_bbox_4326, csw_bbox_4326, 0.001) + @pytest.mark.parametrize('style_file, thumbnail_style_postfix', [ (None, '_sld'), diff --git a/src/layman/layer/micka/soap_tasks.py b/src/layman/layer/micka/soap_tasks.py new file mode 100644 index 000000000..858a43065 --- /dev/null +++ b/src/layman/layer/micka/soap_tasks.py @@ -0,0 +1,26 @@ +from celery.utils.log import get_task_logger + +from layman.celery import AbortedException +from layman import celery_app +from . import soap + +logger = get_task_logger(__name__) + + +@celery_app.task( + name='layman.layer.micka.soap.patch_after_wfst', + bind=True, + base=celery_app.AbortableTask +) +def patch_after_wfst( + self, + workspace, + layer, +): + if self.is_aborted(): + raise AbortedException + + soap.patch_layer(workspace, layer, metadata_properties_to_refresh=['extent']) + + if self.is_aborted(): + raise AbortedException From 9af6e627ca7df9ded4d3ed536c374b13cc6bcb4d Mon Sep 17 00:00:00 2001 From: Jiri Kozel Date: Wed, 5 May 2021 13:46:18 +0200 Subject: [PATCH 07/10] layer.micka.csw uses get_publication_info instead of wms --- src/layman/common/metadata.py | 6 ++++++ src/layman/layer/micka/csw.py | 18 +++++++----------- src/layman/layer/rest_test_filled_template.xml | 6 +++--- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/layman/common/metadata.py b/src/layman/common/metadata.py index 95dc58b93..988e5053d 100644 --- a/src/layman/common/metadata.py +++ b/src/layman/common/metadata.py @@ -1,4 +1,6 @@ import json +from layman import settings +from layman.common import bbox as bbox_util from layman.util import get_publication_types PUBL_TYPE_DEF_KEY = __name__ @@ -11,6 +13,10 @@ def get_syncable_prop_names(publ_type): def extent_equals(a, b, limit=0.95): + if not bbox_util.has_area(a): + a = bbox_util.ensure_bbox_with_area(a, settings.NO_AREA_BBOX_PADDING) + if not bbox_util.has_area(b): + b = bbox_util.ensure_bbox_with_area(b, settings.NO_AREA_BBOX_PADDING) isect = _get_extent_intersetion(a, b) if _is_extent_empty(isect): return False diff --git a/src/layman/layer/micka/csw.py b/src/layman/layer/micka/csw.py index 80ad834d0..f1292ded9 100644 --- a/src/layman/layer/micka/csw.py +++ b/src/layman/layer/micka/csw.py @@ -8,7 +8,7 @@ from layman.common.filesystem.uuid import get_publication_uuid_file from layman.common.micka import util as common_util -from layman.common import language as common_language, empty_method, empty_method_returns_none +from layman.common import language as common_language, empty_method, empty_method_returns_none, bbox as bbox_util from layman.layer.filesystem.uuid import get_layer_uuid from layman.layer import db from layman.layer.geoserver import wms @@ -114,19 +114,15 @@ def csw_insert(workspace, layername): def get_template_path_and_values(workspace, layername, http_method=None): assert http_method in ['post', 'patch'] - wmsi = wms.get_wms_proxy(workspace) - wms_layer = wmsi.contents.get(layername) if wmsi else None publ_info = get_publication_info(workspace, LAYER_TYPE, layername, context={ - 'keys': ['title'], + 'keys': ['title', 'bounding_box', 'description'], }) title = publ_info['title'] - - if wms_layer: - abstract = wms_layer.abstract - extent = wms_layer.boundingBoxWGS84 - else: - abstract = None - extent = [-180, -90, 180, 90] + abstract = publ_info.get('description') + bbox_3857 = publ_info.get('bounding_box') + if bbox_util.is_empty(bbox_3857): + bbox_3857 = settings.LAYMAN_DEFAULT_OUTPUT_BBOX + extent = bbox_util.transform(tuple(bbox_3857), epsg_from=3857, epsg_to=4326) uuid_file_path = get_publication_uuid_file(LAYER_TYPE, workspace, layername) publ_datetime = datetime.fromtimestamp(os.path.getmtime(uuid_file_path)) diff --git a/src/layman/layer/rest_test_filled_template.xml b/src/layman/layer/rest_test_filled_template.xml index c20b5a0a8..08d46a5eb 100644 --- a/src/layman/layer/rest_test_filled_template.xml +++ b/src/layman/layer/rest_test_filled_template.xml @@ -245,16 +245,16 @@ - -179.9999999999996 + -180.0 180 - -85.60903777459771 + -85.6090377745977 - 83.64512999999998 + 83.64513 From e29ec700bec3b8cf5e1893a96fb1ae214b67d4e5 Mon Sep 17 00:00:00 2001 From: Jiri Kozel Date: Wed, 5 May 2021 14:10:30 +0200 Subject: [PATCH 08/10] map.micka.csw uses get_publication_info instead of inputfile if possible --- src/layman/map/micka/csw.py | 21 ++++++++++++++------ src/layman/map/rest_test_filled_template.xml | 2 +- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/layman/map/micka/csw.py b/src/layman/map/micka/csw.py index 4d8eaeb7a..7c127c680 100644 --- a/src/layman/map/micka/csw.py +++ b/src/layman/map/micka/csw.py @@ -9,7 +9,7 @@ from flask import current_app from layman import settings, LaymanError -from layman.common import language as common_language, empty_method, empty_method_returns_none +from layman.common import language as common_language, empty_method, empty_method_returns_none, bbox as bbox_util from layman.common.filesystem.uuid import get_publication_uuid_file from layman.common.micka import util as common_util from layman.map import MAP_TYPE @@ -182,23 +182,32 @@ def get_template_path_and_values(username, mapname, http_method=None, actor_name revision_date = datetime.now() map_json = get_map_json(username, mapname) operates_on = map_json_to_operates_on(map_json, editor=actor_name) + publ_info = get_publication_info(username, MAP_TYPE, mapname, context={ + 'keys': ['title', 'bounding_box', 'description'], + }) + bbox_3857 = publ_info.get('bounding_box') + if bbox_util.is_empty(bbox_3857): + bbox_3857 = settings.LAYMAN_DEFAULT_OUTPUT_BBOX + extent = bbox_util.transform(tuple(bbox_3857), epsg_from=3857, epsg_to=4326) + title = publ_info['title'] + abstract = publ_info.get('description') md_language = next(iter(common_language.get_languages_iso639_2(' '.join([ - map_json['title'] or '', - map_json['abstract'] or '' + title or '', + abstract or '', ]))), None) prop_values = _get_property_values( username=username, mapname=mapname, uuid=get_map_uuid(username, mapname), - title=map_json['title'], - abstract=map_json['abstract'] or None, + title=title, + abstract=abstract or None, publication_date=publ_datetime.strftime('%Y-%m-%d'), revision_date=revision_date.strftime('%Y-%m-%d'), md_date_stamp=date.today().strftime('%Y-%m-%d'), identifier=url_for('rest_workspace_map.get', workspace=username, mapname=mapname), identifier_label=mapname, - extent=[float(c) for c in map_json['extent']], + extent=extent, epsg_codes=map_json_to_epsg_codes(map_json), md_organisation_name=None, organisation_name=None, diff --git a/src/layman/map/rest_test_filled_template.xml b/src/layman/map/rest_test_filled_template.xml index 83fff4ebc..013807215 100644 --- a/src/layman/map/rest_test_filled_template.xml +++ b/src/layman/map/rest_test_filled_template.xml @@ -177,7 +177,7 @@ -48.5 - 81.5 + 81.4999999999999 From 5ce9d41ab614d0690779282a5ec8bb9f10d146f2 Mon Sep 17 00:00:00 2001 From: Jiri Kozel Date: Wed, 5 May 2021 14:31:31 +0200 Subject: [PATCH 09/10] Move bbox methods from metadata.py to bbox.py --- src/layman/common/bbox.py | 51 +++++++++++++++++++++++++++++++++ src/layman/common/bbox_test.py | 13 +++++++++ src/layman/common/metadata.py | 52 ++-------------------------------- 3 files changed, 66 insertions(+), 50 deletions(-) diff --git a/src/layman/common/bbox.py b/src/layman/common/bbox.py index 131fb40c0..b2aaca979 100644 --- a/src/layman/common/bbox.py +++ b/src/layman/common/bbox.py @@ -16,10 +16,41 @@ def contains_bbox(bbox1, bbox2): and bbox1[0] <= bbox2[0] and bbox2[2] <= bbox1[2] and bbox1[1] <= bbox2[1] and bbox2[3] <= bbox1[3] +def intersects(bbox1, bbox2): + return not is_empty(bbox1) and not is_empty(bbox2) \ + and bbox1[0] <= bbox2[2] and bbox1[2] >= bbox2[0] and bbox1[1] <= bbox2[3] and bbox1[3] >= bbox2[1] + + +def get_intersection(bbox1, bbox2): + intersection = [None] * 4 + if intersects(bbox1, bbox2): + if bbox1[0] > bbox2[0]: + intersection[0] = bbox1[0] + else: + intersection[0] = bbox2[0] + if bbox1[1] > bbox2[1]: + intersection[1] = bbox1[1] + else: + intersection[1] = bbox2[1] + if bbox1[2] < bbox2[2]: + intersection[2] = bbox1[2] + else: + intersection[2] = bbox2[2] + if bbox1[3] < bbox2[3]: + intersection[3] = bbox1[3] + else: + intersection[3] = bbox2[3] + return intersection + + def has_area(bbox): return not is_empty(bbox) and bbox[0] != bbox[2] and bbox[1] != bbox[3] +def get_area(bbox): + return (bbox[2] - bbox[0]) * (bbox[3] - bbox[1]) + + def ensure_bbox_with_area(bbox, no_area_padding): result = bbox if not has_area(bbox): @@ -46,3 +77,23 @@ def transform(bbox, epsg_from=4326, epsg_to=3857): params = bbox + (epsg_from, epsg_to,) result = db_util.run_query(query, params)[0] return result + + +def are_similar(bbox1, bbox2, *, no_area_bbox_padding=None, limit=0.95): + if not has_area(bbox1): + assert no_area_bbox_padding is not None and no_area_bbox_padding > 0 + bbox1 = ensure_bbox_with_area(bbox1, no_area_bbox_padding) + if not has_area(bbox2): + assert no_area_bbox_padding is not None and no_area_bbox_padding > 0 + bbox2 = ensure_bbox_with_area(bbox2, no_area_bbox_padding) + isect = get_intersection(bbox1, bbox2) + if is_empty(isect): + return False + + a_area = get_area(bbox1) + b_area = get_area(bbox2) + i_area = get_area(isect) + + similarity = i_area / a_area * i_area / b_area + # current_app.logger.info(f"a={a}, b={b}, similarity={similarity}") + return similarity >= limit diff --git a/src/layman/common/bbox_test.py b/src/layman/common/bbox_test.py index 45c74616a..4bfcf36e7 100644 --- a/src/layman/common/bbox_test.py +++ b/src/layman/common/bbox_test.py @@ -39,6 +39,19 @@ def test_contains_bbox(bbox1, bbox2, expected_result): assert bbox_util.contains_bbox(bbox1, bbox2) == expected_result +@pytest.mark.parametrize('bbox1, bbox2, expected_result', [ + ((1, 1, 4, 4, ), (2, 2, 3, 3, ), True), + ((1, 1, 4, 4, ), (1, 1, 4, 4, ), True), + ((1, 1, 4, 4, ), (1, 1, 4, 5, ), True), + ((1, 1, 4, 4, ), (4, 4, 5, 5, ), True), + ((1, 1, 4, 4, ), (5, 5, 6, 6, ), False), + ((1, 1, 4, 4, ), (None, None, None, None, ), False), + ((None, None, None, None, ), (1, 1, 4, 4, ), False), +]) +def test_intersects_bbox(bbox1, bbox2, expected_result): + assert bbox_util.intersects(bbox1, bbox2) == expected_result + + @pytest.mark.parametrize('bbox, expected_result', [ ((1, 1, 4, 4, ), True), ((1, 1, 1, 3, ), False), diff --git a/src/layman/common/metadata.py b/src/layman/common/metadata.py index 988e5053d..9978a43ba 100644 --- a/src/layman/common/metadata.py +++ b/src/layman/common/metadata.py @@ -12,22 +12,8 @@ def get_syncable_prop_names(publ_type): return prop_names -def extent_equals(a, b, limit=0.95): - if not bbox_util.has_area(a): - a = bbox_util.ensure_bbox_with_area(a, settings.NO_AREA_BBOX_PADDING) - if not bbox_util.has_area(b): - b = bbox_util.ensure_bbox_with_area(b, settings.NO_AREA_BBOX_PADDING) - isect = _get_extent_intersetion(a, b) - if _is_extent_empty(isect): - return False - - a_area = _get_extent_area(a) - b_area = _get_extent_area(b) - i_area = _get_extent_area(isect) - - similarity = i_area / a_area * i_area / b_area - # current_app.logger.info(f"a={a}, b={b}, similarity={similarity}") - return similarity >= limit +def extent_equals(a, b): + return bbox_util.are_similar(a, b, no_area_bbox_padding=settings.NO_AREA_BBOX_PADDING, limit=0.95) PROPERTIES = { @@ -148,40 +134,6 @@ def strip_capabilities_and_layers_params(url): return strip_params_from_url(url, ['SERVICE', 'REQUEST', 'VERSION', 'LAYERS']) -def _is_extent_empty(e): - return any((c is None for c in e)) - - -def _get_extent_area(e): - return (e[2] - e[0]) * (e[3] - e[1]) - - -def _get_extent_intersetion(a, b): - intersection = [None] * 4 - if _extent_intersects(a, b): - if a[0] > b[0]: - intersection[0] = a[0] - else: - intersection[0] = b[0] - if a[1] > b[1]: - intersection[1] = a[1] - else: - intersection[1] = b[1] - if a[2] < b[2]: - intersection[2] = a[2] - else: - intersection[2] = b[2] - if a[3] < b[3]: - intersection[3] = a[3] - else: - intersection[3] = b[3] - return intersection - - -def _extent_intersects(a, b): - return a[0] <= b[2] and a[2] >= b[0] and a[1] <= b[3] and a[3] >= b[1] - - def transform_metadata_props_to_comparison(all_props): prop_names = sorted(list(set(pn for po in all_props.values() for pn in po.keys()))) sources = { From 5f5c35f266c1068e4492b3cb8425edf2c336cbd3 Mon Sep 17 00:00:00 2001 From: Jiri Kozel Date: Wed, 5 May 2021 16:58:05 +0200 Subject: [PATCH 10/10] Wait 5 seconds after WFS-T for finishing patch_after_wfst chain --- src/layman/geoserver_proxy_test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/layman/geoserver_proxy_test.py b/src/layman/geoserver_proxy_test.py index 0c624a2fe..792b10ea3 100644 --- a/src/layman/geoserver_proxy_test.py +++ b/src/layman/geoserver_proxy_test.py @@ -296,6 +296,8 @@ def wfs_post(workspace, attr_names_list, data_xml): data_xml = data_wfs.get_wfs11_insert_polygon_new_attr(username, layername, attr_names10) wfs_post(username, [(layername, attr_names10)], data_xml) + time.sleep(5) + client_util.delete_workspace_layer(username, layername, headers=headers) client_util.delete_workspace_layer(username, layername2, headers=headers) @@ -365,6 +367,8 @@ def do_test(wfs_query, attribute_names): data_xml = data_wfs.get_wfs20_update_points_new_attr(username, layername1, attr_names) do_test(data_xml, attr_names) + time.sleep(5) + client_util.delete_workspace_layer(username, layername1, headers=headers1)