feat: Add PolyWeather frontend application with interactive map, city list, and weather details.
This commit is contained in:
@@ -40,6 +40,7 @@ let tempChart = null;
|
|||||||
const AUTO_REFRESH_MS = 60 * 60 * 1000; // 1 hour
|
const AUTO_REFRESH_MS = 60 * 60 * 1000; // 1 hour
|
||||||
let selectedForecastDate = null;
|
let selectedForecastDate = null;
|
||||||
let nearbyLayerGroup = null;
|
let nearbyLayerGroup = null;
|
||||||
|
let heatLayer = null;
|
||||||
|
|
||||||
// ──────────────────────────────────────────────────────────
|
// ──────────────────────────────────────────────────────────
|
||||||
// Map Setup
|
// Map Setup
|
||||||
@@ -67,6 +68,22 @@ function initMap() {
|
|||||||
|
|
||||||
nearbyLayerGroup = L.layerGroup().addTo(map);
|
nearbyLayerGroup = L.layerGroup().addTo(map);
|
||||||
|
|
||||||
|
// Initialize Heatmap layer (requires Leaflet.heat)
|
||||||
|
heatLayer = L.heatLayer([], {
|
||||||
|
radius: 70,
|
||||||
|
blur: 50,
|
||||||
|
maxZoom: 10,
|
||||||
|
gradient: {
|
||||||
|
0.0: "blue",
|
||||||
|
0.2: "cyan",
|
||||||
|
0.4: "lime",
|
||||||
|
0.6: "yellow",
|
||||||
|
0.8: "orange",
|
||||||
|
1.0: "red",
|
||||||
|
},
|
||||||
|
opacity: 0.5,
|
||||||
|
}).addTo(map);
|
||||||
|
|
||||||
// Close panel and clear selection when clicking on empty map space
|
// Close panel and clear selection when clicking on empty map space
|
||||||
map.on("click", () => {
|
map.on("click", () => {
|
||||||
closePanel();
|
closePanel();
|
||||||
@@ -84,8 +101,10 @@ function updateMapVisibility() {
|
|||||||
// These are the "Ankara-style" local station markers
|
// These are the "Ankara-style" local station markers
|
||||||
if (zoom < 7) {
|
if (zoom < 7) {
|
||||||
if (map.hasLayer(nearbyLayerGroup)) map.removeLayer(nearbyLayerGroup);
|
if (map.hasLayer(nearbyLayerGroup)) map.removeLayer(nearbyLayerGroup);
|
||||||
|
if (map.hasLayer(heatLayer)) map.removeLayer(heatLayer);
|
||||||
} else {
|
} else {
|
||||||
if (!map.hasLayer(nearbyLayerGroup)) map.addLayer(nearbyLayerGroup);
|
if (!map.hasLayer(nearbyLayerGroup)) map.addLayer(nearbyLayerGroup);
|
||||||
|
if (!map.hasLayer(heatLayer)) map.addLayer(heatLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Handle Primary City Markers (Major vs Minor)
|
// 2. Handle Primary City Markers (Major vs Minor)
|
||||||
@@ -306,6 +325,16 @@ function renderNearbyStations(data) {
|
|||||||
latLngs.push([st.lat, st.lon]);
|
latLngs.push([st.lat, st.lon]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Update Heatmap
|
||||||
|
if (heatLayer) {
|
||||||
|
const heatData = nearby.map((st) => [st.lat, st.lon, st.temp || 10]);
|
||||||
|
// Add current city center to heat data
|
||||||
|
if (data.lat && data.lon && data.current?.temp != null) {
|
||||||
|
heatData.push([data.lat, data.lon, data.current.temp]);
|
||||||
|
}
|
||||||
|
heatLayer.setLatLngs(heatData);
|
||||||
|
}
|
||||||
|
|
||||||
if (latLngs.length > 1) {
|
if (latLngs.length > 1) {
|
||||||
const bounds = L.latLngBounds(latLngs);
|
const bounds = L.latLngBounds(latLngs);
|
||||||
map.flyToBounds(bounds, {
|
map.flyToBounds(bounds, {
|
||||||
|
|||||||
@@ -207,6 +207,8 @@
|
|||||||
|
|
||||||
<!-- Leaflet JS -->
|
<!-- Leaflet JS -->
|
||||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||||
|
<!-- Leaflet Heatmap Plugin -->
|
||||||
|
<script src="https://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"></script>
|
||||||
<!-- Chart.js -->
|
<!-- Chart.js -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js"></script>
|
||||||
<script src="/static/app.js"></script>
|
<script src="/static/app.js"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user