// Mappa Calabria — Leaflet.js + CartoDB Voyager tiles // Coordinate: x = 100 + (lon-15.6)*250 → lon = (x-100)/250 + 15.6 // y = 80 + (40.15-lat)*278 → lat = 40.15 - (y-80)/278 const KIND_DEFS = [ { key: "citta", label: "Città", color: "#1c1612" }, { key: "costa", label: "Costa", color: "#1a5c7a" }, { key: "parco", label: "Parchi", color: "#2d6a4f" }, { key: "archeologia", label: "Archeologia", color: "#9b5c1a" }, { key: "borgo", label: "Borghi", color: "#7a2e2e" }, { key: "spiaggia", label: "Spiagge", color: "#0077a8" }, { key: "alture", label: "Alture", color: "#4a6741" }, ]; function getKindColor(kind) { return (KIND_DEFS.find(k => k.key === kind) || {}).color || "#6b5f4e"; } function ptToLatLng(pt) { return [ 40.15 - (pt.y - 80) / 278, (pt.x - 100) / 250 + 15.6, ]; } function CalabriaMap() { const [activeKind, setActiveKind] = useState("ALL"); const [hoveredPt, setHoveredPt] = useState(null); const mobile = useMobile(); const mapDivRef = useRef(null); const mapRef = useRef(null); const markersRef = useRef({}); // ── Inizializza Leaflet una sola volta ── useEffect(() => { if (mapRef.current) return; const map = L.map(mapDivRef.current, { center: [38.85, 16.55], zoom: 8, scrollWheelZoom: false, zoomControl: false, attributionControl: true, }); L.control.zoom({ position: "bottomright" }).addTo(map); // CartoDB Voyager — palette calda, ottimo su desktop e mobile L.tileLayer( "https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png", { attribution: '© OpenStreetMap © CARTO', subdomains: "abcd", maxZoom: 17, } ).addTo(map); // ── Marker per ogni luogo ── MAP_POINTS.forEach(pt => { const latlng = ptToLatLng(pt); const color = getKindColor(pt.kind); const isCitta = pt.kind === "citta"; const r = isCitta ? 9 : 7; const circle = L.circleMarker(latlng, { radius: r, fillColor: color, color: "#fff", weight: 2, opacity: 1, fillOpacity: 0.9, }).addTo(map); // Tooltip — permanente per le città, al hover per gli altri circle.bindTooltip(pt.name, { permanent: isCitta, direction: "right", offset: [10, 0], className: "cal-tip", opacity: 1, }); circle.on("mouseover", function () { setHoveredPt(pt); this.setRadius(isCitta ? 13 : 11); if (!isCitta) this.openTooltip(); }); circle.on("mouseout", function () { setHoveredPt(null); this.setRadius(r); if (!isCitta) this.closeTooltip(); }); markersRef.current[pt.id] = { circle, isCitta, r }; }); mapRef.current = map; }, []); // ── Aggiorna opacità marker al cambio filtro ── useEffect(() => { if (!mapRef.current) return; Object.entries(markersRef.current).forEach(([id, { circle }]) => { const pt = MAP_POINTS.find(p => p.id === id); const visible = activeKind === "ALL" || pt?.kind === activeKind; circle.setStyle({ fillOpacity: visible ? 0.9 : 0.06, opacity: visible ? 1 : 0.06, }); }); }, [activeKind]); const toggleKind = (key) => setActiveKind(prev => prev === key ? "ALL" : key); const visibleCount = activeKind === "ALL" ? MAP_POINTS.length : MAP_POINTS.filter(p => p.kind === activeKind).length; return (
{/* ── Pannello sinistro ── */}
{hoveredPt ? ( <> {(KIND_DEFS.find(k => k.key === hoveredPt.kind) || {}).label || hoveredPt.kind}

{hoveredPt.name}

Provincia di {(PROVINCES.find(p => p.code === hoveredPt.province) || {}).name}
Scopri {hoveredPt.name} ) : ( <> Esplora {visibleCount} luoghi

Passa sopra un punto della mappa.

Filtra per tipologia o passa il cursore su un marker per scoprire il luogo.

)} {/* ── Filtri tipologia ── */}
{KIND_DEFS.map(kind => { const isActive = activeKind === kind.key; return ( ); })}
{/* ── Contenitore mappa Leaflet ── */}
); } window.CalabriaMap = CalabriaMap;