Haversine Formulasından (PHP, JavaScript, Java, Python, MySQL, MSSQL Nümunələri) istifadə edərək, Enlem və Boylam Nöqtələri Arasındakı Böyük Dairənin Məsafəsini Hesablayın və ya Sorğulayın
Bu ay mən CIS üçün PHP və MySQL dillərində proqramlaşdırma ilə məşğul oldum. Mövzunu araşdırarkən tapmaqda çətinlik çəkdim coğrafi hesablamalar iki yer arasındakı məsafəni tapmaq üçün onları burada paylaşmaq istədim.
İki nöqtə arasındakı məsafəni hesablamağın sadə yolu üçbucağın (A² + B² = C²) hipotenusunu hesablamaq üçün Pifaqor düsturundan istifadə etməkdir. Bu kimi tanınır Evklid məsafəsi.
Bu, maraqlı başlanğıcdır, lakin coğrafiyaya aid deyil, çünki enlik və uzunluq xətləri arasındakı məsafə bərabər məsafədə deyil. Ekvatora yaxınlaşdıqca enlik xətləri bir-birindən uzaqlaşır. Sadə üçbucaqlı tənlikdən istifadə etsəniz, o, Yerin əyriliyinə görə bir yerdə məsafəni dəqiq, digərində isə səhv ölçə bilər.
Böyük dairə məsafəsi
Yer ətrafında uzun məsafələrə qət edilən marşrutlar Böyük Dairə Məsafəsi kimi tanınır. Yəni... kürənin iki nöqtəsi arasındakı ən qısa məsafə düz xəritədəki nöqtələrdən fərqlənir. Bunu enlem və uzunluq xətlərinin bərabər məsafədə olmaması faktı ilə birləşdirin... və çətin bir hesablama var.
Budur Böyük Dairələrin necə işlədiyini göstərən fantastik video izahatı.
Haversine Formulu
Yerin əyriliyini istifadə edən məsafə Yerin əyriliyinə icazə vermək üçün triqonometriyadan istifadə edən Haversine düsturuna daxil edilmişdir. Yer üzündə 2 yer arasındakı məsafəni tapdığınız zaman (qarğa uçduqca), düz xətt əslində qövsdür.
Bu, hava uçuşunda tətbiq olunur – siz heç uçuşların faktiki xəritəsinə baxmısınız və onların tağlı olduğunu görmüsünüz? Bunun səbəbi, iki nöqtə arasında bir qövsdə uçmağın birbaşa yerə nisbətən daha qısa olmasıdır.
PHP: Enlem və Boylam 2 nöqtəsi arasındakı məsafəni hesablayın
Budur iki nöqtə arasındakı məsafəni hesablamaq üçün PHP düsturu (Mile vs. Kilometrə çevirmə ilə birlikdə) iki onluq yerə yuvarlaqlaşdırılıb.
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));
}
Dəyişənlər bunlardır:
- $Enlem1 – ilk yerinizin eni üçün dəyişən.
- $Uzunluq1 – ilk yerinizin uzunluğu üçün dəyişən
- $Enlem2 – ikinci yerinizin eni üçün dəyişən.
- $Uzunluq2 – ikinci yerinizin uzunluğu üçün dəyişən.
- $vahid – standart varlıq mil. Bu yenilənə və ya ötürülə bilər kilometr.
Java: 2 Enlem və Boylam Nöqtələri Arasındakı Məsafəni Hesablayın
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;
}
}
Dəyişənlər bunlardır:
- enlik1 – ilk yerinizin eni üçün dəyişən.
- uzunluq 1 – ilk yerinizin uzunluğu üçün dəyişən
- enlik2 – ikinci yerinizin eni üçün dəyişən.
- uzunluq 2 – ikinci yerinizin uzunluğu üçün dəyişən.
- vahid – standart varlıq mil. Bu yenilənə və ya ötürülə bilər kilometr.
JavaScript: 2 Enlem və Uzunluq Nöqtələri Arasındakı Məsafəni Hesablayın
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);
}
}
Dəyişənlər bunlardır:
- enlik1 – ilk yerinizin eni üçün dəyişən.
- uzunluq 1 – ilk yerinizin uzunluğu üçün dəyişən
- enlik2 – ikinci yerinizin eni üçün dəyişən.
- uzunluq 2 – ikinci yerinizin uzunluğu üçün dəyişən.
- vahid – standart varlıq mil. Bu yenilənə və ya ötürülə bilər kilometr.
Python: 2 Enlem və Boylam Nöqtələri Arasındakı Məsafəni Hesablayın
Budur iki nöqtə arasındakı məsafəni hesablamaq üçün Python düsturu (Mile vs. Kilometrə çevirmə ilə birlikdə) iki onluq yerə yuvarlaqlaşdırılmışdır. Oğlum Bill Karr, Data Scientist üçün kredit OpenINSIGHTS, kod üçün.
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)
Dəyişənlər bunlardır:
- enlik1 – ilk yeriniz üçün dəyişən Enlem.
- uzunluq 1 – ilk yeriniz üçün dəyişən uzunluq
- enlik2 – ikinci yeriniz üçün dəyişən Enlem.
- uzunluq 2 – ikinci yeriniz üçün dəyişən uzunluq.
- vahid – standart varlıq mil. Bu yenilənə və ya ötürülə bilər kilometr.
MySQL: Enlem və Boylamdan istifadə edərək millərlə məsafəni hesablamaqla bir diapazonda olan bütün qeydləri əldə etmək
MySQL-də Məkan Məlumat Növlərindən istifadə coğrafi məlumatlar, o cümlədən nöqtələr arasındakı məsafələrin hesablanması ilə işləmək üçün daha səmərəli və rahat üsuldur. MySQL kimi məkan məlumat növlərini dəstəkləyir POINT
, LINESTRING
və POLYGON
kimi məkan funksiyaları ilə yanaşı ST_Distance
.
İstifadə edərkən ST_Distance
kimi təmsil olunan coğrafi məlumatlarla MySQL-də funksiya POINT
koordinatları, Yer səthinin əyriliyini nəzərə alır. tərəfindən istifadə edilən sferik model ST_Distance
Haversine düsturundan istifadə edir. Bu yaxınlaşma əksər praktik məqsədlər üçün uyğundur, lakin çox uzun məsafələr üçün kiçik qeyri-dəqiqliklərə səbəb ola bilər.
Məkan Məlumat Növlərindən istifadə edərək iki nöqtə arasındakı məsafələri necə hesablaya bilərsiniz:
- Məkan məlumat növü ilə bir cədvəl yaradın: Əvvəlcə a ilə cədvəl yaradın
POINT
coğrafi nöqtələri saxlamaq üçün sütun. Misal üçün:
CREATE TABLE locations (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
coordinates POINT
);
istifadə edərək coğrafi nöqtələrinizi bu cədvələ daxil edin POINT
konstruktor:
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
- ST_Distance istifadə edərək məsafəni hesablayın: istifadə edərək iki nöqtə arasındakı məsafəni hesablaya bilərsiniz
ST_Distance
funksiyası. İki nöqtə arasındakı məsafəni hesablamaq üçün nümunə sorğu:
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;
Dəyişdirmək 1
və 2
aralarındakı məsafəni hesablamaq istədiyiniz iki nöqtənin identifikatoru ilə.
- Nəticə: Sorğu iki nöqtə arasındakı məsafəni mil ilə qaytaracaq.
Məkan məlumat növlərinin istifadəsi və ST_Distance
funksiyası MySQL-də coğrafi məlumatlarla işləmək üçün daha səmərəli və dəqiq üsul təqdim edir. O, həmçinin nöqtələr arasında məsafələrin hesablanmasını asanlaşdırır, məlumatlarınızı idarə etməyi və sorğulamağı asanlaşdırır.
MySQL: Enlem və Boylamdan istifadə edərək kilometrlərlə məsafəni hesablamaqla bir diapazonda olan bütün qeydləri əldə etmək
Mənim cari olaraq ST_Distance
məsafəni metrlə qaytarır, buna görə də sadəcə kilometrlər üçün sorğunu yeniləməlisiniz:
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 Coğrafi Məsafə: STDistance
Microsoft SQL Serverindən istifadə edirsinizsə, onlar öz funksiyalarını təklif edirlər, STDistance Coğrafiya məlumat növündən istifadə edərək iki nöqtə arasındakı məsafəni hesablamaq üçün.
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);
Şirkətin qurucusu və baş memarı Manash Sahoo-ya papaq ucu İon Üç.