Reiknaðu eða leitaðu að mikilli hringfjarlægð milli breiddar- og lengdargráðu með Haversine formúlunni (PHP, JavaScript, Java, Python, MySQL, MSSQL dæmi)
Í þessum mánuði hef ég verið að forrita í PHP og MySQL fyrir GIS. Þegar ég rannsakaði efnið átti ég erfitt með að finna landfræðilega útreikninga til að finna fjarlægðina milli tveggja staða, svo mig langaði að deila þeim hér.
Einfalda leiðin til að reikna fjarlægð milli tveggja punkta er að nota Pythagorean formúluna til að reikna lágþrýsting þríhyrningsins (A² + B² = C²). Þetta er þekkt sem Evuklídísk fjarlægð.
Það er áhugaverð byrjun, en það á ekki við um landafræði þar sem fjarlægðin milli breiddar- og lengdarlína er ekki jafn fjarlægð á milli. Eftir því sem þú færð nær miðbaugnum mun breiddarlínur verða lengra á milli. Ef þú notar einfalda þríhyrningsjöfnu gæti hún mælt fjarlægð nákvæmlega á einum stað og rangt á hinum vegna sveigju jarðar.
Mikil hringvegalengd
Leiðirnar sem farnar eru langar vegalengdir í kringum jörðina eru þekktar sem mikla hringfjarlægð. Það er... stysta fjarlægðin milli tveggja punkta á kúlu er frábrugðin punktunum á flatu korti. Sameinaðu því við þá staðreynd að breiddar- og lengdarlínur eru ekki í jafnfjarlægð... og þú hefur erfiðan útreikning.
Hér er frábær myndbandsskýring á því hvernig Great Circles virka.
Haversine formúlan
Fjarlægðin sem notar sveigju jarðar er felld inn í Haversine formúluna, sem notar hornafræði til að gera ráð fyrir sveigju jarðar. Þegar þú ert að finna fjarlægðina milli 2 staða á jörðinni (í loftlínunni) er bein lína í raun bogi.
Þetta á við í flugi – hefur þú einhvern tíma skoðað raunverulegt kort af flugi og tekið eftir því að þau eru bogadregin? Það er vegna þess að það er styttra að fljúga í boga milli tveggja punkta en beint á staðinn.
PHP: Reiknaðu fjarlægð milli 2 punkta breiddar- og lengdargráðu
Hér er PHP formúlan til að reikna út fjarlægðina milli tveggja punkta (ásamt Mile vs Kilometer umreikningi) námunduð að tveimur aukastöfum.
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));
}
Breyturnar eru:
- $Latitude1 – breyta fyrir breiddargráðu fyrstu staðsetningu þinnar.
- $ Lengdargráða1 – breyta fyrir lengdargráðu fyrstu staðsetningu þinnar
- $Latitude2 – breyta fyrir breiddargráðu seinni staðsetningar þinnar.
- $ Lengdargráða2 – breyta fyrir lengdargráðu annars staðarins.
- $eining – sjálfgefna veran kílómetra. Þetta er hægt að uppfæra eða senda sem kílómetra.
Java: Reiknaðu fjarlægð milli 2 breiddar- og lengdargráðu
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;
}
}
Breyturnar eru:
- breiddargráðu 1 – breyta fyrir breiddargráðu fyrstu staðsetningu þinnar.
- lengdargráðu 1 – breyta fyrir lengdargráðu fyrstu staðsetningu þinnar
- breiddargráðu 2 – breyta fyrir breiddargráðu seinni staðsetningar þinnar.
- lengdargráðu 2 – breyta fyrir lengdargráðu annars staðarins.
- eining – sjálfgefna veran kílómetra. Þetta er hægt að uppfæra eða senda sem kílómetra.
JavaScript: Reiknaðu fjarlægð milli 2 breiddar- og lengdargráðu
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);
}
}
Breyturnar eru:
- breiddargráðu 1 – breyta fyrir breiddargráðu fyrstu staðsetningu þinnar.
- lengdargráðu 1 – breyta fyrir lengdargráðu fyrstu staðsetningu þinnar
- breiddargráðu 2 – breyta fyrir breiddargráðu seinni staðsetningar þinnar.
- lengdargráðu 2 – breyta fyrir lengdargráðu annars staðarins.
- eining – sjálfgefna veran kílómetra. Þetta er hægt að uppfæra eða senda sem kílómetra.
Python: Reiknaðu fjarlægð milli 2 punkta breiddar- og lengdargráðu
Hér er Python formúlan til að reikna út fjarlægðina milli tveggja punkta (ásamt Mile vs Kilometer umreikningi) námunduð að tveimur aukastöfum. Lof til sonar míns, Bill Karr, gagnafræðings fyrir OpenINSIGHTS, fyrir kóðann.
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)
Breyturnar eru:
- breiddargráðu 1 – breyta fyrir fyrstu staðsetningu þína breiddargráða.
- lengdargráðu 1 – breyta fyrir fyrstu staðsetningu þína lengdargráðu
- breiddargráðu 2 – breyta fyrir seinni staðsetningu þína breiddargráða.
- lengdargráðu 2 – breyta fyrir seinni staðsetningu þína lengdargráðu.
- eining – sjálfgefna veran kílómetra. Þetta er hægt að uppfæra eða senda sem kílómetra.
MySQL: Að sækja allar skrár innan marka með því að reikna fjarlægð í mílum með breiddar- og lengdargráðu
Notkun landgagnategunda í MySQL er skilvirkari og þægilegri leið til að vinna með landfræðileg gögn, þar á meðal að reikna út fjarlægðir milli punkta. MySQL styður landgagnategundir eins og POINT
, LINESTRING
og POLYGON
, ásamt staðbundnum aðgerðum eins og ST_Distance
.
Þegar þú notar ST_Distance
virka í MySQL með landfræðileg gögn táknuð sem POINT
hnit, tekur það mið af sveigju yfirborðs jarðar. Kúlulaga líkanið sem notað er af ST_Distance
notar Haversine formúluna. Þessi nálgun hentar í flestum hagnýtum tilgangi en getur valdið smá ónákvæmni fyrir mjög langar vegalengdir.
Hér er hvernig þú getur reiknað fjarlægð milli tveggja punkta með því að nota landgagnagerðir:
- Búðu til töflu með landgagnagerð: Fyrst skaltu búa til töflu með a
POINT
dálk til að geyma landfræðilega punkta. Til dæmis:
CREATE TABLE locations (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
coordinates POINT
);
Settu landfræðilega punkta inn í þessa töflu með því að nota POINT
smiður:
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
- Reiknaðu fjarlægð með því að nota ST_Distance: Þú getur reiknað út fjarlægðina milli tveggja punkta með því að nota
ST_Distance
virka. Hér er dæmi um fyrirspurn til að reikna út fjarlægðina milli tveggja punkta:
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;
Skipta 1
og 2
með auðkenni punktanna tveggja sem þú vilt reikna út fjarlægðina á milli.
- Niðurstaða: Fyrirspurnin mun skila fjarlægðinni milli punktanna tveggja í mílum.
Notkun landgagnategunda og ST_Distance
aðgerð veitir skilvirkari og nákvæmari leið til að vinna með landfræðileg gögn í MySQL. Það einfaldar einnig útreikning á fjarlægðum milli punkta, sem gerir það auðveldara að stjórna og spyrjast fyrir um gögnin þín.
MySQL: Að sækja allar skrár innan bils með því að reikna fjarlægð í kílómetrum með breiddar- og lengdargráðu
Sjálfgefið ST_Distance
skilar fjarlægðinni í metrum, svo þú þarft einfaldlega að uppfæra fyrirspurnina fyrir kílómetra:
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 Landfræðileg fjarlægð: STDistance
Ef þú ert að nota Microsoft SQL Server bjóða þeir upp á sína eigin virkni, STFjarlægð til að reikna út fjarlægð milli tveggja punkta með því að nota landafræðigagnagerðina.
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);
Hattábending til Manash Sahoo, stofnanda og eldri arkitekt hjá Jón þrjú.