Haversine формуласын (PHP, JavaScript, Java, Python, MySQL, MSSQL мысалдары) пайдалана отырып, ендік пен бойлық нүктелері арасындағы үлкен шеңбер қашықтықты есептеңіз немесе сұраңыз.
Осы айда мен GIS үшін PHP және MySQL тілінде бағдарламалаумен айналыстым. Тақырыпты зерттеу барысында мен табуда қиналдым географиялық есептеулер екі орын арасындағы қашықтықты табу үшін, мен оларды осында бөліскім келді.
Екі нүкте арасындағы қашықтықты есептеудің қарапайым әдісі - үшбұрыштың гипотенузасын есептеу үшін Пифагор формуласын қолдану (A² + B² = C²). Бұл белгілі Евклидтік қашықтық.
Бұл қызықты бастама, бірақ бұл географияға қолданылмайды, өйткені ендік пен бойлық сызықтары арасындағы қашықтық арақашықтығы бірдей емес. Экваторға жақындаған сайын ендік сызықтары бір-бірінен алшақтайды. Қарапайым триангуляция теңдеуін қолдансаңыз, ол Жердің қисықтығына байланысты бір жерде қашықтықты дәл өлшеп, екіншісінде қате өлшеуі мүмкін.
Айналмалы арақашықтық
Жерді айналып өте ұзақ қашықтыққа жүретін жолдар Ұлы шеңбер қашықтығы деп аталады. Яғни... шардағы екі нүкте арасындағы ең қысқа қашықтық жазық картадағы нүктелерден ерекшеленеді. Мұны ендік пен бойлық сызықтарының бірдей қашықтықта еместігімен біріктіріңіз... және сізде қиын есептеу бар.
Мұнда керемет шеңберлердің қалай жұмыс істейтіні туралы фантастикалық бейне түсіндірме бар.
Гаверсин формуласы
Жердің қисаюын пайдаланатын қашықтық Жердің қисықтығына мүмкіндік беру үшін тригонометрияны пайдаланатын Гаверсин формуласына енгізілген. Жердегі 2 жердің арасындағы қашықтықты тапқан кезде (қарға ұшқанда), түзу сызық шын мәнінде доға болып табылады.
Бұл әуе рейсінде қолданылады – сіз ұшулардың нақты картасына қарап, олардың доғалы екенін байқадыңыз ба? Себебі екі нүкте арасындағы доғада ұшу тікелей орынға қарағанда қысқа.
PHP: ендік пен бойлықтың 2 нүктесінің арасындағы қашықтықты есептеңіз
Мұнда екі ондық таңбаға дейін дөңгелектенген екі нүкте арасындағы қашықтықты есептеуге арналған PHP формуласы берілген (Мил мен километрге түрлендірумен бірге).
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));
}
Айнымалылар:
- $Latitude1 – бірінші орынның ендігі үшін айнымалы.
- $Бойлық1 – бірінші орынның бойлығының айнымалысы
- $Latitude2 – екінші орынның ендігі үшін айнымалы.
- $Бойлық2 – екінші орынның бойлығының айнымалысы.
- $бірлік – әдепкі мән миль. Оны жаңартуға немесе жіберуге болады шақырым.
Java: ендік пен бойлықтың 2 нүктесі арасындағы қашықтықты есептеңіз
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;
}
}
Айнымалылар:
- ендік1 – бірінші орынның ендігі үшін айнымалы.
- бойлық 1 – бірінші орынның бойлығының айнымалысы
- ендік2 – екінші орынның ендігі үшін айнымалы.
- бойлық 2 – екінші орынның бойлығының айнымалысы.
- бірлік – әдепкі мән миль. Оны жаңартуға немесе жіберуге болады шақырым.
JavaScript: ендік пен бойлықтың 2 нүктесі арасындағы қашықтықты есептеңіз
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);
}
}
Айнымалылар:
- ендік1 – бірінші орынның ендігі үшін айнымалы.
- бойлық 1 – бірінші орынның бойлығының айнымалысы
- ендік2 – екінші орынның ендігі үшін айнымалы.
- бойлық 2 – екінші орынның бойлығының айнымалысы.
- бірлік – әдепкі мән миль. Оны жаңартуға немесе жіберуге болады шақырым.
Python: ендік пен бойлықтың 2 нүктесі арасындағы қашықтықты есептеңіз
Мұнда екі нүкте арасындағы қашықтықты есептеуге арналған Python формуласы (Мил мен Километр түрлендіруімен бірге) екі ондық таңбаға дейін дөңгелектенеді. Менің ұлым Билл Каррға, деректер жөніндегі маманға OpenINSIGHTS, код үшін.
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)
Айнымалылар:
- ендік1 – бірінші орынға арналған айнымалы ендік.
- бойлық 1 – бірінші орынға арналған айнымалы бойлық
- ендік2 – екінші орынға арналған айнымалы ендік.
- бойлық 2 – екінші орынға арналған айнымалы бойлық.
- бірлік – әдепкі мән миль. Оны жаңартуға немесе жіберуге болады шақырым.
MySQL: ендік пен бойлықты пайдаланып мильдегі қашықтықты есептеу арқылы диапазондағы барлық жазбаларды шығарып алу
MySQL жүйесінде кеңістіктік деректер түрлерін пайдалану нүктелер арасындағы қашықтықты есептеуді қоса алғанда, географиялық деректермен жұмыс істеудің тиімді және ыңғайлы әдісі болып табылады. MySQL Кеңістіктік деректер түрлерін қолдайды, мысалы POINT
, LINESTRING
, және POLYGON
сияқты кеңістіктік функциялармен бірге ST_Distance
.
Пайдалану кезінде ST_Distance
ретінде ұсынылған географиялық деректермен MySQL-де функция POINT
координаттар, ол жер бетінің қисықтығы ескеріледі. Сфералық үлгіні пайдаланған ST_Distance
Гаверсин формуласын қолданады. Бұл жуықтау көптеген практикалық мақсаттарға жарамды, бірақ өте ұзақ қашықтықтарға шамалы дәлсіздіктер әкелуі мүмкін.
Кеңістіктік деректер түрлерін пайдаланып екі нүкте арасындағы қашықтықты қалай есептеуге болады:
- Кеңістіктік деректер түрі бар кесте жасаңыз: Алдымен, кестені жасаңыз
POINT
географиялық нүктелерді сақтауға арналған баған. Мысалы:
CREATE TABLE locations (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
coordinates POINT
);
көмегімен осы кестеге географиялық нүктелерді енгізіңіз POINT
конструктор:
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 көмегімен қашықтықты есептеңіз: көмегімен екі нүкте арасындағы қашықтықты есептеуге болады
ST_Distance
функциясы. Міне, екі нүкте арасындағы қашықтықты есептеуге арналған мысал сұрау:
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;
ауыстырыңыз 1
және 2
арасындағы қашықтықты есептегіңіз келетін екі нүктенің идентификаторларымен.
- нәтиже: Сұрау екі нүкте арасындағы қашықтықты мильмен қайтарады.
Кеңістіктік деректер түрлерін пайдалану және ST_Distance
функциясы MySQL-те географиялық деректермен жұмыс істеудің тиімді және дәл әдісін қамтамасыз етеді. Ол сонымен қатар нүктелер арасындағы қашықтықты есептеуді жеңілдетеді, бұл деректерді басқаруды және сұрауды жеңілдетеді.
MySQL: ендік пен бойлықты пайдаланып километрдегі қашықтықты есептеу арқылы диапазондағы барлық жазбаларды шығарып алу
Әдепкі бойынша ST_Distance
қашықтықты метрмен қайтарады, сондықтан километрлер бойынша сұрауды жаңарту қажет:
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 серверінің географиялық қашықтығы: STDistance
Егер сіз Microsoft SQL серверін пайдалансаңыз, олар өз функцияларын ұсынады, STdistance География деректер түрін пайдаланып екі нүкте арасындағы қашықтықты есептеу үшін.
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);
Манаш Саху, негізін қалаушы және аға сәулетші Үшінші ион.