198 lines
7.6 KiB
PHP
198 lines
7.6 KiB
PHP
|
<?php
|
||
|
session_start();
|
||
|
|
||
|
//AJAX query code
|
||
|
if(!empty($_POST['latitude']) && !empty($_POST['longitude']) && (!empty($_POST['available']) || !empty($_POST['free'])) && !empty($_POST['email']) && !empty($_POST['reverse_geolocation_provider']) && !empty($_POST['directions_provider']))
|
||
|
{
|
||
|
$updated_position = false;
|
||
|
$updated_stations = false;
|
||
|
|
||
|
//Define UserAgent etc
|
||
|
$opts = array(
|
||
|
'http'=>array(
|
||
|
'method'=>"GET",
|
||
|
'header'=>"Accept-language: fr\r\n" .
|
||
|
"Referer: ".$_SERVER['HTTP_REFERER'].
|
||
|
"User-Agent: Velib service at http://velib.phyks.me (contact : webmaster@phyks.me) \r\n"
|
||
|
)
|
||
|
);
|
||
|
$context = stream_context_create($opts);
|
||
|
|
||
|
//Check wether the position was updated
|
||
|
//-------------------------------------
|
||
|
|
||
|
//Convert latitude and longitude to degrees (useful for calculation)
|
||
|
$latitude = deg2rad((float) $_POST['latitude']);
|
||
|
$longitude = deg2rad((float) $_POST['longitude']);
|
||
|
|
||
|
$a = pow(sin($_SESSION['latitude'] - $latitude)/2, 2) + cos($latitude)*cos($_SESSION['latitude'])*pow(sin($_SESSION['longitude'] - $longitude)/2, 2);
|
||
|
$c = 2*atan2(sqrt($a),sqrt(1-$a));
|
||
|
$R = 6371000;
|
||
|
$distance = $R*$c;
|
||
|
|
||
|
if(empty($_SESSION['latitude']) || empty($_SESSION['longitude']) || empty($_SESSION['reverse_geolocation']) || $distance >= 25 || empty($_SESSION['distances']))
|
||
|
{
|
||
|
$_SESSION['latitude'] = $_POST['latitude'];
|
||
|
$_SESSION['longitude'] = $_POST['longitude'];
|
||
|
$updated_position = true;
|
||
|
}
|
||
|
|
||
|
//If yes, update the address
|
||
|
if($updated_position)
|
||
|
{
|
||
|
$reverse_geolocation_json = file_get_contents($_POST['reverse_geolocation_provider']."?format=json&lat=".$_POST['latitude']."&lon=".$_POST['longitude']."&zoom=18&addressdetails=1&email=".$_POST['email'], false, $context);
|
||
|
$reverse_geolocation_json = json_decode($reverse_geolocation_json, true);
|
||
|
|
||
|
$reverse_geolocation = '';
|
||
|
foreach($reverse_geolocation_json['address'] as $key=>$element)
|
||
|
{
|
||
|
if($key == 'city')
|
||
|
break;
|
||
|
|
||
|
if(!empty($reverse_geolocation))
|
||
|
$reverse_geolocation .= ", ";
|
||
|
|
||
|
$reverse_geolocation .= $element;
|
||
|
}
|
||
|
|
||
|
$_SESSION['reverse_geolocation'] = $reverse_geolocation;
|
||
|
}
|
||
|
else //Else, keep what was stored in session
|
||
|
{
|
||
|
$reverse_geolocation = $_SESSION['reverse_geolocation'];
|
||
|
}
|
||
|
|
||
|
if(is_file('data/data')) //And open the data file
|
||
|
{
|
||
|
$data = unserialize(gzinflate(base64_decode(file_get_contents('data/data'))));
|
||
|
$stations = $data[1];
|
||
|
}
|
||
|
else
|
||
|
exit("[{'error': '<p>La liste des stations n'a pu être récupérée. Essayez de la mettre à jour manuellement.</p>'}]");
|
||
|
|
||
|
|
||
|
if(!empty($_POST['station'])) //If we want information about a specific station
|
||
|
{
|
||
|
$stations_used[$_POST['station']] = $stations[$_POST['station']]; //We only use it - little trick to keep the same code
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$stations_used = $stations; //Else, we use all the stations
|
||
|
}
|
||
|
|
||
|
if($updated_position) //If position updated
|
||
|
{
|
||
|
unset($_SESSION['distances']);
|
||
|
|
||
|
//Compute the distance
|
||
|
foreach($stations_used as $key=>$station) //We start by sorting the stations by distance to me
|
||
|
{
|
||
|
$station_lat = deg2rad($station['lat']);
|
||
|
$station_lng = deg2rad($station['lng']);
|
||
|
|
||
|
$a = pow(sin($station_lat - $latitude)/2, 2) + cos($latitude)*cos($station_lat)*pow(sin($station_lng - $longitude)/2, 2);
|
||
|
$c = 2*atan2(sqrt($a),sqrt(1-$a));
|
||
|
$R = 6371000;
|
||
|
$distances[$key] = $R*$c;
|
||
|
}
|
||
|
asort($distances);
|
||
|
|
||
|
if(!empty($_POST['station'])) //But store the result only if not computed for a single station
|
||
|
$_SESSION['distances'] = array_slice($distances, 0, 10, true); //Store the 10 first values in session
|
||
|
}
|
||
|
else //Else, get the result stored
|
||
|
{
|
||
|
if(empty($_POST['station']))
|
||
|
$distances = $_SESSION['distances']; //If list required, get the currently stored list
|
||
|
else //Else, get the only one we want
|
||
|
$distances[(int) $_POST['station']] = $_SESSION['distances'][(int) $_POST['station']];
|
||
|
}
|
||
|
|
||
|
//Print the JSON
|
||
|
echo '[{"reverse_geolocation": "'.htmlentities($reverse_geolocation).'"}, ';
|
||
|
|
||
|
$i = 0;
|
||
|
foreach($distances as $key=>$distance) //Print the information about the 10 nearest stations
|
||
|
{
|
||
|
if($i >= 10)
|
||
|
break;
|
||
|
|
||
|
//Get number of velibs / parkings available
|
||
|
if($stations[$key]['updated'] < time() - 60) //If data is older than 1 minute, update it
|
||
|
{
|
||
|
//Mise à jour du tableau
|
||
|
$station_xml = simplexml_load_file('http://www.velib.paris.fr/service/stationdetails/paris/'.$stations[$key]['id']);
|
||
|
|
||
|
$stations[$key]['updated'] = time(); //Update the stations array
|
||
|
$stations[$key]['available'] = (int) $station_xml->available;
|
||
|
$stations[$key]['free'] = (int) $station_xml->free;
|
||
|
$stations[$key]['open'] = (int) $station_xml->open;
|
||
|
|
||
|
$updated_stations = true; //We updated the array (so we must update the data file)
|
||
|
}
|
||
|
|
||
|
$number = (!empty($_POST['free'])) ? $stations[$key]['free'] : $stations[$key]['available']; //Get the number of velibs / parkings ($stations is always up to date or acceptable)
|
||
|
|
||
|
if($number != 0 && $stations[$key]['open'] == 1) //If this station is interesting and opened
|
||
|
{
|
||
|
echo '{"key": "'.(int) $key.'", "dist": "'.(int) $distance.'", "bonus": "'.(int) $stations[$key]['bonus'].'", "lat": "'.(float) $stations[$key]['lat'].'", "lng": "'.(float) $stations[$key]['lng'].'", "nombre": "'.(int) $number.'", "nom": "'.substr($stations[$key]['name'], strpos($stations[$key]['name'], "-")+1).'"';
|
||
|
|
||
|
if(!empty($_POST['station'])) //If we only want content about this station, get the directions and the address
|
||
|
{
|
||
|
if($updated_position || empty($_SESSION['directions']) || $_SESSION['directions']['key'] != $_POST['station']) //Check wether position was updated, session var doesn't exist or routes isn't stored for this particular station
|
||
|
{
|
||
|
unset($_SESSION['directions']); //Destroy the previous variable
|
||
|
|
||
|
if(is_file('data/checksum')) //Checksum is required in OSRM Usage Policy
|
||
|
$checksum = '&checksum='.file_get_contents('data/checksum');
|
||
|
else
|
||
|
$checksum = '';
|
||
|
|
||
|
$directions_json = file_get_contents($_POST['directions_provider'].'?loc='.$_POST['latitude'].','.$_POST['longitude'].'&loc='.$stations[$key]['lat'].','.$stations[$key]['lng'].'&z=18&output=json&instructions=false&alt=false&geomformat=cmp'.$checksum, false, $context);
|
||
|
|
||
|
$directions_json = json_decode($directions_json, true);
|
||
|
|
||
|
if(!empty($directions_json['hint_data']['checksum']))
|
||
|
file_put_contents('data/checksum', $directions_json['hint_data']['checksum']);
|
||
|
|
||
|
$directions_encoded = json_encode($directions_json['route_geometry']);
|
||
|
|
||
|
if(!empty($directions_json['route_geometry']))
|
||
|
echo ', "directions": '.$directions_encoded;
|
||
|
else
|
||
|
echo ', "directions": ""';
|
||
|
|
||
|
//And then, set new ones
|
||
|
$_SESSION['directions']['key'] = (int) $_POST['station'];
|
||
|
$_SESSION['directions']['directions'] = $directions_encoded;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
echo ', "directions": '.$_SESSION['directions']['directions'];
|
||
|
}
|
||
|
|
||
|
//Get the address
|
||
|
echo ', "address": "'.substr($stations[$key]['address'], 0, strpos($stations[$key]['address'], " - 75")+1).'"';
|
||
|
}
|
||
|
|
||
|
//Print the JSON data
|
||
|
echo '}';
|
||
|
|
||
|
if($i != 9 && $i != count($distances) - 1) //Attention : distance can be less than 9 elements long (if we specify a station for example)
|
||
|
echo ', ';
|
||
|
|
||
|
$i++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
echo ']'; //And close the JSON array
|
||
|
|
||
|
//If needed, update the data file
|
||
|
if($updated_stations)
|
||
|
{
|
||
|
file_put_contents('data/data', base64_encode(gzdeflate(serialize(array($data[0], $stations)))));
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
exit("[{'error': '<p>La liste des stations n'a pu être récupérée. Essayez de la mettre à jour manuellement.</p>'}]");
|