X-Git-Url: https://git.openstreetmap.org./rails.git/blobdiff_plain/3d3b2b47964ec91ef1ab1946b7258a06665caced..437eb1fa8a518e760d76e51a1ab6ddd20c39ffc9:/app/controllers/changesets_controller.rb?ds=sidebyside diff --git a/app/controllers/changesets_controller.rb b/app/controllers/changesets_controller.rb index d5ac49d4c..07e7a365f 100644 --- a/app/controllers/changesets_controller.rb +++ b/app/controllers/changesets_controller.rb @@ -2,6 +2,7 @@ class ChangesetsController < ApplicationController include UserMethods + include PaginationMethods layout "site" @@ -17,12 +18,13 @@ class ChangesetsController < ApplicationController ## # list non-empty changesets in reverse chronological order def index - param! :max_id, Integer, :min => 1 + param! :before, Integer, :min => 1 + param! :after, Integer, :min => 1 - @params = params.permit(:display_name, :bbox, :friends, :nearby, :max_id, :list) + @params = params.permit(:display_name, :bbox, :friends, :nearby, :before, :after, :list) - if request.format == :atom && @params[:max_id] - redirect_to url_for(@params.merge(:max_id => nil)), :status => :moved_permanently + if request.format == :atom && (@params[:before] || @params[:after]) + redirect_to url_for(@params.merge(:before => nil, :after => nil)), :status => :moved_permanently return end @@ -52,16 +54,17 @@ class ChangesetsController < ApplicationController changesets.where("false") end elsif @params[:bbox] - changesets = conditions_bbox(changesets, BoundingBox.from_bbox_params(params)) + bbox_array = @params[:bbox].split(",").map(&:to_f) + raise OSM::APIBadUserInput, "The parameter bbox must be of the form min_lon,min_lat,max_lon,max_lat" unless bbox_array.count == 4 + + changesets = conditions_bbox(changesets, *bbox_array) elsif @params[:friends] && current_user changesets = changesets.where(:user => current_user.followings.identifiable) elsif @params[:nearby] && current_user changesets = changesets.where(:user => current_user.nearby) end - changesets = changesets.where(:changesets => { :id => ..@params[:max_id] }) if @params[:max_id] - - @changesets = changesets.order("changesets.id DESC").limit(20).preload(:user, :changeset_tags, :comments) + @changesets, @newer_changesets_id, @older_changesets_id = get_page_items(changesets, :includes => [:user, :changeset_tags, :comments]) render :action => :index, :layout => false end @@ -113,21 +116,37 @@ class ChangesetsController < ApplicationController #------------------------------------------------------------ ## - # if a bounding box was specified do some sanity checks. # restrict changesets to those enclosed by a bounding box - def conditions_bbox(changesets, bbox) - if bbox - bbox.check_boundaries - bbox = bbox.to_scaled - - changesets.where("min_lon < ? and max_lon > ? and min_lat < ? and max_lat > ?", - bbox.max_lon.to_i, bbox.min_lon.to_i, - bbox.max_lat.to_i, bbox.min_lat.to_i) - else + def conditions_bbox(changesets, min_lon, min_lat, max_lon, max_lat) + db_min_lat = (min_lat * GeoRecord::SCALE).to_i + db_max_lat = (max_lat * GeoRecord::SCALE).to_i + db_min_lon = (wrap_lon(min_lon) * GeoRecord::SCALE).to_i + db_max_lon = (wrap_lon(max_lon) * GeoRecord::SCALE).to_i + + changesets = changesets.where("min_lat < ? and max_lat > ?", db_max_lat, db_min_lat) + + if max_lon - min_lon >= 360 + # the query bbox spans the entire world, therefore no lon checks are necessary changesets + elsif db_min_lon <= db_max_lon + # the normal case when the query bbox doesn't include the antimeridian + changesets.where("min_lon < ? and max_lon > ?", db_max_lon, db_min_lon) + else + # the query bbox includes the antimeridian + # this case works as if there are two query bboxes: + # [-180*SCALE .. db_max_lon], [db_min_lon .. 180*SCALE] + # it would be necessary to check if changeset bboxes intersect with either of the query bboxes: + # (changesets.min_lon < db_max_lon and changesets.max_lon > -180*SCALE) or (changesets.min_lon < 180*SCALE and changesets.max_lon > db_min_lon) + # but the comparisons with -180*SCALE and 180*SCALE are unnecessary: + # (changesets.min_lon < db_max_lon) or (changesets.max_lon > db_min_lon) + changesets.where("min_lon < ? or max_lon > ?", db_max_lon, db_min_lon) end end + def wrap_lon(lon) + ((lon + 180) % 360) - 180 + end + ## # eliminate empty changesets (where the bbox has not been set) # this should be applied to all changeset list displays