Skip to content

Commit

Permalink
Add pollution values to map
Browse files Browse the repository at this point in the history
Rather than create the zone labels together with the zone boundaries, we now split these two processes up so that markers can be updated on each refresh using data from the API.
  • Loading branch information
jdudley1123 committed Nov 29, 2024
1 parent 97f1e4d commit df76103
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 44 deletions.
40 changes: 33 additions & 7 deletions app/assets/stylesheets/leaflet.scss
Original file line number Diff line number Diff line change
@@ -1,19 +1,45 @@
/* Airtext specific styles */

.leaflet-marker-icon.zone-label {
color: black;
font-size: 12px;
width: auto !important;
height: auto !important;
background-color: white;
padding: 0 3px;
text-align: center;
border-radius: 3px;
opacity: 1;

&.zone-label-level-1 {
font-weight: bold;
}

.wrapper {
display: flex;
transform: translate(-50%, -50%);
color: black;
font-size: 12px;
background-color: white;
text-align: center;
border-radius: 3px;
}

.zone-name {
padding: 0 6px;
}

.daqi-indicator {
padding: 0 6px;
border-right: 1px solid #ccc;
display: flex;
align-items: center;

/*
&::before {
content: "";
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 4px;
background-color: red;
}
*/
}
}

.fullscreen-icon {
Expand Down
76 changes: 39 additions & 37 deletions app/javascript/controllers/map_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,43 +207,24 @@ export default class MapController extends Controller {
}

addZonesLayer() {
const { zoneBoundaryLayers, zoneLabelMarkers } = this.zones();
const zoneBoundaryLayers = this.zoneBoundariesLayers();
zoneBoundaryLayers.forEach((layer) => layer.addTo(this.map));
this.updateZoneBoundaryLayerStyles(zoneBoundaryLayers);

this.map.on("zoomend", () => {
this.updateZoneBoundaryLayerStyles(zoneBoundaryLayers);
});

this.addZoneLabelMarkers(zoneLabelMarkers);
}

zones() {
zoneBoundariesLayers() {
const zoneBoundaryLayers = [];
const zoneLabelMarkers = [];

for (const [, zone] of Object.entries(zones)) {
const layer = L.geoJSON(zone, { pane: "zones" });
zoneBoundaryLayers.push(layer);

const bounds = layer.getBounds();
const center = bounds.getCenter();

const label = L.marker(center, {
icon: L.divIcon({
className:
"zone-label " + `zone-label-level-${zone.properties.level}`,
html: zone.properties.name,
}),
});

zoneLabelMarkers.push({
marker: label,
londonBorough: zone.properties.londonBorough,
});
}

return { zoneBoundaryLayers, zoneLabelMarkers };
return zoneBoundaryLayers;
}

updateZoneBoundaryLayerStyles(zoneBoundaryLayers) {
Expand All @@ -258,27 +239,37 @@ export default class MapController extends Controller {
});
}

addZoneLabelMarkers(zoneLabelMarkers) {
async updateZoneLabels() {
const pollutant_forecasts = await this.getForecastData();

// Remove existing zone labels
this.layers.zoneLabels?.forEach((marker) => this.map.removeLayer(marker));
this.layers.zoneLabels = [];

// Only show the zone labels when the map is zoomed in enough
zoneLabelMarkers.forEach(({ marker, londonBorough }) => {
const startZoom = 9 + (londonBorough ? 2 : 0); // Only show London borough labels at higher zoom
for (const [, zone] of Object.entries(zones)) {
const startZoom = 9 + (zone.properties.londonBorough ? 2 : 0); // Only show London borough labels at higher zoom
const endZoom = 20;

// Add the marker to the map initially if within the zoom range
// Add the marker to the map if within the zoom range
if (this.map.getZoom() >= startZoom && this.map.getZoom() <= endZoom) {
const center = {
lat: zone.properties.center[1],
lng: zone.properties.center[0],
};
const pollutant_value = pollutant_forecasts[zone.properties.name];

const marker = L.marker(center, {
icon: L.divIcon({
className:
"zone-label " + `zone-label-level-${zone.properties.level}`,
html: `<div class="wrapper"><span class="daqi-indicator">${pollutant_value}</span><span class="zone-name">${zone.properties.name}</span></div>`,
}),
});
marker.addTo(this.map);
this.layers.zoneLabels.push(marker);
}

// Attach the zoomend event to control visibility
this.map.on("zoomend", () => {
const currentZoom = this.map.getZoom();
if (currentZoom >= startZoom && currentZoom <= endZoom) {
this.map.addLayer(marker);
} else {
this.map.removeLayer(marker);
}
});
});
}
}

findZones(coordinatesLngLat) {
Expand All @@ -303,10 +294,21 @@ export default class MapController extends Controller {
updateMap() {
this.updateSettings();
this.updatePollutionLayer();
this.updateZoneLabels();
}

updatePollutionLayer() {
this.map.removeLayer(this.layers.pollution);
this.addPollutionLayer();
}

async getForecastData() {
const pollutant = this.pollutantSelectorTarget.value;
const date = this.daySelectorTarget.value;

const response = await fetch(
`/pollutant_forecasts?pollutant=${pollutant}&date=${date}`
);
return response.json();
}
}

0 comments on commit df76103

Please sign in to comment.