I am fetching data from a MySQL database using AJAX/jQuery and then doing some calculations (distance between co-ordinates) on client-side. I found that this is quite taxing on the browser and would like to rather do this on the server-side.
My returned JSON data looks like this:
{
"result": [
["148", "osmand", "2", "2016-03-26 13:48:04", "2016-03-26 13:48:01", "2016-03-26 13:48:01", "1", "-39.094856", "46.166472", "1432.7", "0", "0", "20 Maretha street", "{\"battery\":\"0\",\"ip\":\"105.5.117.20\"}"],
["149", "osmand", "2", "2016-03-26 13:48:24", "2016-03-26 13:48:22", "2016-03-26 13:48:22", "1", "-39.099305", "46.162392", "1435.26", "0", "0", "7 Ernst street", "{\"battery\":\"0\",\"ip\":\"105.5.117.20\"}"],
["150", "osmand", "2", "2016-03-26 13:48:45", "2016-03-26 13:48:43", "2016-03-26 13:48:43", "1", "-39.099305", "46.162392", "1435.62", "0", "0", "7 Ernst street", "{\"battery\":\"0\",\"ip\":\"105.5.117.20\"}"],
],
"errors": false
}
The seventh and eighth values are the co-ordinates. I am currently calculating the distance by plotting the co-ordinates and then drawing a polyline and then calculating the distance of the polyline in leaflet.
I however found some sample PHP code that calculates distance between two points:
class test {
public function GetDistance($lat1, $lng1, $lat2, $lng2) {
$radLat1 = $lat1*3.1415926535898/180.0;
$radLat2 = $lat2*3.1415926535898/180.0;
$a = $radLat1 - $radLat2;
$b = ($lng1*3.1415926535898/180.0) - ($lng2*3.1415926535898/180.0);
$s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
$s = $s * 6378.137; // EARTH_RADIUS;
$s = round($s * 1000,3);
return $s;
}
}
usage example
$obj=new test();
$dis=$obj->GetDistance($lat1,$lon1,$lat2,$lon2);
My PHP code currently looks like this:
<?php
$inputvalues = $_POST;
$errors = false;
$result = false;
include_once 'database.php';
if (mysqli_connect_errno()) {
printf("Connect failed: %s
", mysqli_connect_error());
exit();
}
foreach ($inputvalues as $key => $value) {
if(isset($value) && !empty($value)) {
$inputvalues[$key] = $mysqli->real_escape_string( $value );
} else {
$errors[$key] = 'The field '.$key.' is empty';
}
}
if( !$errors ) {
$addresult = "
SELECT * FROM positions WHERE `fixtime` BETWEEN '" . $inputvalues['start'] . "' AND '" . $inputvalues['end'] . "' AND deviceid='" . $inputvalues['deviceid'] . "'
";
if( $result = $mysqli->query($addresult) ) {
while($row = $result->fetch_all())
{
$returnResult = $row;
}
}
}
mysqli_close($mysqli);
echo json_encode(['result' => $returnResult, 'errors' => $errors]);
exit;
?>
How can I implement this into my code? I don't know how to get the co-ordinates from the mysql result, do the calculation for each co-ordinate and then output it via JSON.
Sorry if this is a basic or broad question, I am very new to PHP and i'm still learning.
This is my function which save results in intermediate files. I am not sure if it will work for you but could be helpful. Update MY_KEY and mode for use.
function get_distance($locations, $locs){
$location_distance = array();
foreach($locations as $location_key=>$location){
$locs_keys = array_keys($locs);
$loc_lat_lng = "$location[1],$location[2]";
$locs_lat_lng = join('|',$locs_keys);
$path = './'.$location_key;
if(!file_exists($path)){
$path = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=$loc_lat_lng&destinations=$locs_lat_lng&mode=walking&key=MY_KEY";
}
$map_data = file_get_contents($path);
if($path != './'.$location_key){
file_put_contents('./'.$location_key, $map_data);
}
$map_data = json_decode($map_data, true);
$distance = reslove_distance($map_data);
for($i = 0 ; $i < count($distance); $i++){
$location_distance[$location_key][$locs_keys[$i]] = $distance[$i];
}
}
return $location_distance;
}
function reslove_distance($map_data=null){
$distance = array();
foreach($map_data['rows'][0]['elements'] as $element){
$distance[] = (int)$element['distance']['value'];
}
return $distance;
}
Maybe something like this:
function getDistance($lat1, $lng1, $lat2, $lng2, $distance_unit = 'km')
{
$multiplicator = ($distance_unit == 'km' ? 6371 : 3959);
$lat1_rad = deg2rad($lat1);
$lng1_rad = deg2rad($lng1);
$lat2_rad = deg2rad($lat2);
$lng2_rad = deg2rad($lng2);
return $multiplicator * acos(cos($lat1_rad) * cos($lat2_rad) * cos($lng2 - $lng1) + sin($lat1_rad) * sin($lat2));
}
And then when you're fetching the results from database:
$entries = $result->fetch_all();
foreach ($entries as $index => &$entry) {
if ($index < count($entries)) {
$next = $entries[$index + 1];
$entry['distance'] = self::getDistance($entry['latitude'], $entry['longitude'], $next['latitude'], $next['longitude']);
} else {
$entry['distance'] = 0; // there is no "next" point to calculate the distance.
}
}
This should give you an array where each entry contains the distance to the next point