Skip to content
Snippets Groups Projects
Commit cf0bd9bf authored by Matthew Landauer's avatar Matthew Landauer
Browse files

Add bounding box optimisation to distance query

parent 622cc460
No related branches found
No related tags found
No related merge requests found
......@@ -100,15 +100,18 @@ module Geocoder::Store
options[:units] ||= (geocoder_options[:units] || Geocoder::Configuration.units)
bearing = bearing_sql(latitude, longitude, options)
distance = distance_sql(latitude, longitude, options)
b = Geocoder::Calculations.bounding_box([latitude, longitude], radius, options)
args = b + [
full_column_name(geocoder_options[:latitude]),
full_column_name(geocoder_options[:longitude])
]
bounding_box_conditions = Geocoder::Sql.within_bounding_box(*args)
if using_sqlite?
b = Geocoder::Calculations.bounding_box([latitude, longitude], radius, options)
args = b + [
full_column_name(geocoder_options[:latitude]),
full_column_name(geocoder_options[:longitude])
]
conditions = Geocoder::Sql.within_bounding_box(*args)
conditions = bounding_box_conditions
else
conditions = ["#{distance} <= ?", radius]
conditions = [bounding_box_conditions + " AND #{distance} <= ?", radius]
end
{
:select => select_clause(options[:select], distance, bearing),
......
......@@ -8,7 +8,10 @@ class NearTest < Test::Unit::TestCase
:select =>
"test_table_name.*, 3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((1.0 - test_table_name.latitude) * PI() / 180 / 2), 2) + COS(1.0 * PI() / 180) * COS(test_table_name.latitude * PI() / 180) * POWER(SIN((2.0 - test_table_name.longitude) * PI() / 180 / 2), 2))) AS distance, CAST(DEGREES(ATAN2( RADIANS(test_table_name.longitude - 2.0), RADIANS(test_table_name.latitude - 1.0))) + 360 AS decimal) % 360 AS bearing",
:conditions =>
["3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((1.0 - test_table_name.latitude) * PI() / 180 / 2), 2) + COS(1.0 * PI() / 180) * COS(test_table_name.latitude * PI() / 180) * POWER(SIN((2.0 - test_table_name.longitude) * PI() / 180 / 2), 2))) <= ?", 5],
[
"test_table_name.latitude BETWEEN 0.927634108444576 AND 1.072365891555424 AND test_table_name.longitude BETWEEN 1.9276230850898697 AND 2.07237691491013 AND 3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((1.0 - test_table_name.latitude) * PI() / 180 / 2), 2) + COS(1.0 * PI() / 180) * COS(test_table_name.latitude * PI() / 180) * POWER(SIN((2.0 - test_table_name.longitude) * PI() / 180 / 2), 2))) <= ?",
5
],
:order => "distance ASC"
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment