Кратък код, който можете да използвате, ако искате да пресметнете разстоянието между два 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 клауза, може да накараме базата ни да клекне, особено, ако държим голям набор локации. Препоръчвам в дългосрочен план резултатите да бъдат агрегирани в отделна денормализирана база или някакъв друг тип кеширане. (Макар, че в дългосрочен план може да има разминаване в някои точки по света, заради разместването на тектонските плочи на земята, но мисля, че грешката е достатъчно малка, че да можем да я игнорираме.:) ) (Ако се налага да бъдем изключително точни, можем да видим кои са точките по света засегнати от това движение, какъв е периода на преизчисление на координатите и да го заложим при периода за инвалидиране на кеша 🙂 )

Leave a Reply

Your email address will not be published. Required fields are marked *