Izračunajte ili postavite upit za udaljenost velikog kruga između tačaka geografske širine i dužine koristeći Haversine formulu (PHP, JavaScript, Java, Python, MySQL, MSSQL primjeri)
Ovog mjeseca sam programirao u PHP-u i MySQL-u za GIS. Dok sam istraživao ovu temu, imao sam poteškoća u pronalaženju geografskim proračunima da pronađem udaljenost između dvije lokacije, pa sam ih želio podijeliti ovdje.
Jednostavan način izračuna udaljenosti između dvije točke je pomoću pitagorejske formule za izračunavanje hipotenuze trokuta (A² + B² = C²). Ovo je poznato kao Euklidska udaljenost.
To je zanimljiv početak, ali se ne odnosi na geografiju jer je udaljenost između linija geografske širine i dužine nisu jednake udaljenosti. Kako se približavate ekvatoru, linije geografske širine se dalje udaljavaju. Ako koristite jednostavnu jednadžbu triangulacije, ona može precizno mjeriti udaljenost na jednoj lokaciji, a pogrešno na drugoj zbog zakrivljenosti Zemlje.
Udaljenost velike kružnice
Rute koje se putuju na velike udaljenosti oko Zemlje poznate su kao Velika kružna udaljenost. To jest... najkraća udaljenost između dvije tačke na sferi razlikuje se od tačaka na ravnoj karti. Kombinujte to sa činjenicom da linije geografske širine i dužine nisu jednako udaljene... i dobićete tešku kalkulaciju.
Evo fantastičnog video objašnjenja kako funkcioniraju Veliki krugovi.
Formula Haversine
Udaljenost koja koristi zakrivljenost Zemlje uključena je u Haversine formulu, koja koristi trigonometriju kako bi omogućila zakrivljenost Zemlje. Kada pronalazite udaljenost između 2 mjesta na Zemlji (zračnom linijom), prava linija je zapravo luk.
Ovo je primjenjivo u zračnom letu – da li ste ikada pogledali stvarnu kartu letova i primijetili da su zakrivljeni? To je zato što je letenje u luku između dvije točke kraće nego direktno do lokacije.
PHP: Izračunajte udaljenost između 2 tačke širine i dužine
Evo PHP formule za izračunavanje udaljenosti između dve tačke (zajedno sa konverzijom milja prema kilometru) zaokružene na dve decimale.
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));
}
Varijable su:
- $Latitude1 – varijabla za geografsku širinu vaše prve lokacije.
- $Longitude1 – varijabla za geografsku dužinu vaše prve lokacije
- $Latitude2 – varijabla za geografsku širinu vaše druge lokacije.
- $Longitude2 – varijabla za geografsku dužinu vaše druge lokacije.
- $unit – podrazumevano je hiljade. Ovo se može ažurirati ili proslijediti kao kilometara.
Java: Izračunajte udaljenost između 2 tačke geografske širine i duž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;
}
}
Varijable su:
- geografska širina1 – varijabla za geografsku širinu vaše prve lokacije.
- geografska dužina1 – varijabla za geografsku dužinu vaše prve lokacije
- geografska širina2 – varijabla za geografsku širinu vaše druge lokacije.
- geografska dužina2 – varijabla za geografsku dužinu vaše druge lokacije.
- jedinica – podrazumevano je hiljade. Ovo se može ažurirati ili proslijediti kao kilometara.
JavaScript: Izračunajte udaljenost između 2 tačke geografske širine i duž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);
}
}
Varijable su:
- geografska širina1 – varijabla za geografsku širinu vaše prve lokacije.
- geografska dužina1 – varijabla za geografsku dužinu vaše prve lokacije
- geografska širina2 – varijabla za geografsku širinu vaše druge lokacije.
- geografska dužina2 – varijabla za geografsku dužinu vaše druge lokacije.
- jedinica – podrazumevano je hiljade. Ovo se može ažurirati ili proslijediti kao kilometara.
Python: Izračunajte udaljenost između 2 tačke geografske širine i dužine
Evo Python formule za izračunavanje udaljenosti između dvije točke (zajedno sa konverzijom milja u kilometru) zaokružene na dvije decimale. Svaka čast mom sinu, Billu Karru, Data Scientistu za OpenINSIGHTS, za kod.
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)
Varijable su:
- geografska širina1 – varijabla za vašu prvu lokaciju širina.
- geografska dužina1 – varijabla za vašu prvu lokaciju zemljopisnu dužinu
- geografska širina2 – varijabla za vašu drugu lokaciju širina.
- geografska dužina2 – varijabla za vašu drugu lokaciju zemljopisnu dužinu.
- jedinica – podrazumevano je hiljade. Ovo se može ažurirati ili proslijediti kao kilometara.
MySQL: Dohvaćanje svih zapisa unutar raspona izračunavanjem udaljenosti u miljama koristeći geografsku širinu i dužinu
Korišćenje tipova prostornih podataka u MySQL je efikasniji i praktičniji način rada sa geografskim podacima, uključujući izračunavanje udaljenosti između tačaka. MySQL podržava tipove prostornih podataka kao što su POINT
, LINESTRING
, I POLYGON
, zajedno sa prostornim funkcijama kao što su ST_Distance
.
Kada koristite ST_Distance
funkcija u MySQL sa geografskim podacima predstavljenim kao POINT
koordinate, uzima u obzir zakrivljenost Zemljine površine. Sferni model koji koristi ST_Distance
koristi Haversine formulu. Ova aproksimacija je pogodna za većinu praktičnih svrha, ali može unijeti male nepreciznosti za vrlo velike udaljenosti.
Evo kako možete izračunati udaljenosti između dvije tačke pomoću tipova prostornih podataka:
- Kreirajte tabelu sa tipom prostornih podataka: Prvo kreirajte tabelu sa a
POINT
kolona za pohranjivanje geografskih tačaka. Na primjer:
CREATE TABLE locations (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
coordinates POINT
);
Unesite svoje geografske tačke u ovu tabelu koristeći 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 udaljenost koristeći ST_Distance: Možete izračunati rastojanje između dve tačke koristeći
ST_Distance
funkcija. Evo primjera upita za izračunavanje udaljenosti između dvije tačke:
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;
zamijeniti 1
i 2
sa ID-ovima dvije tačke između kojih želite izračunati udaljenost.
- rezultat: Upit će vratiti udaljenost između dvije točke u miljama.
Korištenje tipova prostornih podataka i ST_Distance
funkcija pruža efikasniji i precizniji način rada sa geografskim podacima u MySQL-u. Također pojednostavljuje izračunavanje udaljenosti između tačaka, što olakšava upravljanje podacima i postavljanje upita.
MySQL: Dohvaćanje svih zapisa unutar raspona izračunavanjem udaljenosti u kilometrima koristeći geografsku širinu i dužinu
Podrazumevano ST_Distance
vraća udaljenost u metrima, tako da jednostavno trebate ažurirati upit 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;
Microsoft SQL Server Geografska udaljenost: STDistance
Ako koristite Microsoft SQL Server, oni nude svoju vlastitu funkciju, STDistance za izračunavanje udaljenosti između dvije tačke koristeći tip podataka 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);
Šešir za Manash Sahoo, osnivač i stariji arhitekta u Ion tri.