18 changed files with 2506 additions and 173 deletions
View File
+16 -2
View File
@@ -1,5 +1,5 @@
@import url("../webgis/js/vendor/bulma/css/bulma.min.css");
@import url("../webgis/js/vendor/fontawesome-free/css/all.min.css");
@import url("../vendor/bulma/css/bulma.min.css");
@import url("../vendor/fontawesome-free/css/all.min.css");
@import url("../fonts/fonts.css");
/* Variables */
:root {
@@ -211,3 +211,17 @@ input:invalid {
.mixed-tech {
color: #f0280f;
}
/* Building view top bar */
.bview-bar {
position: absolute;
top: 4rem;
width: 450px;
left: 50%;
transform: translateX(-50%);
border-radius: 8px;
}
/* Map container border for building view */
.bview-border {
border:#263aac 4px solid;
border-radius: 8px;
}
+3 -3
View File
@@ -4,12 +4,12 @@
<meta charset="UTF-8" />
<link rel="stylesheet" href="css/app.css" />
<link rel="shortcut icon" type="image/png" href="/img/favicon.png">
<link rel="stylesheet" href="webgis/js/vendor/spotlight.js/dist/css/spotlight.min.css" />
<link rel="stylesheet" href="/vendor/spotlight.js/dist/css/spotlight.min.css" />
<title>Carta Archeologica Isola di Capri</title>
<script type="importmap">
{
"imports": {
"@hotwired/stimulus": "./webgis/js/vendor/@hotwired/stimulus/dist/stimulus.js"
"@hotwired/stimulus": "./vendor/@hotwired/stimulus/dist/stimulus.js"
}
}
</script>
@@ -560,7 +560,7 @@
<script type="module">
import { Application } from '@hotwired/stimulus';
import ModalController from './webgis/js/controllers/modal_controller.js';
import Spotlight from './webgis/js/vendor/spotlight.js/src/js/spotlight.js';
import Spotlight from './vendor/spotlight.js/src/js/spotlight.js';
window.Stimulus = Application.start();
Stimulus.register("modal", ModalController);
+7 -2
View File
@@ -3,7 +3,7 @@
"version": "0.01",
"main": "index.js",
"author": "Nicolò P.",
"license": "GPLv3",
"license": "GPL-3.0-or-later",
"dependencies": {
"@hotwired/stimulus": "^3.2.2",
"@kalisio/leaflet-graphicscale": "^1.0.0",
@@ -15,5 +15,10 @@
"proj4": "^2.9.4",
"spotlight.js": "^0.7.8"
},
"devDependencies": {}
"devDependencies": {
"standard": "^17.1.2"
},
"scripts": {
"start": "symfony server:start --port=3000"
}
}
@@ -0,0 +1,13 @@
{
"type": "FeatureCollection",
"name": "reticolata",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "id": null, "Comune": "Capri", "Località": "Bagni di Tiberio", "Tipologia": "Struttura Muraria", "Tecnica": "Opera reticolata", "Materiale": "Tufo", "Funzione": null, "Descrizione": "Murature di fondo e divisorie degli ambienti prospicienti il mare, posti allestremità orientale del complesso dei Bagni di Tiberio", "Elemento": "Alzati", "Componenti": "Cubilia e Blocchetti di ammorsamento angolari" }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 14.229777980072088, 40.559287936017519 ], [ 14.229767127017078, 40.559288012101483 ], [ 14.22976727121063, 40.559297587195999 ], [ 14.229760323645737, 40.559297626052299 ], [ 14.229760154396285, 40.559286387060112 ], [ 14.229750772025486, 40.559286469247525 ] ] ] } },
{ "type": "Feature", "properties": { "id": null, "Comune": "Capri", "Località": "Bagni di Tiberio", "Tipologia": "Struttura Muraria", "Tecnica": "Opera Reticolata", "Materiale": "Tufo", "Funzione": null, "Descrizione": "Lacerto murario in giacitura secondaria, riferibile a una struttura con fondazione in opera cementizia e alzato in opera reticolata", "Elemento": "alzato, attacco di fondazione", "Componenti": "Cubilia, scapoli di calcare, scapoli di tufo" }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 14.229748638716192, 40.559312774822097 ], [ 14.229749854780234, 40.559313917882307 ], [ 14.229749311598642, 40.559316242764893 ], [ 14.229747641045932, 40.559318431170922 ], [ 14.229745404602166, 40.559318825800922 ], [ 14.229707320793663, 40.559318057726777 ], [ 14.229688319593144, 40.559316631832786 ], [ 14.229687414956194, 40.55931462813308 ], [ 14.229689070847257, 40.559311784892955 ], [ 14.229707054884152, 40.559311704425618 ], [ 14.22973485378067, 40.5593122650738 ], [ 14.229745138689067, 40.559312472499833 ], [ 14.229748638716192, 40.559312774822097 ] ] ] } },
{ "type": "Feature", "properties": { "id": null, "Comune": "Capri", "Località": "Bagni di Tiberio", "Tipologia": "Strutture murarie", "Tecnica": "Opera reticolata", "Materiale": "Tufo", "Funzione": null, "Descrizione": "Due murature, rispettivamente di fondo e laterale, pertinenti a un ambiente prospiciente il mare nellarea orientale del complesso dei Bagni di Tiberio", "Elemento": "Alzati", "Componenti": "Cubilia, blocchetti di tufo angolari e terminali" }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 14.229694021609493, 40.55930762924018 ], [ 14.229694082338904, 40.559310341259078 ], [ 14.229682272612358, 40.559310495088383 ], [ 14.229616809841877, 40.559314335557936 ], [ 14.229615693144396, 40.559336306937055 ] ] ] } },
{ "type": "Feature", "properties": { "id": null, "Comune": "Capri", "Località": "Bagni di Tiberio", "Tipologia": "Strutture Murarie", "Tecnica": "Opera reticolata", "Materiale": "Tufo", "Funzione": null, "Descrizione": "Due murature pertinenti a un ambiente ubicato sul livello superiore dellarea occidentale del complesso dei Bagni di Tiberio.", "Elemento": "alzati", "Componenti": "cubilia, blocchetti di ammorsamento" }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 14.229012969950622, 40.559279324646354 ], [ 14.22901299762786, 40.559273288155325 ], [ 14.228949305222281, 40.559271595449403 ] ] ] } },
{ "type": "Feature", "properties": { "id": null, "Comune": "Capri", "Località": "Bagni di Tiberio", "Tipologia": "Strutture Murarie", "Tecnica": "Opera reticolata", "Materiale": "Tufo", "Funzione": null, "Descrizione": "muratura in pessimo stato di conservazione, inglobata in costruzione moderna", "Elemento": "Alzato", "Componenti": "Cubilia" }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 14.228945620292212, 40.559244814778907 ], [ 14.228945097860407, 40.559260882019025 ] ] ] } },
{ "type": "Feature", "properties": { "id": null, "Comune": "Capri", "Località": "Bagni di Tiberio", "Tipologia": "Struttura Muraria", "Tecnica": "Opera reticolata", "Materiale": "Tufo", "Funzione": "sostruttiva", "Descrizione": "Fondazione del terrazzamento prospiciente il mare, con porticato soprastante", "Elemento": "Fondazione", "Componenti": "Cubilia" }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 14.22932061572207, 40.559368986602642 ], [ 14.229319898205036, 40.559370575004976 ], [ 14.229315830697367, 40.559373603453658 ], [ 14.229313913113851, 40.559377741595505 ] ] ] } }
]
}
+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-bricks" viewBox="0 0 16 16">
<path d="M0 .5A.5.5 0 0 1 .5 0h15a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-.5.5H14v2h1.5a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-.5.5H14v2h1.5a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-.5.5H.5a.5.5 0 0 1-.5-.5v-3a.5.5 0 0 1 .5-.5H2v-2H.5a.5.5 0 0 1-.5-.5v-3A.5.5 0 0 1 .5 6H2V4H.5a.5.5 0 0 1-.5-.5zM3 4v2h4.5V4zm5.5 0v2H13V4zM3 10v2h4.5v-2zm5.5 0v2H13v-2zM1 1v2h3.5V1zm4.5 0v2h5V1zm6 0v2H15V1zM1 7v2h3.5V7zm4.5 0v2h5V7zm6 0v2H15V7zM1 13v2h3.5v-2zm4.5 0v2h5v-2zm6 0v2H15v-2z"/>
</svg>

