Use quad tiling to select bugs in an area
Remove the _no_quadtile versiond of the selection routines and switch to using the ordinary ones but with a (large) limit applied on the size of the area to prevent us spending ages working out the list of tiles to be selected.
This commit is contained in:
parent
7bba798990
commit
22bef89d1a
6 changed files with 17 additions and 28 deletions
|
@ -37,9 +37,9 @@ class MapBugsController < ApplicationController
|
||||||
limit = getLimit
|
limit = getLimit
|
||||||
conditions = closedCondition
|
conditions = closedCondition
|
||||||
|
|
||||||
check_boundaries(@min_lon, @min_lat, @max_lon, @max_lat, :false)
|
check_boundaries(@min_lon, @min_lat, @max_lon, @max_lat, MAX_BUG_REQUEST_AREA)
|
||||||
|
|
||||||
@bugs = MapBug.find_by_area_no_quadtile(@min_lat, @min_lon, @max_lat, @max_lon, :include => :comments, :order => "last_changed DESC", :limit => limit, :conditions => conditions)
|
@bugs = MapBug.find_by_area(@min_lat, @min_lon, @max_lat, @max_lon, :include => :comments, :order => "last_changed DESC", :limit => limit, :conditions => conditions)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html {render :template => 'map_bugs/get_bugs.js', :content_type => "text/javascript"}
|
format.html {render :template => 'map_bugs/get_bugs.js', :content_type => "text/javascript"}
|
||||||
|
@ -138,9 +138,9 @@ class MapBugsController < ApplicationController
|
||||||
bbox = bbox.split(',')
|
bbox = bbox.split(',')
|
||||||
@min_lon, @min_lat, @max_lon, @max_lat = sanitise_boundaries(bbox)
|
@min_lon, @min_lat, @max_lon, @max_lat = sanitise_boundaries(bbox)
|
||||||
|
|
||||||
conditions = cond_merge conditions, [OSM.sql_for_area_no_quadtile(@min_lat, @min_lon, @max_lat, @max_lon)]
|
check_boundaries(@min_lon, @min_lat, @max_lon, @max_lat, MAX_BUG_REQUEST_AREA)
|
||||||
|
|
||||||
check_boundaries(@min_lon, @min_lat, @max_lon, @max_lat, :false)
|
conditions = cond_merge conditions, [OSM.sql_for_area(@min_lat, @min_lon, @max_lat, @max_lon)]
|
||||||
end
|
end
|
||||||
|
|
||||||
@comments = MapBugComment.find(:all, :limit => limit, :order => "date_created DESC", :joins => :map_bug, :include => :map_bug, :conditions => conditions)
|
@comments = MapBugComment.find(:all, :limit => limit, :order => "date_created DESC", :joins => :map_bug, :include => :map_bug, :conditions => conditions)
|
||||||
|
|
|
@ -24,6 +24,8 @@ standard_settings: &standard_settings
|
||||||
max_number_of_nodes: 50000
|
max_number_of_nodes: 50000
|
||||||
# Maximum number of nodes that can be in a way (checked on save)
|
# Maximum number of nodes that can be in a way (checked on save)
|
||||||
max_number_of_way_nodes: 2000
|
max_number_of_way_nodes: 2000
|
||||||
|
# The maximum area you're allowed to request bugs from, in square degrees
|
||||||
|
max_bug_request_area: 25
|
||||||
# Zoom level to use for postcode results from the geocoder
|
# Zoom level to use for postcode results from the geocoder
|
||||||
postcode_zoom: 15
|
postcode_zoom: 15
|
||||||
# Zoom level to use for geonames results from the geocoder
|
# Zoom level to use for geonames results from the geocoder
|
||||||
|
|
|
@ -54,12 +54,5 @@ private
|
||||||
return self.find(:all, options)
|
return self.find(:all, options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_by_area_no_quadtile(minlat, minlon, maxlat, maxlon, options)
|
|
||||||
self.with_scope(:find => {:conditions => OSM.sql_for_area_no_quadtile(minlat, minlon, maxlat, maxlon)}) do
|
|
||||||
return self.find(:all, options)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ module MapBoundary
|
||||||
return min_lon, min_lat, max_lon, max_lat
|
return min_lon, min_lat, max_lon, max_lat
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_boundaries(min_lon, min_lat, max_lon, max_lat, limit_small_area = :true)
|
def check_boundaries(min_lon, min_lat, max_lon, max_lat, max_area = MAX_REQUEST_AREA)
|
||||||
# check the bbox is sane
|
# check the bbox is sane
|
||||||
unless min_lon <= max_lon
|
unless min_lon <= max_lon
|
||||||
raise OSM::APIBadBoundingBox.new("The minimum longitude must be less than the maximum longitude, but it wasn't")
|
raise OSM::APIBadBoundingBox.new("The minimum longitude must be less than the maximum longitude, but it wasn't")
|
||||||
|
@ -22,12 +22,10 @@ module MapBoundary
|
||||||
raise OSM::APIBadBoundingBox.new("The latitudes must be between -90 and 90, and longitudes between -180 and 180")
|
raise OSM::APIBadBoundingBox.new("The latitudes must be between -90 and 90, and longitudes between -180 and 180")
|
||||||
end
|
end
|
||||||
|
|
||||||
return unless limit_small_area == :true
|
|
||||||
|
|
||||||
# check the bbox isn't too large
|
# check the bbox isn't too large
|
||||||
requested_area = (max_lat-min_lat)*(max_lon-min_lon)
|
requested_area = (max_lat-min_lat)*(max_lon-min_lon)
|
||||||
if requested_area > MAX_REQUEST_AREA
|
if requested_area > max_area
|
||||||
raise OSM::APIBadBoundingBox.new("The maximum bbox size is " + MAX_REQUEST_AREA.to_s +
|
raise OSM::APIBadBoundingBox.new("The maximum bbox size is " + max_area.to_s +
|
||||||
", and your request was too large. Either request a smaller area, or use planet.osm")
|
", and your request was too large. Either request a smaller area, or use planet.osm")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
11
lib/osm.rb
11
lib/osm.rb
|
@ -499,6 +499,7 @@ module OSM
|
||||||
# Return an SQL fragment to select a given area of the globe
|
# Return an SQL fragment to select a given area of the globe
|
||||||
def self.sql_for_area(minlat, minlon, maxlat, maxlon, prefix = nil)
|
def self.sql_for_area(minlat, minlon, maxlat, maxlon, prefix = nil)
|
||||||
tilesql = QuadTile.sql_for_area(minlat, minlon, maxlat, maxlon, prefix)
|
tilesql = QuadTile.sql_for_area(minlat, minlon, maxlat, maxlon, prefix)
|
||||||
|
|
||||||
minlat = (minlat * 10000000).round
|
minlat = (minlat * 10000000).round
|
||||||
minlon = (minlon * 10000000).round
|
minlon = (minlon * 10000000).round
|
||||||
maxlat = (maxlat * 10000000).round
|
maxlat = (maxlat * 10000000).round
|
||||||
|
@ -507,16 +508,6 @@ module OSM
|
||||||
return "#{tilesql} AND #{prefix}latitude BETWEEN #{minlat} AND #{maxlat} AND #{prefix}longitude BETWEEN #{minlon} AND #{maxlon}"
|
return "#{tilesql} AND #{prefix}latitude BETWEEN #{minlat} AND #{maxlat} AND #{prefix}longitude BETWEEN #{minlon} AND #{maxlon}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return an SQL fragment to select a given area of the globe without using the quadtile index
|
|
||||||
def self.sql_for_area_no_quadtile(minlat, minlon, maxlat, maxlon, prefix = nil, without_quadtile = :false)
|
|
||||||
minlat = (minlat * 10000000).round
|
|
||||||
minlon = (minlon * 10000000).round
|
|
||||||
maxlat = (maxlat * 10000000).round
|
|
||||||
maxlon = (maxlon * 10000000).round
|
|
||||||
|
|
||||||
return "#{prefix}latitude BETWEEN #{minlat} AND #{maxlat} AND #{prefix}longitude BETWEEN #{minlon} AND #{maxlon}"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Return a spam score for a chunk of text
|
# Return a spam score for a chunk of text
|
||||||
def self.spam_score(text)
|
def self.spam_score(text)
|
||||||
link_count = 0
|
link_count = 0
|
||||||
|
|
|
@ -79,10 +79,15 @@ class MapBugsControllerTest < ActionController::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_get_bugs_large_area_success
|
def test_get_bugs_large_area_success
|
||||||
get :get_bugs, {:bbox=>'-10,-10,12,12'}
|
get :get_bugs, {:bbox=>'-2.5,-2.5,2.5,2.5'}
|
||||||
assert_response :success
|
assert_response :success
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_get_bugs_large_area_bad_request
|
||||||
|
get :get_bugs, {:bbox=>'-10,-10,12,12'}
|
||||||
|
assert_response :bad_request
|
||||||
|
end
|
||||||
|
|
||||||
def test_get_bugs_closed_7_success
|
def test_get_bugs_closed_7_success
|
||||||
get :get_bugs, {:bbox=>'1,1,1.2,1.2', :closed => '7'}
|
get :get_bugs, {:bbox=>'1,1,1.2,1.2', :closed => '7'}
|
||||||
assert_response :success
|
assert_response :success
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue