PHP i SQL: calcular o consultar la gran distància del cercle entre els punts de latitud i longitud amb la fórmula Haversine

Fórmula Haversine: calcula la gran distància del cercle amb PHP o MySQL

Aquest mes he estat programant força en PHP i MySQL pel que fa als SIG. Buscant per la xarxa, en realitat em va costar trobar alguns dels Càlculs geogràfics per trobar la distància entre dues ubicacions, així que volia compartir-les aquí.

Mapa de vol Europa amb gran distància de cercle

La forma senzilla de calcular la distància entre dos punts és utilitzar la fórmula pitagòrica per calcular la hipotenusa d’un triangle (A² + B² = C²). Això es coneix com el Distància euclidiana.

Aquest és un començament interessant, però no s’aplica a Geografia ja que la distància entre les línies de latitud i longitud és ni una distància igual a part. A mesura que s’acosta a l’equador, les línies de latitud s’allunyen. Si utilitzeu algun tipus d’equació de triangulació simple, pot mesurar la distància amb precisió en un lloc i terriblement equivocada a l’altra, a causa de la curvatura de la Terra.

Distància Gran Cercle

Les rutes que es recorren a llargues distàncies al voltant de la Terra es coneixen com a Distància Gran Cercle. És a dir ... la distància més curta entre dos punts d'una esfera és diferent als punts d'un mapa pla. Combineu això amb el fet que les línies de latitud i longitud no són equidistants ... i teniu un càlcul difícil.

Aquí teniu una fantàstica explicació en vídeo de com funcionen els grans cercles.

La Fórmula Haversine

La distància que utilitza la curvatura de la Terra s'incorpora a la Fórmula Haversine, que utilitza la trigonometria per permetre la curvatura de la terra. Quan trobeu la distància entre dos llocs de la terra (en línia recta), la línia recta és realment un arc.

Això és aplicable al vol aeri: alguna vegada heu mirat el mapa real dels vols i heu observat que estan arquejats? Això és perquè és més curt volar en un arc entre dos punts que directament a la ubicació.

PHP: Calculeu la distància entre 2 punts de latitud i longitud

De totes maneres, aquí teniu la fórmula PHP per calcular la distància entre dos punts (juntament amb la conversió Milles vs. Kilòmetres) arrodonides a dos decimals.

function getDistanceBetweenPointsNew($latitude1, $longitude1, $latitude2, $longitude2, $unit = 'miles') {
  $theta = $longitude1 - $longitude2; 
  $distance = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))) + (cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * cos(deg2rad($theta))); 
  $distance = acos($distance); 
  $distance = rad2deg($distance); 
  $distance = $distance * 60 * 1.1515; 
  switch($unit) { 
    case 'miles': 
      break; 
    case 'kilometers' : 
      $distance = $distance * 1.609344; 
  } 
  return (round($distance,2)); 
}

SQL: Recuperació de tots els registres dins d'un rang mitjançant el càlcul de la distància en quilòmetres mitjançant latitud i longitud

També és possible utilitzar SQL per fer un càlcul per trobar tots els registres a una distància específica. En aquest exemple, vaig a consultar MyTable a MySQL per trobar tots els registres que siguin inferiors o iguals a la distància variable $ (en milles) de la meva ubicació a $ latitud i $ longitud:

La consulta per recuperar tots els registres d'un determinat document distància calculant la distància en milles entre dos punts de latitud i longitud són:

$query = "SELECT *, (((acos(sin((".$latitude."*pi()/180)) * sin((`latitude`*pi()/180)) + cos((".$latitude."*pi()/180)) * cos((`latitude`*pi()/180)) * cos(((".$longitude."- `longitude`)*pi()/180)))) * 180/pi()) * 60 * 1.1515) as distance FROM `table` WHERE distance <= ".$distance."

Haureu de personalitzar això:

  • $ longitud - Aquesta és una variable PHP on estic passant la longitud del punt.
  • $ latitud - Aquesta és una variable PHP on estic passant la longitud del punt.
  • $ distància - aquesta és la distància a la qual voldríeu trobar tots els registres menys o iguals.
  • taula - aquesta és la taula ... voldreu substituir-la pel nom de la vostra taula.
  • latitud - aquest és el camp de la vostra latitud.
  • longitud - aquest és el camp de la vostra longitud.

SQL: Recuperació de tots els registres dins d'un rang mitjançant el càlcul de la distància en quilòmetres mitjançant latitud i longitud

I aquí teniu la consulta SQL que utilitza quilòmetres a MySQL:

$query = "SELECT *, (((acos(sin((".$latitude."*pi()/180)) * sin((`latitude`*pi()/180)) + cos((".$latitude."*pi()/180)) * cos((`latitude`*pi()/180)) * cos(((".$longitude."- `longitude`) * pi()/180)))) * 180/pi()) * 60 * 1.1515 * 1.609344) as distance FROM `table` WHERE distance <= ".$distance."

Haureu de personalitzar això:

  • $ longitud - Aquesta és una variable PHP on estic passant la longitud del punt.
  • $ latitud - Aquesta és una variable PHP on estic passant la longitud del punt.
  • $ distància - aquesta és la distància a la qual voldríeu trobar tots els registres menys o iguals.
  • taula - aquesta és la taula ... voldreu substituir-la pel nom de la vostra taula.
  • latitud - aquest és el camp de la vostra latitud.
  • longitud - aquest és el camp de la vostra longitud.

He utilitzat aquest codi en una plataforma de mapes empresarials que hem utilitzat per a una botiga minorista amb més de 1,000 ubicacions a tota Amèrica del Nord i ha funcionat molt bé.