سؤال

أواجه مشكلات في تنفيذ الوظيفة الموضحة هنا هنا.

هذا هو تطبيق Java الخاص بي:

private static double[] pointRadialDistance(double lat1, double lon1, 
        double radianBearing, double radialDistance) {
     double lat = Math.asin(Math.sin(lat1)*Math.cos(radialDistance)+Math.cos(lat1)
             *Math.sin(radialDistance)*Math.cos(radianBearing));
     double lon;
     if(Math.cos(lat) == 0) {  // Endpoint a pole
        lon=lon1;      
     }
     else {
        lon = ((lon1-Math.asin(Math.sin(radianBearing)*Math.sin(radialDistance)/Math.cos(lat))
                +Math.PI) % (2*Math.PI)) - Math.PI;
     }
    return (new double[]{lat, lon});
}

أقوم بتحويل محمل الدرجة إلى راديان وتحويل المسافة (كم) إلى مسافة راديان قبل استدعاء الوظيفة - لذلك ليست هذه هي المشكلة.

ومع ذلك، عندما أقوم بإدخال الإحداثيات مثل:خطوط العرض = 49.25705؛خط الطول = -123.140259؛بإتجاه 225 (جنوب غرب) ومسافة 1 كم

أحصل على هذا عاد:خطوط العرض:-1.0085434360125864 LON:-3.7595299668539504

من الواضح أن هذا ليس صحيحًا، هل يمكن لأي شخص أن يرى الخطأ الذي أفعله؟

شكرًا

هل كانت مفيدة؟

المحلول

يبدو أن هذه هي المشكلات الموجودة في التعليمات البرمجية الخاصة بك:

  1. تحتاج إلى تحويل lat1 و lon1 إلى راديان قبل استدعاء وظيفتك.
  2. ربما تقوم بالتحجيم radialDistance بشكل غير صحيح.
  3. يعد اختبار رقم الفاصلة العائمة للمساواة أمرًا خطيرًا.قد لا يكون الرقمان المتساويان بعد الحساب الدقيق متساويين تمامًا بعد حساب الفاصلة العائمة.هكذا abs(x-y) < threshold أكثر أمانا من x == y لاختبار رقمين الفاصلة العائمة x و y من أجل المساواة.
  4. أعتقد أنك تريد التحويل lat و lon من راديان إلى درجات.

هذا هو تنفيذ التعليمات البرمجية الخاصة بك في بايثون:

#!/usr/bin/env python

from math import asin,cos,pi,sin

rEarth = 6371.01 # Earth's average radius in km
epsilon = 0.000001 # threshold for floating-point equality


def deg2rad(angle):
    return angle*pi/180


def rad2deg(angle):
    return angle*180/pi


def pointRadialDistance(lat1, lon1, bearing, distance):
    """
    Return final coordinates (lat2,lon2) [in degrees] given initial coordinates
    (lat1,lon1) [in degrees] and a bearing [in degrees] and distance [in km]
    """
    rlat1 = deg2rad(lat1)
    rlon1 = deg2rad(lon1)
    rbearing = deg2rad(bearing)
    rdistance = distance / rEarth # normalize linear distance to radian angle

    rlat = asin( sin(rlat1) * cos(rdistance) + cos(rlat1) * sin(rdistance) * cos(rbearing) )

    if cos(rlat) == 0 or abs(cos(rlat)) < epsilon: # Endpoint a pole
        rlon=rlon1
    else:
        rlon = ( (rlon1 - asin( sin(rbearing)* sin(rdistance) / cos(rlat) ) + pi ) % (2*pi) ) - pi

    lat = rad2deg(rlat)
    lon = rad2deg(rlon)
    return (lat, lon)


def main():
    print "lat1 \t lon1 \t\t bear \t dist \t\t lat2 \t\t lon2"
    testcases = []
    testcases.append((0,0,0,1))
    testcases.append((0,0,90,1))
    testcases.append((0,0,0,100))
    testcases.append((0,0,90,100))
    testcases.append((49.25705,-123.140259,225,1))
    testcases.append((49.25705,-123.140259,225,100))
    testcases.append((49.25705,-123.140259,225,1000))
    for lat1, lon1, bear, dist in testcases:
        (lat,lon) = pointRadialDistance(lat1,lon1,bear,dist)
        print "%6.2f \t %6.2f \t %4.1f \t %6.1f \t %6.2f \t %6.2f" % (lat1,lon1,bear,dist,lat,lon)


if __name__ == "__main__":
    main()

هنا هو الإخراج:

lat1     lon1        bear    dist        lat2        lon2
  0.00     0.00       0.0       1.0        0.01        0.00
  0.00     0.00      90.0       1.0        0.00       -0.01
  0.00     0.00       0.0     100.0        0.90        0.00
  0.00     0.00      90.0     100.0        0.00       -0.90
 49.26   -123.14     225.0      1.0       49.25      -123.13
 49.26   -123.14     225.0    100.0       48.62      -122.18
 49.26   -123.14     225.0   1000.0       42.55      -114.51

