Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculating Great-Circle Distance with SQLite

Here is my problem, I have a SQLite table with locations and latitudes / longitudes. Basically I need to:

SELECT location, HAVERSINE(lat, lon) AS distance FROM location ORDER BY distance ASC;

HAVERSINE() is a PHP function that should return the Great-Circle Distance (in miles or km) given a pair of latitude and longitude values. One of these pairs should be provided by PHP and the other pair should be provided by each latitude / longitude row available in the locations table.

Since SQLite doesn't has any Geo Spatial extension (AFAIK SpatiaLite exists but still...) I'm guessing the best approach would be to use a custom function with either one of the PDO methods:

  • PDO::sqliteCreateFunction()
  • PDO::sqliteCreateAggregate()

I think for this case PDO::sqliteCreateFunction() would be enough, however my limited experience with this function can be reduced to usage cases similar to the one provided in the PHP Manual:

$db = new PDO('sqlite:geo.db');

function md5_and_reverse($string) { return strrev(md5($string)); }

$db->sqliteCreateFunction('md5rev', 'md5_and_reverse', 1);
$rows = $db->query('SELECT md5rev(filename) FROM files')->fetchAll();

I'm having some trouble figuring out how can I get an SQLite user defined function to process data from PHP and table data at the same time and I would appreciate if someone could help me solve this problem while also understanding SQLite UDFs (a big win of SQLite IMO) a little bit better.

Thanks in advance!

like image 413
Alix Axel Avatar asked Jan 17 '10 23:01

Alix Axel


People also ask

How do you calculate great circle distance?

The great circle formula is given by: d = rcos-1[cos a cos b cos(x-y) + sin a sin b]. Given: r = 4.7 km or 4700 m, a, b= 45°, 32° and x, y = 24°,17°.

How do you calculate distance using latitude?

If you treat the Earth as a sphere with a circumference of 25,000 miles, then one degree of latitude is 25,000/360 = 69.44 miles. A minute is thus 69.44/60 = 1.157 miles, and a second is 1.15/60 = 0.0193 miles, or about 101 feet.

How can I find the distance between two points in MySQL?

Heres is MySQL query and function which use to get distance between two latitude and longitude and distance will return in KM. SELECT getDistance($lat1,$lng1,$lat2,$lng2) as distance FROM your_table. Almost a decade later, this function gives THE SAME results as Google Maps distance measurement. Thank you!

How can I find the distance between two points using latitude and longitude in php?

php function distance($lat1, $lon1, $lat2, $lon2, $unit) { if (($lat1 == $lat2) && ($lon1 == $lon2)) { return 0; } else { $theta = $lon1 - $lon2; $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)); $dist = acos($dist); $dist = rad2deg($dist); $miles = $ ...


1 Answers

So far I could only think of this solution:

$db = new PDO('sqlite:geo.db');

$db->sqliteCreateFunction('ACOS', 'acos', 1);
$db->sqliteCreateFunction('COS', 'cos', 1);
$db->sqliteCreateFunction('RADIANS', 'deg2rad', 1);
$db->sqliteCreateFunction('SIN', 'sin', 1);

And then execute the following lengthy query:

SELECT "location",
       (6371 * ACOS(COS(RADIANS($latitude)) * COS(RADIANS("latitude")) * COS(RADIANS("longitude") - RADIANS($longitude)) + SIN(RADIANS($latitude)) * SIN(RADIANS("latitude")))) AS "distance"
FROM "locations"
HAVING "distance" < $distance
ORDER BY "distance" ASC
LIMIT 10;

If anyone can think of a better solution please let me know.


I just found this interesting link, I'll try it tomorrow.

like image 200
Alix Axel Avatar answered Sep 20 '22 11:09

Alix Axel