Kalkulahin o Pangutana ang Dakong Lingin Distance Taliwala sa mga Punto sa Latitude ug Longitude Gamit ang Haversine Formula (PHP, JavaScript, Java, Python, MySQL, MSSQL Examples)
Karong bulana, nagprograma ko sa PHP ug MySQL para sa GIS. Samtang nagsiksik sa hilisgutan, naglisud ko sa pagpangita geographic nga mga kalkulasyon aron makit-an ang gilay-on tali sa duha ka lokasyon, busa gusto nako nga ipaambit kini dinhi.
Ang yano nga paagi sa pagkalkula sa usa ka gilay-on sa taliwala sa duha ka mga punto mao ang paggamit sa pormula nga Pythagorean aron makalkulo ang hypotenuse sa usa ka triangle (A² + B² = C²). Kini nailhan nga Gilay-on sa Euclidean.
Kana usa ka makapaikag nga pagsugod, apan dili kini magamit sa geograpiya tungod kay ang gilay-on tali sa mga linya sa latitude ug longitude dili patas nga gilay-on. Samtang nagkaduol ka sa ekwador, ang mga linya sa latitud mas magkalayo. Kung mogamit ka ug usa ka yano nga triangulation equation, kini mahimong tukma nga pagsukod sa distansya sa usa ka lokasyon ug sayup sa lain tungod sa pagkakurba sa Yuta.
Maayo nga Distansya sa Circle
Ang mga rota nga mibiyahe ug layo sa palibot sa Yuta nailhan nga Great Circle Distance. Kana mao… ang pinakamubo nga distansiya tali sa duha ka punto sa usa ka sphere lahi sa mga punto sa patag nga mapa. Isagol kana sa kamatuoran nga ang mga linya sa latitude ug longitude dili managsama ang gilay-on… ug adunay ka lisud nga kalkulasyon.
Ania ang us aka maayo nga pagpatin-aw sa video kung giunsa ang pagtrabaho sa Great Circles.
Ang Haversine Formula
Ang gilay-on gamit ang kurbada sa Yuta gilakip sa pormula sa Haversine, nga naggamit sa trigonometrya aron tugotan ang pagkakurba sa Yuta. Kung makit-an nimo ang gilay-on tali sa 2 ka lugar sa Yuta (sama sa paglupad sa uwak), ang usa ka tul-id nga linya sa tinuud usa ka arko.
Magamit kini sa paglupad sa kahanginan - nakatan-aw ka na ba sa aktuwal nga mapa sa mga flight ug nakamatikod nga sila naka-arko? Kana tungod kay ang paglupad sa usa ka arko taliwala sa duha ka punto mas mubo kaysa direkta sa lokasyon.
PHP: Kwentaha ang distansya Tali sa 2 Mga Punto sa Latitude ug Longhitud
Ania ang pormula sa PHP para sa pagkuwenta sa gilay-on tali sa duha ka punto (uban sa Mile vs. Kilometer conversion) nga gilibot ngadto sa duha ka desimal nga mga dapit.
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));
}
Ang mga variable mao ang:
- $Latitude1 – usa ka variable para sa latitude sa imong unang lokasyon.
- $Longitude1 – usa ka variable para sa longitude sa imong unang lokasyon
- $Latitude2 – usa ka variable para sa latitude sa imong ikaduhang lokasyon.
- $Longitude2 – usa ka variable para sa longitude sa imong ikaduhang lokasyon.
- $yunit - ang default nga binuhat linibo. Mahimo kini nga ma-update o mapasa ingon kilometros.
Java: Kalkulahin ang Distansya Taliwala sa 2 ka Punto sa Latitude ug Longitude
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;
}
}
Ang mga variable mao ang:
- latitud1 – usa ka variable para sa latitude sa imong unang lokasyon.
- longitude1 – usa ka variable para sa longitude sa imong unang lokasyon
- latitud2 – usa ka variable para sa latitude sa imong ikaduhang lokasyon.
- longitude2 – usa ka variable para sa longitude sa imong ikaduhang lokasyon.
- yunit - ang default nga binuhat linibo. Mahimo kini nga ma-update o mapasa ingon kilometros.
JavaScript: Kalkulahin ang Distansya Taliwala sa 2 ka Punto sa Latitude ug Longitude
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);
}
}
Ang mga variable mao ang:
- latitud1 – usa ka variable para sa latitude sa imong unang lokasyon.
- longitude1 – usa ka variable para sa longitude sa imong unang lokasyon
- latitud2 – usa ka variable para sa latitude sa imong ikaduhang lokasyon.
- longitude2 – usa ka variable para sa longitude sa imong ikaduhang lokasyon.
- yunit - ang default nga binuhat linibo. Mahimo kini nga ma-update o mapasa ingon kilometros.
Python: Kalkulahin ang Distansya Taliwala sa 2 ka Punto sa Latitude ug Longitude
Ania ang pormula sa Python para sa pagkuwenta sa gilay-on tali sa duha ka punto (uban sa Mile vs. Kilometer conversion) nga gilibot ngadto sa duha ka desimal nga mga dapit. Credit sa akong anak nga lalaki, Bill Karr, usa ka Data Scientist alang sa OpenINSIGHTS, alang sa code.
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)
Ang mga variable mao ang:
- latitud1 – usa ka variable alang sa imong una nga lokasyon latitude.
- longitude1 – usa ka variable alang sa imong una nga lokasyon gitas-on
- latitud2 – usa ka variable alang sa imong ikaduhang lokasyon latitude.
- longitude2 – usa ka variable alang sa imong ikaduhang lokasyon gitas-on.
- yunit - ang default nga binuhat linibo. Mahimo kini nga ma-update o mapasa ingon kilometros.
MySQL: Pagbawi sa Tanang Rekord Sulod sa Usa ka Sakyanan Pinaagi sa Pagkalkulo sa Distansya Sa Milya Gamit ang Latitude ug Longitude
Ang paggamit sa Spatial Data Types sa MySQL usa ka mas episyente ug kombenyente nga paagi sa pagtrabaho sa geograpikanhong datos, lakip ang pagkalkula sa mga distansya tali sa mga punto. Gisuportahan sa MySQL ang Spatial Data Types sama sa POINT
, LINESTRING
, Ug POLYGON
, uban sa spatial functions sama sa ST_Distance
.
Kung gigamit nimo ang ST_Distance
function sa MySQL nga adunay geographical data nga girepresentahan ingon POINT
coordinates, kini naghunahuna sa curvature sa nawong sa Yuta. Ang spherical nga modelo nga gigamit sa ST_Distance
naggamit sa pormula sa Haversine. Kini nga pagbanabana angayan alang sa kadaghanang praktikal nga mga katuyoan apan mahimo’g magpaila sa gamay nga mga sayup sa layo kaayo nga mga distansya.
Ania kung giunsa nimo pagkalkulo ang mga distansya tali sa duha ka punto gamit ang Spatial Data Types:
- Paghimo usa ka Talaan nga adunay Spatial Data Type: Una, paghimo og lamesa nga adunay a
POINT
kolum sa pagtipig sa mga punto sa heyograpiya. Pananglitan:
CREATE TABLE locations (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
coordinates POINT
);
Isulod ang imong geographical nga mga punto niini nga lamesa gamit ang POINT
tigtukod:
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
- Kalkulahin ang Distansya Gamit ang ST_Distance: Mahimo nimong kuwentahon ang gilay-on tali sa duha ka punto gamit ang
ST_Distance
function. Ania ang usa ka pananglitan nga pangutana aron makalkulo ang gilay-on tali sa duha ka punto:
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;
Ibalik 1
ug 2
uban ang mga ID sa duha ka punto nga gusto nimong kuwentahon ang gilay-on tali.
- resulta: Ang pangutana mobalik sa gilay-on tali sa duha ka punto sa milya.
Paggamit sa Spatial Data Types ug ang ST_Distance
Naghatag ang function sa usa ka labi ka episyente ug tukma nga paagi sa pagtrabaho sa geographical data sa MySQL. Gipasimple usab niini ang pagkalkula sa mga distansya tali sa mga punto, nga nagpasayon sa pagdumala ug pagpangutana sa imong data.
MySQL: Pagbawi sa Tanang Rekord Sulod sa Usa ka Sakyanan Pinaagi sa Pagkuwenta sa Distansya Sa Kilometro Gamit ang Latitude ug Longitude
Pinaagi sa default ST_Distance
ibalik ang gilay-on sa mga metro, mao nga kinahanglan nimo nga i-update ang pangutana alang sa mga kilometro:
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 Geographic Distance: STDistance
Kung gigamit nimo ang Microsoft SQL Server, nagtanyag sila sa ilang kaugalingon nga function, STDistance para sa pagkuwenta sa gilay-on tali sa duha ka punto gamit ang Geography data type.
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);
Hat tip kay Manash Sahoo, founder ug senior architect sa Ion Tulo.