222 lines
9.3 KiB
PHP
222 lines
9.3 KiB
PHP
<?php
|
|
// Notes
|
|
// The api key from Scooty's app/account: iPtAHWdOVLEtgkaymXoMHVVg
|
|
// Below is the static html to generate the map, it can also be done more dynamically using https://github.com/LuminFire/leaflet-php but that might be overkill
|
|
|
|
|
|
// array of scooters, artist, title, description
|
|
global $scooters;
|
|
|
|
$scooters = array(
|
|
array('https://opencoil.show/test-json.php?scooterID=1', 'artist name 0', 'title 0', 'desciption 0' ),
|
|
array('https://opencoil.show/test-json.php?scooterID=2', 'artist name 1', 'title 1', 'desciption 1' ),
|
|
array('https://opencoil.show/test-json.php?scooterID=3', 'artist name 2', 'title 2', 'desciption 2' ),
|
|
//array('https://platform.tier-services.io/v1/vehicle/fbd739d6-554f-4eaf-bd9c-afe3d501c94b', 'artist name 1', 'title', 'desciption'),
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// for each scooter in array get the json (TODO, for each, safe to file/database?) $scooters is a multidimensional array: $scooter[0][0] = the first data (api url) of the first scooter, $scooter[1][0] = the first data (api url) of the second scooter, $scooter[0][1] = the artist name of the first scooter etcetc.
|
|
|
|
$id = 0; //get the first scooter for now
|
|
|
|
|
|
|
|
|
|
function makeMarker(int $id){
|
|
global $scooters; //"import" the global variable into the function's scope
|
|
$getJSON = callAPI($scooters[$id][0]); //abstract callAPI for neater reuse
|
|
$arr = json_decode($getJSON, true); // decode JSON data to PHP associative array
|
|
// access values from the associative array
|
|
$lat = $arr["data"]["attributes"]["lat"]; // get lattitude
|
|
$lng = $arr["data"]["attributes"]["lng"]; // get longitude
|
|
$pos = $lat.', '.$lng; // construct lat/lon for use in leafet
|
|
$lst = $arr["data"]["attributes"]["lastLocationUpdate"]; // get time of last position
|
|
$rnt = $arr["data"]["attributes"]["isRentable"]; // check if scooter is rentable,
|
|
$act = $arr["data"]["attributes"]["state"]; // check if scooter is ACTIVE or MAINTAINANCE
|
|
// access values from the multidimensional $scooters array
|
|
$nam = $scooters[$id][1]; // get the artist name
|
|
$tit = $scooters[$id][2]; // get the works title
|
|
$des = $scooters[$id][3]; // get the works description
|
|
|
|
//check scooter status and construct marker with corresponding icon
|
|
|
|
//check if scooter is rentable
|
|
if($rnt == true && $act === 'ACTIVE'){
|
|
$marker = 'var scooter'.$id.' = L.marker(['.$pos.'], {time: "'.$lst.'"}).addTo(map)
|
|
.bindPopup("<b>'.$tit.'</b><br>'.$des.'<br>Last updated: '.$lst.'<br>Status: Rentable, Gallery Offline")
|
|
.bindTooltip("'.$nam.'").setIcon(availableIcon);';
|
|
|
|
} elseif ($rnt == false && $act === 'ACTIVE') {
|
|
$marker = 'var scooter'.$id.' = L.marker(['.$pos.'], {time: "'.$lst.'"}).addTo(map)
|
|
.bindPopup("<b>'.$tit.'</b><br>'.$des.'<br>Last updated: '.$lst.'<br>Status: Rented Out, Gallery Online")
|
|
.bindTooltip("'.$nam.'").setIcon(isRentedIcon);';
|
|
|
|
};
|
|
//check if scooter is in maintenace
|
|
if($act !== "ACTIVE"){
|
|
$marker = 'var scooter'.$id.' = L.marker(['.$pos.'], {time: "'.$lst.'"}).addTo(map)
|
|
.bindPopup("<b>'.$tit.'</b><br>'.$des.'<br>Last updated: '.$lst.'")
|
|
.bindTooltip("'.$nam.'").setIcon(isMaintenanceIcon);';
|
|
};
|
|
|
|
return $marker;
|
|
}
|
|
|
|
|
|
//// make date time file------
|
|
|
|
|
|
|
|
// TODO save json to file?...mmm one big one? seperate ones, timestamped ones?
|
|
// 60 second update interval
|
|
|
|
// make timestamp file like original python one! to check for updates
|
|
// make new custom json:
|
|
// scooter 1/marker time1 { lat long }
|
|
// time2 { lat long }
|
|
// scooter 2/marker time1 { lat long }
|
|
// time2 { lat long }
|
|
//
|
|
//
|
|
|
|
|
|
// for each
|
|
// check if lastlocation is different...if update > latest file (map file..)
|
|
// check if is rentable
|
|
|
|
// TODO make two files
|
|
// 1: current position and state of scooter, latlong, id, status
|
|
// 2: historical json file, contains all scooters, updated everytime php file is loaded (or every 60 sec). No state changes, only lat long and time. even if time does not change
|
|
|
|
|
|
|
|
// Custom functions
|
|
|
|
function checkModified($file, $expiration){ //check if file is older than expiration time
|
|
|
|
}
|
|
|
|
function parseJSON(){
|
|
|
|
}
|
|
|
|
function callAPI($url){
|
|
$curl = curl_init($url);
|
|
curl_setopt($curl, CURLOPT_FAILONERROR, true);
|
|
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
|
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
|
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
|
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
|
|
'x-api-key: bpEUTJEBTf74oGRWxaIcW7aeZMzDDODe1yBoSxi2',
|
|
'Content-Type: application/json',
|
|
)); // set the api key
|
|
curl_setopt($curl, CURLOPT_USERAGENT,'ProductionRelease/3.8.2 (app.tier.sharing; build:3.8.2.0; iOS 12.4.4) Alamofire/4.9.1'); // set user-agent to that of the Tier.app, sniffed by burpsuite
|
|
|
|
$result = curl_exec($curl);
|
|
if(!$result){die("Connection Failure");}
|
|
curl_close($curl);
|
|
return $result;
|
|
}
|
|
|
|
|
|
?>
|
|
|
|
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
|
|
|
<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"/>
|
|
|
|
<!-- begin timeslider -->
|
|
|
|
<script src="SliderControl.js"></script>
|
|
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
|
|
<link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css"/>
|
|
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.2/jquery.ui.touch-punch.min.js"></script>
|
|
<!-- end of timeslider -->
|
|
<style>
|
|
#map {
|
|
height: 500px
|
|
}
|
|
</style>
|
|
<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 isMaintenanceIcon = L.AwesomeMarkers.icon(
|
|
{"icon": "wrench", "iconColor": "white", "markerColor": "black", "prefix": "fa"}
|
|
);
|
|
|
|
|
|
var map = L.map('map').setView([52.516190, 13.377693], 13);
|
|
|
|
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);
|
|
|
|
|
|
//for each scooter in $scooters array, request status and construct marker
|
|
<?php
|
|
$id = 0; //start id
|
|
foreach($scooters as $item) {
|
|
|
|
echo makeMarker($id);
|
|
|
|
$id++;
|
|
}
|
|
?>
|
|
|
|
// time slider
|
|
|
|
//test markers
|
|
//var marker1 = L.marker([52.504926, 13.358061], {time: "2020-10-09T08:00:29Z"});
|
|
//var marker2 = L.marker([52.506926, 13.358061], {time: "2020-10-09T09:00:29Z"});
|
|
//var marker3 = L.marker([52.508926, 13.358061], {time: "2020-10-09T10:00:29Z"});
|
|
|
|
// var map = marker1;
|
|
// layerGroup = L.layerGroup([marker_e7a96a6d6b08479ba6d17d42769e5202]);
|
|
layerGroup = L.layerGroup([scooter0, scooter1, scooter2]); //make this dynamic
|
|
var sliderControl = L.control.sliderControl({layer:layerGroup});
|
|
map.addControl(sliderControl);
|
|
sliderControl.startSlider();
|
|
</script>
|
|
</body>
|
|
</html>
|
|
|