გამოთვალეთ ან მოიძიეთ დიდი წრის მანძილი გრძედისა და განედის წერტილებს შორის Haversine ფორმულის გამოყენებით (PHP, JavaScript, Java, Python, MySQL, MSSQL მაგალითები)
ამ თვეში ვპროგრამირებდი PHP-ში და MySQL-ში GIS-ისთვის. თემის შესწავლისას გამიჭირდა პოვნა გეოგრაფიული გამოთვლები ორ ადგილს შორის მანძილის პოვნა, ამიტომ მინდოდა მათი აქ გაზიარება.
ორ წერტილს შორის მანძილის გამოთვლის მარტივი გზაა პითაგორას ფორმულის გამოყენებით სამკუთხედის ჰიპოტენუზის გამოსათვლელად (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 – ცვლადი თქვენი მეორე მდებარეობის გრძედისთვის.
- $ ერთეული - ნაგულისხმევი არსება მილი. ეს შეიძლება განახლდეს ან გადაიცეს როგორც კილომეტრები.
ჯავა: გამოთვალეთ მანძილი გრძედისა და განედის 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 – ცვლადი თქვენი მეორე მდებარეობის გრძედისთვის.
- ერთეულის - ნაგულისხმევი არსება მილი. ეს შეიძლება განახლდეს ან გადაიცეს როგორც კილომეტრები.
პითონი: გამოთვალეთ მანძილი გრძედისა და განედის 2 წერტილს შორის
აი პითონის ფორმულა ორ წერტილს შორის მანძილის გამოსათვლელად (მაილის წინააღმდეგ კილომეტრის კონვერტაციასთან ერთად) დამრგვალებული ორ ათწილადამდე. მადლობა ჩემს შვილს, ბილ კარს, მონაცემთა მეცნიერს 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
იყენებს Haversine ფორმულას. ეს მიახლოება შესაფერისია უმეტესი პრაქტიკული მიზნებისთვის, მაგრამ შეიძლება გამოიწვიოს მცირე უზუსტობები ძალიან დიდ დისტანციებზე.
აი, როგორ შეგიძლიათ გამოთვალოთ მანძილი ორ წერტილს შორის სივრცითი მონაცემთა ტიპების გამოყენებით:
- შექმენით ცხრილი სივრცითი მონაცემების ტიპით: ჯერ შექმენით ცხრილი ა
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;
Replace 1
მდე 2
ორი წერტილის ID-ებით, რომელთა შორის მანძილი უნდა გამოთვალოთ.
- შედეგი: შეკითხვა დააბრუნებს მანძილს ორ წერტილს შორის მილში.
სივრცითი მონაცემთა ტიპების გამოყენება და 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 Server გეოგრაფიული მანძილი: STDistance
თუ თქვენ იყენებთ Microsoft SQL Server-ს, ისინი გთავაზობთ საკუთარ ფუნქციას, ST მანძილი გეოგრაფიის მონაცემთა ტიპის გამოყენებით ორ წერტილს შორის მანძილის გამოსათვლელად.
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);
ქუდის წვერი მანაშ საჰუსთვის, დამფუძნებელი და უფროსი არქიტექტორი იონი სამი.