From 0c1b41460c0157b90f3941aa2e1cfc1a941dd5c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20P?= Date: Mon, 20 Mar 2023 17:22:46 +0100 Subject: [PATCH] Render report for generic resource (draft) --- .gitignore | 1 + js/ds.js | 160 ++++++++++++++++++++++++++++++++------------- js/views/report.js | 2 +- 3 files changed, 118 insertions(+), 45 deletions(-) diff --git a/.gitignore b/.gitignore index eed67aa..8308e32 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ vendor/ *.log .*.sw* +docs/ \ No newline at end of file diff --git a/js/ds.js b/js/ds.js index d89eb70..78de7ab 100644 --- a/js/ds.js +++ b/js/ds.js @@ -24,22 +24,19 @@ DataSpace.OBJECT_ORDER = { "Object Compiler" : null, "Object Bibliography" : null, }; -/* DataSpace.CONTEXT_ORDER = { - "Cultural Context Name" : null, - "Cultural Context Typology" : null, - "Cultural Context Chronology" : null, - "Cultural Context Era" : null, - "Cultural Context Surface" : null, - "Cultural Context Square meters" : null, - "Cultural Context Quality of the marble used/extracted" : null, - "Cultural Context Description" : null, - "Cultural Context Traces of extraction tools" : null, - "Cultural Context Amount of debris (cm3)" : null, - "Cultural Context Presence of unfinished materials" : null, - + "Context Name" : null, + "Context Typology" : null, + "Context Chronology" : null, + "Context Era" : null, + "Context Surface" : null, + "Context Square meters" : null, + "Context Quality of the marble used/extracted" : null, + "Context Description" : null, + "Context Traces of extraction tools" : null, + "Context Amount of debris (cm3)" : null, + "Context Presence of unfinished materials" : null, }; -*/ const OBJECT_REPORT = new Map(); OBJECT_REPORT.set( 'before-gallery', @@ -70,17 +67,50 @@ OBJECT_REPORT.set( "Object Bibliography" : null, } ); +const CONTEXT_REPORT = new Map(); +CONTEXT_REPORT.set( + 'before-gallery', + { + "Context Name" : null, + "Context Typology" : null, + "Context Chronology" : null, + "Context Era" : null, + "Context Surface" : null, + "Context Square meters" : null, + "Context Quality of the marble used/extracted" : null, + "Context Traces of extraction tools" : null, + "Context Amount of debris (cm3)" : null, + "Context Presence of unfinished materials" : null, + } +); +CONTEXT_REPORT.set( + 'after-gallery-1-col', + { + "Context Description" : null, + } +); +CONTEXT_REPORT.set( + 'after-gallery-2-col', + { + } +); DataSpace.OBJECT_REPORT = OBJECT_REPORT; +DataSpace.CONTEXT_REPORT = CONTEXT_REPORT; +DataSpace.RESOURCE_REPORT = { + 'Object' : DataSpace.OBJECT_REPORT, + 'Context' : DataSpace.CONTEXT_REPORT, +}; /** * Populate partial objects from * resource object based on Map * @todo * @param {object} resource + * @param {string} resType * * @return {Map} */ -DataSpace.createObjectShape = function (resource) { - const shape = this.OBJECT_REPORT; +DataSpace.createShape = function (resource, resType) { + const shape = this.RESOURCE_REPORT[resType]; let beforeGallery = shape.get('before-gallery'), afterGalleryCol1 = shape.get('after-gallery-1-col'), @@ -125,38 +155,38 @@ DataSpace.createObjectShape = function (resource) { * * @return {void} */ -DataSpace.renderObjectReport = function (report, images) +DataSpace.renderReport = function (report, images) { // TODO - const resource = Object.assign(this.OBJECT_ORDER, report.resource); - const shape = this.createObjectShape(resource); - + let resource = report.resource; let resKeys = Object.keys(resource); - // Default value... - let resType = 'Object'; // TODO if (!resKeys.length) { location.href = '/404.html'; return; } - - resType = resKeys[0].split(' ')[0]; - - // TODO use match... - // TODO check if coordinates exists... - const coordinates = resource['Object Coordinates'] - ?.replace(/^.*coordinates\':\s?\[(\d+\.\d+,\s?\d+\.\d+)\].*$/, "$1") - ?.split(', '); - - let lat, long; - [long, lat] = coordinates; - this.createMap([lat, long]); + let resType = resKeys[0].split(' ')[0]; + + const reportOrder = { + 'Object' : this.OBJECT_ORDER, + 'Context' : this.CONTEXT_ORDER, + }; + + resource = Object.assign(reportOrder[resType], resource); + const geoJSON = JSON.parse( + resource[`${resType} Coordinates`] + .replaceAll('\'', '"') + ); + + // TODO this is terrible... + const centerCoords = this.getCenterCoordinates(geoJSON); + this.createMap(geoJSON); // Write coordinates below map document.querySelector('#coord').innerHTML = ` - Latitude: ${lat} - Longitude: ${long} + Latitude: ${centerCoords[0]} + Longitude: ${centerCoords[1]} `; resKeys = resKeys.filter(e => !e.includes('Coordinates')); @@ -164,14 +194,16 @@ DataSpace.renderObjectReport = function (report, images) document.querySelector('#rep-tit') .innerText = `${resType} ${report.displayname}`; - _createObjectTable(resType, shape, resource); + const shape = this.createShape(resource, resType); + + _createReportTable(resType, shape, resource); if (images.length) { _createImgGallery(images, 'gallery'); } // Create after-gallery... - _createObjectTail(resType, shape, resource); + _createReportTail(resType, shape, resource); } /** * Fetch JSON report... @@ -203,16 +235,49 @@ DataSpace.printReport = function () { window.print(); }); } +/** + * Calculate center coordinates + * based on feature geometry + * + * @param {object} geoJSON The geoJSON feature + * @returns {string[]} + */ +DataSpace.getCenterCoordinates = function (geoJSON) +{ + const geometry = geoJSON.features[0].geometry.type; + + let coordinates = geometry === 'Point' ? + geoJSON.features[0].geometry.coordinates : + geoJSON.features[0].geometry.coordinates[0]; + + let centerCoords = [coordinates[1], coordinates[0]]; + + if (geometry !== 'Point') { + let avX = coordinates[0] + .map(el => el[0]) + .reduce((p, c) => p + c) / coordinates[0].length; + + let avY = coordinates[0] + .map(el => el[1]) + .reduce((p, c) => p + c) / coordinates[0].length; + + centerCoords = [avY, avX]; + } + + return centerCoords; +} /** * @todo Use OpenLayers? * Attach Leaflet.js map to HTML element + * and return center coordinates (NOOOO) * - * @param {string[]} coordinates + * @param {string} geoJSON * @param {string} htmlId * - * @return {void} + * @return {string[]} */ -DataSpace.createMap = function (coordinates, htmlId = 'map') { +DataSpace.createMap = function (geoJSON, htmlId = 'map') { + const centerCoords = this.getCenterCoordinates(geoJSON); const mapboxAttribution = `© Mapbox`; const mapboxSat = `https://api.mapbox.com/v4/{id}/{z}/{x}/{y}@2x.jpg90?access_token=${MAPBOX_TOKEN}`; const streets = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { @@ -234,15 +299,21 @@ DataSpace.createMap = function (coordinates, htmlId = 'map') { "Mapbox Satellite": satellite }; const map = L.map(htmlId, { - center: coordinates, + center: centerCoords, zoom: 18, layers: [streets, satellite] }); L.control.layers(baseMaps).addTo(map); + const geoLayer = L.geoJSON().addTo(map); + geoLayer.addData(geoJSON); + + return centerCoords; + /* L.marker(coordinates).addTo(map) .bindPopup(`lat.: ${coordinates[0]}, long. : ${coordinates[1]}`); + */ } /** * @todo Use TS to define object shape @@ -322,7 +393,7 @@ function _createImgGallery(images, htmlId) } } -function _createObjectTable(resType, shape, resource) +function _createReportTable(resType, shape, resource) { const tableElement = document.querySelector('#res-before tbody'); for (const key in shape.get('before-gallery')) { @@ -361,7 +432,8 @@ function _createObjectTable(resType, shape, resource) } } -function _createObjectTail(resType, shape, resource) +// TODO `Read more` for description +function _createReportTail(resType, shape, resource) { let after = document.querySelector('#res-after'); diff --git a/js/views/report.js b/js/views/report.js index ab94fb5..6c5e3f0 100644 --- a/js/views/report.js +++ b/js/views/report.js @@ -19,5 +19,5 @@ document.addEventListener('readystatechange', async () => { document.querySelector('.modal').classList.remove('active'); // Create report HTML - DataSpace.renderObjectReport(report, images); + DataSpace.renderReport(report, images); });