diff --git a/lib/geocoder/calculations.rb b/lib/geocoder/calculations.rb
index 0152cbe0e118f350c50475e5b9df3bc95d1e54f7..f4dd7a42b232baed02af3f064e3d0d340d2ed6e4 100644
--- a/lib/geocoder/calculations.rb
+++ b/lib/geocoder/calculations.rb
@@ -48,23 +48,41 @@ module Geocoder
     # Calculate bearing between two sets of coordinates.
     # Returns a number of degrees from due north (clockwise).
     #
+    # Also accepts an options hash:
+    #
+    # * <tt>:method</tt> - <tt>:linear</tt> (default) or <tt>:spherical</tt>;
+    #   the spherical method is "correct" in that it returns the shortest path
+    #   (one along a great circle) but the linear method is the default as it
+    #   is less confusing (returns due east or west when given two points with
+    #   the same latitude)
+    #
     # Based on: http://www.movable-type.co.uk/scripts/latlong.html
     #
-    def bearing_between(lat1, lon1, lat2, lon2)
+    def bearing_between(lat1, lon1, lat2, lon2, options = {})
+      options[:method] = :linear unless options[:method] == :spherical
 
       # convert degrees to radians
       lat1, lon1, lat2, lon2 = to_radians(lat1, lon1, lat2, lon2)
 
-      # compute delta
+      # compute deltas
+      dlat = lat2 - lat1
       dlon = lon2 - lon1
 
-      y = Math.sin(dlon) * Math.cos(lat2)
-      x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) *
-        Math.cos(lat2) * Math.cos(dlon)
-      brng = Math.atan2(x,y)
-      # brng is in radians counterclockwise from due east.
+      case options[:method]
+      when :linear
+        y = dlon
+        x = dlat
+
+      when :spherical
+        y = Math.sin(dlon) * Math.cos(lat2)
+        x = Math.cos(lat1) * Math.sin(lat2) -
+            Math.sin(lat1) * Math.cos(lat2) * Math.cos(dlon)
+      end
+
+      bearing = Math.atan2(x,y)
+      # Answer is in radians counterclockwise from due east.
       # Convert to degrees clockwise from due north:
-      (90 - to_degrees(brng) + 360) % 360
+      (90 - to_degrees(bearing) + 360) % 360
     end
 
     ##
diff --git a/lib/geocoder/orms/active_record.rb b/lib/geocoder/orms/active_record.rb
index 1194f8dca9b9187f83fc1737d89278e7e00efea5..5123618f4d914cd7133783e155426ad6457e95e2 100644
--- a/lib/geocoder/orms/active_record.rb
+++ b/lib/geocoder/orms/active_record.rb
@@ -27,9 +27,11 @@ module Geocoder::Orm
             "OR #{geocoder_options[:longitude]} IS NULL"}}
 
         ##
