Compare commits

...

6 Commits

Author SHA1 Message Date
106c8f60bc Update GeoJSON layers 2025-07-14 10:17:13 +02:00
e3d98c2e5d Move boundaries to base map control 2025-07-08 14:44:01 +02:00
377447f63a Fix stupid bug... 2025-07-08 12:21:10 +02:00
cfcd1e8e80 Render 3D reconstructions for sites 2025-07-08 12:07:08 +02:00
378e14d56a Add Villa Bismarck geojson; refactor layer options 2025-07-07 13:19:06 +02:00
f68216c84c WMS in layers control 2025-06-30 11:18:13 +02:00
7 changed files with 360 additions and 150 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -61,7 +61,7 @@
<span class="icon mr-2">
<i class="fa fa-map"></i>
</span>
Cartografia
Catasto storico
</button>
<button class="button is-outlined is-rounded is-link mr-4 mt-1" id="howto" title="Istruzioni">
<span class="icon is-large has-text-link">
@@ -284,20 +284,6 @@
</template>
<aside class="menu ml-4 mt-3" data-id="cartography-aside">
<button title="Chiudi menu" class="delete is-pulled-right" data-action="menu#closeCartography"></button>
<ul class="menu-list">
<li>
<input type="checkbox" data-controller="layer" data-action="layer#toggleCadastral" />
Catasto Agenzia delle Entrate (particelle e fabbricati)
</li>
</ul>
<p class="menu-label is-size-5 mt-4 is-clickable" data-id="historic">
<span role="button" data-action="click->menu#toggle" data-id="historic">
Catasto storico
<span class="icon pl-2">
<i class="fa fa-chevron-right" data-menu-target="icon" data-id="historic"></i>
</span>
</span>
</p>
</aside>
</div>
</div>

View File

