Haversine formulasidan foydalanib, kenglik va uzunlik nuqtalari orasidagi katta doira masofasini hisoblang yoki so'rang (PHP, JavaScript, Java, Python, MySQL, MSSQL misollari)
Bu oyda men GIS uchun PHP va MySQL-da dasturlash bilan shug'ullanaman. Mavzuni o'rganar ekanman, topishda qiynaldim geografik hisoblar ikkita joy orasidagi masofani topish uchun, shuning uchun men ularni bu erda baham ko'rmoqchi edim.
Ikki nuqta orasidagi masofani hisoblashning oddiy usuli - uchburchakning gipotenuzasini (A² + B² = C²) hisoblash uchun Pifagor formulasidan foydalanish. Bu sifatida tanilgan Evklid masofasi.
Bu qiziqarli boshlanish, lekin geografiyaga taalluqli emas, chunki kenglik va uzunlik chiziqlari orasidagi masofa bir-biridan teng masofada emas. Ekvatorga yaqinlashganda, kenglik chiziqlari bir-biridan uzoqlashadi. Agar siz oddiy triangulyatsiya tenglamasidan foydalansangiz, u Yerning egriligi tufayli bir joyda masofani aniq, ikkinchisida noto'g'ri o'lchashi mumkin.
Katta doiradagi masofa
Yer atrofida uzoq masofalarni bosib o'tgan marshrutlar Buyuk doira masofasi deb nomlanadi. Ya'ni ... shardagi ikkita nuqta orasidagi eng qisqa masofa tekis xaritadagi nuqtalardan farq qiladi. Buni kenglik va uzunlik chiziqlari bir xil masofada emasligi bilan birlashtiring... va sizda qiyin hisob bor.
Buyuk doiralar qanday ishlashini fantastik video tushuntirish.
Haversine formulasi
Erning egri chizig'idan foydalangan holda masofa Haversine formulasiga kiritilgan bo'lib, u Yerning egriligini ta'minlash uchun trigonometriyadan foydalanadi. Erdagi 2 ta joy orasidagi masofani topayotganingizda (qarg'a uchayotganda), to'g'ri chiziq aslida yoydir.
Bu havo parvozida qo'llaniladi - siz hech qachon parvozlarning haqiqiy xaritasini ko'rib chiqdingizmi va ular kamon shaklida ekanligini payqadingizmi? Buning sababi shundaki, ikkita nuqta orasidagi kamonda uchish to'g'ridan-to'g'ri joyga qaraganda qisqaroq.
PHP: Kenglik va uzunlikning 2 punkti orasidagi masofani hisoblang
Mana ikki nuqta orasidagi masofani hisoblash uchun PHP formulasi (Mile va Kilometrga aylantirish bilan birga) ikkita kasrga yaxlitlangan.
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));
}
O'zgaruvchilar quyidagilardir:
- $Latitude1 – birinchi joylashuvingizning kengligi uchun o‘zgaruvchi.
- $ Longitude1 – birinchi joylashuvingizning uzunligi uchun o‘zgaruvchi
- $Latitude2 – ikkinchi joylashuvingizning kengligi uchun oʻzgaruvchi.
- $ Longitude2 – ikkinchi joylashuvingizning uzunligi uchun oʻzgaruvchi.
- $ birlik – standart mavjudlik milya. Bu yangilanishi yoki o'tkazilishi mumkin kilometr.
Java: 2 kenglik va uzunlik nuqtasi orasidagi masofani hisoblang
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;
}
}
O'zgaruvchilar quyidagilardir:
- kenglik1 – birinchi joylashuvingizning kengligi uchun o‘zgaruvchi.
- uzunlik 1 – birinchi joylashuvingizning uzunligi uchun o‘zgaruvchi
- kenglik2 – ikkinchi joylashuvingizning kengligi uchun oʻzgaruvchi.
- uzunlik 2 – ikkinchi joylashuvingizning uzunligi uchun oʻzgaruvchi.
- birlik – standart mavjudlik milya. Bu yangilanishi yoki o'tkazilishi mumkin kilometr.
JavaScript: 2 kenglik va uzunlik nuqtasi orasidagi masofani hisoblang
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);
}
}
O'zgaruvchilar quyidagilardir:
- kenglik1 – birinchi joylashuvingizning kengligi uchun o‘zgaruvchi.
- uzunlik 1 – birinchi joylashuvingizning uzunligi uchun o‘zgaruvchi
- kenglik2 – ikkinchi joylashuvingizning kengligi uchun oʻzgaruvchi.
- uzunlik 2 – ikkinchi joylashuvingizning uzunligi uchun oʻzgaruvchi.
- birlik – standart mavjudlik milya. Bu yangilanishi yoki o'tkazilishi mumkin kilometr.
Python: 2 kenglik va uzunlik nuqtasi orasidagi masofani hisoblang
Mana, ikki nuqta orasidagi masofani hisoblash uchun Python formulasi (Mile va Kilometrga aylantirish bilan birga) ikkita kasrga yaxlitlangan. O'g'lim Bill Karrga, ma'lumotlar bo'yicha mutaxassis OpenINSIGHTS, kod uchun.
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)
O'zgaruvchilar quyidagilardir:
- kenglik1 – birinchi joylashuvingiz uchun o‘zgaruvchi kenglik.
- uzunlik 1 – birinchi joylashuvingiz uchun o‘zgaruvchi uzunlik
- kenglik2 – ikkinchi joylashuvingiz uchun oʻzgaruvchi kenglik.
- uzunlik 2 – ikkinchi joylashuvingiz uchun oʻzgaruvchi uzunlik.
- birlik – standart mavjudlik milya. Bu yangilanishi yoki o'tkazilishi mumkin kilometr.
MySQL: kenglik va uzunlikdan foydalangan holda millardagi masofani hisoblash orqali barcha yozuvlarni diapazonda olish
MySQL-da fazoviy ma'lumotlar turlaridan foydalanish geografik ma'lumotlar bilan ishlashning, jumladan, nuqtalar orasidagi masofani hisoblashning yanada samarali va qulay usuli hisoblanadi. MySQL fazoviy ma'lumotlar turlarini qo'llab-quvvatlaydi, masalan POINT
, LINESTRING
va POLYGON
, kabi fazoviy funktsiyalar bilan birga ST_Distance
.
Siz foydalanganingizda ST_Distance
sifatida ifodalangan geografik ma'lumotlar bilan MySQL-da funksiya POINT
koordinatalar, u Yer yuzasining egriligini hisobga oladi. tomonidan ishlatiladigan sharsimon model ST_Distance
Haversine formulasidan foydalanadi. Ushbu yaqinlik ko'pgina amaliy maqsadlar uchun mos keladi, lekin juda uzoq masofalar uchun ozgina noaniqliklarni keltirib chiqarishi mumkin.
Fazoviy ma'lumotlar turlaridan foydalanib, ikki nuqta orasidagi masofani qanday hisoblashingiz mumkin:
- Fazoviy ma'lumotlar turi bilan jadval yarating: Birinchidan, a bilan jadval yarating
POINT
geografik nuqtalarni saqlash uchun ustun. Masalan:
CREATE TABLE locations (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
coordinates POINT
);
dan foydalanib, ushbu jadvalga geografik nuqtalaringizni kiriting 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 yordamida masofani hisoblang: yordamida ikki nuqta orasidagi masofani hisoblashingiz mumkin
ST_Distance
funktsiyasi. Ikki nuqta orasidagi masofani hisoblash uchun misol so'rovi:
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;
almashtiring 1
va 2
orasidagi masofani hisoblamoqchi bo'lgan ikkita nuqtaning identifikatorlari bilan.
- natija: So'rov ikki nuqta orasidagi masofani mil bilan qaytaradi.
Fazoviy ma'lumotlar turlaridan foydalanish va ST_Distance
Funktsiya MySQL-da geografik ma'lumotlar bilan ishlashning yanada samarali va aniq usulini ta'minlaydi. Shuningdek, u nuqtalar orasidagi masofani hisoblashni soddalashtiradi, ma'lumotlaringizni boshqarish va so'rovni osonlashtiradi.
MySQL: kenglik va uzunlikdan foydalanib, kilometrlarda masofani hisoblash orqali barcha yozuvlarni diapazonda olish
Avvalboshdan ST_Distance
masofani metrlarda qaytaradi, shuning uchun siz kilometrlar uchun so'rovni yangilashingiz kerak:
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 geografik masofa: STDistance
Agar siz Microsoft SQL Server dan foydalansangiz, ular o'z funksiyalarini taklif qiladilar, ST masofa Geografiya ma'lumotlar turidan foydalangan holda ikki nuqta orasidagi masofani hisoblash uchun.
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);
asoschisi va katta arxitektori Manash Sahooga shlyapa maslahati Ion uchinchi.