diff --git a/app.rb b/app.rb index 7abea43..928f0d6 100644 --- a/app.rb +++ b/app.rb @@ -191,6 +191,10 @@ module Maptool json paths: paths, tree: GPX_STORE.tree end + # ?download=1 exports the file's GeoJSON as an attachment instead of + # rendering it on the map — the only way to get a .gpx/.fit's converted + # form out of the app, since GpxStore#geojson's cache is otherwise an + # internal implementation detail with no filename of its own to expose. get "/api/gpx/file/*" do begin body = GPX_STORE.geojson(params[:splat].first) @@ -203,6 +207,15 @@ module Maptool end content_type :json + if params[:download] + # Matches the tree's own display name for a cached .gpx/.fit + # (public/js/gpx.js's _renderFile) — "ride.gpx" downloads as + # "ride.gpx.geojson", not "ride.geojson", so the two never disagree. + # A .geojson source is already named right and is left alone. + original_name = File.basename(params[:splat].first) + download_name = original_name.downcase.end_with?(".geojson") ? original_name : "#{original_name}.geojson" + attachment download_name + end body end diff --git a/docs/architecture.adoc b/docs/architecture.adoc index 5acda55..6222a91 100644 --- a/docs/architecture.adoc +++ b/docs/architecture.adoc @@ -285,7 +285,23 @@ A `.geojson` upload skips this path entirely — `geojson` reads and returns it directly, no cache file, no `Gpx`/`Fit` involved; the file tree's cached-file icon (`GEOJSON_ICON`, `public/js/icons.js`) always shows for one, since there's no conversion step it could ever be -waiting on. `Gpx` parses the GPX with REXML: `` +waiting on. ++ +Once a `.gpx`/`.fit` is cached, the tree shows it under its converted +name instead — `"ride.gpx"` reads as `"ride.gpx.geojson"`, matching +the real cache file sitting next to it on disk — since the GeoJSON, +not the original, is what's actually rendered on the map from that +point on. The original is never deleted or re-parsed once cached, just +not re-shown as itself; the tree's file name is a real link +(`GET /api/gpx/file/?download=1`), the only way to get that +converted form out of the app as an actual file, since the cache is +otherwise an implementation detail with no name of its own to expose. +It's an ``, not a ``, specifically so clicking it downloads +instead of also toggling the row's checkbox — a native ``/`