-        # Find all objects within a radius (in miles) of the given location
-        # (address string). Location (the first argument) may be either a string
-        # to geocode or an array of coordinates (<tt>[lat,long]</tt>).
+        # Find all objects within a radius of the given location.
+        # Location may be either a string to geocode or an array of
+        # coordinates (<tt>[lat,lon]</tt>). Also takes an options hash
+        # (see Geocoder::Orm::ActiveRecord::ClassMethods.near_scope_options
+        # for details).
         #
         scope :near, lambda{ |location, *args|
           latitude, longitude = location.is_a?(Array) ?
@@ -56,6 +58,10 @@ module Geocoder::Orm
       # * +:units+   - <tt>:mi</tt> (default) or <tt>:km</tt>; to be used
       #   for interpreting radius as well as the +distance+ attribute which
       #   is added to each found nearby object
+      # * +:bearing+ - <tt>:linear</tt> (default) or <tt>:spherical</tt>;
+      #   the method to be used for calculating the bearing (direction)
+      #   between the given point and each found nearby point;
+      #   set to false for no bearing calculation
       # * +:select+  - string with the SELECT SQL fragment (e.g. “id, name”)
       # * +:order+   - column(s) for ORDER BY SQL clause
       # * +:limit+   - number of records to return (for LIMIT SQL clause)
@@ -76,7 +82,8 @@ module Geocoder::Orm
 
       ##
       # Scope options hash for use with a database that supports POWER(),
-      # SQRT(), PI(), and trigonometric functions (SIN(), COS(), and ASIN()).
+      # SQRT(), PI(), and trigonometric functions SIN(), COS(), ASIN(),
+      # ATAN2(), DEGREES(), and RADIANS().
       #
       # Distance calculations based on the excellent tutorial at:
       # http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL
@@ -87,15 +94,28 @@ module Geocoder::Orm
       def full_near_scope_options(latitude, longitude, radius, options)
         lat_attr = geocoder_options[:latitude]
         lon_attr = geocoder_options[:longitude]
-        bearing = "(DEGREES(ATAN2( " +
-          "SIN(RADIANS(#{lon_attr} - #{longitude})) * " +
-          "COS(RADIANS(#{lat_attr})), (" +
-            "COS(RADIANS(#{latitude})) * SIN(RADIANS(#{lat_attr}))" +
-          ") - (" +
-            "SIN(RADIANS(#{latitude})) * COS(RADIANS(#{lat_attr})) * " +
-            "COS(RADIANS(#{lon_attr} - #{longitude}))" +
-          "))) + 360)"
-        bearing = "CAST(#{bearing} AS decimal) % 360"
+        options[:bearing] = :linear unless options.include?(:bearing)
+        bearing = case options[:bearing]
+        when :linear
+          "CAST(" +
+            "DEGREES(ATAN2( " +
+              "RADIANS(#{lon_attr} - #{longitude}), " +
+              "RADIANS(#{lat_attr} - #{latitude})" +
+            ")) + 360 " +
+          "AS decimal) % 360"
+        when :spherical
+          "CAST(" +
+            "DEGREES(ATAN2( " +
+              "SIN(RADIANS(#{lon_attr} - #{longitude})) * " +
+              "COS(RADIANS(#{lat_attr})), (" +
+                "COS(RADIANS(#{latitude})) * SIN(RADIANS(#{lat_attr}))" +
+              ") - (" +
+                "SIN(RADIANS(#{latitude})) * COS(RADIANS(#{lat_attr})) * " +
+                "COS(RADIANS(#{lon_attr} - #{longitude}))" +
+              ")" +
+            ")) + 360 " +
+          "AS decimal) % 360"
+        end
         distance = "#{Geocoder::Calculations.earth_radius} * 2 * ASIN(SQRT(" +
           "POWER(SIN((#{latitude} - #{lat_attr}) * PI() / 180 / 2), 2) + " +
           "COS(#{latitude} * PI() / 180) * COS(#{lat_attr} * PI() / 180) * " +
@@ -103,7 +123,8 @@ module Geocoder::Orm
         options[:order] ||= "#{distance} ASC"
         default_near_scope_options(latitude, longitude, radius, options).merge(
           :select => "#{options[:select] || '*'}, " +
-            "#{distance} AS distance, #{bearing} AS bearing",
+            "#{distance} AS distance" +
+            (bearing ? ", #{bearing} AS bearing" : ""),
           :having => "#{distance} <= #{radius}"
         )
       end
diff --git a/test/geocoder_test.rb b/test/geocoder_test.rb
index d0f53bbfb9fcebaa598d14b3341c4892aa33a652..fe6eae6d3789f9661d7447d5f4226b3cb98f3d1a 100644
--- a/test/geocoder_test.rb
+++ b/test/geocoder_test.rb
@@ -199,17 +199,17 @@ class GeocoderTest < Test::Unit::TestCase
       :w => [40, -76]
     }
     directions = [:n, :e, :s, :w]
-    types = [:spherical]
+    methods = [:linear, :spherical]
 
-    types.each do |t|
+    methods.each do |m|
       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))
+        b = Geocoder::Calculations.bearing_between(*(p1 + p2), :method => m)
         assert (b - bearings[opp]).abs < 1,
-          "Bearing (#{t}) should be close to #{bearings[opp]} but was #{b}."
+          "Bearing (#{m}) should be close to #{bearings[opp]} but was #{b}."
       end
     end
   end