Calculeu o consulteu una gran distància de cercle entre punts de latitud i longitud mitjançant la fórmula Havesine (exemples PHP, JavaScript, Java, Python, MySQL, MSSQL)
Aquest mes, he estat programant en PHP i MySQL per a GIS. Mentre investigava el tema, vaig tenir dificultats per trobar-lo càlculs geogràfics per trobar la distància entre dues ubicacions, així que volia compartir-les aquí.
La forma senzilla de calcular la distància entre dos punts és utilitzar la fórmula pitagòrica per calcular la hipotenusa d’un triangle (A² + B² = C²). Això es coneix com el Distància euclidiana.
És un començament interessant, però no s'aplica a la geografia, ja que la distància entre les línies de latitud i longitud són distàncies no iguals entre si. A mesura que t'acostes a l'equador, les línies de latitud s'allunyen més. Si utilitzeu una equació de triangulació senzilla, pot mesurar la distància amb precisió en una ubicació i incorrecta a l'altra a causa de la curvatura de la Terra.
Distància Gran Cercle
Les rutes recorregudes llargues distàncies al voltant de la Terra es coneixen com la Distància del Gran Cercle. És a dir... la distància més curta entre dos punts d'una esfera difereix dels punts d'un mapa pla. Combineu-ho amb el fet que les línies de latitud i longitud no són equidistants... i teniu un càlcul difícil.
Aquí teniu una fantàstica explicació en vídeo de com funcionen els grans cercles.
La Fórmula Haversine
La distància utilitzant la curvatura de la Terra s'incorpora a la fórmula Havesine, que utilitza la trigonometria per permetre la curvatura de la Terra. Quan trobeu la distància entre 2 llocs de la Terra (en línia recta), una línia recta és en realitat un arc.
Això és aplicable al vol aeri. Alguna vegada has mirat el mapa real dels vols i has notat que estan arquejats? Això és perquè volar en un arc entre dos punts és més curt que directament a la ubicació.
PHP: Calculeu la distància entre 2 punts de latitud i longitud
Aquí teniu la fórmula PHP per calcular la distància entre dos punts (juntament amb la conversió de milla en quilòmetre) arrodonida a dos decimals.
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));
}
Les variables són:
- $Latitude1 – una variable per a la latitud de la vostra primera ubicació.
- $Longitud1 – una variable per a la longitud de la vostra primera ubicació
- $Latitude2 – una variable per a la latitud de la vostra segona ubicació.
- $Longitud2 – una variable per a la longitud de la vostra segona ubicació.
- $unitat - el ser per defecte milles. Això es pot actualitzar o passar com a quilòmetres.
Java: calcula la distància entre 2 punts de latitud i longitud
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;
}
}
Les variables són:
- latitud 1 – una variable per a la latitud de la vostra primera ubicació.
- longitud 1 – una variable per a la longitud de la vostra primera ubicació
- latitud 2 – una variable per a la latitud de la vostra segona ubicació.
- longitud 2 – una variable per a la longitud de la vostra segona ubicació.
- unitat - el ser per defecte milles. Això es pot actualitzar o passar com a quilòmetres.
JavaScript: calcula la distància entre 2 punts de latitud i longitud
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);
}
}
Les variables són:
- latitud 1 – una variable per a la latitud de la vostra primera ubicació.
- longitud 1 – una variable per a la longitud de la vostra primera ubicació
- latitud 2 – una variable per a la latitud de la vostra segona ubicació.
- longitud 2 – una variable per a la longitud de la vostra segona ubicació.
- unitat - el ser per defecte milles. Això es pot actualitzar o passar com a quilòmetres.
Python: calcula la distància entre 2 punts de latitud i longitud
Aquí teniu la fórmula de Python per calcular la distància entre dos punts (juntament amb la conversió de milla a quilòmetre) arrodonida a dos decimals. Crèdit al meu fill, Bill Karr, un científic de dades OpenINSIGHTS, pel codi.
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)
Les variables són:
- latitud 1 – una variable per a la vostra primera ubicació latitud.
- longitud 1 – una variable per a la vostra primera ubicació longitud
- latitud 2 – una variable per a la vostra segona ubicació latitud.
- longitud 2 – una variable per a la vostra segona ubicació longitud.
- unitat - el ser per defecte milles. Això es pot actualitzar o passar com a quilòmetres.
MySQL: recuperant tots els registres dins d'un rang calculant la distància en milles amb latitud i longitud
L'ús de tipus de dades espacials a MySQL és una manera més eficient i còmoda de treballar amb dades geogràfiques, inclòs el càlcul de distàncies entre punts. MySQL admet tipus de dades espacials com ara POINT
, LINESTRING
i POLYGON
, juntament amb funcions espacials com ST_Distance
.
Quan utilitzeu el codi ST_Distance
funció a MySQL amb dades geogràfiques representades com POINT
coordenades, té en compte la curvatura de la superfície terrestre. El model esfèric utilitzat per ST_Distance
empra la fórmula Havesine. Aquesta aproximació és adequada per a la majoria de propòsits pràctics, però pot introduir lleus imprecisions per a distàncies molt llargues.
A continuació s'explica com podeu calcular les distàncies entre dos punts mitjançant els tipus de dades espacials:
- Creeu una taula amb tipus de dades espacials: Primer, creeu una taula amb a
POINT
columna per emmagatzemar punts geogràfics. Per exemple:
CREATE TABLE locations (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
coordinates POINT
);
Inseriu els vostres punts geogràfics en aquesta taula utilitzant el 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 la distància amb ST_Distance: Podeu calcular la distància entre dos punts amb el
ST_Distance
funció. Aquí teniu un exemple de consulta per calcular la distància entre dos punts:
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;
Reemplaçar 1
i 2
amb els ID dels dos punts que voleu calcular la distància entre ells.
- Resultat: la consulta retornarà la distància entre els dos punts en milles.
Ús de tipus de dades espacials i ST_Distance
La funció proporciona una manera més eficient i precisa de treballar amb dades geogràfiques a MySQL. També simplifica el càlcul de distàncies entre punts, facilitant la gestió i consulta de les vostres dades.
MySQL: recuperant tots els registres dins d'un rang calculant la distància en quilòmetres utilitzant latitud i longitud
Per defecte ST_Distance
retorna la distància en metres, de manera que només cal que actualitzeu la consulta per a quilòmetres:
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;
Distància geogràfica de Microsoft SQL Server: STDistance
Si utilitzeu Microsoft SQL Server, ofereixen la seva pròpia funció, STDistance per calcular la distància entre dos punts mitjançant el tipus de dades 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);
Punta de barret a Manash Sahoo, fundador i arquitecte sènior de Ió Tres.