Refactor with sites from DB...

This commit is contained in:
Nicolò P 2025-03-26 16:44:48 +01:00
parent 1067d108e5
commit 1911c0ce9f
2 changed files with 69 additions and 215 deletions

View File

@ -63,20 +63,6 @@ const optionsFabbricati = {
fillColor: '#5b5d5f',
fillOpacity: 0.8
};
const MARKER_NAMES = {
sites: {
'gradola' : 'Villa di Gradola',
'damecuta' : 'Villa di Damecuta',
'matermania' : 'Grotta di Matermania',
'arsenale' : 'Grotta dell\'Arsenale',
'tiberio' : 'Bagni di Tiberio',
'mura' : 'Mura greche',
'san_michele' : 'Villa San Michele',
'scala_fenicia' : 'Scala Fenicia',
'grotta_azzurra' : 'Grotta Azzurra',
'lopozzo' : 'Località Lo Pozzo',
},
};
const clusterOptions = {
spiderfyOnMaxZoom: false,
showCoverageOnHover: false,
@ -110,16 +96,6 @@ function capitalize(text) {
* @returns {Map}
*/
GIS.initMap = async function (mapId, zoomLevel = this.INIT_ZOOM) {
L.LayerGroup.include({
customGetLayer : function (id) {
for (let l in this._layers) {
if (this._layers[l].id === id) {
return this._layers[l];
}
}
}
});
let map = L.map(mapId, {
//attributionControl: false,
minZoom: GIS.MIN_ZOOM,
@ -127,16 +103,20 @@ GIS.initMap = async function (mapId, zoomLevel = this.INIT_ZOOM) {
map.crs = L.CRS.EPSG4326;
const {baseMap, sitesGroup} = await this.initLayers(map);
const baseMap = await this.initLayers(map);
// Add scale and ruler controls
L.control.scale({imperial: false}).addTo(map);
L.control.graphicScale({fill: 'hollow', position: 'bottomright'}).addTo(map);
let layerVincoli = await this.loadLayer('vincoli.geojson', optionsVincoli);
let layerPaesistici = await this.loadLayer('paesistici.geojson', optionsPaesistici);
let layerVincoli = await this.loadGeoJSON('vincoli.geojson', optionsVincoli);
let layerPaesistici = await this.loadGeoJSON('paesistici.geojson', optionsPaesistici);
// Refactor with separate function...
this.sitesMarkers(sitesGroup).then(group => {group.addTo(map); window.Sites = group});
this.sites().then(data => {
data.markers.addTo(map);
data.geom.addTo(map);
window.Sites = data.markers;
});
this.notConserved().then(group => {group.addTo(map); window.NotConserved = group});
this.findings().then(group => {group.addTo(map); window.Findings = group});
this.prehistoric().then(group => {group.addTo(map); window.Prehistoric = group});
@ -145,55 +125,39 @@ GIS.initMap = async function (mapId, zoomLevel = this.INIT_ZOOM) {
'Vincoli archeologici' : layerVincoli,
'Vincoli paesistici' : layerPaesistici,
};
// TEMP!! Remove point for Lo Pozzo...
sitesGroup.removeLayer(sitesGroup.customGetLayer('lopozzo'));
sitesGroup.addTo(map);
L.control.layers(baseMap, archeo).addTo(map);
return map;
}
/**
* Create markers for sites
* @param {L.LayerGroup} sitesGroup
* @returns {L.markerClusterGroup}
* @returns {{markers: L.markerClusterGroup, geom: L.LayerGroup}}
*/
GIS.sitesMarkers = async function (sitesGroup) {
let sitesMarkers = L.markerClusterGroup(
clusterOptions
);
GIS.sites = async function () {
let sitesData = await fetch(`${API_URL}/sites`)
.then(data => data.json());
for (let id in MARKER_NAMES.sites) {
let layer = sitesGroup.customGetLayer(id);
let coords = layer?.getBounds().getCenter();
const fromStorage = localStorage.getItem(id);
let data = {};
let sites = L.markerClusterGroup(clusterOptions);
let geom = [];
if (fromStorage !== 'undefined') {
try {
data = JSON.parse(fromStorage);
const lat = data?.coordinates[0] ?? coords.lat;
const lon = data?.coordinates[1] ?? coords.lng;
coords = [lat, lon];
} catch (error) {
console.log(error);
}
} else {
data = await GIS._fetchData('site/' + id);
for (let record of sitesData) {
if (record.geojson) {
const options = record.gisId === 'grotta_azzurra' ?
optionsGrotta : optionsSiti;
geom.push(await this.loadSiteLayer(record, options));
}
const marker = L.marker(coords, { icon: Icons.site })
.bindTooltip(MARKER_NAMES.sites[id] + '<br>(Clicca per aprire scheda)');
marker.id = id;
marker.on('click', () => UI.openSiteModal(data, '#site-data'));
sitesMarkers.addLayer(marker);
sites.addLayer(L.marker(
record.coordinates,
{icon: Icons.site}
).bindTooltip(record.label + '<br>(Clicca per aprire scheda)')
.on(
'click',
() => UI.openSiteModal(record, '#site-data')
)
);
}
return sitesMarkers;
return {markers: sites, geom: L.layerGroup(geom)};
}
/**
* Create not conserved group
@ -272,103 +236,15 @@ GIS.prehistoric = async function () {
}
return prehistoric;
/*
const geo = await fetch(`${BASE_URL}/geojson/preistorici.geojson`)
.then(res => res.json());
let prehistoric = L.markerClusterGroup(
clusterOptions
);
L.geoJSON(geo, {
pointToLayer: function(geoJsonPoint, latlng) {
prehistoric.addLayer(
L.marker(latlng, {
icon: Icons.prehistoric
}).bindTooltip(geoJsonPoint.properties.denominazione)
.bindPopup(`
<table class="table is-striped is-size-6 m-2">
<tr><th>Denominazione:</th><td>${geoJsonPoint.properties.denominazione}</td></tr>
<tr><th>Oggetto:</th><td>${geoJsonPoint.properties.oggetto}</td></tr>
</table>
`)
);
},
});
return prehistoric;
*/
}
/*
GIS._prepareLayers = async function(layer) {
const fromStorage = localStorage.getItem(layer.id);
let data = {};
let coords = layer.getBounds().getCenter();
if (fromStorage !== 'undefined') {
try {
data = JSON.parse(fromStorage);
const lat = data?.lat ?? coords[0];
const lon = data?.lon ?? coords[1];
coords = [lat, lon];
} catch (error) {
console.log(error);
}
} else {
data = await GIS._fetchData(layer.id);
}
// TODO: terrible!
if (!layer.id.includes('area')) {
const marker = L.marker(coords)
.addTo(map)
.bindTooltip(
Object.keys(archeo).find(k => archeo[k] === layer)
.replace(/\s\(.*$/, '')
)
.openTooltip();
if (typeof data === 'object') {
marker.on('click', () => UI.openModal(data, '#site-data'));
}
}
}
*/
/**
* Adds layers to map and returns an object
* with {baseMap, archeoLayers, sitesLayerGroup}
* @todo Load areas for sites that have them!!
* @param {L.Map} map
* @returns {{baseMap: {"OpenStreetMap": L.TileLayer}, archeo: object, sitesGroup: L.LayerGroup}}
* @returns {{baseMap: {"OpenStreetMap": L.TileLayer}}}
*/
GIS.initLayers = async function(map) {
// TODO Move all this to separate array / object!
let layerMater = await this.loadLayer('matermania.geojson', optionsSiti, false);
let layerMaterArea = await this.loadLayer('matermania_area.geojson', optionsSiti, false);
let layerArsenale = await this.loadLayer('arsenale.geojson', optionsSiti, false);
let layerArsenaleArea = await this.loadLayer('arsenale_area.geojson', optionsSiti, false);
let layerGradola = await this.loadLayer('gradola.geojson', optionsSiti, false);
let layerGradolaArea = await this.loadLayer('gradola_area.geojson', optionsSiti, false);
let layerMura = await this.loadLayer('mura.geojson', optionsSiti, false);
let layerSanMichele = await this.loadLayer('san_michele.geojson', optionsSiti, false);
let layerDamecuta = await this.loadLayer('damecuta.geojson', optionsSiti, false);
let layerTiberio = await this.loadLayer('tiberio.geojson', optionsSiti, false);
let layerScala = await this.loadLayer('scala_fenicia.geojson', optionsSiti, false);
let layerGrotta = await this.loadLayer('grotta_azzurra.geojson', optionsGrotta, false);
let layerLopozzo = await this.loadLayer('lopozzo.geojson', optionsSiti, false);
layerMater.id = 'matermania';
layerMaterArea.id = 'matermania_area';
layerGradola.id = 'gradola';
layerGradolaArea.id = 'gradola_area';
layerArsenale.id = 'arsenale';
layerArsenaleArea.id = 'arsenale_area';
layerMura.id = 'mura';
layerSanMichele.id = 'san_michele';
layerDamecuta.id = 'damecuta';
layerTiberio.id = 'tiberio';
layerScala.id = 'scala_fenicia';
layerGrotta.id = 'grotta_azzurra';
layerLopozzo.id = 'lopozzo';
let osmap = new L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxNativeZoom : GIS.MAX_ZOOM,
@ -383,25 +259,10 @@ GIS.initLayers = async function(map) {
maxZoom: GIS.MAX_ZOOM,
attribution: '&copy; Mapbox'
});
let boundaries = await this.loadLayer('confini.geojson', {}, false);
let buildings = await this.loadLayer('fabbricati.geojson', optionsFabbricati, false);
let boundaries = await this.loadGeoJSON('confini.geojson', {}, false);
let buildings = await this.loadGeoJSON('fabbricati.geojson', optionsFabbricati, false);
let baseCatasto = new L.LayerGroup([buildings, boundaries]);
const sitesGroup = new L.LayerGroup([
layerMater,
layerMaterArea,
layerGradola,
layerGradolaArea,
layerArsenale,
layerArsenaleArea,
layerMura,
layerSanMichele,
layerDamecuta,
layerTiberio,
layerScala,
layerGrotta,
layerLopozzo
]);
const baseGroup = new L.LayerGroup([osmap]);
baseGroup.addTo(map);
const baseMap = {
@ -410,7 +271,7 @@ GIS.initLayers = async function(map) {
"Cartografia catastale" : baseCatasto,
};
return {baseMap, sitesGroup};
return baseMap;
}
/**
* Toggle spherical photos on the map
@ -458,18 +319,43 @@ GIS.toggleSpherical = async function(map) {
});
}
/**
* @param {string} geoJSON
* @param {string} geoJSON geoJSON filename
* @param {{color, opacity, weight, fillColor, fillOpacity}} options Style options for features
* @param {boolean} popup Should the features have a popup?
* @returns {L.Layer}
*/
GIS.loadLayer = async function (geoJSON, options, popup = true) {
GIS.loadGeoJSON = async function (geoJSON, options, popup = true) {
const geo = await fetch(`${BASE_URL}/geojson/${geoJSON}`)
.then(res => res.json())
.catch(error => console.error(`Can't load layer ${geoJSON}. Reason: ${error}`));
const layerId = geoJSON.replace('.geojson', '');
// Show data from feature in popUp?
const layer = new L.geoJson(geo, {
style: function () {
return options;
},
onEachFeature: function (feature, layer) {
if (popup) {
layer.bindPopup(GIS.featurePopup(geoJSON, feature));
}
}
});
return layer;
}
/**
* @param {object} site Site record from DB
* @param {{color, opacity, weight, fillColor, fillOpacity}} options Style options for features
* @param {boolean} popup Should the features have a popup?
* @returns {L.Layer}
*/
GIS.loadSiteLayer = async function (site, options, popup = true) {
const geoJSON = `${site.gisId}.geojson`;
const geo = await fetch(`${BASE_URL}/geojson/${geoJSON}`)
.then(res => res.json())
.catch(error => console.error(`Can't load layer ${geoJSON}. Reason: ${error}`));
this.cacheDBData(layerId);
this.cacheDBData(site.gisId, site.id);
// Show data from feature in popUp?
const layer = new L.geoJson(geo, {
@ -482,7 +368,7 @@ GIS.loadLayer = async function (geoJSON, options, popup = true) {
}
else {
layer.on("click", async () => {
let data = GIS.layerData(layerId);
let data = GIS.layerData(site.gisId, site.id);
if (typeof data === 'object') {
UI.openSiteModal(data);
@ -497,9 +383,10 @@ GIS.loadLayer = async function (geoJSON, options, popup = true) {
/**
* Retrieves data for a given layer
* @param {string} layerId
* @param {string} dbId
* @returns {object} Data for this layer from DB or cache
*/
GIS.layerData = async function (layerId) {
GIS.layerData = async function (layerId, dbId) {
const fromStorage = localStorage.getItem(layerId);
let data = {};
@ -510,7 +397,7 @@ GIS.layerData = async function (layerId) {
console.log(error);
}
} else {
data = await GIS._fetchData('site/' + layerId);
data = await GIS._fetchData('sites/' + dbId);
}
return data;
@ -528,8 +415,8 @@ GIS.getSpherical = async function (siteId) {
* for a given layer
* @param {string} layerId
*/
GIS.cacheDBData = async function (layerId) {
const data = await this._fetchData('site/' + layerId);
GIS.cacheDBData = async function (layerId, dbId) {
const data = await this._fetchData('sites/' + dbId);
localStorage.setItem(layerId, JSON.stringify(data));
}
/**

View File

@ -208,39 +208,6 @@ UI.openPrehistModal = function (data, selector) {
prehistoric.render().then(html => modal.querySelector('#prehist-sheet').innerHTML = html);
modal.classList.add('is-active');
}
/**
* @param {string} menuListSel Menu list selector
* @param {L.Map} map
* @param {L.LayerGroup} sites
*/
UI.sitesMenu = function (menuListSel, map, sites) {
// Close menu if arrow button is clicked...
let markers = [];
map.eachLayer(layer => {
if (layer instanceof L.Marker) {
markers.push(layer);
}
})
const menu = document.querySelector(menuListSel);
menu.addEventListener('click', async event => {
if (event.target.nodeName === 'A') {
const layerId = event.target.id;
const marker = markers.filter(m => m.id === layerId)[0];
// zoom to layer...
const layer = sites.customGetLayer(layerId);
map.setView(
layer.getBounds().getCenter(),
19,
{animate: true, duration: 1, easeLinearity: 0.25}
);
marker.openTooltip();
}
});
}
/**
* Open Spotlight gallery
* @param {string} galleryId The id of the trigger element