From c0daaf5aee2a7de3bdc3a4da26ab35952ff256b3 Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Wed, 3 Jun 2026 10:26:38 -0400 Subject: [PATCH] HTML: add safe bbox function for dateline crossing --- pygeoapi/static/js/default.js | 46 +++++++++++++++++++ .../templates/collections/collection.html | 13 ++++-- pygeoapi/templates/stac/collection_base.html | 13 ++++-- pygeoapi/templates/stac/item.html | 13 ++++-- 4 files changed, 72 insertions(+), 13 deletions(-) create mode 100644 pygeoapi/static/js/default.js diff --git a/pygeoapi/static/js/default.js b/pygeoapi/static/js/default.js new file mode 100644 index 000000000..7a74aba91 --- /dev/null +++ b/pygeoapi/static/js/default.js @@ -0,0 +1,46 @@ +/****************************************************************** +* +* Authors: Tom Kralidis +* +* Copyright (c) 2026 Tom Kralidis +* +* Permission is hereby granted, free of charge, to any person +* obtaining a copy of this software and associated documentation +* files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, +* copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following +* conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +* +******************************************************************/ + +/** + * Generates a dateline safe bbox + * + * @param {[number, number, number, number]} bbox + * Array of minx, miny, maxx, maxy + * + * @returns {[number, number, number, number]} + * Dateline safe bbox +*/ + +function gen_safe_bbox(bbox) { + if (bbox[2] < bbox[0]) { + bbox[2] += 360; + } + + return bbox; +} diff --git a/pygeoapi/templates/collections/collection.html b/pygeoapi/templates/collections/collection.html index 786d9ff54..b96e8c707 100644 --- a/pygeoapi/templates/collections/collection.html +++ b/pygeoapi/templates/collections/collection.html @@ -10,7 +10,8 @@ {% block extrahead %} - + + {% endblock %} {% block body %} @@ -148,11 +149,13 @@

{% trans %}Storage CRS{% endtrans %}

} )); + var bbox = gen_safe_bbox({{ data['extent']['spatial']['bbox'][0] }}); + var bbox_layer = L.polygon([ - ['{{ data['extent']['spatial']['bbox'][0][1] }}', '{{ data['extent']['spatial']['bbox'][0][0] }}'], - ['{{ data['extent']['spatial']['bbox'][0][3] }}', '{{ data['extent']['spatial']['bbox'][0][0] }}'], - ['{{ data['extent']['spatial']['bbox'][0][3] }}', '{{ data['extent']['spatial']['bbox'][0][2] }}'], - ['{{ data['extent']['spatial']['bbox'][0][1] }}', '{{ data['extent']['spatial']['bbox'][0][2] }}'] + [bbox[1], bbox[0]], + [bbox[3], bbox[0]], + [bbox[3], bbox[2]], + [bbox[1], bbox[2]] ]); var lbounds = bbox_layer.getBounds(); diff --git a/pygeoapi/templates/stac/collection_base.html b/pygeoapi/templates/stac/collection_base.html index bbcfe4168..be9f85ce2 100644 --- a/pygeoapi/templates/stac/collection_base.html +++ b/pygeoapi/templates/stac/collection_base.html @@ -10,6 +10,7 @@ {% block extrahead %} + {% endblock %} {% block body %} @@ -102,12 +103,16 @@

{% trans %}Assets{% endtrans %}

attribution: '{{ config['server']['map']['attribution'] | safe }}' } )); + + var bbox = gen_safe_bbox({{ data['extent']['spatial']['bbox'][0] }}); + var bbox_layer = L.polygon([ - [{{ data['extent']['spatial']['bbox'][0][1] }}, {{ data['extent']['spatial']['bbox'][0][0] }}], - [{{ data['extent']['spatial']['bbox'][0][3] }}, {{ data['extent']['spatial']['bbox'][0][0] }}], - [{{ data['extent']['spatial']['bbox'][0][3] }}, {{ data['extent']['spatial']['bbox'][0][2] }}], - [{{ data['extent']['spatial']['bbox'][0][1] }}, {{ data['extent']['spatial']['bbox'][0][2] }}], + [bbox[1], bbox[0]], + [bbox[3], bbox[0]], + [bbox[3], bbox[2]], + [bbox[1], bbox[2]] ]); + map.addLayer(bbox_layer); map.fitBounds(bbox_layer.getBounds(), {maxZoom: 10}); diff --git a/pygeoapi/templates/stac/item.html b/pygeoapi/templates/stac/item.html index f42525e44..cfee31a2c 100644 --- a/pygeoapi/templates/stac/item.html +++ b/pygeoapi/templates/stac/item.html @@ -10,6 +10,7 @@ {% block extrahead %} + {% endblock %} {% block body %} @@ -97,12 +98,16 @@

{% trans %}Assets{% endtrans %}

attribution: '{{ config['server']['map']['attribution'] | safe }}' } )); + + var bbox = gen_safe_bbox({{ data['extent']['spatial']['bbox'][0] }}); + var bbox_layer = L.polygon([ - [{{ data['bbox'][1] }}, {{ data['bbox'][0] }}], - [{{ data['bbox'][3] }}, {{ data['bbox'][0] }}], - [{{ data['bbox'][3] }}, {{ data['bbox'][2] }}], - [{{ data['bbox'][1] }}, {{ data['bbox'][2] }}], + [bbox[1], bbox[0]], + [bbox[3], bbox[0]], + [bbox[3], bbox[2]], + [bbox[1], bbox[2]] ]); + map.addLayer(bbox_layer); map.fitBounds(bbox_layer.getBounds(), {maxZoom: 10});