@@ -43,4 +43,21 @@ export class SiteMedia {
</div>
`;
}
renderReconstructions() {
return `
<div class="content has-text-centered mb-5 pb-5">
<p class="is-size-5 mt-3">Ricostruzioni 3D</p>
<div style="max-width: 70%; margin: 0 auto">
<p class="is-size-6 has-text-centered">Gallery ricostruzioni 3D</p>
<figure class="is-relative is-clickable has-text-centered" id="gallery-3d">
<img src="img/${this._siteData.filename}" width="300"/>
<div class="icon overlay is-flex is-justify-content-center is-align-items-center">
<i class="is-flex fa fa-2x fa-play-circle"></i>
</div>
</figure>
</div>
</div>
`;
}
}

View File

@@ -5,6 +5,7 @@ import API_CONFIG from "./config.js";
import Icons from "./icons.js";
import { SphericalPhoto } from "./components/SphericalPhoto.js";
import { GisState } from "./state.js";
import Options from "./layer_options.js";
const MAPBOX_TOKEN = 'pk.eyJ1Ijoibmljb3BhIiwiYSI6ImNseWNwZjJjbjFidzcya3BoYTU0bHg4NnkifQ.3036JnCXZTEMt6jVgMzVRw';
const BASE_URL = location.href;
@@ -28,47 +29,6 @@ GIS.INIT_ZOOM = 14;
GIS.MIN_ZOOM = 11;
GIS.MAX_ZOOM = 24;
const optionsVincoli = {
color: '#222',
opacity: 0.8,
weight: 1,
fillColor: '#fa7861',
fillOpacity: 0.8
};
const optionsSiti = {
color: '#800040',
opacity: 1,
weight: 1.5,
fillColor: '#800040',
fillOpacity: 0.8
};
const optionsGrotta = {
color: '#205dac',
opacity: 1,
weight: 1.5,
fillColor: '#205dac',
fillOpacity: 0.8
}
const optionsPaesistici = {
color: '#222',
opacity: 1,
weight: 1.5,
fillColor: '#88d28d',
fillOpacity: 0.8
};
const optionsFabbricati = {
color: '#222',
opacity: 1,
weight: 1.5,
fillColor: '#5b5d5f',
fillOpacity: 0.8
};
const clusterOptions = {
spiderfyOnMaxZoom: false,
showCoverageOnHover: false,
disableClusteringAtZoom: 19,
};
/**
* Capitalize a text string
* @todo Move to utils
@@ -108,37 +68,36 @@ GIS.initMap = async function (mapId, zoomLevel = this.INIT_ZOOM) {
L.control.scale({imperial: false}).addTo(map);
L.control.graphicScale({fill: 'hollow', position: 'bottomright'}).addTo(map);
let layerVincoli = await this.loadGeoJSON('vincoli.geojson', optionsVincoli);
let layerPaesistici = await this.loadGeoJSON('paesistici.geojson', optionsPaesistici);
let layerVincoli = await this.loadGeoJSON('vincoli.geojson', Options.constraintsArch);
let layerPaesistici = await this.loadGeoJSON('paesistici.geojson', Options.constraintsLand);
let buildings = await this.loadGeoJSON('fabbricati.geojson', Options.buildings, false);
await this.addLayerGroups(map);
await this.fetchCartographyLayers();
const archeo = {
'Vincoli archeologici' : layerVincoli,
'Vincoli paesistici' : layerPaesistici,
//'Catasto storico' : historicCadastre,
};
L.control.layers(baseMap, archeo).addTo(map);
GisState.map = map;
const reprojectedWMSLayer = GIS.reprojectWMS();
const wmsLayer = new reprojectedWMSLayer(
'https://wms.cartografia.agenziaentrate.gov.it/inspire/wms/ows01.php?',
{
layers: 'CP.CadastralParcel,fabbricati',
layers: 'CP.CadastralParcel,codice_plla,fabbricati',
transparent: true,
format: 'image/png',
version: '1.1.1',
minZoom: 15,
minZoom: this.INIT_ZOOM,
maxZoom: this.MAX_ZOOM,
tileSize: 1024,
opacity: 0.6,
}
);
const cartography = {
'Catasto Agenzia delle Entrate (zoom per visualizzare)' : wmsLayer,
'Fabbricati' : buildings,
'Vincoli archeologici' : layerVincoli,
'Vincoli archeologici indiretti' : layerPaesistici,
};
L.control.layers(baseMap, cartography).addTo(map);
GisState.cartography.cadastral = wmsLayer;
GisState.map = map;
return map;
}
@@ -211,15 +170,20 @@ GIS.sites = async function () {
let sitesData = await fetch(`${API_URL}/sites`)
.then(data => data.json());
let sites = L.markerClusterGroup(clusterOptions);
let sites = L.markerClusterGroup(Options.cluster);
let geom = [];
for (let record of sitesData) {
if (record.geojson) {
const options = record.gisId === 'grotta_azzurra' ?
optionsGrotta : optionsSiti;
Options.grotta : Options.site;
geom.push(await this.loadSiteLayer(record, options));
}
if (record.area) {
const options = record.gisId === 'villa_bismarck' ?
Options.bismarck : Options.site;
geom.push(await this.loadSiteLayer(record, options, false, true));
}
const marker = L.marker(
record.coordinates,
@@ -251,7 +215,7 @@ GIS.notConserved = async function () {
let notConserData = await fetch(`${API_URL}/not_conserved`)
.then(data => data.json());
let notConserved = L.markerClusterGroup(clusterOptions);
let notConserved = L.markerClusterGroup(Options.cluster);
for (let record of notConserData.records) {
const marker = L.marker(
@@ -281,7 +245,7 @@ GIS.findings = async function () {
.then(data => data.json());
let findings = L.markerClusterGroup(
clusterOptions
Options.cluster
);
for (let record of findingsData) {
@@ -313,7 +277,7 @@ GIS.prehistoric = async function () {
.then(data => data.json());
let prehistoric = L.markerClusterGroup(
clusterOptions
Options.cluster
);
for (let record of data.records) {
@@ -345,7 +309,7 @@ GIS.underwater = async function () {
let underwaterData = await fetch(`${API_URL}/underwater`)
.then(data => data.json());
let underwater = L.markerClusterGroup(clusterOptions);
let underwater = L.markerClusterGroup(Options.cluster);
for (let record of underwaterData.records) {
const marker = L.marker(
@@ -370,7 +334,6 @@ GIS.underwater = async function () {
/**
* 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}}}
*/
@@ -389,16 +352,15 @@ GIS.initLayers = async function(map) {
maxZoom: GIS.MAX_ZOOM,
attribution: '&copy; Mapbox'
});
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 baseGroup = new L.LayerGroup([osmap]);
baseGroup.addTo(map);
const baseMap = {
"OpenStreetMap" : osmap,
"Satellite" : mapbox,
"Cartografia catastale" : baseCatasto,
'Limiti amministrativi' : boundaries,
};
return baseMap;
@@ -479,9 +441,10 @@ GIS.loadGeoJSON = async function (geoJSON, options, popup = true) {
* @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}`)
GIS.loadSiteLayer = async function (site, options, popup = true, area = false) {
let geoJSON = site.gisId;
geoJSON += area ? '_area.geojson' : '.geojson';
const geo = await fetch(`${BASE_URL}geojson/${geoJSON}`)
.then(res => res.json())
.catch(error => console.error(`Can't load layer ${geoJSON}. Reason: ${error}`));

View File

@@ -0,0 +1,54 @@
/**
* @namespace Options
*/
let Options = {};
Options.constraintsArch = {
color: '#222',
opacity: 0.8,
weight: 1,
fillColor: '#fa7861',
fillOpacity: 0.8
};
Options.site = {
color: '#800040',
opacity: 1,
weight: 1.5,
fillColor: '#800040',
fillOpacity: 0.8
};
Options.grotta = {
color: '#205dac',
opacity: 1,
weight: 1.5,
fillColor: '#205dac',
fillOpacity: 0.8
}
Options.bismarck = {
color: '#a4a79a',
opacity: 1,
weight: 1.5,
fillColor: '#a4a79a',
fillOpacity: 0.8
}
Options.constraintsLand = {
color: '#222',
opacity: 1,
weight: 1.5,
fillColor: '#88d28d',
fillOpacity: 0.8
};
Options.buildings = {
color: '#222',
opacity: 1,
weight: 1.5,
fillColor: '#5b5d5f',
fillOpacity: 0.8
};
Options.cluster = {
spiderfyOnMaxZoom: false,
showCoverageOnHover: false,
disableClusteringAtZoom: 19,
};
export default Options;

View File

@@ -100,8 +100,14 @@ UI.openSiteModal = function (data, selector) {
let surveys = data.images.filter(i => i.type === 'Survey');
let photos = data.images.filter(i => i.type === 'Photo');
let videos = data.images.filter(i => i.type === 'Video');
let reconstructions = data.images.filter(i => i.type === 'Reconstruction');
if (surveys.length === 0 && photos.length === 0 && videos.length === 0) {
const noMedia = surveys.length === 0
&& photos.length === 0
&& reconstructions.length === 0
&& videos.length === 0;
if (noMedia) {
images.innerHTML = '<p class="has-text-centered">Nessuna risorsa visuale disponibile</p>';
}
@@ -114,6 +120,9 @@ UI.openSiteModal = function (data, selector) {
siteMedia.siteData = photos[0] ?? undefined;
images.innerHTML += photos[0] ? siteMedia.renderPhotos() : '';
siteMedia.siteData = reconstructions[0] ?? undefined;
images.innerHTML += reconstructions[0] ? siteMedia.renderReconstructions() : '';
siteMedia.siteData = videos[0] ?? undefined;
images.innerHTML += videos[0] ? siteMedia.renderVideos() : '';
}
@@ -122,6 +131,7 @@ UI.openSiteModal = function (data, selector) {
this.imageGallery('gallery-1', surveys);
this.imageGallery('gallery-2', photos);
this.imageGallery('gallery-3d', reconstructions);
this.imageGallery('gallery-video', videos, true);
}
/**