Haversine Formula with PHP

Haversine formula with php

The formula you used, seems to be the arccosine instead of the haversine formula. The haversine formula is indeed more appropriate to calculate the distance on a sphere, because it is less prone to rounding errors.

/**
* Calculates the great-circle distance between two points, with
* the Haversine formula.
* @param float $latitudeFrom Latitude of start point in [deg decimal]
* @param float $longitudeFrom Longitude of start point in [deg decimal]
* @param float $latitudeTo Latitude of target point in [deg decimal]
* @param float $longitudeTo Longitude of target point in [deg decimal]
* @param float $earthRadius Mean earth radius in [m]
* @return float Distance between points in [m] (same as earthRadius)
*/
function haversineGreatCircleDistance(
$latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthRadius = 6371000)
{
// convert from degrees to radians
$latFrom = deg2rad($latitudeFrom);
$lonFrom = deg2rad($longitudeFrom);
$latTo = deg2rad($latitudeTo);
$lonTo = deg2rad($longitudeTo);

$latDelta = $latTo - $latFrom;
$lonDelta = $lonTo - $lonFrom;

$angle = 2 * asin(sqrt(pow(sin($latDelta / 2), 2) +
cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2)));
return $angle * $earthRadius;
}

P.S. I couldn't find an error in your code, so is it just a typo that you wrote $lat= 41.9133741000 $lat= 12.5203944000 ? Maybe you just calculated with $lat=12.5203944000 and $long=0 because you overwrote your $lat variable.

Edit:

Tested the code and it returned a correct result:

$center_lat = 41.8350;
$center_lng = 12.470;
$lat = 41.9133741000;
$lng = 12.5203944000;

// test with your arccosine formula
$distance =( 6371 * acos((cos(deg2rad($center_lat)) ) * (cos(deg2rad($lat))) * (cos(deg2rad($lng) - deg2rad($center_lng)) )+ ((sin(deg2rad($center_lat))) * (sin(deg2rad($lat))))) );
print($distance); // prints 9.662174538188

// test with my haversine formula
$distance = haversineGreatCircleDistance($center_lat, $center_lng, $lat, $lng, 6371);
print($distance); // prints 9.6621745381693

MySQL Great Circle Distance (Haversine formula)

From Google Code FAQ - Creating a Store Locator with PHP, MySQL & Google Maps:

Here's the SQL statement that will find the closest 20 locations that are within a radius of 25 miles to the 37, -122 coordinate. It calculates the distance based on the latitude/longitude of that row and the target latitude/longitude, and then asks for only rows where the distance value is less than 25, orders the whole query by distance, and limits it to 20 results. To search by kilometers instead of miles, replace 3959 with 6371.

SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) 
* cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin(radians(lat)) ) ) AS distance
FROM markers
HAVING distance < 25
ORDER BY distance
LIMIT 0 , 20;

PHP: Haversine formula gives HUGE (incorrect) distances

function haversineGreatCircleDistance(
$latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthMeanRadius = 6371)
{
$deltaLatitude = deg2rad($latitudeTo - $latitudeFrom);
$deltaLongitude = deg2rad($longitudeTo - $longitudeFrom);
$a = sin($deltaLatitude / 2) * sin($deltaLatitude / 2) +
cos(deg2rad($latitudeFrom)) * cos(deg2rad($latitudeTo)) *
sin($deltaLongitude / 2) * sin($deltaLongitude / 2);
$c = 2 * atan2(sqrt($a), sqrt(1-$a));
return $earthMeanRadius * $c;
}

A value of 6371 for the $earthMeanRadius argument (which is the default) is the earth mean radius in kilometres, which means that the returned result will be in kilometres.... if you want miles instead, then call it with an $earthMeanRadius argument value of 3,958; if you want nautical miles, change it to 3440, etc.

Using Haversine Formula to workout the distance between two postcodes in PHP

You can request it with the google service :

    function getLongLat($address) {
$url = 'http://maps.googleapis.com/maps/api/geocode/xml?sensor=false&language=nl&address='+$address;

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
curl_close($ch);
$obj = simplexml_load_string($response);
if ($obj) {
$obj = $obj->result;
return array( 'latitude' => $obj->geometry->location->lat.'', 'longitude' => $obj->geometry->location->lng.'',);
}else{
return [];
}

}

Google will try and parse the address for you, guessing postal code, Country should work for you as an address and than you can pass the required data to your MySQL function

haversine formula php / mysql

not sure but :

$R = 6371; // radius of Earth in KM

$lat = '46.98025235521883'; // lat of center point
$lon = '-110.390625'; // longitude of center point
$distance = 1000; // radius in KM of the circle drawn
$rad = $distance / $R; // angular radius for query
$query = '';

// rough cut to exclude results that aren't close
$radR = rad2deg($rad/$R);
$max_lat = $lat + radR;
$min_lat = $lat - radR;
$radR = rad2deg($rad/$R/cos(deg2rad($lat)));
$max_lon = $lon + radR;
$min_lon = $lon - radR;
// this part works just fine!
$query .= '(latitude > ' . $min_lat . ' AND latitude < ' . $max_lat . ')';
$query .= ' AND (longitude > ' . $min_lon . ' AND longitude < ' . $max_lon . ')';
// refining query -- this part returns no results
$query .= ' AND acos(sin('.deg2rad($lat).') * sin(radians(latitude)) + cos('.deg2rad($lat).') * cos(radians(latitude)) *
cos(radians(longitude) - ('.deg2rad($lon).'))) <= '.$rad;

passing variable to Haversine formula

I'm making the assumption here, that you have changed the column names from lat, lng to latitude, longitude in your table definition.

And under the lack of the actual error message, this is the best guess:

SELECT
town,
(
3959 * acos(
cos(
radians($latitude)
) * cos(
radians(latitude)
) * cos(
radians(longitude) - radians($longitude)
) + sin(
radians($latitude)
) * sin(
radians(latitude)
)
)
) AS distance
FROM
uk_postcode_05
HAVING
distance < 25
ORDER BY
distance ASC
LIMIT
0, 5

this should fix the issue, since in your query lat and lng where undefined.



Related Topics



Leave a reply



Submit