Кратък код, който можете да използвате, ако искате да пресметнете разстоянието между два GPS координата с PHP. Предвид навлизането на мобилните устройсва и широкото распространение на PHP / MySQL рано или късно може да се наложи 🙂
function CalculateDistance($nLat1, $nLon1, $nLat2, $nLon2) { $nLongDiference = $nLon2-$nLon1; $nDistance = sin(deg2rad($nLat1)) * sin(deg2rad($nLat2)) + cos(deg2rad($nLat1)) * cos(deg2rad($nLat2)) * cos(deg2rad($nLongDiference)); $nDistance = acos($nDistance); $nDistance = rad2deg($nDistance); //$nDistance - distance in degrees //60 is number of the minutes in the degree //1.1515 is the number of miles in a nautical mile (nautical mile is the length of one minute of latitude at the equator) $nNauticalMiles = $nDistance * 60 * 1.1515; //1.609344 is number of kilometers in nautical mile $nKilometers = $nNauticalMiles * 1.609344; return $nKilometers; } echo CalculateDistance(42.701627, 23.324848, 42.602775, 23.027837) . " km";
Полезно също е и директното изпълнение в MySQL (в случай, че искате да намерите бързо локации спрямо радиус от точка директно в базата данни)
SELECT *, ((ACOS(SIN([LATUTUDE] * PI() / 180) * SIN(latitude * PI() / 180) + COS([LATUTUDE]> * PI() / 180) * COS(latitude * PI() / 180) * COS(([LONGITUDE]> - longitude) * PI() / 180)) * 180 / PI()) * 60 * 1.1515 * 1.609344) as distance FROM locations HAVING distance <= [DISTANCE] ORDER BY distance ASC
Като цяло не го препоръчвам за директно изпълнение, ако се очаква да бъде натоварено изпълнението, поради наличието на агрегирани данни и HAVING клауза, може да накараме базата ни да клекне, особено, ако държим голям набор локации. Препоръчвам в дългосрочен план резултатите да бъдат агрегирани в отделна денормализирана база или някакъв друг тип кеширане. (Макар, че в дългосрочен план може да има разминаване в някои точки по света, заради разместването на тектонските плочи на земята, но мисля, че грешката е достатъчно малка, че да можем да я игнорираме.:) ) (Ако се налага да бъдем изключително точни, можем да видим кои са точките по света засегнати от това движение, какъв е периода на преизчисление на координатите и да го заложим при периода за инвалидиране на кеша 🙂 )