diff --git a/index.html b/index.html index 6346d77..b384587 100644 --- a/index.html +++ b/index.html @@ -59,6 +59,7 @@

+ diff --git a/js/index.js b/js/index.js index 159dadb..baa6d89 100644 --- a/js/index.js +++ b/js/index.js @@ -242,12 +242,10 @@ function compositeGeoJson(features) { } var focusAreaGeoJson; +var focusAreaBoundingBox; -function loadFocusAreaGeoJson() { - if (!focusedEntityInfo) { - focusAreaGeoJson = null; - return; - } +function buildFocusAreaGeoJson() { + if (!focusedEntityInfo) return null var id = omtId(focusedEntityInfo.id, focusedEntityInfo.type) var results = map.querySourceFeatures('openmaptiles', { filter: [ @@ -265,7 +263,21 @@ function loadFocusAreaGeoJson() { sourceLayer: "landcover", }); } - focusAreaGeoJson = compositeGeoJson(results); + return compositeGeoJson(results); +} +function loadFocusArea() { + focusAreaGeoJson = buildFocusAreaGeoJson(); + focusAreaBoundingBox = bboxOfGeoJson(focusAreaGeoJson); + var maxBbox = focusAreaBoundingBox; + var fitBbox = focusAreaBoundingBox; + if (focusAreaBoundingBox) { + var width = focusAreaBoundingBox[2] - focusAreaBoundingBox[0]; + var height = focusAreaBoundingBox[3] - focusAreaBoundingBox[1]; + maxBbox = extendBbox(focusAreaBoundingBox, Math.max(width, height)); + fitBbox = extendBbox(focusAreaBoundingBox, Math.max(width, height) / 10); + } + map.setMaxBounds(maxBbox); + if (fitBbox) map.fitBounds(fitBbox); } function focusEntity(entityInfo) { @@ -284,7 +296,7 @@ function focusEntity(entityInfo) { focus: focusedEntityInfo ? type + "/" + entityId : null }); - loadFocusAreaGeoJson(); + loadFocusArea(); updateTrailLayers(); diff --git a/js/mapController.js b/js/mapController.js index c6cfe98..94db5d3 100644 --- a/js/mapController.js +++ b/js/mapController.js @@ -1653,7 +1653,10 @@ function didClickViewDetails(e) { } function didDoubleClickMap(e) { var entity = entityForEvent(e, ['major-trail-pois']); - if (entity) focusEntity(entity); + if (entity) { + e.preventDefault(); + focusEntity(entity); + } } function didMouseMoveMap(e) { diff --git a/js/utils.js b/js/utils.js new file mode 100644 index 0000000..8cd61e4 --- /dev/null +++ b/js/utils.js @@ -0,0 +1,34 @@ +function getMaxArrayDepth(value) { + return Array.isArray(value) ? + 1 + Math.max(0, ...value.map(getMaxArrayDepth)) : + 0; +} + +function bboxOfGeoJson(geojson) { + + if (!geojson?.geometry?.coordinates?.length) return; + + var depth = getMaxArrayDepth(geojson.geometry.coordinates); + var coords = geojson.geometry.coordinates.flat(depth - 2); + var bbox = [ Infinity, Infinity, -Infinity, -Infinity]; + + bbox = coords.reduce(function(prev, coord) { + return [ + Math.min(coord[0], prev[0]), + Math.min(coord[1], prev[1]), + Math.max(coord[0], prev[2]), + Math.max(coord[1], prev[3]) + ]; + }, bbox); + if (bbox[0].isNaN) return; + return bbox; +}; + +function extendBbox(bbox, buffer) { + bbox = bbox.slice(); + bbox[0] -= buffer; // west + bbox[1] -= buffer; // south + bbox[2] += buffer; // east + bbox[3] += buffer; // north + return bbox; +} \ No newline at end of file