Anton
4 years ago
4 changed files with 454 additions and 0 deletions
@ -0,0 +1,150 @@ |
|||
<?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 === "MAINTAINANCE" || $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);'; |
|||
}; |
|||
|
|||
|
|||
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 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> — Map data © <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> |
@ -0,0 +1,302 @@ |
|||
body { |
|||
height: 100%; |
|||
width: 100%; |
|||
max-width: 100%; |
|||
max-height: 100%; |
|||
margin: 0; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
#map { |
|||
position: absolute; |
|||
height: 100%; |
|||
width: 100%; |
|||
max-height: 100%; |
|||
max-width: 100%; |
|||
border: none; |
|||
} |
|||
|
|||
#title-container { |
|||
position: absolute; |
|||
pointer-events: none; |
|||
display: flex; |
|||
flex-flow: row wrap; |
|||
z-index: 800; |
|||
text-align: right; |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
|
|||
h1, h2, h3 { |
|||
position: absolute; |
|||
width: 100%; |
|||
pointer-events: none; |
|||
font-family: Courier; |
|||
color: #d152b8; |
|||
margin: 0; |
|||
} |
|||
|
|||
h1 { |
|||
padding-top: 2%; |
|||
padding-right: 2%; |
|||
font-size: 10vw; |
|||
align-self: flex-start; |
|||
|
|||
} |
|||
|
|||
h2 { |
|||
padding-top: 10%; |
|||
padding-right: 2.5%; |
|||
font-size: 3vw; |
|||
align-self: flex-start; |
|||
} |
|||
|
|||
h3 { |
|||
padding-top: 15%; |
|||
font-size: 2.5vw; |
|||
padding-right: 2%; |
|||
align-self: flex-start; |
|||
} |
|||
|
|||
#bottom_menu { |
|||
position: absolute; |
|||
pointer-events: all !important; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-self: flex-end; |
|||
z-index: 1000; |
|||
background: white; |
|||
height: 4%; |
|||
width: 100%; |
|||
font-family: Courier; |
|||
font-weight: bold; |
|||
font-size: 2vw; |
|||
text-align: center; |
|||
align-items: center; |
|||
border: 1px #d152b8; |
|||
|
|||
} |
|||
|
|||
#bottom_menu a { |
|||
padding: 1vw 3vw 1vw 3vw; |
|||
color: #d152b8; |
|||
} |
|||
|
|||
/* Hide scrollbar for Chrome, Safari and Opera */ |
|||
#infotext, #infotext_en, #abouttext, #contacttext, #popuptext, #popuptext_en, #howtotext, #howtotext_en:-webkit-scrollbar { |
|||
display: none; |
|||
} |
|||
|
|||
/* Hide scrollbar for IE, Edge and Firefox */ |
|||
#infotext, #infotext_en, #abouttext, #contacttext, #howtotext, #howtotext_en, #popuptext, #popuptext_en { |
|||
-ms-overflow-style: none; /* IE and Edge */ |
|||
scrollbar-width: none; /* Firefox */ |
|||
} |
|||
|
|||
#infotext, #infotext_en, #abouttext, #contacttext, #howtotext, #howtotext_en, #popuptext, #popuptext_en { |
|||
|
|||
visibility: hidden; |
|||
opacity:0; |
|||
overflow-x: hidden !important; |
|||
overflow-y: scroll !important; |
|||
position: absolute; |
|||
z-index: 1000; |
|||
width: 80%; |
|||
height: 70%; |
|||
max-height: 100%; |
|||
max-width: 100%; |
|||
word-wrap: break-word; |
|||
background-color: #d152b8; |
|||
color: white; |
|||
margin: 14% 10% 10% 10%; |
|||
transition: opacity 1s; |
|||
|
|||
} |
|||
|
|||
#infotext p, #infotext_en p, #abouttext p, #howtotext p, #howtotext_en p { |
|||
padding: 0% 10% 10% 10%; |
|||
margin: 0; |
|||
font-family: Arial; |
|||
font-weight: bold; |
|||
font-size: 1.5vw; |
|||
color: white; |
|||
} |
|||
|
|||
#popuptext p, #popuptext_en p { |
|||
padding: 0% 10% 10% 10%; |
|||
margin: 0; |
|||
font-family: Arial; |
|||
font-weight: bold; |
|||
font-size: 2.5vw; |
|||
color: white; |
|||
} |
|||
|
|||
#infotext a, #infotext_en a, #abouttext a, #howtotext a, #howtotext_en a , #popuptext a, #popuptext_en a { |
|||
color: white; |
|||
} |
|||
|
|||
#howtotext a { |
|||
text-decoration: underline !important; |
|||
} |
|||
|
|||
#howto { |
|||
font-size: 2vw; |
|||
} |
|||
|
|||
#contacttext p { |
|||
padding: 0% 10% 10% 10%; |
|||
margin: 0; |
|||
font-family: Arial; |
|||
font-weight: bold; |
|||
font-size: 1.5vw; |
|||
color: white; |
|||
} |
|||
|
|||
#contacttext a, #contacttext span, , #howtotext span, #howtotext_en span { |
|||
color: white; |
|||
padding-left: 5vw; |
|||
font-size: 1.5vw; |
|||
} |
|||
|
|||
#abouttext p { |
|||
font-size: 1.5vw; |
|||
} |
|||
|
|||
#abouttext span { |
|||
font-size: 1.5vw; |
|||
} |
|||
|
|||
#infobuttons { |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
padding: 1vw; |
|||
} |
|||
|
|||
#closeButton { |
|||
height: min-content; |
|||
width: min-content; |
|||
font-family: Arial; |
|||
font-size:2vw; |
|||
font-weight:bold; |
|||
padding:1%; |
|||
cursor: pointer; |
|||
margin: 0; |
|||
} |
|||
|
|||
#enButton { |
|||
position: relative; |
|||
height: min-content; |
|||
width: min-content; |
|||
margin: 0; |
|||
font-family: Arial; |
|||
font-size:2vw; |
|||
font-weight:bold; |
|||
color: white; |
|||
padding:1%; |
|||
text-align: right; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
#closeButtonbottom { |
|||
position: relative; |
|||
font-family: Arial; |
|||
font-size: 2vw; |
|||
font-weight: bold; |
|||
text-align: center; |
|||
padding-bottom: 5vh; |
|||
margin: 0; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
/*client location*/ |
|||
.leaflet-control-locate a { |
|||
padding-top: 4px; |
|||
} |
|||
|
|||
.leaflet-control-locate a span { |
|||
font-size: 1.4em; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.leaflet-control-locate.active a { |
|||
color: #2A93EE; |
|||
} |
|||
.leaflet-control-locate.active.following a { |
|||
color: #2A93EE; |
|||
} |
|||
|
|||
|
|||
@media only screen and (max-width: 768px) { |
|||
|
|||
h1 { |
|||
font-size: 15vw; |
|||
} |
|||
|
|||
h2 { |
|||
padding-top: 10vh; |
|||
font-size: 5vw; |
|||
} |
|||
|
|||
h3 { |
|||
padding-top: 15vh; |
|||
font-size: 5vw; |
|||
} |
|||
|
|||
#howto { |
|||
font-size: 6vw; |
|||
} |
|||
|
|||
#infotext, #infotext_en, #abouttext, #contacttext, #howtotext, #howtotext_en { |
|||
visibility: hidden; |
|||
overflow-x: hidden !important; |
|||
overflow-y: scroll !important; |
|||
position: absolute; |
|||
z-index: 400; |
|||
width: 90%; |
|||
height: 73%; |
|||
max-height: 100%; |
|||
max-width: 100%; |
|||
word-wrap: break-word; |
|||
background-color: #d152b8; |
|||
color: white; |
|||
margin: 28% 5% 0% 5%; |
|||
} |
|||
|
|||
#abouttext span { |
|||
font-size: 4vw; |
|||
} |
|||
|
|||
#contacttext p { |
|||
font-size: 5vw; |
|||
} |
|||
|
|||
#contacttext a, #contacttext span, , #howtotext span, #howtotext_en span { |
|||
font-size: 4vw; |
|||
} |
|||
|
|||
#closeButton, #enButton { |
|||
font-family: Arial; |
|||
font-size:4vw; |
|||
font-weight:bold; |
|||
padding:3%; |
|||
} |
|||
|
|||
#closeButtonbottom { |
|||
font-size:4vw; |
|||
font-weight:bold; |
|||
} |
|||
|
|||
#infotext p, #infotext_en p, #abouttext p, #contacttext p, #howtotext p, #howtotext_en p { |
|||
padding: 20px; |
|||
font-family: Arial; |
|||
font-weight: bold; |
|||
font-size: 4vw; |
|||
margin: 0; |
|||
} |
|||
|
|||
#bottom_menu { |
|||
height: 5%; |
|||
font-size: 5vw; |
|||
} |
|||
} |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue