170 lines
4.9 KiB
JavaScript
170 lines
4.9 KiB
JavaScript
'use strict';
|
|
|
|
import UI from "./ui.js";
|
|
|
|
// Global leaflet
|
|
/**
|
|
* @namespace GIS
|
|
*/
|
|
const GIS = {};
|
|
|
|
GIS.CENTER_COORDS = [40.5492, 14.2317];
|
|
GIS.INIT_ZOOM = 14.5;
|
|
const optionsVincoli = {
|
|
color: '#222',
|
|
opacity: 0.8,
|
|
weight: 1,
|
|
fillColor: '#987db7',
|
|
fillOpacity: 0.8
|
|
};
|
|
const optionsSiti = {
|
|
color: '#800040',
|
|
opacity: 1,
|
|
weight: 2.5,
|
|
fillColor: '#800040',
|
|
fillOpacity: 0.8
|
|
};
|
|
const optionsPaesistici = {
|
|
color: '#222',
|
|
opacity: 1,
|
|
weight: 1.5,
|
|
fillColor: '#ff8000',
|
|
fillOpacity: 0.8
|
|
};
|
|
|
|
const BASE_URL = location.href;
|
|
/**
|
|
* Capitalize a text string
|
|
* @todo Move to utils
|
|
* @param {?string} text
|
|
* @returns {?string} The capitalized string or null
|
|
*/
|
|
function capitalize(text) {
|
|
let capital = text;
|
|
if (text) {
|
|
let words = text.split(' ');
|
|
capital = '';
|
|
|
|
for (let w of words) {
|
|
w = w[0].toUpperCase() + w.slice(1);
|
|
capital += w + ' ';
|
|
}
|
|
capital.trimEnd();
|
|
}
|
|
|
|
return capital;
|
|
}
|
|
/**
|
|
* @param {string} mapId
|
|
* @param {number} zoomLevel
|
|
* @returns {{map: Map, sites: Layer}}
|
|
*/
|
|
GIS.initMap = async function (mapId, zoomLevel = this.INIT_ZOOM) {
|
|
let layerVincoli = await this.loadLayer('vincoli.geojson', optionsVincoli);
|
|
let layerMater = await this.loadLayer('matermania.geojson', optionsSiti, false);
|
|
let layerArsenale = await this.loadLayer('arsenale_planim.geojson', optionsSiti, false);
|
|
let layerGradola = await this.loadLayer('gradola.geojson', optionsSiti, false);
|
|
// TODO named parameters??
|
|
let layerPaesistici = await this.loadLayer('paesistici.geojson', optionsPaesistici);
|
|
let osmap = new L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
maxNativeZoom : 22,
|
|
maxZoom: 22,
|
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
|
});
|
|
let map = L.map(mapId, {
|
|
attributionControl: false,
|
|
minZoom: 11,
|
|
layers: [osmap, layerVincoli, layerMater, layerGradola, layerArsenale, layerPaesistici]
|
|
}).setView(this.CENTER_COORDS, zoomLevel);
|
|
|
|
map.crs = L.CRS.EPSG4326;
|
|
|
|
const baseMap = {
|
|
"Mappa di base (OpenStreetMap)" : osmap
|
|
};
|
|
const archeo = {
|
|
"Villa di Gradola" : layerGradola,
|
|
"Grotta di Matermania" : layerMater,
|
|
"Grotta dell'Arsenale" : layerArsenale,
|
|
"Vincoli archeologici" : layerVincoli,
|
|
"Vincoli paesistici" : layerPaesistici,
|
|
};
|
|
|
|
let layerControl = L.control.layers(
|
|
baseMap,
|
|
archeo,
|
|
{collapsed: false}
|
|
)
|
|
.addTo(map);
|
|
|
|
// TODO Horrible?
|
|
return {map: map, sites: archeo};
|
|
}
|
|
/**
|
|
* @todo Distinguere tipo di geojson per contenuto popup
|
|
* @param {string} geoJSON
|
|
* @param {{color, opacity, weight, fillColor, fillOpacity}} options Style options for features
|
|
* @param {boolean} popup Should the features have a popup?
|
|
*/
|
|
GIS.loadLayer = async function (geoJSON, options, popup = true) {
|
|
const data = await fetch(`${BASE_URL}/geojson/${geoJSON}`)
|
|
.then(res => res.json())
|
|
.catch(error => console.error(`Can't load layer ${geoJSON}. Reason: ${error}`));
|
|
|
|
// Show data from feature in popUp?
|
|
const layer = new L.geoJson(data, {
|
|
style: function (feature) {
|
|
let style = options;
|
|
return style;
|
|
},
|
|
onEachFeature: function (feature, layer) {
|
|
if (popup) {
|
|
layer.bindPopup(GIS.featurePopup(geoJSON, feature));
|
|
}
|
|
else {
|
|
layer.on("click", async () => {
|
|
const data = await GIS._fetchData(geoJSON.replace('.geojson', ''));
|
|
UI.openModal(data);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
return layer;
|
|
}
|
|
/**
|
|
* Generate proper content for features popup
|
|
* @todo Hard-coded names!!
|
|
*
|
|
* @param {string} layerName
|
|
* @param {object} feature
|
|
* @returns {string} The popup's content
|
|
*/
|
|
GIS.featurePopup = function (layerName, feature) {
|
|
const html = `
|
|
<table class="table m-2">
|
|
<tr><td class="text-bold">Oggetto</td><td>${feature.properties.OGGETTO}</td></tr>
|
|
<tr><td class="text-bold">Anno</td><td>${feature.properties.ANNO}</td></tr>
|
|
<tr><td class="text-bold">Comune</td><td>${capitalize(feature.properties.COMUNE)}</td></tr>
|
|
<tr><td class="text-bold">Località</td><td>${capitalize(feature.properties.LOCALITA)}</td></tr>
|
|
<tr><td class="text-bold">Proprietà</td><td>${capitalize(feature.properties.PROPRIETA)}</td></tr>
|
|
</table>
|
|
`;
|
|
const content = {
|
|
'vincoli.geojson' : html,
|
|
'paesistici.geojson' : html,
|
|
};
|
|
|
|
return content[layerName];
|
|
}
|
|
/**
|
|
* Fetch data from DB using API
|
|
* @todo Actually implement it...
|
|
* @param {string} recordId
|
|
*/
|
|
GIS._fetchData = async function (recordId) {
|
|
//const data = await fetch()
|
|
return recordId;
|
|
}
|
|
|
|
export default GIS; |