// uses functions in utils.js
var host = window.location.protocol + "//" + window.location.host;
// "global" map variables
var map;
var previewmap;
var visited_clues_m = L.layerGroup([]); // all clues
var unvisited_clues_m = L.layerGroup([]); // subset of all clues - unvisited clues
var destination_clues_m = L.layerGroup([]); // clues bikers are currently destined for
var bikes_m = L.layerGroup([]); // bike markers
var routes_m = L.layerGroup([]); // polyline routes
var homemarker, homebase, clues, clue_rels, bikes, routes, previewmarker;
var latest_timestamp = -1; // initially -1, otherwise set to value given by server in last successful info update
var baseIcon = L.Icon.extend({
options: {
iconSize: [25, 41], // size of the icon
iconAnchor: [12, 41], // point of the icon which will correspond to marker's location
popupAnchor: [0, -41] // point from which the popup should open relative to the iconAnchor
}
})
var homeIcon = new baseIcon({iconUrl: 'static/img/marker-home.png'}),
activeBikeIcon = new baseIcon({iconUrl: 'static/img/marker-bike-active.png', className:"leaflet-bike-marker"}),
inactiveBikeIcon = new baseIcon({iconUrl: 'static/img/marker-bike-inactive.png'}),
visitedIcon = new baseIcon({iconUrl: 'static/img/marker-icon-green.png'}),
disabledIcon = new baseIcon({iconUrl: 'static/img/marker-icon-black.png'}),
unvisitedIcon = new baseIcon({iconUrl: 'static/img/marker-icon-grey.png'}), // generic, becomes colored when assigned to route
visitedIconReq = new baseIcon({iconUrl: 'static/img/marker-icon-green-req.png'}),
disabledIconReq = new baseIcon({iconUrl: 'static/img/marker-icon-black-req.png'}),
unvisitedIconReq = new baseIcon({iconUrl: 'static/img/marker-icon-grey-req.png'}); // generic, becomes colored when assigned to route
var teamIcons = [ unvisitedIcon,
new baseIcon({iconUrl: 'static/img/marker-icon-orange.png'}),
new baseIcon({iconUrl: 'static/img/marker-icon-red.png'}),
new baseIcon({iconUrl: 'static/img/marker-icon-blue.png'}),
new baseIcon({iconUrl: 'static/img/marker-icon-yellow.png'}) ];
var teamIconsReq = [ unvisitedIconReq,
new baseIcon({iconUrl: 'static/img/marker-icon-orange-req.png'}),
new baseIcon({iconUrl: 'static/img/marker-icon-red-req.png'}),
new baseIcon({iconUrl: 'static/img/marker-icon-blue-req.png'}),
new baseIcon({iconUrl: 'static/img/marker-icon-yellow-req.png'}) ];
team1IconReq = new baseIcon({iconUrl: 'static/img/marker-icon-orange.png'}),
team2IconReq = new baseIcon({iconUrl: 'static/img/marker-icon-red.png'}),
team3IconReq = new baseIcon({iconUrl: 'static/img/marker-icon-green.png'}),
team4Icon = new baseIcon({iconUrl: 'static/img/marker-icon-yellow.png'});
var bikeIcons = {'ACTIVE' : activeBikeIcon, 'INACTIVE' : inactiveBikeIcon, 'DISABLED' : inactiveBikeIcon}
var bikeStatusOpacities = {"ACTIVE" : 1.0, "INACTIVE" : 0.75, "DISABLED" : 0.0};
function zoomToBike(team_name){
map.panTo(bikes[team_name]['marker'].getLatLng());
}
function zoomToClue(clue_name){
map.panTo(clue_rels[clue_name].getLatLng());
}
function previewZoom(){
var long = parseFloat(document.getElementById("new_clue_longitude").value);
var lat = parseFloat(document.getElementById("new_clue_latitude").value);
if (!isNaN(long) && !isNaN(lat)){
previewmarker.setLatLng([lat, long]);
previewmap.panTo(previewmarker.getLatLng());
}
}
function filterClues(text){
for(var i = 0; i < clues.length; i++){
var clue = clues[i]['clue_name'];
if((text == "") || (clue.includes(text))){
clue_rels[clue].setOpacity(1.0);
} else {
clue_rels[clue].setOpacity(0.25);
}
}
}
function drawRoute(route_coords_osrm, team_color) {
//osrm lat/long are swapped
for (var i = 0; i < route_coords_osrm.length; i++){
var t = route_coords_osrm[i][1];
route_coords_osrm[i][1] = route_coords_osrm[i][0];
route_coords_osrm[i][0] = t;
}
var route = new L.polyline(route_coords_osrm, {color: team_color});
routes_m.addLayer(route);
}
function drawRoutes() {
routes_m.clearLayers();
for (var i = 0; i < routes['clusters'].length; i++){
if(routes['clusters'][i].length > 0){
var color;
var r = Math.floor(Math.random() * 155+100);
var g = 0; // no greens -- avoid yellow
var b = Math.floor(Math.random() * 155+100);
color= "rgb("+r+","+g+","+ b+")";
console.log(color);
drawRoute(routes['clusters'][i], color);
}
}
for (var i = 0; i < routes['individual_routes'].length; i++){
if(routes['individual_routes'][i].length > 0){
drawRoute(routes['individual_routes'][i], 'yellow');
}
}
}
function updateBikeStatus(){
var table = document.getElementById("bike-teams-table");
table.innerHTML = '';
var index = 1;
for (const [key, value] of Object.entries(bikes)) {
var name = key;
var bike = value;
var row = document.createElement("tr");
if(bike['team_status'] == "DISABLED")row.classList.add("disabled-class");
var namecell = document.createElement("td"); namecell.innerHTML = ""+name+"";
var statuscell = document.createElement("td"); statuscell.innerHTML = "" + bike['team_status'] + " ("+parseInt(bike['time_since_last_contact']).toString()+"s)";
var targetcell = document.createElement("td"); targetcell.innerHTML = ""+bike['target_clue']+"";
var etacell = document.createElement("td"); etacell.innerHTML = " ";
row.appendChild(namecell);
row.appendChild(statuscell);
row.appendChild(targetcell);
row.appendChild(etacell);
table.appendChild(row);
index += 1;
}
}
function updateClueStats(){
document.getElementById("total_count").innerText = clues.length;
var visited_count = 0;
var avg_distance = 0;
for (var i =0; i < clues.length; i++){
if(clues[i]['clue_status'] == "VISITED"){
visited_count++;
avg_distance += getDistanceFromLatLon(homebase, clues[i]);
}
}
avg_distance /= visited_count;
document.getElementById("unvisited_count").innerText = clues.length-visited_count;
document.getElementById("visited_count").innerText = visited_count;
document.getElementById("percent_visited").innerText = (100*(visited_count/clues.length)).toFixed(2);
document.getElementById("avg_visited_distance").innerText = avg_distance.toFixed(2);
}
function drawClues(){
unvisited_clues_m.clearLayers();
visited_clues_m.clearLayers();
for (var i = 0; i < clues.length; i++) {
var tempIcon = teamIcons[clues[i]['assigned_team']];
if(clues[i]['clue_required']){
tempIcon = teamIconsReq[clues[i]['assigned_team']];
if (clues[i]['clue_status'] == "UNVISITED") tempIcon = unvisitedIconReq;
if (clues[i]['clue_status'] == "VISITED") tempIcon = visitedIconReq;
}
else{
if (clues[i]['clue_status'] == "UNVISITED") tempIcon = unvisitedIcon;
if (clues[i]['clue_status'] == "VISITED") tempIcon = visitedIcon;
}
var popupdiv = document.createElement('p');
var toggleVisitText = clues[i]['clue_status'] == "UNVISITED" ? "Visit" : "Unvisit";
var toggleDisableText = clues[i]['clue_status'] != "DISABLED" ? "Disable" : "Enable";
popupdiv.innerHTML = "" + clues[i]['clue_name'] + ": " + clues[i]['clue_info'] + " ";
popupdiv.innerHTML += "";
popupdiv.innerHTML += "";
popupdiv.innerHTML += "";
popupdiv.innerHTML += "