-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathmain.js
More file actions
146 lines (135 loc) · 5.25 KB
/
Copy pathmain.js
File metadata and controls
146 lines (135 loc) · 5.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
const locations = {
"Germany": [
{name: "Hamburg", id: 3, geo: {lat: 53.57132, lng: 9.95367}},
{name: "Berlin", id: 12, geo: {lat: 52.5069704, lng: 13.2846517}},
{name: "Frankfurt am Main", id: 33, geo: {lat: 50.121301, lng: 8.5665248}},
{name: "München", id: 26, geo: {lat: 48.155004, lng: 11.4717967}},
{name: "Köln", id: 19, geo: {lat: 50.95779, lng: 6.8972834}},
{name: "Stuttgart", id: 18, geo: {lat: 48.779301, lng: 9.1071762}}
],
"France": [
{name: "Paris", id: 48, geo: {lat: 48.8589101, lng: 2.3120407}}
],
"Italy": [
{name: "Mailand", id: 20, geo: {lat: 45.4627887, lng: 9.142713}},
{name: "Rom", id: 31, geo: {lat: 41.9101776, lng: 12.4659587}},
{name: "Turin", id: 44, geo: {lat: 45.073544, lng: 7.6405873}}
],
"Netherlands": [
{name: "Amsterdam", id: 5, geo: {lat: 52.3547498, lng: 4.8339214}}
],
"Austria": [
{name: "Wien", id: 7, geo: {lat: 48.220778, lng: 16.3100209}}
],
"Spain": [
{name: "Madrid", id: 36, geo: {lat: 40.4380638, lng: -3.7495758}}
],
"USA": [
{name: "Washington DC", id: 57, geo: {lat: 38.9072, lng: -77.0369}}
]
};
const idToCity = {};
Object.keys(locations).forEach(country => locations[country].forEach(city => idToCity[city.id] = city));
document.querySelectorAll("#countries li").forEach(li => {
li.onclick = () => {
updateCities(li.innerText);
document.querySelectorAll("#countries li.selected").forEach(li => li.classList.remove("selected"));
li.classList.add("selected");
}
});
registerCityClickListeners();
function registerCityClickListeners() {
document.querySelectorAll("#cities li").forEach(li => {
li.onclick = () => {
changeLocation(li.dataset.id);
document.querySelectorAll("#cities li.selected").forEach(li => li.classList.remove("selected"));
li.classList.add("selected");
}
});
}
function updateCities(country) {
const ul = document.getElementById("cities");
ul.innerHTML = "";
locations[country].forEach(city => {
ul.insertAdjacentHTML("beforeend", `<li data-id="${city.id}">${city.name}</li>`);
});
registerCityClickListeners();
}
function changeLocation(id) {
const city = idToCity[id];
if (!city) return;
map.setView([city.geo.lat, city.geo.lng], 13);
// Clear all existing markers
Object.values(markers).forEach(marker => marker.removeFrom(map));
markers = {};
// Tell the server to switch MQTT location
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({type: "changeLocation", locationId: parseInt(id)}));
}
}
var map = L.map('map').setView([53.57132, 9.95367], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
let markers = {};
function addVehicleMarker(vehicle, initial = false) {
let geoCoords = vehicle.geoCoordinate;
if (geoCoords !== undefined) {
const icon = L.divIcon({
iconAnchor: [0, 24],
labelAnchor: [-6, 0],
popupAnchor: [0, -36],
html: `<span class="marker ${initial ? "available" : "new"}"><i class="fas fa-car"></i></span>`
});
let fuelIcon = vehicle.fuelType === "ELECTRIC" ? '<i class="fas fa-bolt"></i>' : '<i class="fas fa-gas-pump"></i>';
let marker = L.marker([geoCoords.latitude, geoCoords.longitude])
.addTo(map)
.setIcon(icon)
.bindPopup(`
<div class="popup-car">
<div>
<img width="150" height="150" src="${vehicle.imageUrl || ''}">
</div>
<div class="popup-car-details">
<div>${vehicle.plate || ''}</div>
<div>${vehicle.address ? vehicle.address.split(",")[0] : ''}</div>
<div>
<span>${vehicle.fuellevel || 0}%</span>
${fuelIcon}
</div>
</div>
</div>
`);
markers[vehicle.id || vehicle.vin] = marker;
}
}
function removeVehicleMarker(id) {
let marker = markers[id];
if (marker !== undefined) {
const icon = L.divIcon({
iconAnchor: [0, 24],
labelAnchor: [-6, 0],
popupAnchor: [0, -36],
html: `<span class="marker unavailable"><i class="fas fa-car"></i></span>`
});
marker.setIcon(icon);
}
}
var ws = new WebSocket("ws://" + location.host);
ws.onmessage = event => {
const json = JSON.parse(event.data);
if (json.type === "initial") {
// Full vehicle list (initial load or after location change)
if (json.vehicles) {
json.vehicles.forEach(v => addVehicleMarker(v, true));
}
} else if (json.eventType === "VEHICLE_LIST_UPDATE" || json.addedVehicles || json.removedVehicles) {
// Delta update
if (json.addedVehicles) {
json.addedVehicles.forEach(addVehicleMarker);
}
if (json.removedVehicles) {
json.removedVehicles.forEach(removeVehicleMarker);
}
}
};