776 lines
14 KiB
Text
776 lines
14 KiB
Text
// public/js/map/mapboxMarkers.js
|
|
// ===================================
|
|
// MAPBOX MARKERS CONTROLLER
|
|
// ===================================
|
|
|
|
(() => {
|
|
"use strict";
|
|
|
|
let mapboxMap = null;
|
|
|
|
// ===================================
|
|
// STATO
|
|
// ===================================
|
|
|
|
const state = {
|
|
photos: [],
|
|
activities: [],
|
|
routes: [],
|
|
};
|
|
|
|
let mapEventsInitialized = false;
|
|
let mapEventsMap = null;
|
|
|
|
// ===================================
|
|
// MAPPA
|
|
// ===================================
|
|
|
|
function setMap(map) {
|
|
if (!map) {
|
|
console.error(
|
|
"[MapboxMarkers] mappa non valida",
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
// ---------------------------------
|
|
// STESSA MAPPA
|
|
// ---------------------------------
|
|
|
|
if (mapboxMap === map) {
|
|
console.log(
|
|
"[MapboxMarkers] stessa mappa già collegata",
|
|
);
|
|
|
|
initializeModules();
|
|
refreshAll();
|
|
|
|
return;
|
|
}
|
|
|
|
// ---------------------------------
|
|
// NUOVA MAPPA
|
|
// ---------------------------------
|
|
|
|
mapboxMap = map;
|
|
|
|
console.log(
|
|
"[MapboxMarkers] mappa collegata",
|
|
);
|
|
|
|
// =================================
|
|
// PHOTOS
|
|
// =================================
|
|
|
|
if (window.PhotoSource) {
|
|
console.log(
|
|
"[MapboxMarkers] PhotoSource collegato",
|
|
);
|
|
}
|
|
|
|
if (window.MapboxPhotoClusters) {
|
|
window.MapboxPhotoClusters.setMap(
|
|
mapboxMap,
|
|
);
|
|
}
|
|
|
|
if (window.MapboxPhotoMarkers) {
|
|
window.MapboxPhotoMarkers.setMap(
|
|
mapboxMap,
|
|
);
|
|
}
|
|
|
|
if (window.MapboxPhotoSpiderfy) {
|
|
window.MapboxPhotoSpiderfy.setMap(
|
|
mapboxMap,
|
|
);
|
|
}
|
|
|
|
// =================================
|
|
// ACTIVITIES
|
|
// =================================
|
|
|
|
if (window.ActivitySource) {
|
|
console.log(
|
|
"[MapboxMarkers] ActivitySource collegato",
|
|
);
|
|
}
|
|
|
|
if (window.MapboxActivityClusters) {
|
|
window.MapboxActivityClusters.setMap(
|
|
mapboxMap,
|
|
);
|
|
}
|
|
|
|
if (window.MapboxActivityMarkers) {
|
|
window.MapboxActivityMarkers.setMap(
|
|
mapboxMap,
|
|
);
|
|
}
|
|
|
|
// =================================
|
|
// EVENTI
|
|
// =================================
|
|
|
|
setupMapEvents();
|
|
|
|
// =================================
|
|
// INIZIALIZZAZIONE
|
|
// =================================
|
|
|
|
initializeModules();
|
|
|
|
// =================================
|
|
// RIPRISTINO DATI
|
|
// =================================
|
|
|
|
refreshAll();
|
|
}
|
|
|
|
// ===================================
|
|
// INIZIALIZZAZIONE MODULI
|
|
// ===================================
|
|
|
|
function initializeModules() {
|
|
if (!mapboxMap) {
|
|
return;
|
|
}
|
|
|
|
if (!mapboxMap.isStyleLoaded()) {
|
|
return;
|
|
}
|
|
|
|
// =================================
|
|
// PHOTOS SOURCE
|
|
// =================================
|
|
|
|
if (window.PhotoSource) {
|
|
window.PhotoSource.update(
|
|
mapboxMap,
|
|
state.photos,
|
|
);
|
|
}
|
|
|
|
// =================================
|
|
// PHOTOS CLUSTER
|
|
// =================================
|
|
|
|
if (window.MapboxPhotoClusters) {
|
|
window.MapboxPhotoClusters.createLayer();
|
|
}
|
|
|
|
// =================================
|
|
// ACTIVITIES SOURCE
|
|
// =================================
|
|
|
|
if (window.ActivitySource) {
|
|
window.ActivitySource.update(
|
|
mapboxMap,
|
|
state.activities,
|
|
);
|
|
}
|
|
|
|
// =================================
|
|
// ACTIVITIES CLUSTER
|
|
// =================================
|
|
|
|
if (window.MapboxActivityClusters) {
|
|
window.MapboxActivityClusters.createLayer();
|
|
}
|
|
}
|
|
|
|
// ===================================
|
|
// EVENTI MAPPA
|
|
// ===================================
|
|
|
|
function setupMapEvents() {
|
|
if (!mapboxMap) {
|
|
return;
|
|
}
|
|
|
|
if (mapEventsInitialized) {
|
|
return;
|
|
}
|
|
|
|
mapEventsInitialized = true;
|
|
|
|
// =================================
|
|
// HELPER REFRESH MAPBOX MARKERS
|
|
// =================================
|
|
|
|
function refreshMapboxMarkers(reason) {
|
|
if (!mapboxMap) {
|
|
return;
|
|
}
|
|
|
|
if (!mapboxMap.isStyleLoaded()) {
|
|
return;
|
|
}
|
|
|
|
console.log(
|
|
`[MapboxMarkers] refreshMapboxMarkers → ${reason}`,
|
|
);
|
|
|
|
// ---------------------------------
|
|
// PHOTO CLUSTERS
|
|
// ---------------------------------
|
|
|
|
if (window.MapboxPhotoClusters) {
|
|
window.MapboxPhotoClusters.createLayer();
|
|
window.MapboxPhotoClusters.update();
|
|
}
|
|
|
|
// ---------------------------------
|
|
// PHOTO MARKERS
|
|
// ---------------------------------
|
|
|
|
if (window.MapboxPhotoMarkers) {
|
|
window.MapboxPhotoMarkers.update(
|
|
state.photos,
|
|
);
|
|
}
|
|
|
|
// ---------------------------------
|
|
// ACTIVITY CLUSTERS
|
|
// ---------------------------------
|
|
|
|
if (window.MapboxActivityClusters) {
|
|
window.MapboxActivityClusters.createLayer();
|
|
window.MapboxActivityClusters.update();
|
|
}
|
|
|
|
// ---------------------------------
|
|
// ACTIVITY MARKERS
|
|
// ---------------------------------
|
|
|
|
if (window.MapboxActivityMarkers) {
|
|
window.MapboxActivityMarkers.update(
|
|
state.activities,
|
|
);
|
|
}
|
|
}
|
|
|
|
// =================================
|
|
// STYLE LOAD
|
|
// =================================
|
|
|
|
mapboxMap.on(
|
|
"styledata",
|
|
() => {
|
|
if (!mapboxMap) {
|
|
return;
|
|
}
|
|
|
|
console.log(
|
|
"[MapboxMarkers] styledata",
|
|
);
|
|
|
|
initializeModules();
|
|
|
|
/*
|
|
* Non tentiamo di interrogare subito
|
|
* i layer appena creati.
|
|
*
|
|
* Aspettiamo che Mapbox abbia completato
|
|
* il rendering.
|
|
*/
|
|
|
|
mapboxMap.once(
|
|
"idle",
|
|
() => {
|
|
refreshMapboxMarkers(
|
|
"styledata → idle",
|
|
);
|
|
},
|
|
);
|
|
},
|
|
);
|
|
|
|
// =================================
|
|
// MOVE END
|
|
// =================================
|
|
|
|
mapboxMap.on(
|
|
"moveend",
|
|
() => {
|
|
console.log(
|
|
"[MapboxMarkers] moveend",
|
|
);
|
|
},
|
|
);
|
|
|
|
// =================================
|
|
// IDLE
|
|
// =================================
|
|
|
|
mapboxMap.on(
|
|
"idle",
|
|
() => {
|
|
if (!mapboxMap) {
|
|
return;
|
|
}
|
|
|
|
refreshMapboxMarkers(
|
|
"idle",
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
// ===================================
|
|
// REFRESH PHOTOS
|
|
// ===================================
|
|
|
|
function refreshPhotos() {
|
|
if (!mapboxMap) {
|
|
return;
|
|
}
|
|
|
|
// ---------------------------------
|
|
// Durante spiderfy non tocchiamo
|
|
// cluster e marker normali.
|
|
// ---------------------------------
|
|
|
|
if (
|
|
window.MapboxPhotoSpiderfy?.isOpen?.()
|
|
) {
|
|
return;
|
|
}
|
|
|
|
// =================================
|
|
// CLUSTER
|
|
// =================================
|
|
|
|
if (window.MapboxPhotoClusters) {
|
|
window.MapboxPhotoClusters.update();
|
|
}
|
|
|
|
// =================================
|
|
// MARKER
|
|
// =================================
|
|
|
|
if (window.MapboxPhotoMarkers) {
|
|
window.MapboxPhotoMarkers.update(
|
|
state.photos,
|
|
);
|
|
}
|
|
}
|
|
|
|
// ===================================
|
|
// REFRESH ACTIVITIES
|
|
// ===================================
|
|
|
|
function refreshActivities() {
|
|
if (!mapboxMap) {
|
|
return;
|
|
}
|
|
|
|
// =================================
|
|
// CLUSTER
|
|
// =================================
|
|
|
|
if (window.MapboxActivityClusters) {
|
|
window.MapboxActivityClusters.update();
|
|
}
|
|
|
|
// =================================
|
|
// MARKER
|
|
// =================================
|
|
|
|
if (window.MapboxActivityMarkers) {
|
|
window.MapboxActivityMarkers.update(
|
|
state.activities,
|
|
);
|
|
}
|
|
}
|
|
|
|
// ===================================
|
|
// REFRESH ROUTES
|
|
// ===================================
|
|
|
|
function refreshRoutes() {
|
|
/*
|
|
* Le routes vengono gestite
|
|
* direttamente da setRoutes().
|
|
*
|
|
* Non sono clusterizzate e non
|
|
* richiedono un modulo dedicato.
|
|
*/
|
|
}
|
|
|
|
// ===================================
|
|
// REFRESH COMPLETO
|
|
// ===================================
|
|
|
|
function refreshAll() {
|
|
if (!mapboxMap) {
|
|
return;
|
|
}
|
|
|
|
if (!mapboxMap.isStyleLoaded()) {
|
|
return;
|
|
}
|
|
|
|
initializeModules();
|
|
|
|
refreshPhotos();
|
|
|
|
refreshActivities();
|
|
|
|
refreshRoutes();
|
|
}
|
|
|
|
// ===================================
|
|
// PHOTOS
|
|
// ===================================
|
|
|
|
function setPhotos(features = []) {
|
|
state.photos.length = 0;
|
|
|
|
state.photos.push(...features);
|
|
|
|
console.log(
|
|
"[MapboxMarkers] photos:",
|
|
state.photos.length,
|
|
);
|
|
|
|
if (!mapboxMap) {
|
|
return;
|
|
}
|
|
|
|
if (!mapboxMap.isStyleLoaded()) {
|
|
return;
|
|
}
|
|
|
|
// =================================
|
|
// SOURCE
|
|
// =================================
|
|
|
|
if (window.PhotoSource) {
|
|
window.PhotoSource.update(
|
|
mapboxMap,
|
|
state.photos,
|
|
);
|
|
} else {
|
|
console.warn(
|
|
"[MapboxMarkers] PhotoSource non disponibile",
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
// =================================
|
|
// CLUSTER LAYER
|
|
// =================================
|
|
/*
|
|
if (window.MapboxPhotoClusters) {
|
|
window.MapboxPhotoClusters.createLayer();
|
|
}
|
|
*/
|
|
/*
|
|
// =================================
|
|
// ATTESA IDLE
|
|
// =================================
|
|
|
|
mapboxMap.once(
|
|
"idle",
|
|
() => {
|
|
if (!mapboxMap) {
|
|
return;
|
|
}
|
|
|
|
console.log(
|
|
"[MapboxMarkers] setPhotos → idle → refreshPhotos",
|
|
);
|
|
|
|
refreshPhotos();
|
|
|
|
// Sicurezza: garantisce che il layer cluster
|
|
// esista e che venga interrogato dopo il rendering.
|
|
if (window.MapboxPhotoClusters) {
|
|
window.MapboxPhotoClusters.createLayer();
|
|
window.MapboxPhotoClusters.update();
|
|
}
|
|
},
|
|
);*/
|
|
}
|
|
|
|
// ===================================
|
|
// ACTIVITIES
|
|
// ===================================
|
|
|
|
function setActivities(features = []) {
|
|
state.activities.length = 0;
|
|
|
|
state.activities.push(...features);
|
|
|
|
console.log(
|
|
"[MapboxMarkers] activities:",
|
|
state.activities.length,
|
|
);
|
|
|
|
if (!mapboxMap) {
|
|
return;
|
|
}
|
|
|
|
if (!mapboxMap.isStyleLoaded()) {
|
|
return;
|
|
}
|
|
|
|
// =================================
|
|
// SOURCE
|
|
// =================================
|
|
|
|
if (window.ActivitySource) {
|
|
window.ActivitySource.update(
|
|
mapboxMap,
|
|
state.activities,
|
|
);
|
|
} else {
|
|
console.warn(
|
|
"[MapboxMarkers] ActivitySource non disponibile",
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
// =================================
|
|
// CLUSTER LAYER
|
|
// =================================
|
|
|
|
if (window.MapboxActivityClusters) {
|
|
window.MapboxActivityClusters.createLayer();
|
|
}
|
|
|
|
// =================================
|
|
// ATTESA IDLE
|
|
// =================================
|
|
|
|
mapboxMap.once(
|
|
"idle",
|
|
() => {
|
|
if (!mapboxMap) {
|
|
return;
|
|
}
|
|
|
|
refreshActivities();
|
|
},
|
|
);
|
|
}
|
|
|
|
// ===================================
|
|
// ROUTES
|
|
// ===================================
|
|
|
|
function setRoutes(features = []) {
|
|
state.routes.length = 0;
|
|
|
|
state.routes.push(...features);
|
|
|
|
console.log(
|
|
"[MapboxMarkers] routes:",
|
|
state.routes.length,
|
|
);
|
|
|
|
if (!mapboxMap) {
|
|
return;
|
|
}
|
|
|
|
if (!mapboxMap.isStyleLoaded()) {
|
|
return;
|
|
}
|
|
|
|
const data = {
|
|
type: "FeatureCollection",
|
|
features: state.routes,
|
|
};
|
|
|
|
const source =
|
|
mapboxMap.getSource("routes");
|
|
|
|
// =================================
|
|
// SOURCE ESISTENTE
|
|
// =================================
|
|
|
|
if (source) {
|
|
source.setData(data);
|
|
} else {
|
|
// ===============================
|
|
// CREA SOURCE
|
|
// ===============================
|
|
|
|
mapboxMap.addSource("routes", {
|
|
type: "geojson",
|
|
data,
|
|
});
|
|
}
|
|
|
|
// =================================
|
|
// LAYER
|
|
// =================================
|
|
|
|
if (
|
|
!mapboxMap.getLayer(
|
|
"routes-line",
|
|
)
|
|
) {
|
|
mapboxMap.addLayer({
|
|
id: "routes-line",
|
|
|
|
type: "line",
|
|
|
|
source: "routes",
|
|
|
|
paint: {
|
|
"line-color": "#ff6b00",
|
|
|
|
"line-width": 4,
|
|
|
|
"line-opacity": 0.8,
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
// ===================================
|
|
// GET PHOTOS
|
|
// ===================================
|
|
|
|
function getPhotos() {
|
|
return state.photos;
|
|
}
|
|
|
|
// ===================================
|
|
// GET ACTIVITIES
|
|
// ===================================
|
|
|
|
function getActivities() {
|
|
return state.activities;
|
|
}
|
|
|
|
// ===================================
|
|
// GET ROUTES
|
|
// ===================================
|
|
|
|
function getRoutes() {
|
|
return state.routes;
|
|
}
|
|
|
|
// ===================================
|
|
// GET MAP
|
|
// ===================================
|
|
|
|
function getMap() {
|
|
return mapboxMap;
|
|
}
|
|
|
|
// ===================================
|
|
// DEBUG
|
|
// ===================================
|
|
|
|
function debug() {
|
|
console.log(
|
|
"[MapboxMarkers DEBUG]",
|
|
{
|
|
map: !!mapboxMap,
|
|
|
|
photos: state.photos.length,
|
|
|
|
activities:
|
|
state.activities.length,
|
|
|
|
routes:
|
|
state.routes.length,
|
|
|
|
photoSource:
|
|
!!mapboxMap?.getSource(
|
|
"photos",
|
|
),
|
|
|
|
photoClusters:
|
|
!!mapboxMap?.getLayer(
|
|
"photos-clusters",
|
|
),
|
|
|
|
photoMarkers:
|
|
window
|
|
.MapboxPhotoMarkers
|
|
?.size?.() ?? 0,
|
|
|
|
photoClusterMarkers:
|
|
window
|
|
.MapboxPhotoClusters
|
|
?.size?.() ?? 0,
|
|
|
|
spiderfy:
|
|
window
|
|
.MapboxPhotoSpiderfy
|
|
?.isOpen?.() ?? false,
|
|
|
|
spiderMarkers:
|
|
window
|
|
.MapboxPhotoSpiderfy
|
|
?.size?.() ?? 0,
|
|
|
|
activitySource:
|
|
!!mapboxMap?.getSource(
|
|
"activities",
|
|
),
|
|
|
|
activityClusters:
|
|
!!mapboxMap?.getLayer(
|
|
"activities-clusters",
|
|
),
|
|
|
|
activityMarkers:
|
|
window
|
|
.MapboxActivityMarkers
|
|
?.size?.() ?? 0,
|
|
|
|
activityClusterMarkers:
|
|
window
|
|
.MapboxActivityClusters
|
|
?.size?.() ?? 0,
|
|
|
|
routesSource:
|
|
!!mapboxMap?.getSource(
|
|
"routes",
|
|
),
|
|
|
|
routesLayer:
|
|
!!mapboxMap?.getLayer(
|
|
"routes-line",
|
|
),
|
|
},
|
|
);
|
|
}
|
|
|
|
// ===================================
|
|
// API PUBBLICA
|
|
// ===================================
|
|
|
|
window.debugMapboxMarkers = debug;
|
|
|
|
window.MapboxMarkers = {
|
|
setMap,
|
|
|
|
setPhotos,
|
|
|
|
setActivities,
|
|
|
|
setRoutes,
|
|
|
|
getPhotos,
|
|
|
|
getActivities,
|
|
|
|
getRoutes,
|
|
|
|
getMap,
|
|
|
|
refreshAll,
|
|
|
|
debug,
|
|
};
|
|
})();
|