// public/js/map/photos/photoSource.js // =================================== // PHOTO SOURCE // =================================== (() => { "use strict"; const SOURCE_ID = "photos"; const CLUSTER_RADIUS = 80; // =============================== // CREATE / UPDATE SOURCE // =============================== function createPhotoSource(map, features = []) { if (!map) { return null; } if (!map.isStyleLoaded()) { return null; } const existingSource = map.getSource(SOURCE_ID); if (existingSource) { updatePhotoSource(map, features); return existingSource; } const data = { type: "FeatureCollection", features, }; map.addSource(SOURCE_ID, { type: "geojson", data, cluster: true, clusterRadius: CLUSTER_RADIUS, }); return map.getSource(SOURCE_ID); } function updatePhotoSource(map, features = []) { if (!map) { return null; } if (!map.isStyleLoaded()) { return null; } const data = { type: "FeatureCollection", features, }; const source = map.getSource(SOURCE_ID); if (source) { source.setData(data); return source; } return createPhotoSource(map, features); } // =============================== // GET SOURCE // =============================== function getPhotoSource(map) { if (!map) { return null; } return map.getSource(SOURCE_ID) || null; } // =============================== // SOURCE FEATURES // =============================== function getPhotoSourceClusters(map) { if (!map) { return []; } if (!map.getSource(SOURCE_ID)) { return []; } return map.querySourceFeatures(SOURCE_ID, { filter: ["has", "point_count"], }); } function getPhotoSourcePoints(map) { if (!map) { return []; } if (!map.getSource(SOURCE_ID)) { return []; } return map.querySourceFeatures(SOURCE_ID, { filter: ["!", ["has", "point_count"]], }); } // =============================== // PUBLIC API // =============================== window.PhotoSource = { create: createPhotoSource, update: updatePhotoSource, get: getPhotoSource, getClusters: getPhotoSourceClusters, getPoints: getPhotoSourcePoints, }; })();