Skip to content

Instantly share code, notes, and snippets.

@ttilberg
Last active April 27, 2018 16:17
Show Gist options
  • Select an option

  • Save ttilberg/fe5ac60351ad33b865550c08857f612f to your computer and use it in GitHub Desktop.

Select an option

Save ttilberg/fe5ac60351ad33b865550c08857f612f to your computer and use it in GitHub Desktop.

Revisions

  1. ttilberg revised this gist Apr 27, 2018. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions config_initializers_geocoder.rb
    Original file line number Diff line number Diff line change
    @@ -3,6 +3,8 @@
    # - Use `%` operator instead of `MOD()` function
    # This seems like it would be very reasonable to apply more dynamically.
    #
    # Original source: https://github.com/alexreisner/geocoder/blob/317832ca2b7ec234fca6039184686d921bac925d/lib/geocoder/sql.rb#L57
    #
    module Geocoder
    module Sql
    ##
  2. ttilberg renamed this gist Apr 27, 2018. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions sql.rb → config_initializers_geocoder.rb
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,6 @@
    #
    module Geocoder
    module Sql
    extend self
    ##
    #
    # Fairly accurate bearing calculation. Takes a latitude, longitude,
    @@ -18,7 +17,7 @@ module Sql
    # Based on:
    # http://www.beginningspatial.com/calculating_bearing_one_point_another
    #
    def full_bearing(latitude, longitude, lat_attr, lon_attr, options = {})
    def self.full_bearing(latitude, longitude, lat_attr, lon_attr, options = {})
    degrees_per_radian = Geocoder::Calculations::DEGREES_PER_RADIAN
    case options[:bearing] || Geocoder.config.distances
    when :linear
  3. ttilberg created this gist Apr 27, 2018.
    46 changes: 46 additions & 0 deletions sql.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,46 @@
    # Rewritten bearing function that supports SQL Server:
    # - ATAN2 function renamed ATN2
    # - Use `%` operator instead of `MOD()` function
    # This seems like it would be very reasonable to apply more dynamically.
    #
    module Geocoder
    module Sql
    extend self
    ##
    #
    # Fairly accurate bearing calculation. Takes a latitude, longitude,
    # and an options hash which must include a :bearing value
    # (:linear or :spherical).
    #
    # For use with a database that supports MOD() and trigonometric functions
    # SIN(), COS(), ASIN(), ATAN2().
    #
    # Based on:
    # http://www.beginningspatial.com/calculating_bearing_one_point_another
    #
    def full_bearing(latitude, longitude, lat_attr, lon_attr, options = {})
    degrees_per_radian = Geocoder::Calculations::DEGREES_PER_RADIAN
    case options[:bearing] || Geocoder.config.distances
    when :linear
    "CAST(" +
    "(ATN2( " +
    "((#{lon_attr} - #{longitude.to_f}) / #{degrees_per_radian}), " +
    "((#{lat_attr} - #{latitude.to_f}) / #{degrees_per_radian})" +
    ") * #{degrees_per_radian}) + 360 " +
    "AS decimal) % 360"
    when :spherical
    "CAST(" +
    "(ATN2( " +
    "SIN( (#{lon_attr} - #{longitude.to_f}) / #{degrees_per_radian} ) * " +
    "COS( (#{lat_attr}) / #{degrees_per_radian} ), (" +
    "COS( (#{latitude.to_f}) / #{degrees_per_radian} ) * SIN( (#{lat_attr}) / #{degrees_per_radian})" +
    ") - (" +
    "SIN( (#{latitude.to_f}) / #{degrees_per_radian}) * COS((#{lat_attr}) / #{degrees_per_radian}) * " +
    "COS( (#{lon_attr} - #{longitude.to_f}) / #{degrees_per_radian})" +
    ")" +
    ") * #{degrees_per_radian}) + 360 " +
    "AS decimal) % 360"
    end
    end
    end
    end