diff --git a/lib/geocoder/calculations.rb b/lib/geocoder/calculations.rb index 5a9944064fd40612f8feb9058c7e5f8abb3aa0f6..77c4744916e8dabaa0de6bf98372b017701b7898 100644 --- a/lib/geocoder/calculations.rb +++ b/lib/geocoder/calculations.rb @@ -52,7 +52,9 @@ module Geocoder x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dlon) brng = Math.atan2(x,y) - (to_degrees(brng) + 360) % 360 + # brng is in radians counterclockwise from due east. + # Convert to degrees clockwise from due north: + (90 - to_degrees(brng) + 360) % 360 end ## diff --git a/test/geocoder_test.rb b/test/geocoder_test.rb index 1b3f7b08b6c916d39c3151f13e495d00803477e0..d0f53bbfb9fcebaa598d14b3341c4892aa33a652 100644 --- a/test/geocoder_test.rb +++ b/test/geocoder_test.rb @@ -25,17 +25,6 @@ class GeocoderTest < Test::Unit::TestCase assert (la_to_ny - 2444).abs < 10 end - def test_compass_points - assert_equal "N", Geocoder::Calculations.compass_point(0) - assert_equal "N", Geocoder::Calculations.compass_point(1.0) - assert_equal "N", Geocoder::Calculations.compass_point(360) - assert_equal "N", Geocoder::Calculations.compass_point(361) - assert_equal "N", Geocoder::Calculations.compass_point(-22) - assert_equal "NW", Geocoder::Calculations.compass_point(-23) - assert_equal "S", Geocoder::Calculations.compass_point(180) - assert_equal "S", Geocoder::Calculations.compass_point(181) - end - def test_geographic_center_with_arrays assert_equal [0.0, 0.5], Geocoder::Calculations.geographic_center([[0,0], [0,1]]) @@ -183,6 +172,49 @@ class GeocoderTest < Test::Unit::TestCase end + # --- bearing --- + + def test_compass_points + assert_equal "N", Geocoder::Calculations.compass_point(0) + assert_equal "N", Geocoder::Calculations.compass_point(1.0) + assert_equal "N", Geocoder::Calculations.compass_point(360) + assert_equal "N", Geocoder::Calculations.compass_point(361) + assert_equal "N", Geocoder::Calculations.compass_point(-22) + assert_equal "NW", Geocoder::Calculations.compass_point(-23) + assert_equal "S", Geocoder::Calculations.compass_point(180) + assert_equal "S", Geocoder::Calculations.compass_point(181) + end + + def test_bearing_between + bearings = { + :n => 0, + :e => 90, + :s => 180, + :w => 270 + } + points = { + :n => [41, -75], + :e => [40, -74], + :s => [39, -75], + :w => [40, -76] + } + directions = [:n, :e, :s, :w] + types = [:spherical] + + types.each do |t| + directions.each_with_index do |d,i| + opp = directions[(i + 2) % 4] # opposite direction + p1 = points[d] + p2 = points[opp] + + b = Geocoder::Calculations.bearing_between(*(p1 + p2)) + assert (b - bearings[opp]).abs < 1, + "Bearing (#{t}) should be close to #{bearings[opp]} but was #{b}." + end + end + end + + # --- Google --- def test_google_result_components