2 class TracepointsController < ApplicationController
3 skip_before_action :verify_authenticity_token
4 before_action :api_deny_access_handler
8 before_action :check_api_readable
9 around_action :api_call_handle_error, :api_call_timeout
11 # Get an XML response containing a list of tracepoints that have been uploaded
12 # within the specified bounding box, and in the specified page.
14 # retrieve the page number
15 page = params["page"].to_s.to_i
18 report_error("Page number must be greater than or equal to 0")
22 offset = page * Settings.tracepoints_per_page
25 # check boundary is sane and area within defined
26 # see /config/application.yml
28 bbox = BoundingBox.from_bbox_params(params)
31 rescue StandardError => err
32 report_error(err.message)
37 ordered_points = Tracepoint.bbox(bbox).joins(:trace).where(:gpx_files => { :visibility => %w[trackable identifiable] }).order("gpx_id DESC, trackid ASC, timestamp ASC")
38 unordered_points = Tracepoint.bbox(bbox).joins(:trace).where(:gpx_files => { :visibility => %w[public private] }).order("gps_points.latitude", "gps_points.longitude", "gps_points.timestamp")
39 points = ordered_points.union_all(unordered_points).offset(offset).limit(Settings.tracepoints_per_page)
41 doc = XML::Document.new
42 doc.encoding = XML::Encoding::UTF_8
43 root = XML::Node.new "gpx"
44 root["version"] = "1.0"
45 root["creator"] = "OpenStreetMap.org"
46 root["xmlns"] = "http://www.topografix.com/GPX/1/0"
50 # initialise these variables outside of the loop so that they
51 # stay in scope and don't get free'd up by the GC during the
62 points.each do |point|
63 if gpx_id != point.gpx_id
66 gpx_file = Trace.find(gpx_id)
68 if gpx_file.trackable?
69 track = XML::Node.new "trk"
73 if gpx_file.identifiable?
74 track << (XML::Node.new("name") << gpx_file.name)
75 track << (XML::Node.new("desc") << gpx_file.description)
76 track << (XML::Node.new("url") << url_for(:controller => "/traces", :action => "show", :display_name => gpx_file.user.display_name, :id => gpx_file.id))
79 # use the anonymous track segment if the user hasn't allowed
80 # their GPX points to be tracked.
83 anon_track = XML::Node.new "trk"
84 doc.root << anon_track
90 if trackid != point.trackid
91 if gpx_file.trackable?
92 trkseg = XML::Node.new "trkseg"
94 trackid = point.trackid
97 anon_trkseg = XML::Node.new "trkseg"
98 anon_track << anon_trkseg
104 trkseg << point.to_xml_node(timestamps)
107 response.headers["Content-Disposition"] = "attachment; filename=\"tracks.gpx\""
109 render :xml => doc.to_s