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', | ||||
|     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: '© 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)); | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     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?
 | ||||
|     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)); | ||||
| } | ||||
| /** | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user