After

Width:  |  Height:  |  Size: 574 B

+15 -15
View File
@@ -2,32 +2,32 @@
<html lang="it" data-text="html" data-theme="light">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="js/vendor/leaflet/dist/leaflet.css" />
<link rel="stylesheet" href="js/vendor/leaflet.markercluster/dist/MarkerCluster.css" />
<link rel="stylesheet" href="js/vendor/leaflet.markercluster/dist/MarkerCluster.Default.css" />
<link rel="stylesheet" href="/vendor/leaflet/dist/leaflet.css" />
<link rel="stylesheet" href="/vendor/leaflet.markercluster/dist/MarkerCluster.css" />
<link rel="stylesheet" href="/vendor/leaflet.markercluster/dist/MarkerCluster.Default.css" />
<link rel="stylesheet" href="../css/app.css" />
<link rel="stylesheet" href="js/vendor/spotlight.js/dist/css/spotlight.min.css" />
<link rel="stylesheet" href="js/vendor/@kalisio/leaflet-graphicscale/dist/Leaflet.GraphicScale.min.css" />
<link rel="stylesheet" href="js/vendor/@photo-sphere-viewer/core/index.css" />
<link rel="stylesheet" href="/vendor/spotlight.js/dist/css/spotlight.min.css" />
<link rel="stylesheet" href="/vendor/@kalisio/leaflet-graphicscale/dist/Leaflet.GraphicScale.min.css" />
<link rel="stylesheet" href="/vendor/@photo-sphere-viewer/core/index.css" />
<link rel="shortcut icon" type="image/png" href="/img/favicon.png">
<script type="importmap">
{
"imports": {
"three": "./js/vendor/three/build/three.module.js",
"@photo-sphere-viewer/core": "./js/vendor/@photo-sphere-viewer/core/index.module.js",
"@hotwired/stimulus": "./js/vendor/@hotwired/stimulus/dist/stimulus.js"
"three": "../vendor/three/build/three.module.js",
"@photo-sphere-viewer/core": "../vendor/@photo-sphere-viewer/core/index.module.js",
"@hotwired/stimulus": "../vendor/@hotwired/stimulus/dist/stimulus.js"
}
}
</script>
<script src="./js/vendor/proj4/dist/proj4.js"></script>
<script src="js/vendor/leaflet/dist/leaflet-src.js"></script>
<script src="js/vendor/leaflet.markercluster/dist/leaflet.markercluster.js"></script>
<script src="js/vendor/@kalisio/leaflet-graphicscale/dist/Leaflet.GraphicScale.min.js"></script>
<script src="/vendor/proj4/dist/proj4.js"></script>
<script src="/vendor/leaflet/dist/leaflet-src.js"></script>
<script src="/vendor/leaflet.markercluster/dist/leaflet.markercluster.js"></script>
<script src="/vendor/@kalisio/leaflet-graphicscale/dist/Leaflet.GraphicScale.min.js"></script>
<script src="js/index.js" type="module"></script>
<title>WebGIS Isola di Capri</title>
</head>
<body data-controller="menu modal"
data-action="menu-ready@document->menu#buildMenu menu-ready@document->menu#buildCartographyMenu">
<body data-controller="menu modal bview"
data-action="menu-ready@document->menu#buildMenu menu-ready@document->menu#buildCartographyMenu keydown.esc->bview#closeView">
<nav class="navbar mb-0" role="navigation">
<div class="navbar-brand">
<a href="/" class="navbar-item is-size-5 has-text-dark ml-4" title="Torna alla home page">
+39
View File
@@ -0,0 +1,39 @@
import { Controller } from "@hotwired/stimulus"
import { GisState } from '../state.js';
export default class extends Controller {
static targets = ['bar'];
closeView(event) {
// Don't do anything if ESC keyboard event
// is not fired from the building view
if (event instanceof KeyboardEvent && !GisState.bViewActive) return;
this.resetMap();
this.barTarget.remove();
GisState.bViewActive = false;
}
resetMap() {
// Restore previous map state before closing view
const map = GisState.map;
map.removeLayer(GisState.baseLayers['Limiti amministrativi']);
//map.removeLayer(GisState.cartography.buildings);
const walls = GisState.layers.walls;
// map.removeLayer(GisState.layers.walls) doesn't work, i.e.
// it doesn't remove the layer group (fails silently)
walls.eachLayer(layer => map.removeLayer(layer));
GisState.layers.walls.removeFrom(map);
map.addLayer(GisState.currentMapState.baseLayer);
map.setMinZoom(GisState.currentMapState.minZoom);
map.setMaxZoom(GisState.currentMapState.maxZoom);
map.setView(
GisState.currentMapState.center,
GisState.currentMapState.zoom
);
map._container.classList.remove('bview-border');
}
}
+6 -1
View File
@@ -7,7 +7,8 @@ export default class extends Controller {
'menu',
'cartography',
'search',
'icon'
'icon',
'element',
];
static values = {
@@ -169,4 +170,8 @@ export default class extends Controller {
return icon;
}
removeElement() {
this.elementTarget.remove();
}
}
+101 -30
View File
@@ -6,9 +6,19 @@ import Icons from "./icons.js";
import { SphericalPhoto } from "./components/SphericalPhoto.js";
import { GisState } from "./state.js";
import Options from "./layer_options.js";
import { saveCurrentState } from "./map.js";
const MAPBOX_TOKEN = 'pk.eyJ1Ijoibmljb3BhIiwiYSI6ImNseWNwZjJjbjFidzcya3BoYTU0bHg4NnkifQ.3036JnCXZTEMt6jVgMzVRw';
const BASE_URL = location.href;
// TODO: Use DB to handle these?
const WALL_TECHNIQUES = [
'reticolata',
'incerta',
'mista',
'laterizia',
'cementizia',
'poligonale',
];
let API_URL = API_CONFIG.prod;
@@ -40,15 +50,8 @@ export const INIT_ZOOM = 14;
*/
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();
if (text !== null && text !== undefined && text.at && text.length) {
capital = text.at(0).toLocaleUpperCase() + text.slice(1);
}
return capital;
@@ -62,6 +65,7 @@ GIS.initMap = async function (mapId, zoomLevel = this.INIT_ZOOM) {
let map = L.map(mapId, {
//attributionControl: false,
minZoom: GIS.MIN_ZOOM,
maxZoom: GIS.MAX_ZOOM,
}).setView(this.CENTER_COORDS, zoomLevel);
map.crs = L.CRS.EPSG4326;
@@ -102,10 +106,63 @@ GIS.initMap = async function (mapId, zoomLevel = this.INIT_ZOOM) {
};
L.control.layers(baseMap, cartography).addTo(map);
// TEST: marker with SVG icon...
L.marker([40.5591380,14.2296069], { icon: Icons.wall, id: 'tiberio' })
.on('click', () => this.activateBuildingView('tiberio'))
.bindTooltip('Mappa USM')
.addTo(map);
GisState.map = map;
GisState.cartography.buildings = buildings;
return map;
}
/**
* Draft implementation to activate
* a dedicated view with details
* to navigate building walls
* @todo Find better name
* @param {string} layerId
*/
GIS.activateBuildingView = async function(layerId) {
const map = GisState.map;
saveCurrentState(map);
let currentBase = GisState.currentMapState.baseLayer;
map.removeLayer(currentBase);
// Remove site layers then re-add it so vector lines
// are placed correctly above the new base map
GisState.layers.geometries.removeFrom(map);
map.addLayer(GisState.baseLayers['Limiti amministrativi']);
//GisState.cartography.buildings.addTo(map);
GisState.layers.geometries.addTo(map);
// Cache!
const wallLayer = await this.loadGeoJSON(
`murarie/${layerId}/reticolata.geojson`,
// TODO: create color lookup table...
Options.walls,
true
);
wallLayer.addTo(map);
// The group of all added walls...
GisState.layers.walls = L.layerGroup([wallLayer]);
map.setView(
wallLayer.getBounds().getCenter(),
20,
{animate: false},
);
map.setMinZoom(19);
map.setMaxZoom(25);
// This is terrible...
UI.addBuildingViewBar();
map._container.classList.add('bview-border');
GisState.bViewActive = true;
}
/**
* Fetches references to cartography layers
* and updates GisState
@@ -187,6 +244,9 @@ GIS.addLayerGroups = async function (map) {
sites.markers.addTo(map);
sites.geom.addTo(map);
// A layer group with all site geometries (GeoJSON)
GisState.layers.geometries = sites.geom;
const groups = await Promise.all(
[
this.notConserved(),
@@ -213,7 +273,7 @@ GIS.sites = async function () {
if (record.geojson) {
const options = record.gisId === 'grotta_azzurra' ?
Options.grotta : Options.site;
geom.push(await this.loadSiteLayer(record, options));
geom.push(await this.loadSiteLayer(record, options, false));
}
if (record.area) {
const options = record.gisId === 'villa_bismarck' ?
@@ -412,7 +472,6 @@ GIS.reuse = async function () {
* @returns {{baseMap: {"OpenStreetMap": L.TileLayer}}}
*/
GIS.initLayers = async function(map) {
let osmap = new L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxNativeZoom : GIS.MAX_ZOOM,
maxZoom: GIS.MAX_ZOOM,
@@ -427,7 +486,7 @@ GIS.initLayers = async function(map) {
attribution: '&copy; Mapbox'
});
let boundaries = await this.loadGeoJSON('confini.geojson', {}, false);
let boundaries = await this.loadGeoJSON('confini.geojson', Options.boundaries, false);
const baseGroup = new L.LayerGroup([osmap]);
baseGroup.addTo(map);
@@ -437,6 +496,8 @@ GIS.initLayers = async function(map) {
'Limiti amministrativi' : boundaries,
};
GisState.baseLayers = baseMap;
return baseMap;
}
/**
@@ -466,7 +527,7 @@ GIS.toggleSpherical = async function(map) {
});
modal.querySelector('.modal-close').addEventListener('click', () => {
modal.classList.remove('is-active');
})
});
sPhoto.setViewer(pano.filename);
});
@@ -488,7 +549,7 @@ GIS.toggleSpherical = async function(map) {
* @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}
* @returns {L.GeoJSON}
*/
GIS.loadGeoJSON = async function (geoJSON, options, popup = true) {
const geo = await fetch(`${BASE_URL}/geojson/${geoJSON}`)
@@ -496,6 +557,9 @@ GIS.loadGeoJSON = async function (geoJSON, options, popup = true) {
.catch(error => console.error(`Can't load layer ${geoJSON}. Reason: ${error}`));
// Show data from feature in popUp?
/**
* @type {L.GeoJSON} layer
*/
const layer = new L.geoJson(geo, {
style: function () {
return options;
@@ -545,6 +609,8 @@ GIS.loadSiteLayer = async function (site, options, popup = true, area = false) {
}
});
layer.options.id = site.gisId;
return layer;
}
/**
@@ -595,23 +661,28 @@ GIS.cacheDBData = async function (layerId, dbId) {
* @returns {string} The popup's content
*/
GIS.featurePopup = function (layerName, feature) {
const html = `
<table class="table is-striped is-size-6 m-2">
<tr><th>Oggetto</th><td>${feature.properties.OGGETTO ?? 'n.d.'}</td></tr>
<tr><th>Anno</th><td>${feature.properties.ANNO}</td></tr>
<tr><th>Comune</th><td>${capitalize(feature.properties.COMUNE)}</td></tr>
<tr><th>Località</th><td>${capitalize(feature.properties.LOCALITA) ?? 'n.d.'}</td></tr>
<tr><th>Proprietà</th><td>${capitalize(feature.properties.PROPRIETA) ?? 'n.d.'}</td></tr>
<tr><th>Foglio</th><td>${feature.properties.FOGLIO}</td></tr>
<tr><th>Particella</th><td>${feature.properties.PART_BIS ?? 'n.d.'}</td></tr>
</table>
`;
const content = {
'vincoli.geojson' : html,
'paesistici.geojson' : html,
};
const html = String.raw;
return content[layerName];
let content = html`
<table class="table is-striped is-size-6 m-2">
`;
for (let key of Object.keys(feature.properties)) {
const label = key === 'PART_BIS' ? 'Particella' :
key === 'PROPRIETA' ? 'Proprietà' :
key === 'LOCALITA' ? 'Località' :
key;
if (key !== 'PERCENTUAL' && key !== 'AREA' && key.toLowerCase() !== 'id') {
content += html`
<tr><th>${capitalize(label.toLocaleLowerCase())}</th><td>${capitalize(feature.properties[key]) ?? 'n.d.'}</td></tr>
`;
}
}
content += '</table>'
return content;
}
/**
* Reproject WMS layer to map's CRS
+19 -24
View File
@@ -14,61 +14,56 @@ const buildingTechColors = {
*/
const Icons = {};
Icons.site = L.icon(
{
Icons.site = L.icon({
iconUrl: 'img/icons/siti.png',
iconSize: [18, 27],
iconAnchor: [10, 24],
tooltipAnchor: [0, -22],
}
);
Icons.notConserved = L.icon(
{
});
Icons.notConserved = L.icon({
iconUrl: 'img/icons/non_conserv.png',
iconSize: [18, 27],
iconAnchor: [10, 24],
tooltipAnchor: [0, -22],
}
);
});
Icons.finding = L.icon(
{
Icons.finding = L.icon({
iconUrl: 'img/icons/rinvenimenti.png',
iconSize: [18, 27],
iconAnchor: [10, 24],
tooltipAnchor: [0, -22],
}
);
});
Icons.prehistoric = L.icon(
{
Icons.prehistoric = L.icon({
iconUrl: 'img/icons/preistorici.png',
iconSize: [18, 27],
iconAnchor: [10, 24],
tooltipAnchor: [0, -22],
}
);
});
Icons.underwater = L.icon(
{
Icons.underwater = L.icon({
iconUrl: 'img/icons/subacquei.png',
iconSize: [18, 27],
iconAnchor: [10, 24],
tooltipAnchor: [0, -22],
}
);
});
Icons.reuse = L.icon(
{
Icons.reuse = L.icon({
iconUrl: 'img/icons/reimpiego.png',
iconSize: [18, 27],
iconAnchor: [10, 24],
tooltipAnchor: [0, -22],
}
);
});
Icons.camera = L.divIcon({className: 'fa fa-camera'});
Icons.wall = L.icon({
iconUrl: 'img/icons/bricks.svg',
iconSize: [18, 27],
iconAnchor: [10, 24],
tooltipAnchor: [0, -22],
});
/**
* Assigns a different color to the icon
* based on building tech type
+2
View File
@@ -9,6 +9,7 @@ import BiblioController from './controllers/biblio_controller.js';
import TabsController from './controllers/tabs_controller.js';
import LayerController from './controllers/layer_controller.js';
import SearchController from './controllers/search_controller.js';
import BViewController from './controllers/bview_controller.js';
document.addEventListener('DOMContentLoaded', async () => {
// Register Stimulus controllers
@@ -39,4 +40,5 @@ function initStimulus() {
Stimulus.register("tabs", TabsController);
Stimulus.register("layer", LayerController);
Stimulus.register("search", SearchController);
Stimulus.register("bview", BViewController);
}
+15 -1
View File
@@ -42,9 +42,23 @@ Options.buildings = {
color: '#222',
opacity: 1,
weight: 1.5,
fillColor: '#5b5d5f',
fillColor: '#717274',
fillOpacity: 0.8
};
Options.boundaries = {
color: '#222',
opacity: 1,
weight: 1.5,
fillColor: '#d8dbdd',
fillOpacity: 0.5
};
Options.walls = {
color: '#10ee47',
fillColor: '#10ee47',
fillOpacity: 1,
opacity: 1,
weight: 4.5,
};
Options.cluster = {
spiderfyOnMaxZoom: false,
showCoverageOnHover: false,
+31
View File
@@ -0,0 +1,31 @@
import { GisState } from "./state.js";
/**
* Functions / utilities to manipulate the Leaflet map
* @module Map
*/
/**
* Saves the current state of the map
* @param {L.Map} map
*/
export function saveCurrentState(map) {
let currentBase = {};
for (let key of Object.keys(GisState.baseLayers)) {
if (map.hasLayer(GisState.baseLayers[key])) {
currentBase = GisState.baseLayers[key];
break;
}
}
GisState.currentMapState = {
baseLayer: currentBase,
zoom: map.getZoom(),
center: map.getCenter(),
minZoom: map.getMinZoom(),
maxZoom: map.getMaxZoom(),
}
}
function getCurrentState() {
//TODO
}
+22
View File
@@ -8,9 +8,22 @@
* A lookup table of Leaflet layer groups by category
*/
/**
* @typedef {Object} MapState
* @property {L.Layer} baseLayer
* @property {number} zoom
* @property {L.LatLngExpression} center
* @property {number} minZoom
* @property {number} maxZoom
* A representation of the (current) Leaflet map state
*/
/**
* @typedef {Object} GisStateType
* @property {L.Map|null} map
* @property {{string: L.Layer}|null} baseLayers
* @property {?MapState} currentMapState
* @property {boolean} bViewActive
* @property {MarkerLookup} markers
* @property {LayerGroupLookup} layers
* @property {Object|null} bibliography
@@ -21,6 +34,9 @@
/** @type {GisStateType} */
export const GisState = {
map: null,
baseLayers: null,
currentMapState: null,
bViewActive: false,
markers: {
sites: {},
notConserved: {},
@@ -31,6 +47,11 @@ export const GisState = {
buildingTechs: {},
},
layers: {
geometries: {},
/**
* @type {L.LayerGroup}
*/
walls: {},
sites: {},
notConserved: {},
findings: {},
@@ -44,6 +65,7 @@ export const GisState = {
cartography : {
historic: [],
cadastral: null,
buildings: null,
}
}
+16 -2
View File
@@ -1,6 +1,6 @@
'use strict';
import Spotlight from './vendor/spotlight.js/src/js/spotlight.js';
import Spotlight from '/vendor/spotlight.js/src/js/spotlight.js';
import { SiteSheet } from './components/SiteSheet.js';
import { SiteDocuments } from './components/SiteDocuments.js';
import { SiteSurveys } from './components/SiteSurveys.js';
@@ -42,7 +42,7 @@ UI.addCenterMapControl = function (map, centerCoords, zoom) {
let controlUI = L.DomUtil.create('a', 'leaflet-draw-edit-remove', controlDiv);
controlUI.title = 'Centra la mappa';
controlUI.href = '#';
controlUI.innerHTML = `
controlUI.innerHTML = html`
<span class="icon is-medium">
<i>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" class="pt-2" viewBox="0 0 16 16">
@@ -59,6 +59,20 @@ UI.addCenterMapControl = function (map, centerCoords, zoom) {
let centerCtr = new L.Control.CenterControl();
map.addControl(centerCtr);
}
UI.addBuildingViewBar = function() {
const bar = document.createElement('div');
bar.className = 'container bview-bar has-background-primary-90 p-3';
bar.setAttribute('data-bview-target', 'bar');
bar.innerHTML = html`
<button title="Esci da mappa USM" class="delete is-pulled-right" data-action="bview#closeView"></button>
<p class="has-text-centered has-text-weight-semibold is-size-5 p-2">Mappa Unità Stratigrafica Muraria (USM)</p>
<p class="has-text-centered is-size-6 mt-0 pt-0">(Chiudere questo riquadro o premere ESC per uscire)</p>
`;
document.body.appendChild(bar);
}
/**
* Toggle burger menu for small screens
* @param {string} burgerClass The CSS class of the burger element
-68
View File
@@ -1,68 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@hotwired/stimulus@^3.2.2":
version "3.2.2"
resolved "https://registry.yarnpkg.com/@hotwired/stimulus/-/stimulus-3.2.2.tgz#071aab59c600fed95b97939e605ff261a4251608"
integrity sha512-eGeIqNOQpXoPAIP7tC1+1Yc1yl1xnwYqg+3mzqxyrbE5pg5YFBZcA6YoTiByJB6DKAEsiWtl6tjTJS4IYtbB7A==
"@kalisio/leaflet-graphicscale@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@kalisio/leaflet-graphicscale/-/leaflet-graphicscale-1.0.0.tgz#5a163e01805208b08ddafd9301e6ad0d4c603e51"
integrity sha512-iy42jngdr8c+9iymJ+TCRmotYjcRAHz+4V1OXhuDt4vy49dYjsCpeYOi27m6UOWrSkwNLqPkn2q0OXXYVhutUg==
"@photo-sphere-viewer/core@^5.11.1":
version "5.11.1"
resolved "https://registry.yarnpkg.com/@photo-sphere-viewer/core/-/core-5.11.1.tgz#e0aaf83812dd78a5fd63a1d99a7032feec8497e4"
integrity sha512-bxWnoQGYjXfmHGee4OSkoYLZmdgqvJWMn7wmpK0V0Vf46Fqu+TJ4Yt8+dY2PgpM89HoKzNr15Dzt6jqOfjkFxQ==
dependencies:
three "^0.169.0"
bulma@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/bulma/-/bulma-1.0.1.tgz#e37261d6f8e1a3494c9378803d9958effb2715ce"
integrity sha512-+xv/BIAEQakHkR0QVz+s+RjNqfC53Mx9ZYexyaFNFo9wx5i76HXArNdwW7bccyJxa5mgV/T5DcVGqsAB19nBJQ==
fontawesome-free@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/fontawesome-free/-/fontawesome-free-1.0.4.tgz#c7c499708dabd59eb5dedf232b590a862e05957b"
integrity sha512-7sX6Lbg2oQiClFFFFitJlKg20h3YTBON6rdmq3uGjNwDo8G6EjF2bfj2OjjcCUmf4OvZCgyHaXfW2JseqissLw==
leaflet.markercluster@^1.5.3:
version "1.5.3"
resolved "https://registry.yarnpkg.com/leaflet.markercluster/-/leaflet.markercluster-1.5.3.tgz#9cdb52a4eab92671832e1ef9899669e80efc4056"
integrity sha512-vPTw/Bndq7eQHjLBVlWpnGeLa3t+3zGiuM7fJwCkiMFq+nmRuG3RI3f7f4N4TDX7T4NpbAXpR2+NTRSEGfCSeA==
leaflet@^1.9.4:
version "1.9.4"
resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.9.4.tgz#23fae724e282fa25745aff82ca4d394748db7d8d"
integrity sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==
mgrs@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/mgrs/-/mgrs-1.0.0.tgz#fb91588e78c90025672395cb40b25f7cd6ad1829"
integrity sha512-awNbTOqCxK1DBGjalK3xqWIstBZgN6fxsMSiXLs9/spqWkF2pAhb2rrYCFSsr1/tT7PhcDGjZndG8SWYn0byYA==
proj4@^2.9.4:
version "2.19.4"
resolved "https://registry.yarnpkg.com/proj4/-/proj4-2.19.4.tgz#38cf347309f523309ead94d565788de94f07098f"
integrity sha512-1l6JiJ2ZOzXIoo6k64diOQVOvHIF0IACMrHTaFHrEQmuo1tY1vb73mrWfTSyPH+muc0Lut4zuj5encvB1Ccuhg==
dependencies:
mgrs "1.0.0"
wkt-parser "^1.5.1"
spotlight.js@^0.7.8:
version "0.7.8"
resolved "https://registry.yarnpkg.com/spotlight.js/-/spotlight.js-0.7.8.tgz#0620371701508222d736e0658e8db3fbe9ddc53b"
integrity sha512-zq822gqhjaMHt31oZi4do211NwqBcxZ4u7Xtb+OEsbLrz37dcELhBCoQXFu/0sTiomqD6tm5g6tmqvE7S6h4ng==
three@^0.169.0:
version "0.169.0"
resolved "https://registry.yarnpkg.com/three/-/three-0.169.0.tgz#4a62114988ad9728d73526d1f1de6760c56b4adc"
integrity sha512-Ed906MA3dR4TS5riErd4QBsRGPcx+HBDX2O5yYE5GqJeFQTPU+M56Va/f/Oph9X7uZo3W3o4l2ZhBZ6f6qUv0w==
wkt-parser@^1.5.1:
version "1.5.2"
resolved "https://registry.yarnpkg.com/wkt-parser/-/wkt-parser-1.5.2.tgz#a8eaf86ac2cc1d0a2e6a8082a930f5c7ebdb5771"
integrity sha512-1ZUiV1FTwSiSrgWzV9KXJuOF2BVW91KY/mau04BhnmgOdroRQea7Q0s5TVqwGLm0D2tZwObd/tBYXW49sSxp3Q==
+2173
View File
File diff suppressed because it is too large Load Diff