141 lines
3.4 KiB
TypeScript
141 lines
3.4 KiB
TypeScript
"use client";
|
|
|
|
import { MapContainer, ImageOverlay, useMap } from "react-leaflet";
|
|
import L from "leaflet";
|
|
import "leaflet/dist/leaflet.css";
|
|
import "leaflet.heat";
|
|
import { useEffect } from "react";
|
|
|
|
// Ajustar vista automáticamente
|
|
function AjustarVista({ bounds }) {
|
|
const map = useMap();
|
|
|
|
useEffect(() => {
|
|
map.fitBounds(bounds);
|
|
}, [map, bounds]);
|
|
|
|
return null;
|
|
}
|
|
|
|
function HeatLayer() {
|
|
const map = useMap();
|
|
|
|
useEffect(() => {
|
|
|
|
// A 4768x3368
|
|
const edificios = {
|
|
A1: [[1400, 3060], [1470, 3060], [1470, 3360], [1400, 3360]],
|
|
A2: [[1570, 3130], [1570, 3190], [1850, 3190], [1850, 3130]],
|
|
A3: [[1640, 2650], [1705, 2650], [1705, 2950], [1640, 2950]],
|
|
A4: [[1268, 2765], [1268, 2830], [1540, 2830], [1540, 2765]],
|
|
A5: [[995, 2405], [1295, 2405], [1295, 2470], [995, 2470]],
|
|
A6: [[1390, 2385], [1450, 2385], [1450, 2655], [1390, 2655]],
|
|
A7: [[1234, 2014], [1296, 2014], [1296, 2317], [1234, 2317]],
|
|
A8: [[1390, 2055], [1700, 2055], [1700, 2118], [1390, 2118]],
|
|
A9: [[1730, 1550], [1980, 1550], [1980, 1640], [1730, 1640]],
|
|
A10: [[1580, 1660], [1580, 1960], [1660, 1960], [1580, 1660]],
|
|
A11: [[1525, 1370], [1825, 1370], [1825, 1440], [1525, 1440]],
|
|
A12: [[1750, 1140], [1750, 1520], [1910, 1520], [1910, 1140]],
|
|
A13: [[1380, 680], [1380, 1020], [1480, 1020], [1480, 680]],
|
|
A14: [[1320, 480], [1680, 480], [1680, 580], [1320, 580]],
|
|
A15: [[2027, 2580], [2087, 2580], [2087, 2900], [2027, 2900]],
|
|
CEDTEC: [[900, 2900], [1100, 2900], [1100, 3200], [900, 3200]],
|
|
BIBLIOTECA: [[1600, 2200], [1900, 2200], [1900, 2500], [1600, 2500]],
|
|
POSGRADO: [[1100, 1525], [860, 1525], [860, 1325], [1100, 1325]]
|
|
|
|
};
|
|
|
|
|
|
const puntos = [];
|
|
|
|
Object.entries(edificios).forEach(([nombre, poligono]) => {
|
|
for (let i = 0; i < 15; i++) {
|
|
|
|
const x = poligono[0][0] + Math.random() * (poligono[1][0] - poligono[0][0]);
|
|
const y = poligono[0][1] + Math.random() * (poligono[2][1] - poligono[0][1]);
|
|
|
|
const intensidad = Math.random();
|
|
|
|
puntos.push([x, y, intensidad]);
|
|
}
|
|
});
|
|
|
|
|
|
const heat = L.heatLayer(puntos, {
|
|
radius: 35,
|
|
blur: 25,
|
|
maxZoom: 2,
|
|
gradient: {
|
|
0.2: "#00f",
|
|
0.4: "#0ff",
|
|
0.6: "#0f0",
|
|
0.8: "#ff0",
|
|
1.0: "#f00"
|
|
}
|
|
});
|
|
|
|
heat.addTo(map);
|
|
|
|
|
|
Object.entries(edificios).forEach(([nombre, coords]) => {
|
|
L.polygon(coords, {
|
|
color: "#77ee9f",
|
|
weight: 2,
|
|
fillOpacity: 0.25
|
|
})
|
|
.bindPopup(`🏢 ${nombre}`)
|
|
.addTo(map);
|
|
});
|
|
|
|
// DEBUG PRO (CLICK PARA COORDENADAS EXACTAS)
|
|
map.on("click", function (e) {
|
|
console.log(" Coordenadas exactas:", e.latlng);
|
|
});
|
|
|
|
return () => {
|
|
map.removeLayer(heat);
|
|
};
|
|
|
|
}, [map]);
|
|
|
|
return null;
|
|
}
|
|
|
|
export default function MapaCalor() {
|
|
|
|
const bounds = [
|
|
[0, 0],
|
|
[3368, 4768]
|
|
];
|
|
|
|
return (
|
|
|
|
<div style={{
|
|
width: "100%",
|
|
height: "650px",
|
|
marginTop: "40px",
|
|
borderRadius: "12px",
|
|
overflow: "hidden",
|
|
boxShadow: "0 6px 25px rgba(0,0,0,0.3)"
|
|
}}>
|
|
|
|
<MapContainer
|
|
crs={L.CRS.Simple}
|
|
minZoom={-2}
|
|
style={{ height: "100%", width: "100%" }}
|
|
>
|
|
|
|
<ImageOverlay
|
|
url="/plano.png"
|
|
bounds={bounds}
|
|
/>
|
|
|
|
<AjustarVista bounds={bounds} />
|
|
|
|
<HeatLayer />
|
|
|
|
</MapContainer>
|
|
|
|
</div>
|
|
);
|
|
} |