This commit is contained in:
Daniel Barlow 2025-05-29 12:48:21 +01:00
parent 398693bc07
commit 995880e5a3
3 changed files with 80 additions and 32 deletions

25
README
View File

@ -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

View File

@ -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]

View File

@ -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 }