نصائح أخرى

وفي الأساس، يبدو أن مشكلتك هي أنك تمر خطوط الطول والعرض وتحمل كما درجة بدلا من راديان. محاولة ضمان ان كنت دائما يمر راديان إلى وظيفة الخاص بك ومعرفة ما تحصل عليه العودة.

وPS: انظر قضايا مماثلة ناقش هنا و <لأ href = " https://stackoverflow.com/questions/695065/geoalgorithm-for-finding-coordinates-of-point-from-a-known-location-by-distance-a">here .

وأعتقد أن هناك مشكلة في خوارزمية المقدمة في رسالة 5.

وكان يعمل ولكن فقط لخطوط العرض والطول للوجود مشكلة بسبب علامة.

والبيانات تتحدث عن نفسها:

<اقتباس فقرة>   

49.26 -123.14 225.0 1.0 49.25 -123.13

إذا كنت تبدأ من على -123.14 ° و تذهب WEST يجب أن يكون لديك شيء FAR في WEST. هنا نذهب مرة أخرى على EAST (-123.13)!

وتتضمن الصيغة ينبغي مكان ما:

<اقتباس فقرة>   

وdegreeBearing = ((360 degreeBearing)٪ 360)

وقبل التحويل راديان.

وعندما تنفذ هذه، كانت لي خطوط العرض مما أدى الصحيحة ولكن كانت الطول الخطأ. على سبيل المثال نقطة انطلاق: 36.9460678N 9.434807E، وإذ تضع 45.03334، المسافة 15.0083313km وكانت النتيجة 37.0412865N 9.315302E هذا إلى الغرب من نقطة البداية بالنسبة لي، وليس مزيدا من الشرق. في واقع الأمر كما لو كان تأثير 315،03334 درجة.

والمزيد من البحث على شبكة الإنترنت قادني إلى: HTTP: //www.movable- type.co.uk/scripts/latlong.html رمز العرض هو إظهار أدناه (في C # مع كل شيء في راديان)

        if ((Math.Cos(rLat2) == 0) || (Math.Abs(Math.Cos(rLat2)) < EPSILON))
        {
            rLon2 = rLon1;
        }
        else
        {
            rLon2 = rLon1 + Math.Atan2(Math.Sin(rBearing) * Math.Sin(rDistance) * Math.Cos(rLat1), Math.Cos(rDistance) - Math.Sin(rLat1) * Math.Sin(rLat2));
        }

ويبدو أن هذا العمل غرامة بالنسبة لي. نأمل أن تكون مفيدة.

والشكر لرمز الثعبان الخاص بك حاولت وضع هذا الامر في حال استخدامي حيث أحاول العثور على خط الطول خطوط الطول نقطة في بين اثنين آخرين على مسافة مجموعة من النقطة الأولى حتى انها سميلر تماما إلى التعليمات البرمجية APPART أن بلدي تحمل يحسب حيوي

وstartpoint (lat1) lon1 / lat1 = 55.625541، -21.142463

ونقطة النهاية (lat2) lon2 / lat2 = 55.625792، -22.142248

ويجب أن يكون نتيجة بلدي نقطة بين هذين في lon3 / lat3 لكن لسوء الحظ أحصل lon3 / lat3 = 0.0267695450609،0.0223553243666

وأعتقد أن هذا قد يكون الفرق في خط الطول خطوط الطول ولكن لا عندما أضيف أو دون ذلك انها ليست جيدة

وأن أي نصيحة تكون كبيرة حقا بفضل

وهنا تنفيذ بلدي

وبعد = 0.001 إبسيلون = 0.000001

حساب تحمل حيوي

y = math.sin(distance) * math.cos(lat2);
x = math.cos(lat1)*math.sin(lat2) - math.sin(lat1)*math.cos(lat2)*math.cos(distance);
bearing = math.atan2(y, x)

حساب lon3 lat3 حيوي

rlat1 = (lat1 * 180) / math.pi
rlon1 = (lon1 * 180) / math.pi
rbearing = (bearing * 180) / math.pi
rdistance = distance / R # normalize linear distance to radian angle

rlat = math.asin( math.sin(rlat1) * math.cos(rdistance) + math.cos(rlat1) * math.sin(rdistance) * math.cos(rbearing) )
if math.cos(rlat) == 0 or abs(math.cos(rlat)) < epsilon: # Endpoint a pole
      rlon=rlon1
else:
    rlon = ( (rlon1 + math.asin( math.sin(rbearing)* math.sin(rdistance) / math.cos(rlat) ) + math.pi ) % (2*math.pi) ) - math.pi

lat3 = (rlat * math.pi)/ 180
lon3 = (rlon * math.pi)/ 180

وكل شيء يعمل على النحو المنشود، ولكن المشكلة هي أن الرياضيات الخاص تفترض الأرض ليكون المجال عندما تكون في واقع الأمر يقترب من الإهليلجي.

وسوف الجر السريع لمحرك البحث المفضلة لديك ل"الفورمولا Vincenty" يثبت نأمل مفيدة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top