حساب المسافة بين اثنين من خط العرض-خط الطول النقاط ؟ (Haversine الصيغة)
-
09-06-2019 - |
سؤال
كيف يمكنني حساب المسافة بين نقطتين المحدد من قبل خط العرض و خط الطول ؟
للتوضيح, أود المسافة بالكيلومترات;النقاط استخدام نظام WGS84 و أود أن نفهم النسبية دقة من الأساليب المتاحة.
المحلول
هذا الرابط قد يكون من المفيد لك ، كما تفاصيل استخدام Haversine الصيغة لحساب المسافة.
مقتطفات:
هذا البرنامج النصي [في جافا سكريبت] يحسب الدائرة العظمى المسافات بين نقطتين – هذا هو أقصر مسافة أكثر من سطح الأرض باستخدام 'Haversine' الصيغة.
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI/180)
}
نصائح أخرى
أنا في حاجة إلى حساب الكثير من المسافات بين النقاط ، لذلك ذهبت إلى الأمام و حاول تحسين التعليمات البرمجية ، لقد وجدت هنا.في المتوسط في مختلف المتصفحات الجديد التنفيذ يعمل 2 مرات أسرع من أكثر upvoted الإجابة.
function distance(lat1, lon1, lat2, lon2) {
var p = 0.017453292519943295; // Math.PI / 180
var c = Math.cos;
var a = 0.5 - c((lat2 - lat1) * p)/2 +
c(lat1 * p) * c(lat2 * p) *
(1 - c((lon2 - lon1) * p))/2;
return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
}
يمكنك أن تلعب مع jsPerf ونرى النتائج هنا.
في الآونة الأخيرة كنت بحاجة إلى أن تفعل الشيء نفسه في بيثون ، حتى هنا هو تنفيذ الثعبان:
from math import cos, asin, sqrt
def distance(lat1, lon1, lat2, lon2):
p = 0.017453292519943295 #Pi/180
a = 0.5 - cos((lat2 - lat1) * p)/2 + cos(lat1 * p) * cos(lat2 * p) * (1 - cos((lon2 - lon1) * p)) / 2
return 12742 * asin(sqrt(a)) #2*R*asin...
ومن أجل اكتمال: Haversine على ويكي.
هنا هو C# تنفيذ:
static class DistanceAlgorithm
{
const double PIx = 3.141592653589793;
const double RADIUS = 6378.16;
/// <summary>
/// Convert degrees to Radians
/// </summary>
/// <param name="x">Degrees</param>
/// <returns>The equivalent in radians</returns>
public static double Radians(double x)
{
return x * PIx / 180;
}
/// <summary>
/// Calculate the distance between two places.
/// </summary>
/// <param name="lon1"></param>
/// <param name="lat1"></param>
/// <param name="lon2"></param>
/// <param name="lat2"></param>
/// <returns></returns>
public static double DistanceBetweenPlaces(
double lon1,
double lat1,
double lon2,
double lat2)
{
double dlon = Radians(lon2 - lon1);
double dlat = Radians(lat2 - lat1);
double a = (Math.Sin(dlat / 2) * Math.Sin(dlat / 2)) + Math.Cos(Radians(lat1)) * Math.Cos(Radians(lat2)) * (Math.Sin(dlon / 2) * Math.Sin(dlon / 2));
double angle = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
return angle * RADIUS;
}
}
هنا هو جافا تنفيذ Haversine الصيغة.
public final static double AVERAGE_RADIUS_OF_EARTH_KM = 6371;
public int calculateDistanceInKilometer(double userLat, double userLng,
double venueLat, double venueLng) {
double latDistance = Math.toRadians(userLat - venueLat);
double lngDistance = Math.toRadians(userLng - venueLng);
double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
+ Math.cos(Math.toRadians(userLat)) * Math.cos(Math.toRadians(venueLat))
* Math.sin(lngDistance / 2) * Math.sin(lngDistance / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return (int) (Math.round(AVERAGE_RADIUS_OF_EARTH_KM * c));
}
نلاحظ أن هنا نحن التقريب الجواب إلى أقرب كم.
شكرا جزيلا على كل هذا.أنا استخدم التعليمات البرمجية التالية في الهدف-C فون التطبيق:
const double PIx = 3.141592653589793;
const double RADIO = 6371; // Mean radius of Earth in Km
double convertToRadians(double val) {
return val * PIx / 180;
}
-(double)kilometresBetweenPlace1:(CLLocationCoordinate2D) place1 andPlace2:(CLLocationCoordinate2D) place2 {
double dlon = convertToRadians(place2.longitude - place1.longitude);
double dlat = convertToRadians(place2.latitude - place1.latitude);
double a = ( pow(sin(dlat / 2), 2) + cos(convertToRadians(place1.latitude))) * cos(convertToRadians(place2.latitude)) * pow(sin(dlon / 2), 2);
double angle = 2 * asin(sqrt(a));
return angle * RADIO;
}
خطوط الطول والعرض في عشري.لم أكن استخدام مين() عن كمافي() الدعوة المسافات التي أنا باستخدام صغيرة جدا لدرجة أنها لا تتطلب ذلك.
أنه أعطى إجابات غير صحيحة حتى مررت في القيم في راديان - الآن انها الى حد كبير نفس القيم التي تم الحصول عليها من أبل خريطة التطبيق :-)
إضافية التحديث:
إذا كنت تستخدم iOS4 أو في وقت لاحق ثم أبل توفر بعض الطرق للقيام بذلك حتى نفس الوظائف يتحقق مع:
-(double)kilometresBetweenPlace1:(CLLocationCoordinate2D) place1 andPlace2:(CLLocationCoordinate2D) place2 {
MKMapPoint start, finish;
start = MKMapPointForCoordinate(place1);
finish = MKMapPointForCoordinate(place2);
return MKMetersBetweenMapPoints(start, finish) / 1000;
}
هذا هو بسيط PHP وظيفة من شأنها أن تعطي معقول جدا التقريب (تحت +/-1% وهامش الخطأ).
<?php
function distance($lat1, $lon1, $lat2, $lon2) {
$pi80 = M_PI / 180;
$lat1 *= $pi80;
$lon1 *= $pi80;
$lat2 *= $pi80;
$lon2 *= $pi80;
$r = 6372.797; // mean radius of Earth in km
$dlat = $lat2 - $lat1;
$dlon = $lon2 - $lon1;
$a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlon / 2) * sin($dlon / 2);
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
$km = $r * $c;
//echo '<br/>'.$km;
return $km;
}
?>
كما قلت من قبل ؛ الأرض ليست كروية.هو مثل قديم البيسبول أن علامة [مكغوير] قررت الممارسة مع - هو الكامل من الخدوش والصدمات.أبسط العمليات الحسابية (مثل هذا) التعامل معها مثل المجال.
أساليب مختلفة قد تكون أكثر أو أقل دقة وفقا أين أنت في هذا غير النظامية بيضوي الشكل و كم نقاطك (أقرب هم أصغر مطلقة خطأ هامش).أكثر دقة التوقعات الخاصة بك ، وأكثر تعقيدا الرياضيات.
لمزيد من المعلومات: ويكيبيديا المسافة الجغرافية
أنا هنا آخر العمل على سبيل المثال.
قائمة جميع النقاط في الجدول وجود مسافة بين نقطة معينة (نستخدم نقطة عشوائية - اللات:45.20327 طويلة:23.7806) أقل من 50 كم ، مع خطوط الطول والعرض في الخلية (الجدول الحقول coord_lat و coord_long):
قائمة بجميع بعد المسافة<50 في كم (يعتبر نصف قطر الأرض 6371 كم):
SELECT denumire, (6371 * acos( cos( radians(45.20327) ) * cos( radians( coord_lat ) ) * cos( radians( 23.7806 ) - radians(coord_long) ) + sin( radians(45.20327) ) * sin( radians(coord_lat) ) )) AS distanta
FROM obiective
WHERE coord_lat<>''
AND coord_long<>''
HAVING distanta<50
ORDER BY distanta desc
المثال أعلاه تم اختباره في الخلية 5.0.95 و 5.5.16 (لينكس).
في إجابات أخرى تنفيذية في r هو في عداد المفقودين.
حساب المسافة بين نقطتين هي واضحة تماما مع distm
وظيفة من geosphere
الحزمة:
distm(p1, p2, fun = distHaversine)
حيث:
p1 = longitude/latitude for point(s)
p2 = longitude/latitude for point(s)
# type of distance calculation
fun = distCosine / distHaversine / distVincentySphere / distVincentyEllipsoid
كما أن الأرض ليست كروية تماما ، Vincenty معادلة القطع الناقص هو على الأرجح أفضل طريقة لحساب المسافات.وهكذا في geosphere
الحزمة يمكنك استخدام ثم:
distm(p1, p2, fun = distVincentyEllipsoid)
طبعا ليس لديك بالضرورة إلى استخدام geosphere
حزمة يمكنك أيضا حساب المسافة في قاعدة R
مع وظيفة:
hav.dist <- function(long1, lat1, long2, lat2) {
R <- 6371
diff.long <- (long2 - long1)
diff.lat <- (lat2 - lat1)
a <- sin(diff.lat/2)^2 + cos(lat1) * cos(lat2) * sin(diff.long/2)^2
b <- 2 * asin(pmin(1, sqrt(a)))
d = R * b
return(d)
}
على haversine هو بالتأكيد جيدة صيغة ربما معظم الحالات إجابات أخرى تشمل بالفعل لذلك لن تأخذ مساحة.ولكن من المهم أن نلاحظ أنه لا يهم ما يستخدم صيغة (نعم وليس واحدة فقط).بسبب مجموعة واسعة من دقة ممكنة فضلا عن حساب الوقت المطلوب.اختيار الصيغة يتطلب أكثر قليلا من التفكير مجرد عدم التفكير في الإجابة.
هذا المنشور من شخص في وكالة ناسا ، هو أفضل واحد لقد وجدت في مناقشة الخيارات
http://www.cs.nyu.edu/visual/home/proj/tiger/gisfaq.html
على سبيل المثال ، إذا كنت مجرد فرز الصفوف من خلال المسافة في دائرة نصف قطرها 100 ميل.الأرض مسطحة الصيغة سوف يكون أسرع بكثير من haversine.
HalfPi = 1.5707963;
R = 3956; /* the radius gives you the measurement unit*/
a = HalfPi - latoriginrad;
b = HalfPi - latdestrad;
u = a * a + b * b;
v = - 2 * a * b * cos(longdestrad - longoriginrad);
c = sqrt(abs(u + v));
return R * c;
لاحظت أن هناك واحد فقط التمام واحدة الجذر التربيعي.مقابل 9 منهم على Haversine الصيغة.
يمكنك استخدام بناء في CLLocationDistance لحساب هذا:
CLLocation *location1 = [[CLLocation alloc] initWithLatitude:latitude1 longitude:longitude1];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:latitude2 longitude:longitude2];
[self distanceInMetersFromLocation:location1 toLocation:location2]
- (int)distanceInMetersFromLocation:(CLLocation*)location1 toLocation:(CLLocation*)location2 {
CLLocationDistance distanceInMeters = [location1 distanceFromLocation:location2];
return distanceInMeters;
}
في حالة إذا كنت تريد كيلومترا فقط القسمة على 1000.
أنا لا أحب إضافة بعد آخر الجواب ، ولكن خرائط جوجل API v. 3 كروية الهندسة (وأكثر).بعد تحويل WGS84 إلى الدرجات العشرية يمكنك القيام بذلك:
<script src="http://maps.google.com/maps/api/js?sensor=false&libraries=geometry" type="text/javascript"></script>
distance = google.maps.geometry.spherical.computeDistanceBetween(
new google.maps.LatLng(fromLat, fromLng),
new google.maps.LatLng(toLat, toLng));
لا كلمة عن مدى دقة جوجل الحسابات أو حتى ما يستخدم نموذج (على الرغم من أنه لا يقول "كروية" بدلا من "geoid".بالمناسبة "خط مستقيم" المسافة ستكون مختلفة عن المسافة إذا كان أحد يسافر على سطح الأرض وهو ما يبدو أن الجميع افتراض.
بيثون implimentation الأصل هو مركز الولايات المتحدة متجاورة.
from haversine import haversine
origin = (39.50, 98.35)
paris = (48.8567, 2.3508)
haversine(origin, paris, miles=True)
للحصول على الجواب في كم ببساطة تعيين ميل=false.
يمكن أن يكون هناك حل أبسط وأكثر الصحيح:محيط الأرض هو 40000 كم عند خط الاستواء حوالي 37,000 على غرينيتش (أو أي خط الطول) دورة.وبالتالي:
pythagoras = function (lat1, lon1, lat2, lon2) {
function sqr(x) {return x * x;}
function cosDeg(x) {return Math.cos(x * Math.PI / 180.0);}
var earthCyclePerimeter = 40000000.0 * cosDeg((lat1 + lat2) / 2.0);
var dx = (lon1 - lon2) * earthCyclePerimeter / 360.0;
var dy = 37000000.0 * (lat1 - lat2) / 360.0;
return Math.sqrt(sqr(dx) + sqr(dy));
};
أوافق على أنه ينبغي أن يكون على ما يرام ضبطها كما أنا نفسي قال أنه الاهليلجي ، حتى نصف قطر أن يكون مضروبا في جيب تمام يختلف.ولكن هذا قليلا أكثر دقة.مقارنة مع خرائط جوجل و لم تقلل من خطأ كبير.
كل الإجابات أعلاه يفترض أن الأرض كرة.ومع ذلك ، فإن أكثر دقة التقريب أن يكون ذلك من أحد كروي مفلطح.
a= 6378.137#equitorial radius in km
b= 6356.752#polar radius in km
def Distance(lat1, lons1, lat2, lons2):
lat1=math.radians(lat1)
lons1=math.radians(lons1)
R1=(((((a**2)*math.cos(lat1))**2)+(((b**2)*math.sin(lat1))**2))/((a*math.cos(lat1))**2+(b*math.sin(lat1))**2))**0.5 #radius of earth at lat1
x1=R*math.cos(lat1)*math.cos(lons1)
y1=R*math.cos(lat1)*math.sin(lons1)
z1=R*math.sin(lat1)
lat2=math.radians(lat2)
lons2=math.radians(lons2)
R1=(((((a**2)*math.cos(lat2))**2)+(((b**2)*math.sin(lat2))**2))/((a*math.cos(lat2))**2+(b*math.sin(lat2))**2))**0.5 #radius of earth at lat2
x2=R*math.cos(lat2)*math.cos(lons2)
y2=R*math.cos(lat2)*math.sin(lons2)
z2=R*math.sin(lat2)
return ((x1-x2)**2+(y1-y2)**2+(z1-z2)**2)**0.5
هنا نسخة مطبوعة على الآلة الكاتبة تنفيذ Haversine الصيغة
static getDistanceFromLatLonInKm(lat1: number, lon1: number, lat2: number, lon2: number): number {
var deg2Rad = deg => {
return deg * Math.PI / 180;
}
var r = 6371; // Radius of the earth in km
var dLat = deg2Rad(lat2 - lat1);
var dLon = deg2Rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2Rad(lat1)) * Math.cos(deg2Rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = r * c; // Distance in km
return d;
}
هذا البرنامج النصي [PHP] يحسب المسافات بين نقطتين.
public static function getDistanceOfTwoPoints($source, $dest, $unit='K') {
$lat1 = $source[0];
$lon1 = $source[1];
$lat2 = $dest[0];
$lon2 = $dest[1];
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$miles = $dist * 60 * 1.1515;
$unit = strtoupper($unit);
if ($unit == "K") {
return ($miles * 1.609344);
}
else if ($unit == "M")
{
return ($miles * 1.609344 * 1000);
}
else if ($unit == "N") {
return ($miles * 0.8684);
}
else {
return $miles;
}
}
هنا هو SQL تنفيذ لحساب المسافة في كم ،
SELECT UserId, ( 3959 * acos( cos( radians( your latitude here ) ) * cos( radians(latitude) ) *
cos( radians(longitude) - radians( your longitude here ) ) + sin( radians( your latitude here ) ) *
sin( radians(latitude) ) ) ) AS distance FROM user HAVING
distance < 5 ORDER BY distance LIMIT 0 , 5;
لحساب المسافة بين نقطتين على سطح الكرة تحتاج إلى القيام الدائرة الكبرى الحساب.
هناك عدد من C/C++ المكتبات إلى مساعدة مع خريطة الإسقاط في MapTools إذا كنت بحاجة إلى reproject الخاص بك المسافات على سطح مستو.للقيام بذلك سوف تحتاج الإسقاط سلسلة من مختلف أنظمة الإحداثيات.
قد تجد أيضا MapWindow أداة مفيدة في تصور نقطة.كما المفتوحة المصدر مفيدة دليل كيفية استخدام proj.dll المكتبة التي يبدو أن النواة مفتوحة المصدر الإسقاط المكتبة.
هنا الجواب المقبول تنفيذ استدار إلى جافا في حالة أي شخص يحتاج إليها.
package com.project529.garage.util;
/**
* Mean radius.
*/
private static double EARTH_RADIUS = 6371;
/**
* Returns the distance between two sets of latitudes and longitudes in meters.
* <p/>
* Based from the following JavaScript SO answer:
* http://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula,
* which is based on https://en.wikipedia.org/wiki/Haversine_formula (error rate: ~0.55%).
*/
public double getDistanceBetween(double lat1, double lon1, double lat2, double lon2) {
double dLat = toRadians(lat2 - lat1);
double dLon = toRadians(lon2 - lon1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(toRadians(lat1)) * Math.cos(toRadians(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double d = EARTH_RADIUS * c;
return d;
}
public double toRadians(double degrees) {
return degrees * (Math.PI / 180);
}
كما أشار إلى حساب دقيق ينبغي أن تأخذ في الاعتبار أن الأرض ليست كرة مثالية.هنا بعض المقارنات من خوارزميات مختلفة عرضت هنا:
geoDistance(50,5,58,3)
Haversine: 899 km
Maymenn: 833 km
Keerthana: 897 km
google.maps.geometry.spherical.computeDistanceBetween(): 900 km
geoDistance(50,5,-58,-3)
Haversine: 12030 km
Maymenn: 11135 km
Keerthana: 10310 km
google.maps.geometry.spherical.computeDistanceBetween(): 12044 km
geoDistance(.05,.005,.058,.003)
Haversine: 0.9169 km
Maymenn: 0.851723 km
Keerthana: 0.917964 km
google.maps.geometry.spherical.computeDistanceBetween(): 0.917964 km
geoDistance(.05,80,.058,80.3)
Haversine: 33.37 km
Maymenn: 33.34 km
Keerthana: 33.40767 km
google.maps.geometry.spherical.computeDistanceBetween(): 33.40770 km
على مسافات صغيرة ، Keerthana خوارزمية لا يبدو أن يتزامن مع ذلك من خرائط جوجل.خرائط جوجل لا يبدو أن تتبع أي خوارزمية بسيطة ، مما يشير إلى أنه قد يكون الأسلوب الأكثر دقة هنا.
على أية حال هنا هو جافا سكريبت تنفيذ Keerthana خوارزمية:
function geoDistance(lat1, lng1, lat2, lng2){
const a = 6378.137; // equitorial radius in km
const b = 6356.752; // polar radius in km
var sq = x => (x*x);
var sqr = x => Math.sqrt(x);
var cos = x => Math.cos(x);
var sin = x => Math.sin(x);
var radius = lat => sqr((sq(a*a*cos(lat))+sq(b*b*sin(lat)))/(sq(a*cos(lat))+sq(b*sin(lat))));
lat1 = lat1 * Math.PI / 180;
lng1 = lng1 * Math.PI / 180;
lat2 = lat2 * Math.PI / 180;
lng2 = lng2 * Math.PI / 180;
var R1 = radius(lat1);
var x1 = R1*cos(lat1)*cos(lng1);
var y1 = R1*cos(lat1)*sin(lng1);
var z1 = R1*sin(lat1);
var R2 = radius(lat2);
var x2 = R2*cos(lat2)*cos(lng2);
var y2 = R2*cos(lat2)*sin(lng2);
var z2 = R2*sin(lat2);
return sqr(sq(x1-x2)+sq(y1-y2)+sq(z1-z2));
}
هنا هو تنفيذ VB.NET, هذا التطبيق سوف تعطيك النتيجة في كم أو ميل على أساس قيمة تعداد يمكنك تمرير.
Public Enum DistanceType
Miles
KiloMeters
End Enum
Public Structure Position
Public Latitude As Double
Public Longitude As Double
End Structure
Public Class Haversine
Public Function Distance(Pos1 As Position,
Pos2 As Position,
DistType As DistanceType) As Double
Dim R As Double = If((DistType = DistanceType.Miles), 3960, 6371)
Dim dLat As Double = Me.toRadian(Pos2.Latitude - Pos1.Latitude)
Dim dLon As Double = Me.toRadian(Pos2.Longitude - Pos1.Longitude)
Dim a As Double = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(Me.toRadian(Pos1.Latitude)) * Math.Cos(Me.toRadian(Pos2.Latitude)) * Math.Sin(dLon / 2) * Math.Sin(dLon / 2)
Dim c As Double = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)))
Dim result As Double = R * c
Return result
End Function
Private Function toRadian(val As Double) As Double
Return (Math.PI / 180) * val
End Function
End Class
أنا المكثف حساب إلى أسفل من خلال تبسيط الصيغة.
هنا هو في روبي:
include Math
earth_radius_mi = 3959
radians = lambda { |deg| deg * PI / 180 }
coord_radians = lambda { |c| { :lat => radians[c[:lat]], :lng => radians[c[:lng]] } }
# from/to = { :lat => (latitude_in_degrees), :lng => (longitude_in_degrees) }
def haversine_distance(from, to)
from, to = coord_radians[from], coord_radians[to]
cosines_product = cos(to[:lat]) * cos(from[:lat]) * cos(from[:lng] - to[:lng])
sines_product = sin(to[:lat]) * sin(from[:lat])
return earth_radius_mi * acos(cosines_product + sines_product)
end
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2,units) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
var miles = d / 1.609344;
if ( units == 'km' ) {
return d;
} else {
return miles;
}}
تشاك الحل صالحة ميل أيضا.
هنا هو بلدي جافا تنفيذ لحساب المسافة عبر الدرجات العشرية بعد بعض البحث.اعتدت يعني نصف قطرها من العالم (من ويكيبيديا) في كم.إذا كنت تريد نتيجة ميل ثم استخدام العالم في دائرة نصف قطرها ميل.
public static double distanceLatLong2(double lat1, double lng1, double lat2, double lng2)
{
double earthRadius = 6371.0d; // KM: use mile here if you want mile result
double dLat = toRadian(lat2 - lat1);
double dLng = toRadian(lng2 - lng1);
double a = Math.pow(Math.sin(dLat/2), 2) +
Math.cos(toRadian(lat1)) * Math.cos(toRadian(lat2)) *
Math.pow(Math.sin(dLng/2), 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return earthRadius * c; // returns result kilometers
}
public static double toRadian(double degrees)
{
return (degrees * Math.PI) / 180.0d;
}
في الخلية استخدام الدالة التالية تمرير المعلمات باستخدام POINT(LONG,LAT)
CREATE FUNCTION `distance`(a POINT, b POINT)
RETURNS double
DETERMINISTIC
BEGIN
RETURN
GLength( LineString(( PointFromWKB(a)), (PointFromWKB(b)))) * 100000; -- To Make the distance in meters
END;
function getDistanceFromLatLonInKm(position1, position2) {
"use strict";
var deg2rad = function (deg) { return deg * (Math.PI / 180); },
R = 6371,
dLat = deg2rad(position2.lat - position1.lat),
dLng = deg2rad(position2.lng - position1.lng),
a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
+ Math.cos(deg2rad(position1.lat))
* Math.cos(deg2rad(position1.lat))
* Math.sin(dLng / 2) * Math.sin(dLng / 2),
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
}
console.log(getDistanceFromLatLonInKm(
{lat: 48.7931459, lng: 1.9483572},
{lat: 48.827167, lng: 2.2459745}
));
هنا مثال في بوستجرس sql (في كم على بعد أميال النسخة استبدال 1.609344 قبل 0.8684 الإصدار)
CREATE OR REPLACE FUNCTION public.geodistance(alat float, alng float, blat
float, blng float)
RETURNS float AS
$BODY$
DECLARE
v_distance float;
BEGIN
v_distance = asin( sqrt(
sin(radians(blat-alat)/2)^2
+ (
(sin(radians(blng-alng)/2)^2) *
cos(radians(alat)) *
cos(radians(blat))
)
)
) * cast('7926.3352' as float) * cast('1.609344' as float) ;
RETURN v_distance;
END
$BODY$
language plpgsql VOLATILE SECURITY DEFINER;
alter function geodistance(alat float, alng float, blat float, blng float)
owner to postgres;
هناك مثال جيد هنا لحساب المسافة مع PHP http://www.geodatasource.com/developers/php :
function distance($lat1, $lon1, $lat2, $lon2, $unit) {
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$miles = $dist * 60 * 1.1515;
$unit = strtoupper($unit);
if ($unit == "K") {
return ($miles * 1.609344);
} else if ($unit == "N") {
return ($miles * 0.8684);
} else {
return $miles;
}
}
لدي مشكلة مع الرياضيات.درجة في لوا...إذا كان أي شخص يعرف إصلاح يرجى تنظيف هذا الرمز!
في هذه الأثناء هنا تنفيذ Haversine في لوا (استخدام هذا مع رديس!)
function calcDist(lat1, lon1, lat2, lon2)
lat1= lat1*0.0174532925
lat2= lat2*0.0174532925
lon1= lon1*0.0174532925
lon2= lon2*0.0174532925
dlon = lon2-lon1
dlat = lat2-lat1
a = math.pow(math.sin(dlat/2),2) + math.cos(lat1) * math.cos(lat2) * math.pow(math.sin(dlon/2),2)
c = 2 * math.asin(math.sqrt(a))
dist = 6371 * c -- multiply by 0.621371 to convert to miles
return dist
end
هتاف!
هنا آخر تحويلها إلى روبي كود:
include Math
#Note: from/to = [lat, long]
def get_distance_in_km(from, to)
radians = lambda { |deg| deg * Math.PI / 180 }
radius = 6371 # Radius of the earth in kilometer
dLat = radians[to[0]-from[0]]
dLon = radians[to[1]-from[1]]
cosines_product = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(radians[from[0]]) * Math.cos(radians[to[1]]) * Math.sin(dLon/2) * Math.sin(dLon/2)
c = 2 * Math.atan2(Math.sqrt(cosines_product), Math.sqrt(1-cosines_product))
return radius * c # Distance in kilometer
end