Izračunajte ali poizvedite razdaljo velikega kroga med točkama zemljepisne širine in dolžine z uporabo formule Haversine (primeri PHP, JavaScript, Java, Python, MySQL, MSSQL)
Ta mesec sem programiral v PHP in MySQL za GIS. Med raziskovanjem teme sem imel težave pri iskanju geografski izračuni najti razdaljo med dvema lokacijama, zato sem jih želel deliti tukaj.
Preprost način izračuna razdalje med dvema točkama je uporaba pitagorejske formule za izračun hipotenuze trikotnika (A² + B² = C²). To je znano kot Evklidska razdalja.
To je zanimiv začetek, vendar ne velja za geografijo, saj je razdalja med črtami zemljepisne širine in dolžine ne na enaki razdalji. Ko se približujete ekvatorju, se črte zemljepisne širine bolj oddaljujejo. Če uporabite preprosto triangulacijsko enačbo, lahko zaradi ukrivljenosti Zemlje na eni lokaciji natančno izmeri razdaljo, na drugi pa napačno.
Oddaljenost od velikega kroga
Poti, prevožene na velike razdalje okoli Zemlje, so znane kot razdalja velikega kroga. To je ... najkrajša razdalja med dvema točkama na krogli se razlikuje od točk na ravnem zemljevidu. Združite to z dejstvom, da črte zemljepisne širine in dolžine niso enako oddaljene … in dobili boste težak izračun.
Tu je fantastična video razlaga, kako delujejo Veliki krogi.
Formula Haversine
Razdalja z uporabo ukrivljenosti Zemlje je vključena v formulo Haversine, ki uporablja trigonometrijo za upoštevanje ukrivljenosti Zemlje. Ko ugotavljate razdaljo med dvema mestoma na Zemlji (v zračni črti), je ravna črta pravzaprav lok.
To velja za letalske lete – ste kdaj pogledali dejanski zemljevid letov in opazili, da so obokani? To je zato, ker je letenje v loku med dvema točkama krajše kot neposredno na lokacijo.
PHP: Izračunajte razdaljo med dvema točkama zemljepisne širine in dolžine
Tukaj je PHP formula za izračun razdalje med dvema točkama (skupaj s pretvorbo milj v kilometer), zaokrožena na dve decimalni mesti.
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));
}
Spremenljivke so:
- $Latitude1 – spremenljivka za zemljepisno širino vaše prve lokacije.
- $Longitude1 – spremenljivka za zemljepisno dolžino vaše prve lokacije
- $Latitude2 – spremenljivka za zemljepisno širino vaše druge lokacije.
- $Longitude2 – spremenljivka za zemljepisno dolžino vaše druge lokacije.
- $enota – privzeto je milj. To je mogoče posodobiti ali posredovati kot kilometrov.
Java: Izračunajte razdaljo med dvema točkama zemljepisne širine in dolžine
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;
}
}
Spremenljivke so:
- zemljepisna širina 1 – spremenljivka za zemljepisno širino vaše prve lokacije.
- zemljepisna dolžina 1 – spremenljivka za zemljepisno dolžino vaše prve lokacije
- zemljepisna širina 2 – spremenljivka za zemljepisno širino vaše druge lokacije.
- zemljepisna dolžina 2 – spremenljivka za zemljepisno dolžino vaše druge lokacije.
- Enota – privzeto je milj. To je mogoče posodobiti ali posredovati kot kilometrov.
JavaScript: Izračunajte razdaljo med dvema točkama zemljepisne širine in dolžine
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);
}
}
Spremenljivke so:
- zemljepisna širina 1 – spremenljivka za zemljepisno širino vaše prve lokacije.
- zemljepisna dolžina 1 – spremenljivka za zemljepisno dolžino vaše prve lokacije
- zemljepisna širina 2 – spremenljivka za zemljepisno širino vaše druge lokacije.
- zemljepisna dolžina 2 – spremenljivka za zemljepisno dolžino vaše druge lokacije.
- Enota – privzeto je milj. To je mogoče posodobiti ali posredovati kot kilometrov.
Python: Izračunajte razdaljo med 2 točkama zemljepisne širine in dolžine
Tukaj je formula Python za izračun razdalje med dvema točkama (skupaj s pretvorbo milj v kilometre), zaokrožena na dve decimalni mesti. Zasluge mojemu sinu, Billu Karru, podatkovnemu znanstveniku za Odpri INSIGHTS, za kodo.
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)
Spremenljivke so:
- zemljepisna širina 1 – spremenljivka za vašo prvo lokacijo zemljepisna širina.
- zemljepisna dolžina 1 – spremenljivka za vašo prvo lokacijo zemljepisne dolžine
- zemljepisna širina 2 – spremenljivka za vašo drugo lokacijo zemljepisna širina.
- zemljepisna dolžina 2 – spremenljivka za vašo drugo lokacijo zemljepisne dolžine.
- Enota – privzeto je milj. To je mogoče posodobiti ali posredovati kot kilometrov.
MySQL: pridobivanje vseh zapisov znotraj območja z izračunom razdalje v miljah z uporabo zemljepisne širine in dolžine
Uporaba vrst prostorskih podatkov v MySQL je bolj učinkovit in priročen način za delo z geografskimi podatki, vključno z izračunom razdalj med točkami. MySQL podpira tipe prostorskih podatkov, kot je npr POINT
, LINESTRING
in POLYGON
, skupaj s prostorskimi funkcijami, kot je ST_Distance
.
Ko uporabljate ST_Distance
funkcija v MySQL z geografskimi podatki, predstavljenimi kot POINT
koordinate, upošteva ukrivljenost zemeljskega površja. Sferični model, ki ga uporablja ST_Distance
uporablja formulo Haversine. Ta približek je primeren za večino praktičnih namenov, vendar lahko povzroči manjše netočnosti za zelo velike razdalje.
Tukaj je opisano, kako lahko izračunate razdalje med dvema točkama z uporabo vrst prostorskih podatkov:
- Ustvarite tabelo z vrsto prostorskih podatkov: Najprej ustvarite tabelo z a
POINT
stolpec za shranjevanje geografskih točk. Na primer:
CREATE TABLE locations (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
coordinates POINT
);
V to tabelo vnesite svoje geografske točke z uporabo POINT
konstruktor:
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
- Izračunajte razdaljo z uporabo ST_Distance: Razdaljo med dvema točkama lahko izračunate z uporabo
ST_Distance
funkcijo. Tukaj je primer poizvedbe za izračun razdalje med dvema točkama:
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;
Zamenjaj 1
in 2
z ID-jema dveh točk, med katerima želite izračunati razdaljo.
- Rezultat: poizvedba vrne razdaljo med obema točkama v miljah.
Uporaba vrst prostorskih podatkov in ST_Distance
funkcija zagotavlja učinkovitejši in natančnejši način dela z geografskimi podatki v MySQL. Prav tako poenostavlja izračun razdalj med točkami, kar olajša upravljanje in poizvedovanje po podatkih.
MySQL: pridobivanje vseh zapisov znotraj območja z izračunom razdalje v kilometrih z uporabo zemljepisne širine in dolžine
Privzeto ST_Distance
vrne razdaljo v metrih, zato morate preprosto posodobiti poizvedbo za kilometre:
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;
Geografska razdalja Microsoft SQL Server: STDistance
Če uporabljate Microsoft SQL Server, ponujajo lastno funkcijo, STDstance za izračun razdalje med dvema točkama z uporabo podatkovnega tipa Geografija.
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);
Namig za Manasha Sahooja, ustanovitelja in višjega arhitekta pri Ion tri.