Refactor with sites from DB...
This commit is contained in:
parent
1067d108e5
commit
1911c0ce9f
251
webgis/js/gis.js
251
webgis/js/gis.js
@ -63,20 +63,6 @@ const optionsFabbricati = {
|
|||||||
fillColor: '#5b5d5f',
|
fillColor: '#5b5d5f',
|
||||||
fillOpacity: 0.8
|
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 = {
|
const clusterOptions = {
|
||||||
spiderfyOnMaxZoom: false,
|
spiderfyOnMaxZoom: false,
|
||||||
showCoverageOnHover: false,
|
showCoverageOnHover: false,
|
||||||
@ -110,16 +96,6 @@ function capitalize(text) {
|
|||||||
* @returns {Map}
|
* @returns {Map}
|
||||||
*/
|
*/
|
||||||
GIS.initMap = async function (mapId, zoomLevel = this.INIT_ZOOM) {
|
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, {
|
let map = L.map(mapId, {
|
||||||
//attributionControl: false,
|
//attributionControl: false,
|
||||||
minZoom: GIS.MIN_ZOOM,
|
minZoom: GIS.MIN_ZOOM,
|
||||||
@ -127,16 +103,20 @@ GIS.initMap = async function (mapId, zoomLevel = this.INIT_ZOOM) {
|
|||||||
|
|
||||||
map.crs = L.CRS.EPSG4326;
|
map.crs = L.CRS.EPSG4326;
|
||||||
|
|
||||||
const {baseMap, sitesGroup} = await this.initLayers(map);
|
const baseMap = await this.initLayers(map);
|
||||||
// Add scale and ruler controls
|
// Add scale and ruler controls
|
||||||
L.control.scale({imperial: false}).addTo(map);
|
L.control.scale({imperial: false}).addTo(map);
|
||||||
L.control.graphicScale({fill: 'hollow', position: 'bottomright'}).addTo(map);
|
L.control.graphicScale({fill: 'hollow', position: 'bottomright'}).addTo(map);
|
||||||
|
|
||||||
let layerVincoli = await this.loadLayer('vincoli.geojson', optionsVincoli);
|
let layerVincoli = await this.loadGeoJSON('vincoli.geojson', optionsVincoli);
|
||||||
let layerPaesistici = await this.loadLayer('paesistici.geojson', optionsPaesistici);
|
let layerPaesistici = await this.loadGeoJSON('paesistici.geojson', optionsPaesistici);
|
||||||
|
|
||||||
// Refactor with separate function...
|
// 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.notConserved().then(group => {group.addTo(map); window.NotConserved = group});
|
||||||
this.findings().then(group => {group.addTo(map); window.Findings = group});
|
this.findings().then(group => {group.addTo(map); window.Findings = group});
|
||||||
this.prehistoric().then(group => {group.addTo(map); window.Prehistoric = 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 archeologici' : layerVincoli,
|
||||||
'Vincoli paesistici' : layerPaesistici,
|
'Vincoli paesistici' : layerPaesistici,
|
||||||
};
|
};
|
||||||
// TEMP!! Remove point for Lo Pozzo...
|
|
||||||
sitesGroup.removeLayer(sitesGroup.customGetLayer('lopozzo'));
|
|
||||||
|
|
||||||
sitesGroup.addTo(map);
|
|
||||||
|
|
||||||
L.control.layers(baseMap, archeo).addTo(map);
|
L.control.layers(baseMap, archeo).addTo(map);
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Create markers for sites
|
* Create markers for sites
|
||||||
* @param {L.LayerGroup} sitesGroup
|
* @returns {{markers: L.markerClusterGroup, geom: L.LayerGroup}}
|
||||||
* @returns {L.markerClusterGroup}
|
|
||||||
*/
|
*/
|
||||||
GIS.sitesMarkers = async function (sitesGroup) {
|
GIS.sites = async function () {
|
||||||
let sitesMarkers = L.markerClusterGroup(
|
let sitesData = await fetch(`${API_URL}/sites`)
|
||||||
clusterOptions
|
.then(data => data.json());
|
||||||
);
|
|
||||||
|
|
||||||
for (let id in MARKER_NAMES.sites) {
|
let sites = L.markerClusterGroup(clusterOptions);
|
||||||
let layer = sitesGroup.customGetLayer(id);
|
let geom = [];
|
||||||
let coords = layer?.getBounds().getCenter();
|
|
||||||
const fromStorage = localStorage.getItem(id);
|
|
||||||
let data = {};
|
|
||||||
|
|
||||||
if (fromStorage !== 'undefined') {
|
for (let record of sitesData) {
|
||||||
try {
|
if (record.geojson) {
|
||||||
data = JSON.parse(fromStorage);
|
const options = record.gisId === 'grotta_azzurra' ?
|
||||||
const lat = data?.coordinates[0] ?? coords.lat;
|
optionsGrotta : optionsSiti;
|
||||||
const lon = data?.coordinates[1] ?? coords.lng;
|
geom.push(await this.loadSiteLayer(record, options));
|
||||||
coords = [lat, lon];
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
data = await GIS._fetchData('site/' + id);
|
|
||||||
}
|
}
|
||||||
|
sites.addLayer(L.marker(
|
||||||
const marker = L.marker(coords, { icon: Icons.site })
|
record.coordinates,
|
||||||
.bindTooltip(MARKER_NAMES.sites[id] + '<br>(Clicca per aprire scheda)');
|
{icon: Icons.site}
|
||||||
|
).bindTooltip(record.label + '<br>(Clicca per aprire scheda)')
|
||||||
marker.id = id;
|
.on(
|
||||||
|
'click',
|
||||||
marker.on('click', () => UI.openSiteModal(data, '#site-data'));
|
() => UI.openSiteModal(record, '#site-data')
|
||||||
|
)
|
||||||
sitesMarkers.addLayer(marker);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sitesMarkers;
|
return {markers: sites, geom: L.layerGroup(geom)};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Create not conserved group
|
* Create not conserved group
|
||||||
@ -272,103 +236,15 @@ GIS.prehistoric = async function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return prehistoric;
|
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
|
* Adds layers to map and returns an object
|
||||||
* with {baseMap, archeoLayers, sitesLayerGroup}
|
* with {baseMap, archeoLayers, sitesLayerGroup}
|
||||||
|
* @todo Load areas for sites that have them!!
|
||||||
* @param {L.Map} map
|
* @param {L.Map} map
|
||||||
* @returns {{baseMap: {"OpenStreetMap": L.TileLayer}, archeo: object, sitesGroup: L.LayerGroup}}
|
* @returns {{baseMap: {"OpenStreetMap": L.TileLayer}}}
|
||||||
*/
|
*/
|
||||||
GIS.initLayers = async function(map) {
|
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', {
|
let osmap = new L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||||
maxNativeZoom : GIS.MAX_ZOOM,
|
maxNativeZoom : GIS.MAX_ZOOM,
|
||||||
@ -383,25 +259,10 @@ GIS.initLayers = async function(map) {
|
|||||||
maxZoom: GIS.MAX_ZOOM,
|
maxZoom: GIS.MAX_ZOOM,
|
||||||
attribution: '© Mapbox'
|
attribution: '© Mapbox'
|
||||||
});
|
});
|
||||||
let boundaries = await this.loadLayer('confini.geojson', {}, false);
|
let boundaries = await this.loadGeoJSON('confini.geojson', {}, false);
|
||||||
let buildings = await this.loadLayer('fabbricati.geojson', optionsFabbricati, false);
|
let buildings = await this.loadGeoJSON('fabbricati.geojson', optionsFabbricati, false);
|
||||||
let baseCatasto = new L.LayerGroup([buildings, boundaries]);
|
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]);
|
const baseGroup = new L.LayerGroup([osmap]);
|
||||||
baseGroup.addTo(map);
|
baseGroup.addTo(map);
|
||||||
const baseMap = {
|
const baseMap = {
|
||||||
@ -410,7 +271,7 @@ GIS.initLayers = async function(map) {
|
|||||||
"Cartografia catastale" : baseCatasto,
|
"Cartografia catastale" : baseCatasto,
|
||||||
};
|
};
|
||||||
|
|
||||||
return {baseMap, sitesGroup};
|
return baseMap;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Toggle spherical photos on the map
|
* 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 {{color, opacity, weight, fillColor, fillOpacity}} options Style options for features
|
||||||
* @param {boolean} popup Should the features have a popup?
|
* @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}`)
|
const geo = await fetch(`${BASE_URL}/geojson/${geoJSON}`)
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.catch(error => console.error(`Can't load layer ${geoJSON}. Reason: ${error}`));
|
.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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.cacheDBData(layerId);
|
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(site.gisId, site.id);
|
||||||
|
|
||||||
// Show data from feature in popUp?
|
// Show data from feature in popUp?
|
||||||
const layer = new L.geoJson(geo, {
|
const layer = new L.geoJson(geo, {
|
||||||
@ -482,7 +368,7 @@ GIS.loadLayer = async function (geoJSON, options, popup = true) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
layer.on("click", async () => {
|
layer.on("click", async () => {
|
||||||
let data = GIS.layerData(layerId);
|
let data = GIS.layerData(site.gisId, site.id);
|
||||||
|
|
||||||
if (typeof data === 'object') {
|
if (typeof data === 'object') {
|
||||||
UI.openSiteModal(data);
|
UI.openSiteModal(data);
|
||||||
@ -497,9 +383,10 @@ GIS.loadLayer = async function (geoJSON, options, popup = true) {
|
|||||||
/**
|
/**
|
||||||
* Retrieves data for a given layer
|
* Retrieves data for a given layer
|
||||||
* @param {string} layerId
|
* @param {string} layerId
|
||||||
|
* @param {string} dbId
|
||||||
* @returns {object} Data for this layer from DB or cache
|
* @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);
|
const fromStorage = localStorage.getItem(layerId);
|
||||||
let data = {};
|
let data = {};
|
||||||
|
|
||||||
@ -510,7 +397,7 @@ GIS.layerData = async function (layerId) {
|
|||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
data = await GIS._fetchData('site/' + layerId);
|
data = await GIS._fetchData('sites/' + dbId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
@ -528,8 +415,8 @@ GIS.getSpherical = async function (siteId) {
|
|||||||
* for a given layer
|
* for a given layer
|
||||||
* @param {string} layerId
|
* @param {string} layerId
|
||||||
*/
|
*/
|
||||||
GIS.cacheDBData = async function (layerId) {
|
GIS.cacheDBData = async function (layerId, dbId) {
|
||||||
const data = await this._fetchData('site/' + layerId);
|
const data = await this._fetchData('sites/' + dbId);
|
||||||
localStorage.setItem(layerId, JSON.stringify(data));
|
localStorage.setItem(layerId, JSON.stringify(data));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -208,39 +208,6 @@ UI.openPrehistModal = function (data, selector) {
|
|||||||
prehistoric.render().then(html => modal.querySelector('#prehist-sheet').innerHTML = html);
|
prehistoric.render().then(html => modal.querySelector('#prehist-sheet').innerHTML = html);
|
||||||
modal.classList.add('is-active');
|
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
|
* Open Spotlight gallery
|
||||||
* @param {string} galleryId The id of the trigger element
|
* @param {string} galleryId The id of the trigger element
|
||||||
|
Loading…
Reference in New Issue
Block a user