Kira atau Soal Jarak Bulatan Besar Antara Titik Latitud dan Longitud Menggunakan Formula Haversine (Contoh PHP, JavaScript, Java, Python, MySQL, MSSQL)
Bulan ini, saya telah memprogramkan dalam PHP dan MySQL untuk GIS. Semasa meneliti topik, saya mengalami kesukaran mencari pengiraan geografi untuk mencari jarak antara dua lokasi, jadi saya ingin berkongsinya di sini.
Cara mudah untuk mengira jarak antara dua titik adalah dengan menggunakan formula Pythagoras untuk mengira hipotenus segitiga (A² + B² = C²). Ini dikenali sebagai Jarak Euclidean.
Itu permulaan yang menarik, tetapi ia tidak digunakan untuk geografi kerana jarak antara garisan latitud dan longitud adalah jarak yang tidak sama. Apabila anda semakin hampir dengan khatulistiwa, garisan latitud semakin terpisah. Jika anda menggunakan persamaan triangulasi mudah, ia mungkin mengukur jarak dengan tepat di satu lokasi dan salah di lokasi lain kerana kelengkungan Bumi.
Jarak Bulatan Hebat
Laluan yang menempuh jarak jauh mengelilingi Bumi dikenali sebagai Jarak Bulatan Besar. Iaitu… jarak terpendek antara dua titik pada sfera berbeza daripada titik pada peta rata. Gabungkan itu dengan fakta bahawa garis latitud dan longitud tidak sama jarak… dan anda mempunyai pengiraan yang sukar.
Berikut adalah penjelasan video yang hebat tentang bagaimana Great Circles berfungsi.
Formula Haversine
Jarak menggunakan kelengkungan Bumi digabungkan dalam formula Haversine, yang menggunakan trigonometri untuk membenarkan kelengkungan Bumi. Apabila anda mencari jarak antara 2 tempat di Bumi (semasa burung gagak terbang), garis lurus sebenarnya ialah lengkok.
Ini terpakai dalam penerbangan udara – pernahkah anda melihat peta sebenar penerbangan dan mendapati ia melengkung? Itu kerana terbang dalam gerbang antara dua titik adalah lebih pendek daripada terus ke lokasi.
PHP: Hitung Jarak Antara 2 Titik Lintang dan Bujur
Berikut ialah formula PHP untuk mengira jarak antara dua titik (bersama-sama dengan penukaran Batu lwn Kilometer) yang dibundarkan kepada dua tempat perpuluhan.
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));
}
Pembolehubah tersebut ialah:
- $Latitud1 – pembolehubah untuk latitud lokasi pertama anda.
- $Longitude1 – pembolehubah untuk longitud lokasi pertama anda
- $Latitud2 – pembolehubah untuk latitud lokasi kedua anda.
- $Longitude2 – pembolehubah untuk longitud lokasi kedua anda.
- $unit – makhluk lalai batu. Ini boleh dikemas kini atau diluluskan sebagai kilometer.
Java: Kira Jarak Antara 2 Titik Latitud dan 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;
}
}
Pembolehubah tersebut ialah:
- garis lintang1 – pembolehubah untuk latitud lokasi pertama anda.
- longitud1 – pembolehubah untuk longitud lokasi pertama anda
- garis lintang2 – pembolehubah untuk latitud lokasi kedua anda.
- longitud2 – pembolehubah untuk longitud lokasi kedua anda.
- unit – makhluk lalai batu. Ini boleh dikemas kini atau diluluskan sebagai kilometer.
JavaScript: Kira Jarak Antara 2 Titik Latitud dan 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);
}
}
Pembolehubah tersebut ialah:
- garis lintang1 – pembolehubah untuk latitud lokasi pertama anda.
- longitud1 – pembolehubah untuk longitud lokasi pertama anda
- garis lintang2 – pembolehubah untuk latitud lokasi kedua anda.
- longitud2 – pembolehubah untuk longitud lokasi kedua anda.
- unit – makhluk lalai batu. Ini boleh dikemas kini atau diluluskan sebagai kilometer.
Python: Kira Jarak Antara 2 Titik Latitud dan Longitud
Berikut ialah formula Python untuk mengira jarak antara dua titik (bersama-sama dengan penukaran Batu lwn Kilometer) yang dibundarkan kepada dua tempat perpuluhan. Kredit kepada anak saya, Bill Karr, seorang Saintis Data untuk OpenINSIGHTS, untuk 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)
Pembolehubah tersebut ialah:
- garis lintang1 – pembolehubah untuk lokasi pertama anda latitud.
- longitud1 – pembolehubah untuk lokasi pertama anda longitud
- garis lintang2 – pembolehubah untuk lokasi kedua anda latitud.
- longitud2 – pembolehubah untuk lokasi kedua anda longitud.
- unit – makhluk lalai batu. Ini boleh dikemas kini atau diluluskan sebagai kilometer.
MySQL: Mendapatkan Semua Rekod Dalam Julat Dengan Mengira Jarak Dalam Batu Menggunakan Latitud dan Longitud
Menggunakan Jenis Data Spatial dalam MySQL ialah cara yang lebih cekap dan mudah untuk bekerja dengan data geografi, termasuk mengira jarak antara titik. MySQL menyokong Jenis Data Spatial seperti POINT
, LINESTRING
, dan POLYGON
, bersama-sama dengan fungsi spatial seperti ST_Distance
.
Apabila anda menggunakan ST_Distance
fungsi dalam MySQL dengan data geografi diwakili sebagai POINT
koordinat, ia mengambil kira kelengkungan permukaan Bumi. Model sfera yang digunakan oleh ST_Distance
menggunakan formula Haversine. Anggaran ini sesuai untuk kebanyakan tujuan praktikal tetapi mungkin menimbulkan sedikit ketidaktepatan untuk jarak yang sangat jauh.
Begini cara anda boleh mengira jarak antara dua titik menggunakan Jenis Data Spatial:
- Buat Jadual dengan Jenis Data Spatial: Pertama, buat jadual dengan a
POINT
lajur untuk menyimpan titik geografi. Sebagai contoh:
CREATE TABLE locations (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
coordinates POINT
);
Masukkan titik geografi anda ke dalam jadual ini menggunakan POINT
pembina:
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
- Kira Jarak Menggunakan ST_Distance: Anda boleh mengira jarak antara dua titik menggunakan
ST_Distance
fungsi. Berikut ialah contoh pertanyaan untuk mengira jarak antara dua titik:
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;
Ganti 1
and 2
dengan ID dua titik yang anda ingin kira jarak antara.
- Hasilnya: Pertanyaan akan mengembalikan jarak antara dua titik dalam batu.
Menggunakan Jenis Data Spatial dan ST_Distance
fungsi menyediakan cara yang lebih cekap dan tepat untuk bekerja dengan data geografi dalam MySQL. Ia juga memudahkan pengiraan jarak antara titik, menjadikannya lebih mudah untuk mengurus dan menanyakan data anda.
MySQL: Mendapatkan Semua Rekod Dalam Julat Dengan Mengira Jarak Dalam Kilometer Menggunakan Latitud dan Longitud
Secara lalai ST_Distance
mengembalikan jarak dalam meter, jadi anda hanya perlu mengemas kini pertanyaan untuk kilometer:
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;
Jarak Geografi Pelayan Microsoft SQL: STDistance
Jika anda menggunakan Microsoft SQL Server, mereka menawarkan fungsi mereka sendiri, STJarak untuk mengira jarak antara dua titik menggunakan jenis data Geografi.
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);
Tip untuk Manash Sahoo, pengasas dan arkitek kanan di Ion Tiga.