حساب المسافة بين نقطتين على سطح الكرة الأرضية

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث

يمكن حساب المسافة الفاصلة بين نقطتين على سطح الكرة الأرضية إذا علم خط الطول ودائرة العرض لكل نقطة.

مثال:

Input : Latitude 1: 53.32055555555556
        Latitude 2: 53.31861111111111
        Longitude 1: -1.7297222222222221
        Longitude 2: -1.6997222222222223
Output: Distance is: 2.0043678382716137 Kilometers

خطوات الخوارزمية

يمكن حساب المسافة بين نقطتين على سطح الكرة الأرضية باستخدام صيغة هافرساين Haversine:

تعرف مسافة الدائرة العظمى أو مسافة المسار السوي orthodromic بأنّها أقصر مسافة تفصل بين نقطتين على كرة (أو سطح الكرة الأرضية). وتتطلب هذه الطريقة معرفة إحداثيات النقطتين A و B.

تحوّل قيم خطي الطول والعرض من نظام الدرجات العشري decimal degrees إلى النظام نصف القطري radians وذلك بقسمة القيمتين على المقدار PI/180 والذي يساوي 57.29577951 تقريبًا.

تستخدم القيمة 3963 لحساب المسافة بوحدات الميل، ويمثّل هذا الرقم نصف قطر الأرض بالأميال، أما لحساب المسافة بوحدات الكيلومتر فتستخدم القيمة 6378.8 والتي تمثّل نصف قطر الأرض بالكيلومترات.

بعد تحويل إحداثيات النقطتين إلى النظام نصف القطري، تُحسب المسافة الفاصلة بينهما باستخدام العلاقة:

MILES:

d = 3963.0 * arccos[(sin(lat1) * sin(lat2)) + cos(lat1) * cos(lat2) * cos(long2 – long1)]

KILOMETERS:

d = 6378.8 * arccos[(sin(lat1) * sin(lat2)) + cos(lat1) * cos(lat2) * cos(long2 – long1)]

تنفيذ الخوارزمية

تعرض الأمثلة التالية طريقة حساب المسافة الفاصلة بين نقطتين على سطح الكرة الأرضية في عدد من لغات البرمجة:

  • C++‎:
#include <bits/stdc++.h> 
using namespace std; 

// دالة مساعدة لتحويل الدرجات إلى نصف قطر
long double toRadians(const long double °ree) 
{ 
	// cmath تقدم مكتبة
	// M_PI الثابت
	// كقيمة للنسبة الثابتة تصل دقتها إلى 1e-30
	long double one_deg = (M_PI) / 180; 
	return (one_deg * degree); 
} 

long double distance(long double lat1, long double long1, 
					long double lat2, long double long2) 
{ 
	// تحويل خطي الطول والعرض من نظام الدرجات إلى النظام نصف القطري
	lat1 = toRadians(lat1); 
	long1 = toRadians(long1); 
	lat2 = toRadians(lat2); 
	long2 = toRadians(long2); 
	
	// صيغة هافرساين
	long double dlong = long2 - long1; 
	long double dlat = lat2 - lat1; 

	long double ans = pow(sin(dlat / 2), 2) + 
						cos(lat1) * cos(lat2) * 
						pow(sin(dlong / 2), 2); 

	ans = 2 * asin(sqrt(ans)); 

	// نصف قطر الأرض بوحدات الكيلومتر
	// استخدم القيمة الخاصة بالأميال لحساب المسافة بالأميال
	long double R = 6371; 
	
	// حساب النتيجة
	ans = ans * R; 

	return ans; 
} 

// اختبار الدالة السابقة
int main() 
{ 
	long double lat1 = 53.32055555555556; 
	long double long1 = -1.7297222222222221; 
	long double lat2 = 53.31861111111111; 
	long double long2 = -1.6997222222222223; 
	
	// استدعاء دالة حساب المسافة 
	cout << setprecision(15) << fixed; 
	cout << distance(lat1, long1, 
					lat2, long2) << " K.M"; 

	return 0; 
}
  • بايثون:
from math import radians, cos, sin, asin, sqrt 
def distance(lat1, lat2, lon1, lon2): 
	
	# math تحتوي وحدة 
	# radians على دالة
	# والتي تحوّل الزوايا من نظام الدرجات إلى نظام نصف القطر
	lon1 = radians(lon1) 
	lon2 = radians(lon2) 
	lat1 = radians(lat1) 
	lat2 = radians(lat2) 
	
	# صيغة هافرساين
	dlon = lon2 - lon1 
	dlat = lat2 - lat1 
	a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2

	c = 2 * asin(sqrt(a)) 
	
	# نصف قطر الأرض بوحدات الكيلومتر.
	r = 6371
	
	# حساب النتيجة
	return(c * r) 
	
	
# اختبار الدالة السابقة
lat1 = 53.32055555555556
lat2 = 53.31861111111111
lon1 = -1.7297222222222221
lon2 = -1.6997222222222223
print(distance(lat1, lat2, lon1, lon2), "K.M")
  • جافا:
import java.util.*; 
import java.lang.*; 

class GFG { 

	public static double distance(double lat1, 
					double lat2, double lon1, 
								double lon2) 
	{ 

		// math تحتوي وحدة
		// toRadians على الدالة
		// والتي تحوّل الزوايا من نظام الدرجات إلى نظام نصف القطر
		lon1 = Math.toRadians(lon1); 
		lon2 = Math.toRadians(lon2); 
		lat1 = Math.toRadians(lat1); 
		lat2 = Math.toRadians(lat2); 

		// صيغة هافرساين
		double dlon = lon2 - lon1; 
		double dlat = lat2 - lat1; 
		double a = Math.pow(Math.sin(dlat / 2), 2) 
				+ Math.cos(lat1) * Math.cos(lat2) 
				* Math.pow(Math.sin(dlon / 2),2); 
			
		double c = 2 * Math.asin(Math.sqrt(a)); 

		// نصف قطر الكرة الأرضية بوحدات الكيلومتر
		double r = 6371; 

		// حساب النتيجة
		return(c * r); 
	} 

	// اختبار التوابع السابقة
	public static void main(String[] args) 
	{ 
		double lat1 = 53.32055555555556; 
		double lat2 = 53.31861111111111; 
		double lon1 = -1.7297222222222221; 
		double lon2 = -1.6997222222222223; 
		System.out.println(distance(lat1, lat2, 
						lon1, lon2) + " K.M"); 
	} 
}

مصادر