Add cartography menu with image overlays (WIP)
This commit is contained in:
@@ -1,8 +1,37 @@
|
||||
import { Controller } from "@hotwired/stimulus";
|
||||
import { GisState } from "../state.js";
|
||||
import GIS from "../gis.js";
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ['sites', 'findings', 'notconserved', 'prehist',];
|
||||
static targets = [
|
||||
'sites',
|
||||
'findings',
|
||||
'notconserved',
|
||||
'prehist',
|
||||
];
|
||||
|
||||
static values = {
|
||||
'id': Number,
|
||||
'type': String,
|
||||
};
|
||||
|
||||
async toggleCartography() {
|
||||
const map = GisState.map;
|
||||
const id = this.idValue;
|
||||
|
||||
let currentLayer = await GIS.getImageOverlay(id);
|
||||
let hasLayer = false;
|
||||
|
||||
map.eachLayer(function (layer) {
|
||||
if (layer.options.label === currentLayer.options.label) {
|
||||
hasLayer |= true;
|
||||
currentLayer = layer;
|
||||
}
|
||||
});
|
||||
|
||||
if (!hasLayer) currentLayer.addTo(map);
|
||||
else map.removeLayer(currentLayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Use Stimulus values?
|
||||
|
||||
@@ -2,7 +2,17 @@ import { Controller } from "@hotwired/stimulus"
|
||||
import { GisState } from '../state.js';
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ['list', 'menu', 'icon'];
|
||||
static targets = [
|
||||
'list',
|
||||
'menu',
|
||||
'cartography',
|
||||
'icon'
|
||||
];
|
||||
|
||||
static values = {
|
||||
'cartography' : String,
|
||||
'main' : String,
|
||||
};
|
||||
|
||||
buildMenu() {
|
||||
const groups = Object.keys(GisState.markers);
|
||||
@@ -17,7 +27,6 @@ export default class extends Controller {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {String} group
|
||||
@@ -47,8 +56,50 @@ export default class extends Controller {
|
||||
return ul;
|
||||
}
|
||||
|
||||
toggleMenu() {
|
||||
this.menuTarget.classList.toggle('is-hidden');
|
||||
buildCartographyMenu() {
|
||||
const historicCadastre = GisState.cartography.historic;
|
||||
const template = document.getElementById('cartography-item-template');
|
||||
const ul = document.createElement('ul');
|
||||
ul.className = 'menu-list';
|
||||
ul.id = 'historic-sub';
|
||||
|
||||
const aside = document.querySelector('[data-id="cartography-aside"]');
|
||||
|
||||
for (let geoImage of historicCadastre) {
|
||||
const clone = template.content.cloneNode(true);
|
||||
const label = clone.querySelector('label');
|
||||
const checkbox = clone.querySelector('input[type="checkbox"]');
|
||||
|
||||
checkbox.dataset.layerIdValue = geoImage.id;
|
||||
checkbox.dataset.layerTypeValue = 'historic';
|
||||
const span = document.createElement('span');
|
||||
span.className = 'pl-3';
|
||||
span.textContent = geoImage.label;
|
||||
label.appendChild(span);
|
||||
|
||||
ul.appendChild(clone);
|
||||
}
|
||||
|
||||
aside.appendChild(ul);
|
||||
}
|
||||
|
||||
toggleMenu(event) {
|
||||
const menuId = event.target.dataset.id;
|
||||
|
||||
// Stupid...
|
||||
if (menuId === 'main') {
|
||||
this.menuTarget.classList.toggle('is-hidden');
|
||||
if (!this.cartographyTarget.classList.contains('is-hidden')) {
|
||||
this.cartographyTarget.classList.add('is-hidden');
|
||||
}
|
||||
}
|
||||
|
||||
if (menuId === 'cartography') {
|
||||
this.cartographyTarget.classList.toggle('is-hidden');
|
||||
if (!this.menuTarget.classList.contains('is-hidden')) {
|
||||
this.menuTarget.classList.add('is-hidden');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
|
||||
@@ -113,13 +113,12 @@ GIS.initMap = async function (mapId, zoomLevel = this.INIT_ZOOM) {
|
||||
let layerPaesistici = await this.loadGeoJSON('paesistici.geojson', optionsPaesistici);
|
||||
|
||||
await this.addLayerGroups(map);
|
||||
|
||||
const historicCadastre = await this.imageOverlays();
|
||||
await this.fetchCartographyLayers();
|
||||
|
||||
const archeo = {
|
||||
'Vincoli archeologici' : layerVincoli,
|
||||
'Vincoli paesistici' : layerPaesistici,
|
||||
'Catasto storico' : historicCadastre,
|
||||
//'Catasto storico' : historicCadastre,
|
||||
};
|
||||
L.control.layers(baseMap, archeo).addTo(map);
|
||||
|
||||
@@ -128,35 +127,45 @@ GIS.initMap = async function (mapId, zoomLevel = this.INIT_ZOOM) {
|
||||
return map;
|
||||
}
|
||||
/**
|
||||
* Load georeferenced image overlays layer group
|
||||
* Fetches references to cartography layers
|
||||
* and updates GisState
|
||||
*/
|
||||
GIS.imageOverlays = async function () {
|
||||
const data = await this._fetchData('geoimage')
|
||||
GIS.fetchCartographyLayers = async function () {
|
||||
const data = await this._fetchData('geoimages/menu')
|
||||
.catch(error => console.error(`Could not fetch data for geo images: ${error}`));
|
||||
|
||||
const overlays = L.layerGroup();
|
||||
|
||||
for (let image of data) {
|
||||
let polygonCoords = JSON.parse(image.polygon).coordinates[0];
|
||||
// Image rectangle bounds are SE and NW coordinates from the PostGIS polygon
|
||||
// with long/lat swapped...
|
||||
const se = [polygonCoords[0][1], polygonCoords[0][0]];
|
||||
const nw = [polygonCoords[2][1], polygonCoords[2][0]];
|
||||
const bounds = [se, nw];
|
||||
|
||||
const imageOverlay = L.imageOverlay(
|
||||
`/webgis/img/geo/${image.filename}`,
|
||||
bounds,
|
||||
{
|
||||
opacity: 0.8,
|
||||
alt: `Immagine georeferita dal catasto storico di Capri`
|
||||
}
|
||||
);
|
||||
|
||||
overlays.addLayer(imageOverlay);
|
||||
for (let item of data) {
|
||||
let {id, label} = item;
|
||||
GisState.cartography.historic.push({id, label});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Load georeferenced image overlays layer group
|
||||
* @param {Number} imageId - The API id of the georeferenced image
|
||||
* @returns {L.ImageOverlay}
|
||||
*/
|
||||
GIS.getImageOverlay = async function (imageId) {
|
||||
const imageData = await this._fetchData(`geoimages/${imageId}`)
|
||||
.catch(error => console.error(`Could not fetch data for geo image ${imageId}: ${error}`));
|
||||
|
||||
return overlays;
|
||||
let polygonCoords = JSON.parse(imageData.polygon).coordinates[0];
|
||||
// Image rectangle bounds are SE and NW coordinates from the PostGIS polygon
|
||||
// with long/lat swapped...
|
||||
const se = [polygonCoords[0][1], polygonCoords[0][0]];
|
||||
const nw = [polygonCoords[2][1], polygonCoords[2][0]];
|
||||
const bounds = [se, nw];
|
||||
|
||||
const imageOverlay = L.imageOverlay(
|
||||
`/webgis/img/geo/${imageData.filename}`,
|
||||
bounds,
|
||||
{
|
||||
opacity: 0.8,
|
||||
alt: `Immagine georeferita (${imageData.label})`,
|
||||
label: `geoimage:${imageData.id}:${imageData.label}`,
|
||||
}
|
||||
);
|
||||
|
||||
return imageOverlay;
|
||||
}
|
||||
/**
|
||||
* Add layer groups to map
|
||||
|
||||
@@ -11,10 +11,11 @@
|
||||
/**
|
||||
* @typedef {Object} GisStateType
|
||||
* @property {L.Map|null} map
|
||||
* @property {String|null} apiUrl
|
||||
* @property {MarkerLookup} markers
|
||||
* @property {LayerGroupLookup} layers
|
||||
* @property {Object|null} bibliography
|
||||
* @property {String|null} apiUrl
|
||||
* @property {Object} cartography
|
||||
*/
|
||||
|
||||
/** @type {GisStateType} */
|
||||
@@ -36,6 +37,9 @@ export const GisState = {
|
||||
},
|
||||
bibliography: null,
|
||||
apiUrl : null,
|
||||
cartography : {
|
||||
historic: [],
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -68,31 +68,6 @@ UI.toggleBurger = function(burgerClass) {
|
||||
document.querySelector(`#${menuId}`).classList.toggle('is-active');
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Toggle side menu
|
||||
* @param {string} triggerId The ID of the trigger element
|
||||
* @param {?string} listId The ID of the menu list to open (if any)
|
||||
*/
|
||||
UI.toggleMenu = function (triggerId, listId = null) {
|
||||
const trigger = document.querySelector(`#${triggerId}`);
|
||||
const menu = document.querySelector('#menu');
|
||||
trigger.addEventListener('click', () => {
|
||||
menu.classList.remove('is-hidden');
|
||||
//menu.classList.add('is-3');
|
||||
const lists = menu.querySelectorAll('ul');
|
||||
|
||||
if (listId !== null) {
|
||||
const list = document.querySelector(`#${listId}`);
|
||||
list.classList.remove('is-hidden');
|
||||
|
||||
for (let ul of lists) {
|
||||
if (ul.id !== listId && !ul.id.includes('sub')) {
|
||||
ul.classList.add('is-hidden');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Open a modal with DB site data
|
||||
* @param {object} data The data retrieved from the DB to display as modal content
|
||||
|
||||
Reference in New Issue
Block a user