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 în 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.
Acesta este un început interesant, dar nu se aplică geografiei, deoarece distanța dintre liniile de latitudine și longitudine sunt distanțe nu egale între ele. Pe măsură ce te apropii de ecuator, liniile de latitudine se depărtează mai mult. Dacă utilizați o ecuație simplă de triangulație, poate măsura distanța cu precizie într-o locație și greșită în cealaltă 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 Marelui Cerc. Adică... cea mai scurtă distanță dintre două puncte de pe o sferă diferă de punctele de pe o hartă plată. Combină asta cu faptul că liniile de latitudine și longitudine nu sunt echidistante... și ai 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. Când găsești distanța dintre 2 locuri de pe Pământ (în aer liber), o linie dreaptă este de fapt un arc.
Acest lucru este aplicabil în zborurile aeriene – v-ați uitat vreodată la harta reală a zborurilor și ați observat că sunt arcuite? Asta pentru că zborul într-un arc între două puncte este mai scurt decât 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, ține cont de curbura suprafeței Pământului. Modelul sferic folosit de ST_Distance
folosește formula Havesine. Această aproximare este potrivită pentru majoritatea scopurilor practice, dar poate introduce ușoare inexactități pentru distanțe foarte mari.
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
POINT
coloană 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_Distance
funcţ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ă propria lor funcție, 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.