2019-01-17 13:56:25 +00:00
|
|
|
"use strict";
|
|
|
|
|
2019-01-17 14:07:31 +00:00
|
|
|
// Import leaflet, but some plugins require it to have the variable name 'L' :-/
|
|
|
|
import L from 'leaflet';
|
|
|
|
import 'leaflet-fullscreen';
|
2019-06-09 22:51:41 +00:00
|
|
|
// import '../../node_modules/leaflet-timedimension/dist/leaflet.timedimension.src.withlog.js';
|
2019-01-17 13:56:25 +00:00
|
|
|
|
|
|
|
import Config from './Config.mjs';
|
2019-01-17 16:13:27 +00:00
|
|
|
import LayerDeviceMarkers from './LayerDeviceMarkers.mjs';
|
2019-06-10 23:19:37 +00:00
|
|
|
import VoronoiManager from './Overlay/VoronoiManager.mjs';
|
2019-06-09 22:51:41 +00:00
|
|
|
// import LayerHeatmap from './LayerHeatmap.mjs';
|
|
|
|
// import LayerHeatmapGlue from './LayerHeatmapGlue.mjs';
|
2019-04-16 17:08:15 +00:00
|
|
|
import DeviceData from './DeviceData.mjs';
|
2019-01-18 21:25:30 +00:00
|
|
|
import UI from './UI.mjs';
|
2019-01-17 13:56:25 +00:00
|
|
|
|
2019-01-19 22:04:51 +00:00
|
|
|
class MapManager {
|
2019-01-17 13:56:25 +00:00
|
|
|
constructor() {
|
2019-01-26 22:00:37 +00:00
|
|
|
console.log(Config);
|
2019-01-17 13:56:25 +00:00
|
|
|
}
|
|
|
|
|
2019-04-16 17:08:15 +00:00
|
|
|
async setup() {
|
2019-01-17 16:13:27 +00:00
|
|
|
// Create the map
|
2019-01-17 14:07:31 +00:00
|
|
|
this.map = L.map("map", {
|
2019-03-18 20:44:12 +00:00
|
|
|
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
|
|
|
|
}
|
2019-01-17 14:07:31 +00:00
|
|
|
});
|
2019-01-17 13:56:25 +00:00
|
|
|
this.map.setView(Config.default_location, Config.default_zoom);
|
|
|
|
|
2019-01-17 16:13:27 +00:00
|
|
|
// Add the OpenStreetMap tile layer
|
2019-01-20 23:41:45 +00:00
|
|
|
this.layer_openstreet = L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
2019-01-17 13:56:25 +00:00
|
|
|
id: "openstreetmap",
|
|
|
|
maxZoom: 19,
|
2019-01-17 13:58:56 +00:00
|
|
|
attribution: "© <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap contributors</a>"
|
2019-01-17 13:56:25 +00:00
|
|
|
}).addTo(this.map);
|
2019-01-17 16:13:27 +00:00
|
|
|
|
2019-03-18 20:44:12 +00:00
|
|
|
// Add the attribution
|
2019-01-21 11:48:29 +00:00
|
|
|
this.map.attributionControl.addAttribution("Data: <a href='https://connectedhumber.org/'>Connected Humber</a>");
|
|
|
|
this.map.attributionControl.addAttribution("<a href='https://github.com/ConnectedHumber/Air-Quality-Web/'>Air Quality Web</a> by <a href='https://starbeamrainbowlabs.com/'>Starbeamrainbowlabs</a>");
|
|
|
|
|
2019-03-18 20:44:12 +00:00
|
|
|
|
2019-04-16 17:08:15 +00:00
|
|
|
// Load the device information
|
|
|
|
this.device_data = new DeviceData();
|
|
|
|
await this.device_data.setup();
|
|
|
|
console.log("[map] Device data loaded");
|
|
|
|
|
2019-01-17 16:13:27 +00:00
|
|
|
// Add the device markers
|
|
|
|
console.info("[map] Loading device markers....");
|
2019-04-16 17:08:15 +00:00
|
|
|
this.setup_device_markers()
|
|
|
|
.then(() => console.info("[map] Device markers loaded successfully."))
|
2019-06-11 11:22:01 +00:00
|
|
|
.then(this.setup_overlay.bind(this))
|
2019-04-16 17:08:15 +00:00
|
|
|
.then(this.setup_layer_control.bind(this));
|
2019-01-17 16:38:15 +00:00
|
|
|
|
2019-01-17 17:31:59 +00:00
|
|
|
// Add the heatmap
|
2019-06-09 22:51:41 +00:00
|
|
|
// 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."));
|
2019-01-17 17:31:59 +00:00
|
|
|
|
2019-01-19 13:14:00 +00:00
|
|
|
this.ui = new UI(Config, this);
|
2019-06-11 14:35:31 +00:00
|
|
|
this.ui.setup().then(() => console.log("[map] UI setup complete."));
|
2019-06-09 22:51:41 +00:00
|
|
|
}
|
|
|
|
|
2019-06-11 11:42:59 +00:00
|
|
|
async setup_overlay() {
|
2019-06-10 23:19:37 +00:00
|
|
|
this.overlay = new VoronoiManager(this.device_data, this.map);
|
2019-06-11 13:00:59 +00:00
|
|
|
await this.overlay.setup();
|
|
|
|
// No need to do this here, as it does it automatically
|
|
|
|
// await this.overlay.set_data(new Date(), "PM25");
|
2019-01-17 17:31:59 +00:00
|
|
|
}
|
|
|
|
|
2019-04-13 13:54:44 +00:00
|
|
|
setup_time_dimension() {
|
2019-06-11 13:00:59 +00:00
|
|
|
// FUTURE: Replace leaflet-time-dimension with our own solution that's got a better ui & saner API?
|
2019-04-13 13:54:44 +00:00
|
|
|
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({
|
2019-04-14 20:01:54 +00:00
|
|
|
transitionTime: 500,
|
2019-04-13 13:54:44 +00:00
|
|
|
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,
|
2019-04-14 20:01:54 +00:00
|
|
|
timeSliderDragUpdate: false
|
2019-04-13 13:54:44 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2019-01-17 17:31:59 +00:00
|
|
|
async setup_device_markers() {
|
2019-04-16 17:08:15 +00:00
|
|
|
this.device_markers = new LayerDeviceMarkers(this.map, this.device_data);
|
2019-01-17 17:31:59 +00:00
|
|
|
await this.device_markers.setup();
|
|
|
|
}
|
|
|
|
|
2019-01-17 16:38:15 +00:00
|
|
|
setup_layer_control() {
|
|
|
|
this.layer_control = L.control.layers({
|
|
|
|
// Base layer(s)
|
|
|
|
"OpenStreetMap": this.layer_openstreet
|
|
|
|
}, { // Overlay(s)
|
2019-01-17 17:31:59 +00:00
|
|
|
"Devices": this.device_markers.layer,
|
2019-06-11 13:00:59 +00:00
|
|
|
// FUTURE: Have 1 heatmap layer per reading type?
|
2019-06-11 11:22:01 +00:00
|
|
|
"Heatmap": this.overlay.layer
|
2019-01-17 16:38:15 +00:00
|
|
|
}, { // Options
|
2019-01-17 16:39:47 +00:00
|
|
|
|
2019-01-17 16:38:15 +00:00
|
|
|
});
|
|
|
|
this.layer_control.addTo(this.map);
|
2019-01-17 13:56:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-20 00:17:54 +00:00
|
|
|
export default MapManager;
|