photo_server_json_con_aves22/public/js/mapGlobal.js
2026-04-18 20:14:42 +02:00

204 lines
No EOL
5.5 KiB
JavaScript

// ===============================
// MAPPA GLOBALE — stile Google Photos Web
// ===============================
window.globalMap = null;
window.globalMarkers = null;
document.addEventListener("DOMContentLoaded", () => {
const openBtn = document.getElementById("openMapBtn");
if (!openBtn) return;
openBtn.addEventListener("click", openGlobalMap);
const RADIUS_PX = 50;
const DISABLE_CLUSTER_AT_ZOOM = 18;
const OPEN_STRIP_CHILDREN_MAX = 20;
// ===============================
// APRI / CHIUDI MAPPA
// ===============================
async function openGlobalMap() {
const mapDiv = document.getElementById("globalMap");
const gallery = document.getElementById("gallery");
if (!mapDiv) return;
const isOpen = mapDiv.classList.contains("open");
if (isOpen) {
mapDiv.classList.remove("open");
gallery?.classList.remove("hidden");
window.closeBottomSheet?.();
return;
}
mapDiv.classList.add("open");
gallery?.classList.add("hidden");
await new Promise(r => requestAnimationFrame(r));
if (!window.globalMap) initMap();
else window.globalMap.invalidateSize();
redrawPhotoMarkers();
}
// ===============================
// INIZIALIZZA MAPPA
// ===============================
function initMap() {
console.log("Inizializzo mappa Leaflet + MarkerCluster…");
window.globalMap = L.map("globalMap", {
zoomControl: true,
attributionControl: true
}).setView([42.5, 12.5], 6);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19
}).addTo(window.globalMap);
window.globalMarkers = L.markerClusterGroup({
showCoverageOnHover: false,
spiderfyOnMaxZoom: true,
disableClusteringAtZoom: DISABLE_CLUSTER_AT_ZOOM,
iconCreateFunction: clusterIconRenderer
});
window.globalMarkers.on("clusterclick", onClusterClick);
window.globalMap.addLayer(window.globalMarkers);
}
// ===============================
// RENDER CLUSTER
// ===============================
function clusterIconRenderer(cluster) {
const count = cluster.getChildCount();
const size = Math.min(92, Math.round(28 + Math.sqrt(count) * 6));
const cls = count > 200 ? "cluster-xl" :
count > 50 ? "cluster-lg" :
count > 10 ? "cluster-md" : "cluster-sm";
const children = cluster.getAllChildMarkers().slice(0, 4);
const thumbs = children
.map(m => m.__photo?.thub2 || m.__photo?.thub1)
.filter(Boolean)
.map(t => toAbsoluteUrl(t, children[0].__photo.name, "thumbs", children[0].__photo.cartella));
const collage = thumbs.length
? `<div class="cluster-collage">${thumbs.map((t,i)=>`<div class="c${i}"><img src="${t}"></div>`).join("")}</div>`
: "";
return L.divIcon({
html: `
<div class="gp-cluster ${cls}" style="width:${size}px;height:${size}px;">
${collage}
<div class="gp-count"><span>${count}</span></div>
</div>`,
className: "marker-cluster-wrapper",
iconSize: L.point(size, size)
});
}
// ===============================
// CLICK SU CLUSTER
// ===============================
function onClusterClick(a) {
const markers = a.layer.getAllChildMarkers();
const count = markers.length;
if (count <= OPEN_STRIP_CHILDREN_MAX ||
window.globalMap.getZoom() >= DISABLE_CLUSTER_AT_ZOOM - 1) {
const photos = markers.map(m => m.__photo).filter(Boolean);
if (photos.length > 1) window.openBottomSheet?.(photos);
else if (photos.length === 1) openPhotoModal(photos[0]);
} else {
window.globalMap.fitBounds(a.layer.getBounds(), {
padding: [60, 60],
maxZoom: DISABLE_CLUSTER_AT_ZOOM,
animate: true
});
}
}
// ===============================
// ICONA FOTO
// ===============================
function createPhotoIcon(photo) {
const thumb = toAbsoluteUrl(
photo.thub2 || photo.thub1,
photo.name,
"thumbs",
photo.cartella
);
return L.icon({
iconUrl: thumb,
iconSize: [56, 56],
iconAnchor: [28, 28],
className: "photo-marker"
});
}
// ===============================
// APRI MODAL FOTO
// ===============================
function openPhotoModal(photo) {
const thumb = toAbsoluteUrl(
photo.thub2 || photo.thub1 || photo.path,
photo.name,
"thumbs",
photo.cartella
);
const original = toAbsoluteUrl(
photo.path,
photo.name,
"original",
photo.cartella
);
window.closeBottomSheet?.();
window.openModal?.(original, thumb, photo);
}
// ===============================
// REDRAW MARKERS
// ===============================
function redrawPhotoMarkers() {
if (!window.globalMarkers) return;
window.globalMarkers.clearLayers();
const photos = getLocalPhotos();
photos.forEach(photo => {
const lat = +photo?.gps?.lat;
const lng = +photo?.gps?.lng;
if (!lat || !lng) return;
const marker = L.marker([lat, lng], {
icon: createPhotoIcon(photo),
title: photo.name || ""
});
marker.__photo = photo;
marker.on("click", () => openPhotoModal(photo));
window.globalMarkers.addLayer(marker);
});
}
// ===============================
// AGGANCIA REFRESH GALLERY
// ===============================
const originalRefresh = window.refreshGallery;
window.refreshGallery = function (...args) {
originalRefresh?.apply(this, args);
redrawPhotoMarkers();
};
});