mirror of
https://github.com/ConnectedHumber/Air-Quality-Web
synced 2024-11-25 06:53:00 +00:00
[client] Refactor to support new HTTP API changes
This commit is contained in:
parent
530876ab5f
commit
deb02b0ede
4 changed files with 72 additions and 18 deletions
43
client_src/js/DeviceData.mjs
Normal file
43
client_src/js/DeviceData.mjs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
import Config from './Config.mjs';
|
||||||
|
|
||||||
|
import GetFromUrl from './Helpers/GetFromUrl.mjs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles and caches data about devices.
|
||||||
|
*/
|
||||||
|
class DeviceData {
|
||||||
|
/**
|
||||||
|
* Creates a new DeviceData class instance.
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
this.devices = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the device data from the server.
|
||||||
|
* @return {Promise} A promise that resolves when the data has been fetched from the server.
|
||||||
|
*/
|
||||||
|
async setup() {
|
||||||
|
this.devices = JSON.parse(await GetFromUrl(
|
||||||
|
`${Config.api_root}?action=list-devices`
|
||||||
|
));
|
||||||
|
|
||||||
|
// Create a map to help us lookup ids faster
|
||||||
|
this.device_map = new Map();
|
||||||
|
for(let device of this.devices)
|
||||||
|
this.device_map.set(device.id, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks up a device by its id.
|
||||||
|
* @param {Number} device_id The ID of the device to return
|
||||||
|
* @return {object} The info about the device with the specified id.
|
||||||
|
*/
|
||||||
|
get_by_id(device_id) {
|
||||||
|
return this.device_map.get(device_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DeviceData;
|
|
@ -12,8 +12,9 @@ import DeviceReadingDisplay from './DeviceReadingDisplay.mjs';
|
||||||
import GetFromUrl from './Helpers/GetFromUrl.mjs';
|
import GetFromUrl from './Helpers/GetFromUrl.mjs';
|
||||||
|
|
||||||
class LayerDeviceMarkers {
|
class LayerDeviceMarkers {
|
||||||
constructor(in_map) {
|
constructor(in_map, in_device_data) {
|
||||||
this.map = in_map;
|
this.map = in_map;
|
||||||
|
this.device_data = in_device_data;
|
||||||
|
|
||||||
// Create a new clustering layer
|
// Create a new clustering layer
|
||||||
this.layer = L.markerClusterGroup({
|
this.layer = L.markerClusterGroup({
|
||||||
|
@ -22,14 +23,12 @@ class LayerDeviceMarkers {
|
||||||
}
|
}
|
||||||
|
|
||||||
async setup() {
|
async setup() {
|
||||||
|
|
||||||
// Fetch the device list
|
|
||||||
let device_list = JSON.parse(await GetFromUrl(
|
|
||||||
`${Config.api_root}?action=list-devices&only-with-location=yes`
|
|
||||||
));
|
|
||||||
|
|
||||||
// Add a marker for each device
|
// Add a marker for each device
|
||||||
for (let device of device_list) {
|
for (let device of this.device_data.devices) {
|
||||||
|
// If the device doesn't have a location, we're not interested
|
||||||
|
// FUTURE: We might be able to displaymobile devices by adding additional logic here
|
||||||
|
if(typeof device.latitude != "number" || typeof device.longitude != "number")
|
||||||
|
continue;
|
||||||
this.add_device_marker(device);
|
this.add_device_marker(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,9 @@ class LayerHeatmap {
|
||||||
* Creates a new heatmap manager wrapper class fort he given map.
|
* Creates a new heatmap manager wrapper class fort he given map.
|
||||||
* @param {L.Map} in_map The leaflet map to attach to.
|
* @param {L.Map} in_map The leaflet map to attach to.
|
||||||
*/
|
*/
|
||||||
constructor(in_map) {
|
constructor(in_map, in_device_data) {
|
||||||
this.map = in_map;
|
this.map = in_map;
|
||||||
|
this.device_data = in_device_data;
|
||||||
|
|
||||||
this.overlay_config = {
|
this.overlay_config = {
|
||||||
radius: Config.heatmap.blob_radius,
|
radius: Config.heatmap.blob_radius,
|
||||||
|
@ -101,6 +102,13 @@ class LayerHeatmap {
|
||||||
* @param {object[]} readings_list The array of data points to display.
|
* @param {object[]} readings_list The array of data points to display.
|
||||||
*/
|
*/
|
||||||
set_data(readings_list) {
|
set_data(readings_list) {
|
||||||
|
// Substitute in the device locations
|
||||||
|
for(let reading of readings_list) {
|
||||||
|
let device_info = this.device_data.get_by_id(reading.device_id);
|
||||||
|
reading.latitude = device_info.latitude;
|
||||||
|
reading.longitude = device_info.longitude;
|
||||||
|
}
|
||||||
|
|
||||||
let data_object = {
|
let data_object = {
|
||||||
max: 0,
|
max: 0,
|
||||||
data: readings_list
|
data: readings_list
|
||||||
|
|
|
@ -9,6 +9,7 @@ import Config from './Config.mjs';
|
||||||
import LayerDeviceMarkers from './LayerDeviceMarkers.mjs';
|
import LayerDeviceMarkers from './LayerDeviceMarkers.mjs';
|
||||||
import LayerHeatmap from './LayerHeatmap.mjs';
|
import LayerHeatmap from './LayerHeatmap.mjs';
|
||||||
import LayerHeatmapGlue from './LayerHeatmapGlue.mjs';
|
import LayerHeatmapGlue from './LayerHeatmapGlue.mjs';
|
||||||
|
import DeviceData from './DeviceData.mjs';
|
||||||
import UI from './UI.mjs';
|
import UI from './UI.mjs';
|
||||||
|
|
||||||
class MapManager {
|
class MapManager {
|
||||||
|
@ -16,7 +17,7 @@ class MapManager {
|
||||||
console.log(Config);
|
console.log(Config);
|
||||||
}
|
}
|
||||||
|
|
||||||
setup() {
|
async setup() {
|
||||||
// Create the map
|
// Create the map
|
||||||
this.map = L.map("map", {
|
this.map = L.map("map", {
|
||||||
fullscreenControl: true,
|
fullscreenControl: true,
|
||||||
|
@ -40,14 +41,16 @@ class MapManager {
|
||||||
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>");
|
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>");
|
||||||
|
|
||||||
|
|
||||||
|
// Load the device information
|
||||||
|
this.device_data = new DeviceData();
|
||||||
|
await this.device_data.setup();
|
||||||
|
console.log("[map] Device data loaded");
|
||||||
|
|
||||||
// Add the device markers
|
// Add the device markers
|
||||||
console.info("[map] Loading device markers....");
|
console.info("[map] Loading device markers....");
|
||||||
this.setup_device_markers().then(() => {
|
this.setup_device_markers()
|
||||||
console.info("[map] Device markers loaded successfully.");
|
.then(() => console.info("[map] Device markers loaded successfully."))
|
||||||
|
.then(this.setup_layer_control.bind(this));
|
||||||
// Display a layer controller
|
|
||||||
this.setup_layer_control();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add the heatmap
|
// Add the heatmap
|
||||||
console.info("[map] Loading heatmap....");
|
console.info("[map] Loading heatmap....");
|
||||||
|
@ -59,6 +62,7 @@ class MapManager {
|
||||||
|
|
||||||
this.ui = new UI(Config, this);
|
this.ui = new UI(Config, this);
|
||||||
this.ui.setup().then(() => console.log("[map] Settings initialised."));
|
this.ui.setup().then(() => console.log("[map] Settings initialised."));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_time_dimension() {
|
setup_time_dimension() {
|
||||||
|
@ -97,12 +101,12 @@ class MapManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
async setup_device_markers() {
|
async setup_device_markers() {
|
||||||
this.device_markers = new LayerDeviceMarkers(this.map);
|
this.device_markers = new LayerDeviceMarkers(this.map, this.device_data);
|
||||||
await this.device_markers.setup();
|
await this.device_markers.setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
async setup_heatmap() {
|
async setup_heatmap() {
|
||||||
this.heatmap = new LayerHeatmap(this.map);
|
this.heatmap = new LayerHeatmap(this.map, this.device_data);
|
||||||
|
|
||||||
// TODO: Use leaflet-timedimension here
|
// TODO: Use leaflet-timedimension here
|
||||||
// TODO: Allow configuration of the different reading types here
|
// TODO: Allow configuration of the different reading types here
|
||||||
|
|
Loading…
Reference in a new issue