Nagyköri távolság kiszámítása vagy lekérdezése a szélességi és hosszúsági pontok között a Haversine képlet segítségével (PHP, JavaScript, Java, Python, MySQL, MSSQL példák)
Ebben a hónapban PHP-ben és MySQL-ben programoztam GIS-hez. A téma kutatása közben nehezen találtam meg földrajzi számítások hogy megtalálja a két hely közötti távolságot, ezért szerettem volna megosztani őket itt.
A két pont közötti távolság kiszámításának egyszerű módja a Pitagorasz-képlet segítségével egy háromszög hipotenuszának kiszámítása (A² + B² = C²). Ez az úgynevezett Euklideszi távolság.
Ez egy érdekes kezdet, de nem vonatkozik a földrajzra, mivel a szélességi és hosszúsági vonalak távolsága nem egyenlő távolságra egymástól. Ahogy közeledik az Egyenlítőhöz, a szélességi vonalak távolabb kerülnek egymástól. Ha egyszerű háromszögelési egyenletet használ, előfordulhat, hogy az egyik helyen pontosan méri a távolságot, a másik helyen pedig rosszul, a Föld görbülete miatt.
Nagy körtávolság
A Föld körül nagy távolságokat megtett útvonalakat Nagy Kör távolságnak nevezik. Azaz… egy gömb két pontja közötti legrövidebb távolság különbözik a sík térkép pontjaitól. Ha ezt kombinálja azzal a ténnyel, hogy a szélességi és hosszúsági vonalak nem egyenlő távolságra vannak… és nehéz számítást kell végeznie.
Itt van egy fantasztikus videó magyarázat a Nagy Körök működéséről.
A Haversine Formula
A Föld görbületét használó távolság beépül a Haversine-képletbe, amely trigonometriát használ a Föld görbületének figyelembevételére. Ha megtalálja a távolságot a Föld két helye között (légvonalban), az egyenes valójában egy ív.
Ez alkalmazható légi repülésre – nézte már valaha a járatok tényleges térképét, és észrevette, hogy ívesek? Ez azért van, mert a két pont közötti ívben való repülés rövidebb, mint közvetlenül a helyszínre.
PHP: Számítsa ki a távolságot 2 szélességi és hosszúsági pont között
Íme a PHP képlet két pont közötti távolság kiszámításához (a Mérföld és Kilométer közötti átszámítással együtt), két tizedesjegyre kerekítve.
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));
}
A változók a következők:
- $Latitude1 – az első hely szélességi fokának változója.
- $hosszúság1 – az első hely hosszúsági fokának változója
- $Latitude2 – a második hely szélességi fokának változója.
- $hosszúság2 – a második hely hosszúsági fokának változója.
- $egység – az alapértelmezett lény mérföld. Ez frissíthető vagy átadható kilométerre.
Java: Számítsa ki a távolságot 2 szélességi és hosszúsági pont között
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;
}
}
A változók a következők:
- szélesség1 – az első hely szélességi fokának változója.
- hosszúság1 – az első hely hosszúsági fokának változója
- szélesség2 – a második hely szélességi fokának változója.
- hosszúság2 – a második hely hosszúsági fokának változója.
- egység – az alapértelmezett lény mérföld. Ez frissíthető vagy átadható kilométerre.
JavaScript: Számítsa ki a távolságot 2 szélességi és hosszúsági pont között
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);
}
}
A változók a következők:
- szélesség1 – az első hely szélességi fokának változója.
- hosszúság1 – az első hely hosszúsági fokának változója
- szélesség2 – a második hely szélességi fokának változója.
- hosszúság2 – a második hely hosszúsági fokának változója.
- egység – az alapértelmezett lény mérföld. Ez frissíthető vagy átadható kilométerre.
Python: Számítsa ki a távolságot 2 szélességi és hosszúsági pont között
Íme a Python képlet a két pont közötti távolság kiszámításához (a Mérföld/Kilométer átszámítással együtt) két tizedesjegyre kerekítve. Köszönet a fiamnak, Bill Karrnak, az adatkutatónak OpenINSIGHTS, a kódért.
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)
A változók a következők:
- szélesség1 – az első hely változója szélesség.
- hosszúság1 – az első hely változója hosszúság
- szélesség2 – a második hely változója szélesség.
- hosszúság2 – a második hely változója hosszúság.
- egység – az alapértelmezett lény mérföld. Ez frissíthető vagy átadható kilométerre.
MySQL: Egy tartományon belüli összes rekord lekérése a távolság mérföldben történő kiszámításával a szélesség és hosszúság segítségével
A téradattípusok használata a MySQL-ben hatékonyabb és kényelmesebb módja a földrajzi adatok kezelésének, beleértve a pontok közötti távolságok kiszámítását. A MySQL támogatja a térbeli adattípusokat, mint pl POINT
, LINESTRING
és POLYGON
, valamint olyan térbeli funkciókat, mint a ST_Distance
.
Amikor a ST_Distance
függvény a MySQL-ben a földrajzi adatokkal, mint POINT
koordinátákat, figyelembe veszi a Föld felszínének görbületét. által használt gömbmodell ST_Distance
Haversine formulát alkalmazza. Ez a közelítés a legtöbb gyakorlati célra alkalmas, de nagyon nagy távolságok esetén enyhe pontatlanságokat okozhat.
A következőképpen számíthatja ki két pont közötti távolságot téradattípusok használatával:
- Hozzon létre egy táblázatot téradattípussal: Először hozzon létre egy táblázatot a
POINT
oszlop a földrajzi pontok tárolására. Például:
CREATE TABLE locations (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
coordinates POINT
);
Írja be földrajzi pontjait ebbe a táblázatba a segítségével POINT
konstruktőr:
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
- Számítsa ki a távolságot az ST_Distance segítségével: Kiszámíthatja két pont távolságát a segítségével
ST_Distance
funkció. Íme egy példalekérdezés két pont távolságának kiszámításához:
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;
Cserélje 1
és a 2
annak a két pontnak az azonosítójával, amelyek közötti távolságot ki akarjuk számítani.
- Eredmény: A lekérdezés visszaadja a két pont közötti távolságot mérföldben.
A téradattípusok és a ST_Distance
A funkció hatékonyabb és pontosabb módszert biztosít a földrajzi adatokkal való munkavégzéshez a MySQL-ben. Ezenkívül leegyszerűsíti a pontok közötti távolság kiszámítását, megkönnyítve az adatok kezelését és lekérdezését.
MySQL: Az összes rekord lekérése egy tartományon belül a távolság kiszámításával kilométerben a szélesség és hosszúság segítségével
Alapértelmezés szerint ST_Distance
visszaadja a távolságot méterben, így egyszerűen frissítenie kell a kilométerekre vonatkozó lekérdezést:
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 földrajzi távolság: STDistance
Ha a Microsoft SQL Servert használja, ezek saját funkciót kínálnak, STDistance két pont közötti távolság kiszámításához a Földrajz adattípus használatával.
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);
Kalaptipp Manash Sahoo-nak, a cég alapítójának és vezető építészének Ion Three.