2012-10-19 11 views
19

मुझे आश्चर्य है कि Google मानचित्र API पर भरोसा किए बिना दो जीपीएस निर्देशांक की दूरी की गणना करने का कोई तरीका है या नहीं।Google मानचित्र API का उपयोग किए बिना दो जीपीएस निर्देशांक के बीच की दूरी की गणना कैसे करें?

मेरा ऐप फ्लोट में निर्देशांक प्राप्त कर सकता है या मुझे पते पर जीईओ रिवर्स करना होगा।

उत्तर

62

पृथ्वी पर दो निर्देशांक के बीच की दूरी आमतौर पर Haversine formula का उपयोग करके गणना की जाती है। यह सूत्र पृथ्वी के आकार और त्रिज्या को ध्यान में रखता है। यह वह कोड है जिसका उपयोग मैं मीटर में दूरी की गणना करने के लिए करता हूं।

def distance loc1, loc2 
    rad_per_deg = Math::PI/180 # PI/180 
    rkm = 6371     # Earth radius in kilometers 
    rm = rkm * 1000    # Radius in meters 

    dlat_rad = (loc2[0]-loc1[0]) * rad_per_deg # Delta, converted to rad 
    dlon_rad = (loc2[1]-loc1[1]) * rad_per_deg 

    lat1_rad, lon1_rad = loc1.map {|i| i * rad_per_deg } 
    lat2_rad, lon2_rad = loc2.map {|i| i * rad_per_deg } 

    a = Math.sin(dlat_rad/2)**2 + Math.cos(lat1_rad) * Math.cos(lat2_rad) * Math.sin(dlon_rad/2)**2 
    c = 2 * Math::atan2(Math::sqrt(a), Math::sqrt(1-a)) 

    rm * C# Delta in meters 
end 

puts distance [46.3625, 15.114444],[46.055556, 14.508333] 
# => 57794.35510874037 
+6

हावर्सिन फॉर्मूला का उपयोग [जियोकोडर] (http://rubygems.org/gems/geocoder) में भी किया जाता है, फ़ाइल [गणना.आरबी] (https: //github.com/alexreisner/geocoder/blob/master/lib/geocoder/calculations.rb#L72)। –

+2

यह विधि 'ए' और' बी' के मानों को संशोधित करती है जो अप्रत्याशित है। मुझे लगता है कि '.map' के बजाय' .map! 'का उपयोग करने या फिर' ए 'का पुन: उपयोग करने की आवश्यकता नहीं है। – joscas

+1

संपादित किया गया है कि अब नहीं होता है। – Lunivore

2

मणि Geocoder (railscast) पर देखो

आप DB में अपने निर्देशांक संग्रहीत करते हैं, इसे का उपयोग दूरी की गणना डेटाबेस। लेकिन अन्य मामलों में भी अच्छा काम करता है।

+0

कैसे क्या मैं https://github.com/alexreisner/geocoder/blob/master/lib/geocoder/calculations.rb में विधि का उपयोग करूंगा? –

+0

जैसे '' 'जिओकोडर :: कैलकुलेशन.कोर्डिनेट्स_पेंटेड?' '' –

5

आप geokit ruby gem का उपयोग कर सकते हैं। यह इन गणनाओं को आंतरिक रूप से करता है, लेकिन यदि आपको इसकी आवश्यकता हो तो Google और अन्य सेवाओं के माध्यम से पते को हल करने का भी समर्थन करता है।

require 'geokit' 

current_location = Geokit::LatLng.new(37.79363,-122.396116) 
destination = "37.786217,-122.41619" 
current_location.distance_to(destination) 

# Returns distance in miles: 1.211200074136264 

तुम भी bearing_to (दिशा 0-360 डिग्री के बीच में एक नाव के रूप में व्यक्त) और midpoint_to (एक वस्तु आप पर .latitude और .longitude तरीकों से चला सकते हैं रिटर्न) पता कर सकते हैं।

3

बस में थोड़ा छोटा & अलग पैरामीटर का @ Lunivore के जवाब

RAD_PER_DEG = Math::PI/180 
RM = 6371000 # Earth radius in meters 

def distance_between(lat1, lon1, lat2, lon2) 
    lat1_rad, lat2_rad = lat1 * RAD_PER_DEG, lat2 * RAD_PER_DEG 
    lon1_rad, lon2_rad = lon1 * RAD_PER_DEG, lon2 * RAD_PER_DEG 

    a = Math.sin((lat2_rad - lat1_rad)/2) ** 2 + Math.cos(lat1_rad) * Math.cos(lat2_rad) * Math.sin((lon2_rad - lon1_rad)/2) ** 2 
    c = 2 * Math::atan2(Math::sqrt(a), Math::sqrt(1 - a)) 

    RM * C# Delta in meters 
end 
1

मामले किसी में स्विफ्ट 3.1 (Xcode 8.3 पर काम करता है), के लिए स्वीकार किए जाते हैं जवाब परिवर्तित संस्करण इसकी आवश्यकता है:

public static func calculateDistanceMeters(departure: CLLocationCoordinate2D, arrival: CLLocationCoordinate2D) -> Double { 

    let rad_per_deg = Double.pi/180.0 // PI/180 
    let rkm = 6371.0     // Earth radius in kilometers 
    let rm = rkm * 1000.0    // Radius in meters 

    let dlat_rad = (arrival.latitude - departure.latitude) * rad_per_deg // Delta, converted to rad 
    let dlon_rad = (arrival.longitude - departure.longitude) * rad_per_deg 

    let lat1_rad = departure.latitude * rad_per_deg 
    let lat2_rad = arrival.latitude * rad_per_deg 

    let sinDlat = sin(dlat_rad/2) 
    let sinDlon = sin(dlon_rad/2) 
    let a = sinDlat * sinDlat + cos(lat1_rad) * cos(lat2_rad) * sinDlon * sinDlon 
    let c = 2.0 * atan2(sqrt(a), sqrt(1-a)) 

    return rm * c 
} 
संबंधित मुद्दे