No custom Planetiler profile needed after all — Maptool::HikingTrails runs osmium tags-filter r/route=hiking against the same .osm.pbf PmtilesBuilder already downloads per country for offline.pmtiles, then osmium cat -f opl (locations_on_ways=true) to get member-way geometry back as plain text, no separate node-id lookup table to build. No general OSM tool stitches a route relation into one line (routes are a semantic grouping, not a geometry type) — parse_opl does that walk itself, same as the Overpass-based click handler already does client-side. Kept pure/testable apart from the two osmium subprocess calls, mirroring OverpassPois.fetch vs .to_geojson. rake hiking:trails[pbf,out] to try it by hand against a real cached extract. Not wired into the actual offline build or rendering yet — still just a prototype, per TODO.adoc.
72 lines
2.9 KiB
Ruby
72 lines
2.9 KiB
Ruby
require "rake/testtask"
|
|
|
|
Rake::TestTask.new(:test) do |t|
|
|
t.libs << "test" << "lib"
|
|
t.test_files = FileList["test/test_*.rb"]
|
|
end
|
|
|
|
task default: :test
|
|
|
|
namespace :overpass do
|
|
desc "Fetch camper-relevant POIs (water, dump stations, LPG, toilets, laundry, shops, springs) " \
|
|
"for a bbox from Overpass and write GeoJSON. Usage: rake overpass:pois[south,west,north,east,out.geojson]"
|
|
task :pois, [:south, :west, :north, :east, :out] do |_t, args|
|
|
%i[south west north east out].each { |key| abort("usage: rake overpass:pois[south,west,north,east,out.geojson]") unless args[key] }
|
|
|
|
require_relative "lib/maptool/overpass_pois"
|
|
bbox = [args[:south], args[:west], args[:north], args[:east]].map(&:to_f)
|
|
|
|
puts "Querying Overpass for #{bbox.join(",")}..."
|
|
response = Maptool::OverpassPois.fetch(bbox)
|
|
geojson = Maptool::OverpassPois.to_geojson(response)
|
|
File.write(args[:out], JSON.generate(geojson))
|
|
puts "Wrote #{geojson["features"].size} POIs to #{args[:out]}"
|
|
end
|
|
end
|
|
|
|
namespace :hiking do
|
|
desc "Extract route=hiking relations (name/colour/network/operator, full geometry) from a local " \
|
|
".osm.pbf (e.g. one of PmtilesBuilder's own data/geofabrik_cache/*.osm.pbf) and write GeoJSON. " \
|
|
"Prototype — see lib/maptool/hiking_trails.rb. Usage: rake hiking:trails[input.osm.pbf,out.geojson]"
|
|
task :trails, %i[pbf out] do |_t, args|
|
|
%i[pbf out].each { |key| abort("usage: rake hiking:trails[input.osm.pbf,out.geojson]") unless args[key] }
|
|
|
|
require_relative "lib/maptool/hiking_trails"
|
|
|
|
puts "Extracting hiking routes from #{args[:pbf]}..."
|
|
geojson = Maptool::HikingTrails.extract(args[:pbf])
|
|
File.write(args[:out], JSON.generate(geojson))
|
|
puts "Wrote #{geojson["features"].size} route(s) to #{args[:out]}"
|
|
end
|
|
end
|
|
|
|
namespace :gpx do
|
|
desc "Backfill properties.id on Note-category features saved before edit/delete (and its id targeting) existed"
|
|
task :backfill_note_ids do
|
|
require "json"
|
|
require "securerandom"
|
|
|
|
data_dir = ENV.fetch("MAPTOOL_DATA_DIR") { File.join(__dir__, "data") }
|
|
count = 0
|
|
Dir.glob(File.join(data_dir, "gpx", "**", "*.geojson")).each do |file|
|
|
# ".gpx.geojson"/".fit.geojson" are GpxStore's own cache sidecars for
|
|
# an uploaded GPX/FIT (regenerated from the source on demand, see
|
|
# GpxStore#geojson) — never hand-drawn notes, not worth touching.
|
|
next if file.end_with?(".gpx.geojson", ".fit.geojson")
|
|
|
|
collection = JSON.parse(File.read(file))
|
|
changed = false
|
|
(collection["features"] || []).each do |feature|
|
|
properties = (feature["properties"] ||= {})
|
|
next unless properties["category"] == "Note" && !properties["id"]
|
|
|
|
properties["id"] = SecureRandom.uuid
|
|
changed = true
|
|
count += 1
|
|
end
|
|
File.write(file, JSON.generate(collection)) if changed
|
|
end
|
|
puts "Backfilled #{count} note id(s)"
|
|
end
|
|
end
|