Calculați sau interogați distanța cercului mare dintre punctele de latitudine și longitudine folosind formula Havesine (exemple PHP, JavaScript, Java, Python, MySQL, MSSQL)

Luna aceasta am programat PHP și MySQL pentru GIS. În timp ce cercetam subiectul, am avut dificultăți în a găsi calcule geografice pentru a găsi distanța dintre două locații, așa că am vrut să le împărtășesc aici.
Modul simplu de a calcula distanța dintre două puncte este utilizarea formulei pitagorice pentru a calcula ipotenuza unui triunghi (A² + B² = C²). Acest lucru este cunoscut sub numele de distanta euclidiana.
1 Pe măsură ce te apropii de ecuator, liniile de latitudine se depărtează tot mai mult. Dacă folosești o ecuație simplă de triangulație, aceasta poate măsura distanța cu precizie într-o locație și greșit în alta din cauza curburii Pământului.

Distanța cercului mare
Rutele parcurse pe distanțe lungi în jurul Pământului sunt cunoscute sub numele de Distanța Ortodromică. Adică... cea mai scurtă distanță dintre două puncte de pe o sferă diferă de cea de pe o hartă plană. Combinați acest lucru cu faptul că liniile de latitudine și longitudine nu sunt echidistante... și aveți un calcul dificil.
Iată o explicație video fantastică despre modul în care funcționează Cercurile mari.
Formula Haversine
Distanța folosind curbura Pământului este încorporată în formula Havesine, care folosește trigonometria pentru a permite curbura Pământului. O linie dreaptă este un arc atunci când găsiți distanța dintre 2 locuri de pe Pământ (în aer liber).
Acest lucru este aplicabil călătoriilor cu avionul. Te-ai uitat vreodată la harta actuală a zborurilor și ai observat că sunt arcuite? Asta pentru că zborul într-un arc între două puncte este mai scurt decât zborul direct către locație.
PHP: Calculați distanța dintre 2 puncte de latitudine și longitudine
Iată formula PHP pentru calcularea distanței dintre două puncte (împreună cu conversia milă vs. kilometru) rotunjită la două zecimale.
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));
} Variabilele sunt:
- $Latitude1 – o variabilă pentru latitudinea primei locații.
- $Longitudine1 – o variabilă pentru longitudinea primei locații
- $Latitude2 – o variabilă pentru latitudinea celei de-a doua locații.
- $Longitudine2 – o variabilă pentru longitudinea celei de-a doua locații.
- $unitate – implicit fiind mile. Acesta poate fi actualizat sau transmis ca kilometri.
Java: Calculați distanța dintre 2 puncte de latitudine și longitudine
public static double getDistanceBetweenPointsNew(double latitude1, double longitude1, double latitude2, double longitude2, String unit) {
double theta = longitude1 - longitude2;
double distance = 60 * 1.1515 * (180/Math.PI) * Math.acos(
Math.sin(latitude1 * (Math.PI/180)) * Math.sin(latitude2 * (Math.PI/180)) +
Math.cos(latitude1 * (Math.PI/180)) * Math.cos(latitude2 * (Math.PI/180)) * Math.cos(theta * (Math.PI/180))
);
if (unit.equals("miles")) {
return Math.round(distance, 2);
} else if (unit.equals("kilometers")) {
return Math.round(distance * 1.609344, 2);
} else {
return 0;
}
} Variabilele sunt:
- latitudinea 1 – o variabilă pentru latitudinea primei locații.
- longitudine1 – o variabilă pentru longitudinea primei locații
- latitudinea 2 – o variabilă pentru latitudinea celei de-a doua locații.
- longitudine2 – o variabilă pentru longitudinea celei de-a doua locații.
- unitate – implicit fiind mile. Acesta poate fi actualizat sau transmis ca kilometri.
JavaScript: Calculați distanța dintre 2 puncte de latitudine și longitudine
function getDistanceBetweenPoints(latitude1, longitude1, latitude2, longitude2, unit = 'miles') {
let theta = longitude1 - longitude2;
let distance = 60 * 1.1515 * (180/Math.PI) * Math.acos(
Math.sin(latitude1 * (Math.PI/180)) * Math.sin(latitude2 * (Math.PI/180)) +
Math.cos(latitude1 * (Math.PI/180)) * Math.cos(latitude2 * (Math.PI/180)) * Math.cos(theta * (Math.PI/180))
);
if (unit == 'miles') {
return Math.round(distance, 2);
} else if (unit == 'kilometers') {
return Math.round(distance * 1.609344, 2);
}
} Variabilele sunt:
- latitudinea 1 – o variabilă pentru latitudinea primei locații.
- longitudine1 – o variabilă pentru longitudinea primei locații
- latitudinea 2 – o variabilă pentru latitudinea celei de-a doua locații.
- longitudine2 – o variabilă pentru longitudinea celei de-a doua locații.
- unitate – implicit fiind mile. Acesta poate fi actualizat sau transmis ca kilometri.
Python: Calculați distanța dintre 2 puncte de latitudine și longitudine
Iată formula Python pentru calcularea distanței dintre două puncte (împreună cu conversia milă vs. kilometru) rotunjită la două zecimale. Merită fiului meu, Bill Karr, un Data Scientist pentru OpenINSIGHTS, pentru cod.
from numpy import sin, cos, arccos, pi, round
def rad2deg(radians):
degrees = radians * 180 / pi
return degrees
def deg2rad(degrees):
radians = degrees * pi / 180
return radians
def getDistanceBetweenPointsNew(latitude1, longitude1, latitude2, longitude2, unit = 'miles'):
theta = longitude1 - longitude2
distance = 60 * 1.1515 * rad2deg(
arccos(
(sin(deg2rad(latitude1)) * sin(deg2rad(latitude2))) +
(cos(deg2rad(latitude1)) * cos(deg2rad(latitude2)) * cos(deg2rad(theta)))
)
)
if unit == 'miles':
return round(distance, 2)
if unit == 'kilometers':
return round(distance * 1.609344, 2) Variabilele sunt:
- latitudinea 1 – o variabilă pentru prima locație latitudine.
- longitudine1 – o variabilă pentru prima locație longitudine
- latitudinea 2 – o variabilă pentru cea de-a doua locație latitudine.
- longitudine2 – o variabilă pentru cea de-a doua locație longitudine.
- unitate – implicit fiind mile. Acesta poate fi actualizat sau transmis ca kilometri.
MySQL: Preluarea tuturor înregistrărilor dintr-un interval prin calculul distanței în mile utilizând latitudinea și longitudinea
Utilizarea tipurilor de date spațiale în MySQL este o modalitate mai eficientă și mai convenabilă de a lucra cu date geografice, inclusiv calcularea distanțelor dintre puncte. MySQL acceptă tipuri de date spațiale, cum ar fi POINT, LINESTRING și POLYGON, împreună cu funcții spațiale precum ST_Distance.
Când utilizați ST_Distance funcția în MySQL cu date geografice reprezentate ca POINT coordonate, ia în considerare curbura suprafeței Pământului. Modelul sferic folosit de ST_Distance folosește formula Haversine. Această aproximare este potrivită pentru majoritatea scopurilor practice, dar poate introduce ușoare inexactități pentru distanțe lungi.
Iată cum puteți calcula distanțele dintre două puncte utilizând tipurile de date spațiale:
- Creați un tabel cu tip de date spațiale: Mai întâi, creați un tabel cu a
POINTcoloană pentru stocarea punctelor geografice. De exemplu:
CREATE TABLE locations (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
coordinates POINT
); Introduceți punctele dvs. geografice în acest tabel folosind POINT constructor:
INSERT INTO locations (name, coordinates)
VALUES
('Point A', POINT(40.7128, -74.0060)), -- New York City
('Point B', POINT(34.0522, -118.2437)); -- Los Angeles - Calculați distanța folosind ST_Distance: Puteți calcula distanța dintre două puncte folosind
ST_Distancefuncţie. Iată un exemplu de interogare pentru a calcula distanța dintre două puncte:
SELECT
id1,
id2,
(ST_Distance(coordinates1, coordinates2) / 1609.344) AS distance_in_miles
FROM (
SELECT
l1.id AS id1,
l2.id AS id2,
l1.coordinates AS coordinates1,
l2.coordinates AS coordinates2
FROM
locations l1,
locations l2
WHERE
l1.id = 1 AND l2.id = 2
) AS distances; Înlocui 1 și 2 cu ID-urile celor două puncte dintre care doriți să calculați distanța.
- Rezultat: Interogarea va returna distanța dintre cele două puncte în mile.
Utilizarea tipurilor de date spațiale și ST_Distance funcția oferă o modalitate mai eficientă și mai precisă de a lucra cu datele geografice în MySQL. De asemenea, simplifică calcularea distanțelor dintre puncte, facilitând gestionarea și interogarea datelor.
MySQL: Preluarea tuturor înregistrărilor dintr-un interval prin calculul distanței în kilometri folosind latitudinea și longitudinea
În mod implicit ST_Distance returnează distanța în metri, așa că trebuie pur și simplu să actualizați interogarea pentru kilometri:
SELECT
id1,
id2,
(ST_Distance(coordinates1, coordinates2) / 1000) AS distance_in_kilometers
FROM (
SELECT
l1.id AS id1,
l2.id AS id2,
l1.coordinates AS coordinates1,
l2.coordinates AS coordinates2
FROM
locations l1,
locations l2
WHERE
l1.id = 1 AND l2.id = 2
) AS distances; Distanța geografică Microsoft SQL Server: STDistance
Dacă utilizați Microsoft SQL Server, acestea oferă o funcție numită STDistanța pentru calcularea distanței dintre două puncte folosind tipul de date Geography.
DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656)', 4326);
SET @h = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326);
SELECT @g.STDistance(@h); Sfat de pălărie pentru Manash Sahoo, fondator și arhitect senior la Ion Trei.