Add GPX upload with hierarchical folders and map display

Upload GPX files into a folder hierarchy (traversal-safe path
resolution against the store root), browse them in a tree panel, and
toggle each one's waypoints/tracks on the map. Waypoints render as
clickable points showing name, description and time; bare URLs in the
description are turned into safe links. GPX layers survive switching
between the Online/Offline base map, same as the radar overlay.

Adds rexml as an explicit dependency — it moved to a bundled gem in
this Ruby version and isn't picked up by Bundler otherwise.
This commit is contained in:
randy committed 2026-08-25 14:05:39 +02:00
1 parent 16e06b2ffe
commit 4e0d2abbd0
13 files changed
+629 -2

No files matched your search

+35
View File
@@ -1,5 +1,7 @@
require "sinatra/base"
require "sinatra/json"
require_relative "lib/maptool/gpx"
require_relative "lib/maptool/gpx_store"
module Maptool
class App < Sinatra::Base
@@ -7,6 +9,7 @@ module Maptool
set :views, File.join(__dir__, "views")
OFFLINE_PMTILES_PATH = File.join(__dir__, "data", "offline.pmtiles")
GPX_STORE = GpxStore.new(File.join(__dir__, "data", "gpx"))
get "/" do
erb :index
@@ -28,5 +31,37 @@ module Maptool
send_file OFFLINE_PMTILES_PATH, type: "application/octet-stream"
end
get "/api/gpx/tree" do
json GPX_STORE.tree
end
post "/api/gpx" do
file = params[:file]
halt 400, json(error: "file is required") unless file && file[:tempfile]
begin
path = GPX_STORE.save(folder: params[:folder].to_s, filename: file[:filename], io: file[:tempfile])
rescue GpxStore::InvalidPath
halt 400, json(error: "invalid folder")
end
json path: path, tree: GPX_STORE.tree
end
get "/api/gpx/file/*" do
begin
path = GPX_STORE.resolve_file(params[:splat].first)
rescue GpxStore::InvalidPath
halt 400
end
halt 404 unless File.file?(path)
begin
json Gpx.to_geojson(path)
rescue Gpx::ParseError
halt 422, json(error: "could not parse GPX file")
end
end
end
end