Support uploading .geojson files directly
A .geojson file needs no GPX/FIT conversion — it's already the shape gpx.js expects — so GpxStore#geojson now just reads and returns it as-is, no cache sidecar. save/tree/the upload dropzone and its zip handling all pick it up through the existing TRACK_EXTENSIONS list. Also fixes a bug the new "cached" tree icon would have shipped with: a GPX/FIT's own .geojson cache sidecar (e.g. "ride.gpx.geojson") also matches the new .geojson branch in list_children, which would have listed it as a second, phantom tree entry — excluded explicitly, with a regression test.
This commit is contained in:
1 parent
44d235bbcf
commit
b4f205667b
8 files changed
+110
-19
No files matched your search
@@ -0,0 +1,18 @@
|
||||
module Maptool
|
||||
# A directly-uploaded .geojson file needs no conversion — GpxStore serves
|
||||
# it straight from disk (see GpxStore#geojson) — so unlike Gpx/Fit there's
|
||||
# no to_geojson here. Only kind-detection lives here, for the tree's badge
|
||||
# icons, mirroring Gpx.kinds' cheap substring-search rather than a full
|
||||
# JSON parse: a POI export can be tens of MB, geojson or not, and a full
|
||||
# parse just to answer "does this have any points/lines" would cost the
|
||||
# same either way.
|
||||
module Geojson
|
||||
def self.kinds(path)
|
||||
content = File.read(path)
|
||||
kinds = []
|
||||
kinds << "waypoint" if content.include?('"Point"')
|
||||
kinds << "track" if content.include?('"LineString"') # matches MultiLineString too
|
||||
kinds
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2,6 +2,7 @@ require "fileutils"
|
||||
require "json"
|
||||
require_relative "gpx"
|
||||
require_relative "fit"
|
||||
require_relative "geojson"
|
||||
|
||||
module Maptool
|
||||
# Filesystem-backed store for uploaded GPX/FIT files, organized in
|
||||
@@ -110,9 +111,14 @@ module Maptool
|
||||
# can take tens of seconds, every single time the file is toggled
|
||||
# visible. Cached alongside the source file and invalidated by mtime,
|
||||
# so only the first read after a save (or edit) pays that cost.
|
||||
#
|
||||
# A directly-uploaded .geojson file skips all of this — it's already in
|
||||
# the shape gpx.js expects, so there's nothing to convert or cache;
|
||||
# it's just read and served as-is.
|
||||
def geojson(relative_path)
|
||||
path = resolve_file(relative_path)
|
||||
raise Errno::ENOENT, path unless File.file?(path)
|
||||
return File.read(path) if path.downcase.end_with?(".geojson")
|
||||
|
||||
cache = geojson_cache_path(path)
|
||||
unless geojson_cached?(path)
|
||||
@@ -139,12 +145,16 @@ module Maptool
|
||||
"#{path}.geojson"
|
||||
end
|
||||
|
||||
# A .geojson source needs no separate cache file — it already is the
|
||||
# target format, so it's always "ready".
|
||||
def geojson_cached?(path)
|
||||
return true if path.downcase.end_with?(".geojson")
|
||||
|
||||
cache = geojson_cache_path(path)
|
||||
File.file?(cache) && File.mtime(cache) >= File.mtime(path)
|
||||
end
|
||||
|
||||
TRACK_EXTENSIONS = %w[.gpx .fit].freeze
|
||||
TRACK_EXTENSIONS = %w[.gpx .fit .geojson].freeze
|
||||
|
||||
def safe_filename(filename)
|
||||
base = File.basename(filename.to_s)
|
||||
@@ -176,6 +186,12 @@ module Maptool
|
||||
{ "type" => "file", "name" => entry, "path" => rel, "kinds" => Gpx.kinds(full), "cached" => geojson_cached?(full) }
|
||||
elsif entry.downcase.end_with?(".fit")
|
||||
{ "type" => "file", "name" => entry, "path" => rel, "kinds" => Fit.kinds(full), "cached" => geojson_cached?(full) }
|
||||
# A GPX/FIT's own cache sidecar (e.g. "ride.gpx.geojson", written by
|
||||
# `geojson` above) also ends in ".geojson" — excluded here so it
|
||||
# doesn't show up as a second, phantom tree entry next to the file
|
||||
# it was derived from.
|
||||
elsif entry.downcase.end_with?(".geojson") && !entry.downcase.end_with?(".gpx.geojson", ".fit.geojson")
|
||||
{ "type" => "file", "name" => entry, "path" => rel, "kinds" => Geojson.kinds(full), "cached" => true }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in new issue
Block a user