From b91a54d3baa771b97414202793cb5fd2d2dd20bb Mon Sep 17 00:00:00 2001 From: Alex Reisner <alex@alexreisner.com> Date: Thu, 24 Mar 2011 13:20:36 -0400 Subject: [PATCH] Convert bearing to degrees CW from North. --- lib/geocoder/calculations.rb | 4 ++- test/geocoder_test.rb | 54 ++++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/lib/geocoder/calculations.rb b/lib/geocoder/calculations.rb index 5a994406..77c47449 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 1b3f7b08..d0f53bbf 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 -- GitLab