Cache parsed GPX/FIT GeoJSON to fix large POI-export loads
A several-thousand-waypoint park4night area export re-parses the whole file with REXML on every toggle — ~2.4s for a 5k-waypoint/3.6MB sample, so tens of seconds for a 50k-waypoint one, likely the actual cause behind a "Could not load" report on a 41.5MB export. MapLibre already clusters the waypoint layer client-side, so the bottleneck was never rendering — cache the GeoJSON conversion alongside the source file (invalidated by mtime) instead of a bigger bbox/tiling rework.
This commit is contained in:
1 parent
b6a9c1546e
commit
ddf2ee4990
4 files changed
+94
-9
No files matched your search
@@ -1,4 +1,5 @@
|
||||
require "fileutils"
|
||||
require "json"
|
||||
require_relative "gpx"
|
||||
require_relative "fit"
|
||||
|
||||
@@ -58,6 +59,7 @@ module Maptool
|
||||
raise Errno::ENOENT, path unless File.file?(path)
|
||||
|
||||
File.delete(path)
|
||||
File.delete(geojson_cache_path(path)) if File.file?(geojson_cache_path(path))
|
||||
end
|
||||
|
||||
def delete_folder(relative_path)
|
||||
@@ -79,10 +81,30 @@ module Maptool
|
||||
dest_dir = resolve_dir(to_folder.to_s)
|
||||
FileUtils.mkdir_p(dest_dir)
|
||||
name = unique_filename(dest_dir, File.basename(source))
|
||||
FileUtils.mv(source, File.join(dest_dir, name))
|
||||
dest = File.join(dest_dir, name)
|
||||
FileUtils.mv(source, dest)
|
||||
FileUtils.mv(geojson_cache_path(source), geojson_cache_path(dest)) if File.file?(geojson_cache_path(source))
|
||||
to_folder.to_s.empty? ? name : "#{to_folder}/#{name}"
|
||||
end
|
||||
|
||||
# The GeoJSON conversion (Gpx.to_geojson/Fit.to_geojson) re-parses the
|
||||
# whole file with REXML every call — fine for a small track, but a
|
||||
# several-thousand-waypoint POI export (e.g. a park4night area export)
|
||||
# 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.
|
||||
def geojson(relative_path)
|
||||
path = resolve_file(relative_path)
|
||||
raise Errno::ENOENT, path unless File.file?(path)
|
||||
|
||||
cache = geojson_cache_path(path)
|
||||
if !File.file?(cache) || File.mtime(cache) < File.mtime(path)
|
||||
data = path.downcase.end_with?(".fit") ? Fit.to_geojson(path) : Gpx.to_geojson(path)
|
||||
File.write(cache, JSON.generate(data))
|
||||
end
|
||||
File.read(cache)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def resolve_dir(folder)
|
||||
@@ -96,6 +118,10 @@ module Maptool
|
||||
path == @root || path.start_with?(@root + File::SEPARATOR)
|
||||
end
|
||||
|
||||
def geojson_cache_path(path)
|
||||
"#{path}.geojson"
|
||||
end
|
||||
|
||||
TRACK_EXTENSIONS = %w[.gpx .fit].freeze
|
||||
|
||||
def safe_filename(filename)
|
||||
|
||||
Reference in new issue
Block a user