diff options
author | Guilhem Moulin <guilhem@fripost.org> | 2025-05-27 12:27:16 +0200 |
---|---|---|
committer | Guilhem Moulin <guilhem@fripost.org> | 2025-06-04 17:14:05 +0200 |
commit | f2c3e05955bec324b7e2a011fdde3894aa53ebd5 (patch) | |
tree | 1bd0b4ce2a3c4a4c4a1c8ad1fc1a0edff87298ae /main.js | |
parent | 4c2dbeecd7bafa5e55893c939c800edc9eb5f4a7 (diff) |
info-modal: Fetch source copyright and mtime remotely from metadata.json.
Source URL and copyright information are now defined tools' config.yml.
This change exposes MVT creation time as well as source mtime to the
info modal.
See 052536f62d2e58f6b9b142e035c49cb033458d7f in tools for the generation
logic behind metadata.json.
Diffstat (limited to 'main.js')
-rw-r--r-- | main.js | 229 |
1 files changed, 228 insertions, 1 deletions
@@ -483,10 +483,189 @@ if (window.location === window.parent.location) { btn.classList.replace('btn-dark', 'btn-light'); btn.setAttribute('aria-expanded', 'false'); backdrop.classList.remove('modal-backdrop', 'show'); + infoMetadataAccordions.forEach(function(x, idx) { + /* collapse all accordions */ + const body = x.element.parentNode.parentNode; + const name = 'info-accordion-collapse-' + idx; + if (body.id === name) { + body.classList.remove('show'); + } + if (body.parentNode !== null) { + const headers = body.parentNode.getElementsByClassName('accordion-header'); + for (let i = 0; i < headers.length; i++) { + const buttons = headers[i].getElementsByClassName('accordion-button'); + for (let j = 0; j < buttons.length; j++) { + const btn = buttons[j]; + if (btn.getAttribute('data-bs-target') === '#' + name) { + btn.setAttribute('aria-expanded', 'false'); + btn.classList.add('collapsed'); + } + } + } + } + }); }); btn.onclick = function(event) { - modal.toggle(); + infoMetadataAccordions.forEach((x) => x.element.replaceChildren()); + modal.show(); + Promise.allSettled(Object.entries(vectorLayers).map(function([grp,lyr]) { + const url = lyr.getSource().getUrls()[0]; + if (url === undefined || url.length <= 16 || url.substr(url.length - 16) !== '/{z}/{x}/{y}.pbf') { + throw new Error(`Invalid URL ${url}`); + } + return fetch(url.substr(0, url.length - 16) + '/metadata.json') + .then(function(resp0) { + if (resp0.status === 200) { + return resp0.json().then((x) => [grp,x]); + } else { + throw new Error(`${resp0.url} [${resp0.status}]`); + } + }); + })) + .then(function(rs) { + const metadata = Object.fromEntries(rs.filter(function(r) { + if (r.status === 'fulfilled') { + return true; + } else if (r.status === 'rejected') { + console.log(r.reason); + } + return false; + }).map((r) => r.value)); + + infoMetadataAccordions.forEach(function(x) { + const ul = x.element; + const groupnames = new Set(); + const last_updated = []; + x.items.forEach(function([groupname, _]) { + const layer_group = metadata[groupname]; + if (layer_group === undefined) { + return; + } + if (!groupnames.has(groupname)) { + groupnames.add(groupname); + if (layer_group.last_updated !== undefined) { + last_updated.push(layer_group.last_updated); + } + } + }); + if (last_updated.length > 0) { + /* show creation time of the MVT layers */ + const li = document.createElement('li'); + li.classList.add('list-group-item', 'text-muted'); + ul.appendChild(li) + const i = document.createElement('i'); + i.classList.add('bi', 'bi-clock'); + li.appendChild(i); + const t = document.createTextNode( + ' Lokalt skikt (vectiler) genererades ' + + last_updated + .sort() + .map((ts) => new Date(ts).toLocaleDateString('sv-SE')) + .join('; ') + '.' + ); + li.appendChild(t); + } + + const source_files = new Set(); + x.items.forEach(function([groupname, layername]) { + /* for each source file associated with the accordion header, show copyright, license and timing information */ + const layer_group = metadata[groupname]; + if (layer_group === undefined || layer_group.layers === undefined || layer_group.source_files === undefined) { + return; + } + const def = layer_group.layers[layername]; + if (def === undefined || def.source_files === undefined) { + return; + } + def.source_files.forEach(function(source_file) { + if (source_files.has(source_file)) { + return; + } + const x = layer_group.source_files[source_file]; + source_files.add(source_file); + + const li = document.createElement('li'); + li.classList.add('list-group-item'); + ul.appendChild(li) + const h = document.createElement('h6'); + li.appendChild(h) + if (x.description !== undefined && x.description !== null) { + const t = document.createTextNode(x.description); + h.appendChild(t); + } + + if (x.copyright !== undefined && x.copyright !== null) { + let p = document.createElement('p'); + li.appendChild(p) + const t = document.createTextNode(x.copyright); + p.appendChild(t); + } + + if (x.license !== undefined && x.license !== null) { + let p = document.createElement('p'); + li.appendChild(p) + p.appendChild(document.createTextNode('Licensvillkor: ')); + const t = document.createTextNode(x.license.name); + if (x.license.url === undefined || x.license.url === null) { + p.appendChild(t); + } else { + const a = document.createElement('a'); + a.href = x.license.url; + a.target = '_blank'; + a.appendChild(t); + p.appendChild(a); + } + } + + if (x.product_url !== undefined && x.product_url !== null) { + let p = document.createElement('p'); + li.appendChild(p) + const t = document.createTextNode('Produktlänk '); + const i = document.createElement('i'); + i.classList.add('bi', 'bi-box-arrow-up-right'); + const a = document.createElement('a'); + a.href = x.product_url; + a.target = '_blank'; + a.appendChild(t); + a.appendChild(i); + p.appendChild(a); + } + + if (x.last_modified !== undefined && x.last_modified !== null) { + const p = document.createElement('p'); + p.classList.add('small', 'text-muted'); + li.appendChild(p); + const i = document.createElement('i'); + i.classList.add('bi', 'bi-file-earmark-code'); + p.appendChild(i); + p.appendChild(document.createTextNode(' ')); + const t0 = document.createTextNode('Källfil'); + if (x.url === undefined || x.url === null) { + p.appendChild(t0); + } else { + const a = document.createElement('a'); + p.appendChild(a); + const i = document.createElement('i'); + i.classList.add('bi', 'bi-box-arrow-up-right'); + a.appendChild(t0); + a.appendChild(document.createTextNode(' ')); + a.appendChild(i); + a.href = x.url; + a.target = '_blank'; + } + const t1 = document.createTextNode(' ändrades senast '); + p.appendChild(t1); + const d = new Date(x.last_modified); + const td = document.createTextNode(d.toLocaleDateString('sv-SE')); + p.appendChild(td); + const t2 = document.createTextNode('.') + p.appendChild(t2); + } + }); + }); + }); + }); }; })(); @@ -3270,6 +3449,7 @@ const [vectorLayers, featureOverlayLayer] = (function() { /* layer selection panel */ +const infoMetadataAccordions = []; (function() { const modal = document.getElementById('layer-selection-panel'); modal.classList.add('modal'); @@ -3502,6 +3682,53 @@ const [vectorLayers, featureOverlayLayer] = (function() { location.hash = '#' + searchParams.toString(); }; })(); + + (function() { + const accordion = document.getElementById('info-accordion'); + layerHierarchy.forEach(function(x, idx) { + const item = document.createElement('div'); + accordion.appendChild(item); + item.classList.add('accordion-item'); + + const header = document.createElement('div'); + item.appendChild(header); + header.classList.add('accordion-header'); + + const btn = document.createElement('button'); + header.appendChild(btn); + + const collapse = document.createElement('div'); + item.appendChild(collapse); + collapse.id = 'info-accordion-collapse-' + idx; + collapse.classList.add('accordion-collapse', 'collapse'); + + btn.type = 'button'; + btn.setAttribute('data-bs-toggle', 'collapse'); + btn.setAttribute('data-bs-target', '#' + collapse.id); + btn.setAttribute('aria-expanded', 'false'); + btn.setAttribute('aria-controls', collapse.id); + btn.classList.add('accordion-button', 'collapsed'); + + const t = document.createTextNode(x.text); + btn.appendChild(t); + + const body = document.createElement('div'); + body.classList.add('accordion-body'); + collapse.appendChild(body); + + const ul = document.createElement('ul'); + ul.classList.add('list-group', 'list-group-flush'); + body.appendChild(ul); + + infoMetadataAccordions.push({ + element: ul, + items: x._layers.map(function(k) { + const groupname = k.split('_', 1)[0]; + return [ groupname, k.slice(groupname.length + 1) ]; + }), + }); + }); + })(); })(); /* legend panel */ |