পাইথনের হাভারসাইন সূত্র (দুটি জিপিএস পয়েন্টের মধ্যে ভারবহন এবং দূরত্ব)


119

সমস্যা

আমি কীভাবে 2 জিপিএস পয়েন্টের মধ্যে দূরত্ব এবং ভারবহন পেতে পারি তা জানতে চাই । আমি haversine সূত্র উপর গবেষণা করেছি। কেউ আমাকে বলেছিল যে একই ডেটা ব্যবহার করে আমি বেয়ারিংটিও খুঁজে পেতে পারি।

সম্পাদন করা

সবকিছু ঠিকঠাক চলছে তবে ভারবহন সঠিকভাবে এখনও কাজ করে না। ভারবহন আউটপুটগুলি নেতিবাচক তবে 0 - 360 ডিগ্রির মধ্যে হওয়া উচিত। সেট ডেটাটি অনুভূমিক ভারবহন করা উচিত 96.02166666666666 এবং তা হ'ল:

Start point: 53.32055555555556 , -1.7297222222222221   
Bearing:  96.02166666666666  
Distance: 2 km  
Destination point: 53.31861111111111, -1.6997222222222223  
Final bearing: 96.04555555555555

আমার নতুন কোডটি এখানে:

from math import *

Aaltitude = 2000
Oppsite  = 20000

lat1 = 53.32055555555556
lat2 = 53.31861111111111
lon1 = -1.7297222222222221
lon2 = -1.6997222222222223

lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * atan2(sqrt(a), sqrt(1-a))
Base = 6371 * c


Bearing =atan2(cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon2-lon1), sin(lon2-lon1)*cos(lat2)) 

Bearing = degrees(Bearing)
print ""
print ""
print "--------------------"
print "Horizontal Distance:"
print Base
print "--------------------"
print "Bearing:"
print Bearing
print "--------------------"


Base2 = Base * 1000
distance = Base * 2 + Oppsite * 2 / 2
Caltitude = Oppsite - Aaltitude

a = Oppsite/Base
b = atan(a)
c = degrees(b)

distance = distance / 1000

print "The degree of vertical angle is:"
print c
print "--------------------"
print "The distance between the Balloon GPS and the Antenna GPS is:"
print distance
print "--------------------"

পাইথন haversine বাস্তবায়ন codecodex.com/wiki/… পাওয়া যাবে । তবে স্বল্প দূরত্বের গণনার জন্য খুব সহজ উপায় বিদ্যমান। এখন, আপনার সর্বোচ্চ দূরত্বটি কী প্রত্যাশিত? আপনি কি কিছু স্থানীয় কার্তেসিয়ান সমন্বয় ব্যবস্থাতে আপনার সমন্বয় পেতে সক্ষম?
খাবেন

পাইথনে কিছু বাস্তবায়ন: - কোড. activestate.com/recips/… - প্লটোস্কেভ.
ফ্যাবিও ডিনিজ

1
@ জেমস ডাইসন: ১৫ কিলোমিটারের মতো দূরত্ব সহ, ক্রিয়েট সার্কেল কিছুই গণনা করে না। আমার পরামর্শ: প্রথমে ইউক্লিডিয়ান দূরত্ব সহ সমাধানটি বের করুন! এটি আপনাকে একটি কার্যক্ষম সমাধান দেবে এবং তারপরে যদি আপনার দূরত্বগুলি আরও দীর্ঘ হয় তবে আপনার অ্যাপ্লিকেশনটি সামঞ্জস্য করুন। ধন্যবাদ
খাওয়া

