+ else
+ @not_found_user = params[:display_name]
+ render :template => 'user/no_such_user', :status => :not_found
+ end
+ end
+
+ ##
+ # list changesets in a bbox
+ def list_bbox
+ # support 'bbox' param or alternatively 'minlon', 'minlat' etc
+ if params['bbox']
+ bbox = params['bbox']
+ elsif params['minlon'] and params['minlat'] and params['maxlon'] and params['maxlat']
+ bbox = h(params['minlon']) + ',' + h(params['minlat']) + ',' + h(params['maxlon']) + ',' + h(params['maxlat'])
+ else
+ #TODO: fix bugs in location determination for history tab (and other tabs) then uncomment this redirect
+ #redirect_to :action => 'list'
+
+ # For now just render immediately, and skip the db
+ render
+ return
+ end
+
+ conditions = conditions_bbox(bbox);
+ conditions = cond_merge conditions, conditions_nonempty
+
+ @edit_pages, @edits = paginate(:changesets,
+ :include => [:user, :changeset_tags],
+ :conditions => conditions,
+ :order => "changesets.created_at DESC",
+ :per_page => 20)
+
+ @bbox = sanitise_boundaries(bbox.split(/,/)) unless bbox==nil
+ end
+
+ ##
+ # list changesets in a bbox
+ def list_bbox_rss
+ # support 'bbox' param or alternatively 'minlon', 'minlat' etc
+ if params['bbox']
+ bbox = params['bbox']
+ elsif params['minlon'] and params['minlat'] and params['maxlon'] and params['maxlat']
+ bbox = h(params['minlon']) + ',' + h(params['minlat']) + ',' + h(params['maxlon']) + ',' + h(params['maxlat'])
+ else
+ #TODO: fix bugs in location determination for history tab (and other tabs) then uncomment this redirect
+ #redirect_to :action => 'list'
+
+ # For now just render immediately, and skip the db
+ render
+ return
+ end
+
+ conditions = conditions_bbox(bbox);
+ conditions = cond_merge conditions, conditions_nonempty
+
+ @edit_pages, @edits = paginate(:changesets,
+ :include => [:user, :changeset_tags],
+ :conditions => conditions,
+ :order => "changesets.created_at DESC",
+ :per_page => 20)
+
+ @bbox = sanitise_boundaries(bbox.split(/,/)) unless bbox==nil
+ end
+
+private
+ #------------------------------------------------------------
+ # utility functions below.
+ #------------------------------------------------------------
+
+ ##
+ # merge two conditions
+ def cond_merge(a, b)
+ if a and b
+ a_str = a.shift
+ b_str = b.shift
+ return [ a_str + " AND " + b_str ] + a + b
+ elsif a
+ return a
+ else b
+ return b
+ end
+ end
+
+ ##
+ # if a bounding box was specified then parse it and do some sanity
+ # checks. this is mostly the same as the map call, but without the
+ # area restriction.
+ def conditions_bbox(bbox)
+ unless bbox.nil?
+ raise OSM::APIBadUserInput.new("Bounding box should be min_lon,min_lat,max_lon,max_lat") unless bbox.count(',') == 3
+ bbox = sanitise_boundaries(bbox.split(/,/))
+ raise OSM::APIBadUserInput.new("Minimum longitude should be less than maximum.") unless bbox[0] <= bbox[2]
+ raise OSM::APIBadUserInput.new("Minimum latitude should be less than maximum.") unless bbox[1] <= bbox[3]
+ return ['min_lon < ? and max_lon > ? and min_lat < ? and max_lat > ?',
+ bbox[2] * GeoRecord::SCALE, bbox[0] * GeoRecord::SCALE, bbox[3]* GeoRecord::SCALE, bbox[1] * GeoRecord::SCALE]
+ else
+ return nil
+ end
+ end
+
+ ##
+ # restrict changesets to those by a particular user
+ def conditions_user(user)
+ unless user.nil?
+ # user input checking, we don't have any UIDs < 1
+ raise OSM::APIBadUserInput.new("invalid user ID") if user.to_i < 1
+
+ u = User.find(user.to_i)
+ # should be able to get changesets of public users only, or
+ # our own changesets regardless of public-ness.
+ unless u.data_public?
+ # get optional user auth stuff so that users can see their own
+ # changesets if they're non-public
+ setup_user_auth
+
+ raise OSM::APINotFoundError if @user.nil? or @user.id != u.id