"use strict"; // Import leaflet, but some plugins require it to have the variable name 'L' :-/ import L from 'leaflet'; import 'leaflet-fullscreen'; import 'iso8601-js-period'; import '../../node_modules/leaflet-timedimension/dist/leaflet.timedimension.src.withlog.js'; import Config from './Config.mjs'; import LayerDeviceMarkers from './LayerDeviceMarkers.mjs'; import LayerHeatmap from './LayerHeatmap.mjs'; import LayerHeatmapGlue from './LayerHeatmapGlue.mjs'; import UI from './UI.mjs'; class MapManager { constructor() { console.log(Config); } setup() { // Create the map this.map = L.map("map", { fullscreenControl: true, timeDimension: true, timeDimensionOptions: { timeInterval: `2019-01-01/${(new Date()).toISOString().split("T")[0]}`, period: "PT6M" // 6 minutes, in ISO 8601 Durations format: https://en.wikipedia.org/wiki/ISO_8601#Durations } }); this.map.setView(Config.default_location, Config.default_zoom); // Add the OpenStreetMap tile layer this.layer_openstreet = L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { id: "openstreetmap", maxZoom: 19, attribution: "© OpenStreetMap contributors" }).addTo(this.map); // Add the attribution this.map.attributionControl.addAttribution("Data: Connected Humber"); this.map.attributionControl.addAttribution("Air Quality Web by Starbeamrainbowlabs"); // Add the device markers console.info("[map] Loading device markers...."); this.setup_device_markers().then(() => { console.info("[map] Device markers loaded successfully."); // Display a layer controller this.setup_layer_control(); }); // Add the heatmap console.info("[map] Loading heatmap...."); this.setup_heatmap() .then(() => console.info("[map] Heatmap loaded successfully.")) // ...and the time dimension .then(this.setup_time_dimension.bind(this)) .then(() => console.info("[map] Time dimension initialised.")); this.ui = new UI(Config, this); this.ui.setup().then(() => console.log("[map] Settings initialised.")); } setup_time_dimension() { // Ensure terser doesn't tree-shake iso8601-js-period if(nezasa.iso8601.period) console.debug("iso8601-js-period is loaded."); this.layer_time = new L.TimeDimension({ period: "PT1H", // 1 hour timeInterval: `2019-01-01T12:00:00Z/${new Date().toISOString()}` }); //this.layer_time.on("timeloading", console.log.bind(null, "timeloading")); this.layer_time_player = new L.TimeDimension.Player({ transitionTime: 500, loop: false, startOver: true, buffer: 10 // Default: 5 }, this.layer_time); this.layer_time_control = new L.Control.TimeDimension({ player: this.layer_time_player, timeDimension: this.layer_time, position: "bottomright", autoplay: false, minSpeed: 1, speedStep: 0.25, maxSpeed: 15, timeSliderDragUpdate: false }); this.map.addControl(this.layer_time_control); // Create the time dimension <---> heatmap glue object this.layer_heatmap_glue = new LayerHeatmapGlue( this.layer_time, this.heatmap ); this.layer_heatmap_glue.attachTo(this.map); } async setup_device_markers() { this.device_markers = new LayerDeviceMarkers(this.map); await this.device_markers.setup(); } async setup_heatmap() { this.heatmap = new LayerHeatmap(this.map); // TODO: Use leaflet-timedimension here // TODO: Allow configuration of the different reading types here this.heatmap.update_data(new Date(new Date-10*60), "PM25"); } setup_layer_control() { this.layer_control = L.control.layers({ // Base layer(s) "OpenStreetMap": this.layer_openstreet }, { // Overlay(s) "Devices": this.device_markers.layer, // TODO: Have 1 heatmap layer per reading type? "Heatmap": this.heatmap.layer }, { // Options }); this.layer_control.addTo(this.map); } } export default MapManager;