Repo for non destructive e-scooter intervention materials
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

160 lines
8.1 KiB

<?php
function makeMarker($id){ // generate appropriate markers based on latest JSON
$readJSON = file_get_contents('./nonactiveScooters.json'); //read latest data
$latestData = json_decode($readJSON, true);
$scooter = $latestData[$id]["data"];
$lat = $scooter["attributes"]["lat"]; // get lattitude
$lng = $scooter["attributes"]["lng"]; // get longitude
$pos = $lat.', '.$lng; // construct lat/lon for use in leafet
$lst = $scooter["attributes"]["lastLocationUpdate"]; // get time of last position
$rnt = $scooter["attributes"]["isRentable"]; // check if scooter is rentable,
$act = $scooter["attributes"]["state"]; // check if scooter is: ACTIVE, INACTIVE, MAINTAINANCE, DAMAGED
$bat = $scooter["attributes"]["batteryLevel"]; // battery level 0-100
$nam = $scooter["attributes"]["code"]; // get the artist name
//check scooter status and construct marker with corresponding icon
//check if scooter is rentable
if($rnt == true && $act === 'ACTIVE'){
$marker = 'var scooter'.$nam.' = L.marker(['.$pos.'], {time: "'.$lst.'"}).addTo(map)
.bindPopup("<b>'.$nam.'</b><br><b>batteryLevel: </b>'.$bat.'<br><b>Status: </b>'.$act.'<br>Last updated: '.$lst=str_replace(array('T', 'Z'), ' ', $lst).'")
.bindTooltip("'.$nam.'").setIcon(availableIcon);';
};
//check if scooter is rented out
if ($rnt == false && $act === 'ACTIVE') {
$marker = 'var scooter'.$nam.' = L.marker(['.$pos.'], {time: "'.$lst.'"}).addTo(map)
.bindPopup("<b>'.$nam.'</b><br><b>batteryLevel:</b>'.$bat.'<br><b>Status: </b>'.$act.'<br>Last updated: '.$lst=str_replace(array('T', 'Z'), ' ', $lst).'")
.bindTooltip("'.$nam.'").setIcon(isRentedIcon);';
};
//check if scooter battery is low
if($act === "INACTIVE" && $bat > 0){
$marker = 'var scooter'.$nam.' = L.marker(['.$pos.'], {time: "'.$lst.'"}).addTo(map)
.bindPopup("<b>'.$nam.'</b><br><b>batteryLevel:</b>'.$bat.'<br><b>Status: </b>'.$act.'<br>Last updated: '.$lst=str_replace(array('T', 'Z'), ' ', $lst).'")
.bindTooltip("'.$nam.'").setIcon(lowBatIcon);';
};
//check if scooters battery is dead
if($act === "INACTIVE" && $bat == 0){
$marker = 'var scooter'.$nam.' = L.marker(['.$pos.'], {time: "'.$lst.'"}).addTo(map)
.bindPopup("<b>'.$nam.'</b><br><b>batteryLevel:</b>'.$bat.'<br><b>Status: </b>'.$act.'<br>Last updated: '.$lst=str_replace(array('T', 'Z'), ' ', $lst).'")
.bindTooltip("'.$nam.'").setIcon(noBatIcon);';
};
//check if scooters is dead
if($act === "DAMAGED" || $act === "MAINTENANCE" || $act === "OUT_OF_ORDER" || $act === "GPS_ISSUE"){
$marker = 'var scooter'.$nam.' = L.marker(['.$pos.'], {time: "'.$lst.'"}).addTo(map)
.bindPopup("<b>'.$nam.'</b><br><b>batteryLevel:</b>'.$bat.'<br><b>Status: </b>'.$act.'<br>Last updated: '.$lst=str_replace(array('T', 'Z'), ' ', $lst).'")
.bindTooltip("'.$nam.'").setIcon(isMaintenanceIcon);';
};
//check if scooters is lost
if($act === "LOST"){
$marker = 'var scooter'.$nam.' = L.marker(['.$pos.'], {time: "'.$lst.'"}).addTo(map)
.bindPopup("<b>'.$nam.'</b><br><b>batteryLevel:</b>'.$bat.'<br><b>Status: </b>'.$act.'<br>Last updated: '.$lst=str_replace(array('T', 'Z'), ' ', $lst).'")
.bindTooltip("'.$nam.'").setIcon(isLostIcon);';
};
return $marker;
};
?>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>TIER Hamburg</title>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://unpkg.com/leaflet@1.3.3/dist/leaflet.css">
<script src='https://unpkg.com/leaflet@1.3.3/dist/leaflet.js'></script>
<!-- icons -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet@1.6.0/dist/leaflet.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css"/>
<link rel="stylesheet" href="https://rawcdn.githack.com/python-visualization/folium/master/folium/templates/leaflet.awesome.rotate.css"/>
<!-- location -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet.locatecontrol@0.72.0/dist/L.Control.Locate.min.css" />
<script src="https://cdn.jsdelivr.net/npm/leaflet.locatecontrol@0.72.0/dist/L.Control.Locate.min.js" charset="utf-8"></script>
<!-- main css -->
<link rel="stylesheet" href="main.css"/>
<script>
L_NO_TOUCH = false;
L_DISABLE_3D = false;
</script>
</head>
<body>
<div id="map"></div>
<script>
// define icons
// prefix: glyphicon = bootstrap, list can be found here: https://getbootstrap.com/docs/3.3/components/
// prefix: fa = fontawesome, list is here: https://fontawesome.com/v4.7.0/cheatsheet/
var availableIcon = L.AwesomeMarkers.icon(
{"icon": "wifi", "iconColor": "white", "markerColor": "purple", "prefix": "fa"}
);
var isRentedIcon = L.AwesomeMarkers.icon(
{"icon": "hourglass-half", "iconColor": "white", "spin": "true", "markerColor": "pink", "prefix": "fa"}
);
var lowBatIcon = L.AwesomeMarkers.icon(
{"icon": "battery-1", "iconColor": "white", "markerColor": "pink", "prefix": "fa"}
);
var noBatIcon = L.AwesomeMarkers.icon(
{"icon": "battery-empty", "iconColor": "white", "markerColor": "black", "prefix": "fa"}
);
var isMaintenanceIcon = L.AwesomeMarkers.icon(
{"icon": "wrench", "iconColor": "white", "markerColor": "black", "prefix": "fa"}
);
var isLostIcon = L.AwesomeMarkers.icon(
{"icon": "question", "iconColor": "white", "markerColor": "black", "prefix": "fa"}
);
var map = L.map('map', { zoomControl: false, attributionControl: false }).setView([52.516190, 13.377693], 11.5);
var Stamen_Toner = L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}.{ext}', {
attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
subdomains: 'abcd',
minZoom: 0,
maxZoom: 20,
ext: 'png'
});
map.addLayer(Stamen_Toner);
//the magic: for each scooter in $scooters array, request status and construct marker
<?php
$readJSON = file_get_contents('./nonactiveScooters.json'); //read latest data
$latestData = json_decode($readJSON, true);
$id = 0; //start id
foreach ($latestData as $item) {
$scooter = $item['data'];
print_r($scooter.PHP_EOL);
echo makeMarker($id);
$id++;
};
?>
L.control.locate(
{ "keepCurrentZoomLevel": "true",
icon: 'fa fa-crosshairs',
follow: true,
circleStyle: {}, // change the style of the circle around the user's location
markerStyle: {},
locateOptions: {
enableHighAccuracy: true
}
}).addTo(map);
</script>
</body>
</html>