From 61ee67875cd6cdaa0f45d0bc9338ff0ea2eb21ad Mon Sep 17 00:00:00 2001 From: Chandler Swift Date: Mon, 29 Jan 2024 01:39:46 -0600 Subject: [PATCH] Add basic popup for item information --- index.html | 4 ++++ main.js | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ style.css | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) diff --git a/index.html b/index.html index 00f505d..e812452 100644 --- a/index.html +++ b/index.html @@ -15,6 +15,10 @@
+ diff --git a/main.js b/main.js index d333838..aa623af 100644 --- a/main.js +++ b/main.js @@ -2,15 +2,36 @@ import './style.css'; import {Map, View} from 'ol'; import {fromLonLat, get} from 'ol/proj.js'; import {defaults as defaultControls} from 'ol/control.js'; +import Overlay from 'ol/Overlay.js'; import ToggleMenuControl from './ui/controls.js'; import layerCategories from './layers/index.js'; +// from https://openlayers.org/en/latest/examples/popup.html +const container = document.getElementById('popup'); +const content = document.getElementById('popup-content'); +const closer = document.getElementById('popup-closer'); +const popupOverlay = new Overlay({ + element: container, + autoPan: { + animation: { + duration: 250, + }, + }, +}); + +closer.onclick = function () { + popupOverlay.setPosition(undefined); + closer.blur(); + return false; +}; + const map = new Map({ controls: defaultControls().extend([new ToggleMenuControl()]), target: 'map', layers: [], + overlays: [popupOverlay], view: new View({ center: fromLonLat([-93.24151, 44.80376]), zoom: 10, @@ -56,3 +77,35 @@ for (let category of layerCategories) { } } } + +function objectToTable(o) { + // TODO: hack hack hack + let table = ``; + for (let [key, value] of Object.entries(o)) { + if (typeof value === "object") { + value = objectToTable(value); + } + if (typeof value === "string" && value.startsWith('https://')) { + value = `${value}` + } + table += ``; + } + table += `
${key}${value}
`; + return table; +} + +// from https://openlayers.org/en/latest/examples/icon.html +map.on('click', function (evt) { + const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) { + return feature; + }); + if (!feature) { + return; + } + + // exclude geometry -- https://stackoverflow.com/a/208106 + const {geometry: _, ...featureData} = feature.values_; + + content.innerHTML = objectToTable(featureData); + popupOverlay.setPosition(evt.coordinate); +}); diff --git a/style.css b/style.css index b1beee7..3973b8b 100644 --- a/style.css +++ b/style.css @@ -82,3 +82,47 @@ aside summary { right: 0.5em; } } + +/* POPUP (from https://openlayers.org/en/latest/examples/popup.html) */ +.ol-popup { + position: absolute; + background-color: white; + box-shadow: 0 1px 4px rgba(0,0,0,0.2); + padding: 15px; + border-radius: 10px; + border: 1px solid #cccccc; + bottom: 12px; + left: -50px; + min-width: 280px; +} +.ol-popup:after, .ol-popup:before { + top: 100%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; +} +.ol-popup:after { + border-top-color: white; + border-width: 10px; + left: 48px; + margin-left: -10px; +} +.ol-popup:before { + border-top-color: #cccccc; + border-width: 11px; + left: 48px; + margin-left: -11px; +} +.ol-popup-closer { + text-decoration: none; + position: absolute; + top: 2px; + right: 8px; +} +.ol-popup-closer:after { + content: "✖"; +} +/* END POPUP */