From 995880e5a32e6b520b9f63ee7ca434f0f61035d9 Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Thu, 29 May 2025 12:48:21 +0100 Subject: [PATCH] wip --- README | 25 ++++++++++++++++--- pkgs/maps/main.fnl | 61 +++++++++++++++++++++++++++++++-------------- pkgs/maps/tiles.fnl | 26 +++++++++++-------- 3 files changed, 80 insertions(+), 32 deletions(-) diff --git a/README b/README index 70bdb5a..dec6e66 100644 --- a/README +++ b/README @@ -127,9 +127,28 @@ the benefit of the caching. If we're going to do that, should it also do transformation e.g. from lat/long to x/y co-ordinates? We don't need this bit yet though -3) alternatively we could use mapbox vector tiles, but tbh I'm -struggling to see now that helps. we don't have to transform from -lat/long but instead we have to parse a protobuf, how is that simpler? + +https://git.syndicate-lang.org/tonyg/squeak-phone/raw/commit/474960ddc665ed445a1f5afb0164fe39057720f9/devices/pine64-pinephone/modem-docs/80545ST10798A_LM940_QMI_Command_Reference_Guide_r3.pdf + +---- + + +we need to extend to multiple tiles'-worth of map + + +* get tile for curent lat/long and request overpass data for enough + surrounding tiles to fill the screen + +* I think a way is served with all its nodes whether or not they're in +the bbox, so we can just store the ids of ways we've seen and skip +them if the come up again + +* render all the polylines into the widget (some day also the labels etc) + +* to get it centred on the cyclist, take the tile fractional part * + 256, and translate the canvas up and left by that amount + +* add a cache of [x,y,z] -> polylines so that we don't keep hitting overpass diff --git a/pkgs/maps/main.fnl b/pkgs/maps/main.fnl index fc2cf33..3590cf1 100644 --- a/pkgs/maps/main.fnl +++ b/pkgs/maps/main.fnl @@ -30,7 +30,9 @@ label.readout { (os.difftime (os.time localt) (os.time utct)))) - +(local map-width 720) +(local map-height 800) +(local tile-size 256) (fn styles [] (let [style_provider (Gtk.CssProvider)] @@ -44,8 +46,8 @@ label.readout { (local window (Gtk.Window { :title "Map" :name "toplevel" - :default_width 720 - :default_height 800 + :default_width map-width + :default_height map-height :on_destroy Gtk.main_quit })) @@ -59,29 +61,52 @@ label.readout { :speed 14 :lat 49 :lon 0 + :zoom 17 :course 22 } ) +(fn merge [table1 table2] + (collect [k v (pairs table2) &into table1] + k v)) + +;; given lat/lon +;; we want the tile containing lat to be roughly centred +;; on the screen, and enough tiles either side of it +;; to fill the width of the screen plus a bit + (fn osm-widget [] - (let [height 256] + (let [height tile-size + num-tiles-x (+ 1 (math.ceil (/ map-width tile-size))) + num-tiles-y (+ 1 (math.ceil (/ map-height tile-size))) + (tile-x tile-y) (tiles.latlon->tile app-state.lat app-state.lon app-state.zoom) + min-tile-x (math.floor (- tile-x (/ num-tiles-x 2))) + max-tile-x (math.ceil (+ tile-x (/ num-tiles-x 2))) + min-tile-y (math.floor (- tile-y (/ num-tiles-y 2))) + max-tile-y (math.ceil (+ tile-y (/ num-tiles-y 2))) + lines []] + + (for [x min-tile-x max-tile-x] + (for [y min-tile-y max-tile-y] + (print :x x :y y) + (merge lines (tiles.polylines x y app-state.zoom)))) + (Gtk.Label { :width height :height height :on_draw (fn [self g] (print app-state.lat app-state.lon ) - (let [lines (tiles.polylines app-state.lat app-state.lon 17)] - (g:set_source_rgb 0.2 0.2 0.4) - (g:set_line_width 3) - (each [_ line (ipairs lines)] - (case line - [[sx sy] & more] - (do - (g:move_to sx sy) - (each [_ [x y] (ipairs more)] - (g:line_to x y))))) - (g:stroke) - true)) + (g:set_source_rgb 0.2 0.2 0.4) + (g:set_line_width 3) + (each [_ line (pairs lines)] + (case line + [[sx sy] & more] + (do + (g:move_to sx sy) + (each [_ [x y] (ipairs more)] + (g:line_to x y))))) + (g:stroke) + true) }))) (fn readout [name text] @@ -106,9 +131,7 @@ label.readout { (expect= (hhmmss (+ 45 (* 60 12) (* 60 60 3))) "3:12:45") -(fn merge [table1 table2] - (collect [k v (pairs table2) &into table1] - k v)) + (fn update-app-state [new-vals] diff --git a/pkgs/maps/tiles.fnl b/pkgs/maps/tiles.fnl index 79a444c..b9c853e 100644 --- a/pkgs/maps/tiles.fnl +++ b/pkgs/maps/tiles.fnl @@ -43,9 +43,11 @@ (expect= (math.floor y) 43221)) -(fn overpass [lat lon] - (let [n (+ lat 0.01) - w (- lon 0.01) +(fn overpass [lat lon zoom] + (let [width (/ 360 (^ 2 zoom)) + _ (print :w zoom width) + n (+ lat width) ;XXX adjust for latitude + w (- lon width) s lat e lon] (-> @@ -59,13 +61,14 @@ (fn canvas [elements offset-x offset-y] (let [nodes {} - lines []] + lines {}] (each [_ e (ipairs elements)] (case e.type :node (tset nodes e.id e) :way - (table.insert + (tset lines + e.id (icollect [_ nd (ipairs e.nodes)] (let [node (. nodes nd) (tx ty) (latlon->tile node.lat node.lon 17)] @@ -73,16 +76,19 @@ [ (* 256 (- tx offset-x)) (* 256 (- ty offset-y)) ]))))) lines)) -(fn polylines [lat long zoom] - (let [r +(fn polylines [x y zoom] + (let [(lat lon) (tile->latlon x y zoom) + o (overpass lat lon zoom) + _ (print :polylines x y o) + r (req.new_from_uri "https://overpass-api.de/api/interpreter") - query { :data (overpass lat long zoom) }] + query { :data o }] (tset r.headers ":method" "POST") (r:set_body (dict_to_query query)) (let [(headers stream) (r:go) - (tx ty) (latlon->tile lat long zoom) + (tx ty) (latlon->tile lat lon zoom) data (json.decode (stream:get_body_as_string))] (canvas data.elements (math.floor tx) (math.floor ty))))) -{ : polylines } +{ : polylines : latlon->tile }