Skip to content

Instantly share code, notes, and snippets.

@rmanalan
Created March 5, 2009 19:58
Show Gist options
  • Save rmanalan/74525 to your computer and use it in GitHub Desktop.
Save rmanalan/74525 to your computer and use it in GitHub Desktop.
# Returns the distance SQL using the spherical world formula (Haversine). The SQL is tuned
# to the database in use.
def sphere_distance_sql(origin, units)
lat = deg2rad(origin.lat)
lng = deg2rad(origin.lng)
multiplier = units_sphere_multiplier(units)
case connection.adapter_name.downcase
when "mysql"
sql=<<-SQL_END
(ACOS(least(1,COS(#{lat})*COS(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*COS(RADIANS(#{qualified_lng_column_name}))+
COS(#{lat})*SIN(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*SIN(RADIANS(#{qualified_lng_column_name}))+
SIN(#{lat})*SIN(RADIANS(#{qualified_lat_column_name}))))*#{multiplier})
SQL_END
when "postgresql"
sql=<<-SQL_END
(ACOS(least(1,COS(#{lat})*COS(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*COS(RADIANS(#{qualified_lng_column_name}))+
COS(#{lat})*SIN(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*SIN(RADIANS(#{qualified_lng_column_name}))+
SIN(#{lat})*SIN(RADIANS(#{qualified_lat_column_name}))))*#{multiplier})
SQL_END
when "oracle"
radian = PI/180
sql=<<-SQL_END
(ACOS(least(1,COS(#{lat})*COS(#{lng})*COS(#{qualified_lat_column_name}*#{radian})*COS#{qualified_lng_column_name}*#{radian})+
COS(#{lat})*SIN(#{lng})*COS(#{qualified_lat_column_name}*#{radian})*SIN(#{qualified_lng_column_name}*#{radian})+
SIN(#{lat})*SIN(#{qualified_lat_column_name}*#{radian})))*#{multiplier})
SQL_END
else
sql = "unhandled #{connection.adapter_name.downcase} adapter"
end
end
# Returns the distance SQL using the flat-world formula (Phythagorean Theory). The SQL is tuned
# to the database in use.
def flat_distance_sql(origin, units)
lat_degree_units = units_per_latitude_degree(units)
lng_degree_units = units_per_longitude_degree(origin.lat, units)
case connection.adapter_name.downcase
when "mysql"
sql=<<-SQL_END
SQRT(POW(#{lat_degree_units}*(#{origin.lat}-#{qualified_lat_column_name}),2)+
POW(#{lng_degree_units}*(#{origin.lng}-#{qualified_lng_column_name}),2))
SQL_END
when "postgresql"
sql=<<-SQL_END
SQRT(POW(#{lat_degree_units}*(#{origin.lat}-#{qualified_lat_column_name}),2)+
POW(#{lng_degree_units}*(#{origin.lng}-#{qualified_lng_column_name}),2))
SQL_END
when "oracle"
sql=<<-SQL_END
SQRT(POWER(#{lat_degree_units}*(#{origin.lat}-#{qualified_lat_column_name}),2)+
POWER(#{lng_degree_units}*(#{origin.lng}-#{qualified_lng_column_name}),2))
SQL_END
else
sql = "unhandled #{connection.adapter_name.downcase} adapter"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment