diff --git a/lib/geocoder/calculations.rb b/lib/geocoder/calculations.rb
index bd0ed118a459f2afec6836bfd926c6d626907450..83cf25ddb6350761d3710428e9109ead216dac7f 100644
--- a/lib/geocoder/calculations.rb
+++ b/lib/geocoder/calculations.rb
@@ -117,11 +117,8 @@ module Geocoder
     #
     def geographic_center(points)
 
-      # convert objects to [lat,lon] arrays and remove nils
-      points = points.map{ |p| p.is_a?(Array) ? p : p.to_coordinates }.compact
-
-      # convert degrees to radians
-      points.map!{ |p| to_radians(p) }
+      # convert objects to [lat,lon] arrays and convert degrees to radians
+      points = points.map{ |p| to_radians(extract_coordinates(p)) }
 
       # convert to Cartesian coordinates
       x = []; y = []; z = []
@@ -236,5 +233,19 @@ module Geocoder
     def mi_in_km
       1.0 / KM_IN_MI
     end
+
+    ##
+    # Takes an object which is a [lat,lon] array, a geocodable string,
+    # or an object that implements +to_coordinates+ and returns a
+    # [lat,lon] array. Note that if a string is passed this may be a slow-
+    # running method and may return nil.
+    #
+    def extract_coordinates(point)
+      case point
+        when Array; point
+        when String; Geocoder.coordinates(point)
+        else point.to_coordinates
+      end
+    end
   end
 end
diff --git a/lib/geocoder/orms/active_record.rb b/lib/geocoder/orms/active_record.rb
index 908dca1d4c171d34a8f4b70c8fed016e888c0267..615b044f2a6cf63402507f3cf0f0327a6d3f0be6 100644
--- a/lib/geocoder/orms/active_record.rb
+++ b/lib/geocoder/orms/active_record.rb
@@ -34,8 +34,7 @@ module Geocoder::Orm
         # for details).
         #
         scope :near, lambda{ |location, *args|
-          latitude, longitude = location.is_a?(Array) ?
-            location : Geocoder.coordinates(location)
+          latitude, longitude = Geocoder::Calculations.extract_coordinates(location)
           if latitude and longitude
             near_scope_options(latitude, longitude, *args)
           else
diff --git a/lib/geocoder/orms/base.rb b/lib/geocoder/orms/base.rb
index 0c018a497f73f093d3c6c8203999710ed0394f94..cf256ddb9e68582fac0b1aacca681dec41bc07aa 100644
--- a/lib/geocoder/orms/base.rb
+++ b/lib/geocoder/orms/base.rb
@@ -29,6 +29,33 @@ module Geocoder
 
       alias_method :distance_from, :distance_to
 
+      ##
+      # Calculate the bearing from the object to another point.
+      # The point can be:
+      #
+      # * an array of coordinates ([lat,lon])
+      # * a geocoded object (one which implements a +to_coordinates+ method
+      #   which returns a [lat,lon] array
+      # * a geocodable address (string)
+      #
+      def bearing_to(point, options = {})
+        return nil unless them = Geocoder::Calculations.extract_coordinates(point)
+        us = to_coordinates
+        Geocoder::Calculations.bearing_between(
+          us[0], us[1], them[0], them[1], options)
+      end
+
+      ##
+      # Calculate the bearing from another point to the object.
+      # See bearing_to for details.
+      #
+      def bearing_from(point, options = {})
+        return nil unless them = Geocoder::Calculations.extract_coordinates(point)
+        us = to_coordinates
+        Geocoder::Calculations.bearing_between(
+          them[0], them[1], us[0], us[1], options)
+      end
+
       ##
       # Get nearby geocoded objects.
       # Takes the same options hash as the near class method (scope).
@@ -40,7 +67,7 @@ module Geocoder
           warn "DEPRECATION WARNING: The units argument to the nearbys method has been replaced with an options hash (same options hash as the near scope). You should instead call: obj.nearbys(#{radius}, :units => #{options[:units]}). The old syntax will not be supported in Geocoder v1.0."
         end
         options.merge!(:exclude => self)
-        self.class.near(to_coordinates, radius, options)
+        self.class.near(self, radius, options)
       end
 
       ##
diff --git a/lib/geocoder/orms/mongoid.rb b/lib/geocoder/orms/mongoid.rb
index 462089635f2a9fa101d6b70c5f5ad573aa868277..76506f273ddf2f2a417a691e226f30b79d92fa9f 100644
--- a/lib/geocoder/orms/mongoid.rb
+++ b/lib/geocoder/orms/mongoid.rb
@@ -16,11 +16,10 @@ module Geocoder::Orm
         }
 
         scope :near, lambda{ |location, *args|
+          coords  = Geocoder::Calculations.extract_coordinates(location)
           radius  = args.size > 0 ? args.shift : 20
           options = args.size > 0 ? args.shift : {}
-          coords  = location.is_a?(Array) ?
-            location : Geocoder.coordinates(location)
-          conds = {:coordinates => {
+          conds   = {:coordinates => {
             "$nearSphere" => coords.reverse,
             "$maxDistance" => Geocoder::Calculations.distance_to_radians(
               radius, options[:units] || :mi)
diff --git a/test/geocoder_test.rb b/test/geocoder_test.rb
index cad207d299250d52250ffe1183fe320abce60fb0..16ccee5dccc341e18def9427ca13ae53aae542e8 100644
--- a/test/geocoder_test.rb
+++ b/test/geocoder_test.rb
@@ -248,6 +248,21 @@ class GeocoderTest < Test::Unit::TestCase
     end
   end
 
+  def test_spherical_bearing_to
+    l = Landmark.new(*landmark_params(:msg))
+    assert_equal 324, l.bearing_to([50,-85], :method => :spherical).round
+  end
+
+  def test_spherical_bearing_from
+    l = Landmark.new(*landmark_params(:msg))
+    assert_equal 136, l.bearing_from([50,-85], :method => :spherical).round
+  end
+
+  def test_linear_bearing_from_and_to_are_exactly_opposite
+    l = Landmark.new(*landmark_params(:msg))
+    assert_equal l.bearing_from([50,-86.1]), l.bearing_to([50,-86.1]) - 180
+  end
+
 
   # --- input handling ---
 
@@ -280,6 +295,13 @@ class GeocoderTest < Test::Unit::TestCase
     end
   end
 
+  def test_extract_coordinates
+    coords = [-23,47]
+    l = Landmark.new("Madagascar", coords[0], coords[1])
+    assert_equal coords, Geocoder::Calculations.extract_coordinates(l)
+    assert_equal coords, Geocoder::Calculations.extract_coordinates(coords)
+  end
+
 
   # --- error handling ---