1
@ জেমস ডাইসন: আপনার উপরের মন্তব্যটি যদি আমার উদ্দেশ্যে করা হয়েছিল (এবং আমার আগের পরামর্শ অনুসারে) তবে উত্তরটি অবশ্যই অবশ্যই (এবং বেশ 'তুচ্ছ' পাশাপাশি) রয়েছে। আমি কিছু উদাহরণ কোড দিতে সক্ষম হতে পারি, তবে এটি ত্রিকোণমিতিটি ব্যবহার করবে না, বরং জ্যামিতি (সুতরাং আমি নিশ্চিত না যে এটি আপনাকে কিছুটা সহায়তা করবে কিনা। আপনি কি ভেক্টরের ধারণার সাথে আদৌ পরিচিত? আপনার ক্ষেত্রে অবস্থানের ক্ষেত্রে এবং দিকনির্দেশগুলি ভেক্টরগুলির সাথে সবচেয়ে সোজা পদ্ধতিতে পরিচালনা করা যেতে পারে)।
খাবেন

1
atan2(sqrt(a), sqrt(1-a))হিসাবে একইasin(sqrt(a))
user102008

উত্তর:


241

এখানে পাইথন সংস্করণ রয়েছে:

from math import radians, cos, sin, asin, sqrt

def haversine(lon1, lat1, lon2, lat2):
    """
    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

    # haversine formula 
    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 # Radius of earth in kilometers. Use 3956 for miles
    return c * r

10
একই প্রভাব, পিআই / 180 দ্বারা গুণিত করার পরিবর্তে গণিত.আরডিয়ানস () ফাংশন ব্যবহার করতে পারে - তবে কিছুটা স্ব-ডকুমেন্টিং।
হিউ বোথওয়েল

4
আপনি পারেন, তবে আপনি যদি বলেন import mathতবে আপনাকে নির্দিষ্ট করতে হবে math.pi, math.sinইত্যাদি। সাথে from math import *আপনি সমস্ত মডিউল সামগ্রীতে সরাসরি অ্যাক্সেস পান। পাইথন টিউটোরিয়ালটিতে "নেমস্পেসগুলি" দেখুন (যেমন ডকস.পাইথন.অর্গ / টিউটোরিয়াল / মডেলস html )
মাইকেল ডান

2
আপনি কেবল আসিন (স্কয়ার্ট (ক)) এর পরিবর্তে কীভাবে আতান 2 (স্কয়ার্ট (ক), স্কয়ার্ট (1-এ) ব্যবহার করবেন? এটান 2 কি এই ক্ষেত্রে আরও সঠিক?
এয়াল

4
যদি গড়ের ব্যাসার্ধটিকে 63৩71১ কিলোমিটার হিসাবে সংজ্ঞায়িত করা হয় তবে তা 3959 মাইলের সমান নয় 3959 মাইলের সমান। এই মানগুলি গণনা করার জন্য বিভিন্ন উপায়ে গ্লোবাল গড় রেডিয়ি দেখুন ।
এখুমোরো

3
এই ফিরে কি? ভারবহন নাকি দূরত্ব?
এস্কুলাস ম্যাক্সিমাস

11

এই উত্তরগুলির বেশিরভাগই পৃথিবীর ব্যাসার্ধকে "বৃত্তাকার" করে। আপনি যদি অন্যান্য দূরত্বের ক্যালকুলেটরগুলির (যেমন ভূ-প্রকৃতির) বিপরীতে এটি পরীক্ষা করেন তবে এই ফাংশনগুলি বন্ধ হয়ে যাবে।

এটি ভাল কাজ করে:

from math import radians, cos, sin, asin, sqrt

def haversine(lat1, lon1, lat2, lon2):

      R = 3959.87433 # this is in miles.  For Earth radius in kilometers use 6372.8 km

      dLat = radians(lat2 - lat1)
      dLon = radians(lon2 - lon1)
      lat1 = radians(lat1)
      lat2 = radians(lat2)

      a = sin(dLat/2)**2 + cos(lat1)*cos(lat2)*sin(dLon/2)**2
      c = 2*asin(sqrt(a))

      return R * c

# Usage
lon1 = -103.548851
lat1 = 32.0004311
lon2 = -103.6041946
lat2 = 33.374939

print(haversine(lat1, lon1, lat2, lon2))

2
এই এক তারপর আরও উদাহরণস্বরূপ উপরের উদাহরণ!
অ্যালেক্স ভ্যান এস

এটি মেরুতে আর 6৩66.7575২ কিমি এর নিরক্ষরেখায় 78৩37 km.১3737 কিমি পর্যন্ত পরিবর্তনকে সম্বোধন করে না
ldmtwo

3
ত্রুটিটি কি আপনার অ্যাপ্লিকেশনটির জন্য সত্যিই গুরুত্বপূর্ণ? cs.nyu.edu/visual/home/proj/tiger/gisfaq.html
তেজস কালে

8

এখানে একটি ভেক্টরাইজড বাস্তবায়নও রয়েছে , যা স্থানাঙ্কগুলির জন্য স্ক্যালার মানগুলির পরিবর্তে 4 টি নমপি অ্যারে ব্যবহার করতে দেয়:

def distance(s_lat, s_lng, e_lat, e_lng):

   # approximate radius of earth in km
   R = 6373.0

   s_lat = s_lat*np.pi/180.0                      
   s_lng = np.deg2rad(s_lng)     
   e_lat = np.deg2rad(e_lat)                       
   e_lng = np.deg2rad(e_lng)  

   d = np.sin((e_lat - s_lat)/2)**2 + np.cos(s_lat)*np.cos(e_lat) * np.sin((e_lng - s_lng)/2)**2

   return 2 * R * np.arcsin(np.sqrt(d))

4

ভারবহন গণনাটি ভুল, আপনাকে ইনপুটগুলি অ্যাটান 2 এ অদলবদল করতে হবে।

    bearing = atan2(sin(long2-long1)*cos(lat2), cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(long2-long1))
    bearing = degrees(bearing)
    bearing = (bearing + 360) % 360

এটি আপনাকে সঠিক ভারবহন দেবে।


আমি যখন একটি কাগজ পড়ছি তখন এই সমীকরণগুলি কীভাবে উত্পন্ন হয়েছিল তা বুঝতে আমি লড়াই করছি। আপনি আমাকে একটি পয়েন্টার দিয়েছেন: haversine formulaএটি শোনার জন্য আমার প্রথমবার, আপনাকে ধন্যবাদ।
arilwan

4

আপনি নিম্নলিখিত চেষ্টা করতে পারেন:

from haversine import haversine
haversine((45.7597, 4.8422),(48.8567, 2.3508), unit='mi')
243.71209416020253

এটি কীভাবে জ্যাঙ্গোর ওআরএম কোয়েরিতে ব্যবহার করা যেতে পারে?
গোচট

3

@ মিশেল ডান দ্বারা প্রদত্ত হাভারসাইন ফর্মুলার একটি ন্যাক্কারজনক ভেক্টরাইজড বাস্তবায়ন এখানে বড় ভেক্টরগুলির তুলনায় 10-50 গুণ উন্নতি দেয়।

from numpy import radians, cos, sin, arcsin, sqrt

def haversine(lon1, lat1, lon2, lat2):
    """
    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees)
    """

    #Convert decimal degrees to Radians:
    lon1 = np.radians(lon1.values)
    lat1 = np.radians(lat1.values)
    lon2 = np.radians(lon2.values)
    lat2 = np.radians(lat2.values)

    #Implementing Haversine Formula: 
    dlon = np.subtract(lon2, lon1)
    dlat = np.subtract(lat2, lat1)

    a = np.add(np.power(np.sin(np.divide(dlat, 2)), 2),  
                          np.multiply(np.cos(lat1), 
                                      np.multiply(np.cos(lat2), 
                                                  np.power(np.sin(np.divide(dlon, 2)), 2))))
    c = np.multiply(2, np.arcsin(np.sqrt(a)))
    r = 6371

    return c*r

2

আপনি 360 360 যোগ করে নেতিবাচক ভারবহন সমস্যা সমাধান করতে পারেন ° দুর্ভাগ্যক্রমে, এর ফলে ইতিবাচক বিয়ারিংয়ের জন্য 360 than এর বেশি বিয়ারিংয়ের ফলস্বরূপ। এটি মডুলো অপারেটরের পক্ষে ভাল প্রার্থী, সুতরাং আপনার সমস্ত ক্ষেত্রে লাইনটি যুক্ত করা উচিত

Bearing = (Bearing + 360) % 360

আপনার পদ্ধতি শেষে।


1
আমি মনে করি এটি ঠিক: Bear = Bear% 360
হলগার বিলে

1

ডিফল্টরূপে প্রথম প্যারামিটারটি হ'ল atan2 Y এখানে ডকুমেন্টেশন দেওয়া আছে । সঠিক ভারবহন কোণ পেতে আপনাকে আপনার ইনপুটগুলি পরিবর্তন করতে হবে।

bearing = atan2(sin(lon2-lon1)*cos(lat2), cos(lat1)*sin(lat2)in(lat1)*cos(lat2)*cos(lon2-lon1))
bearing = degrees(bearing)
bearing = (bearing + 360) % 360

1

এই লিঙ্কটি দেখুন: /gis/84885/what-the-differences-between-vincency-and-great-circle-distance-calculations

এটি আসলে দূরত্ব পাওয়ার দুটি উপায় দেয়। তারা হ্যাভারসাইন এবং ভিনসেন্টিস। আমার গবেষণা থেকে আমি জানতে পারি যে ভিনসেন্টিস তুলনামূলকভাবে সঠিক। বাস্তবায়ন করতে আমদানির বিবৃতিও ব্যবহার করুন।


0

দূরত্ব এবং ভারবহন গণনা করার জন্য এখানে দুটি ফাংশন রয়েছে, যা পূর্ববর্তী বার্তাগুলিতে কোডের উপর ভিত্তি করে এবং https://gist.github.com/jeromer/2005586 (স্পষ্টতার জন্য উভয় ফাংশনের জন্য ল্যাট, দীর্ঘ বিন্যাসে ভৌগলিক পয়েন্টগুলির জন্য টুপল প্রকার যুক্ত হয়েছে) )। আমি উভয় ফাংশন পরীক্ষা করেছি এবং তারা সঠিকভাবে কাজ করছে বলে মনে হচ্ছে।

#coding:UTF-8
from math import radians, cos, sin, asin, sqrt, atan2, degrees

def haversine(pointA, pointB):

    if (type(pointA) != tuple) or (type(pointB) != tuple):
        raise TypeError("Only tuples are supported as arguments")

    lat1 = pointA[0]
    lon1 = pointA[1]

    lat2 = pointB[0]
    lon2 = pointB[1]

    # convert decimal degrees to radians 
    lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2]) 

    # haversine formula 
    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 # Radius of earth in kilometers. Use 3956 for miles
    return c * r


def initial_bearing(pointA, pointB):

    if (type(pointA) != tuple) or (type(pointB) != tuple):
        raise TypeError("Only tuples are supported as arguments")

    lat1 = radians(pointA[0])
    lat2 = radians(pointB[0])

    diffLong = radians(pointB[1] - pointA[1])

    x = sin(diffLong) * cos(lat2)
    y = cos(lat1) * sin(lat2) - (sin(lat1)
            * cos(lat2) * cos(diffLong))

    initial_bearing = atan2(x, y)

    # Now we have the initial bearing but math.atan2 return values
    # from -180° to + 180° which is not what we want for a compass bearing
    # The solution is to normalize the initial bearing as shown below
    initial_bearing = degrees(initial_bearing)
    compass_bearing = (initial_bearing + 360) % 360

    return compass_bearing

pA = (46.2038,6.1530)
pB = (46.449, 30.690)

print haversine(pA, pB)

print initial_bearing(pA, pB)

এই পদ্ধতিটি অন্যান্য সমস্ত পদ্ধতির চেয়ে উপরে ফলাফল দেয়!
বেসিলিস্ক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.