Compare commits
4 Commits
53e377cabd
...
4aa140c264
Author | SHA1 | Date | |
---|---|---|---|
4aa140c264 | |||
406cedbce1 | |||
4edf246cf6 | |||
d7852700a5 |
116
README
116
README
@ -37,6 +37,24 @@ note that IPS LCD requires as much battery for dark pixels
|
|||||||
as light ones, so we get no power saving by colouring only part
|
as light ones, so we get no power saving by colouring only part
|
||||||
of the screen
|
of the screen
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
we need to not rotate the text labels
|
||||||
|
which means we need to redraw whenever the angle changes
|
||||||
|
which is much more often than when we cross a tile boundary
|
||||||
|
so caching the bitmap isn't going to work
|
||||||
|
|
||||||
|
put map features in a table in app-state keyed on tile key
|
||||||
|
use the fetch on-complete callback to update app-state directly.
|
||||||
|
side issue: we could move widget updates from update-app-state
|
||||||
|
to the timer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
maybe we could put the polylines in app-state. if we store
|
||||||
|
|
||||||
------
|
------
|
||||||
|
|
||||||
@ -47,104 +65,6 @@ random notes follow ...
|
|||||||
https://git.syndicate-lang.org/tonyg/squeak-phone/raw/commit/474960ddc665ed445a1f5afb0164fe39057720f9/devices/pine64-pinephone/modem-docs/80545ST10798A_LM940_QMI_Command_Reference_Guide_r3.pdf
|
https://git.syndicate-lang.org/tonyg/squeak-phone/raw/commit/474960ddc665ed445a1f5afb0164fe39057720f9/devices/pine64-pinephone/modem-docs/80545ST10798A_LM940_QMI_Command_Reference_Guide_r3.pdf
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1) [done] connect Satellite to qmi-nmea
|
|
||||||
|
|
||||||
https://codeberg.org/tpikonen/satellite/src/branch/main/satellite/nmeasource.py#L106
|
|
||||||
|
|
||||||
2) [nope] do we need modemmanager? might be required if we want lte data,
|
|
||||||
but that's up to the "site admin" - we don't need it for biscuit itself
|
|
||||||
|
|
||||||
3) we should make saturn give visual feedback while it's loading an
|
|
||||||
app. How does it know when the app has finished loading? Maybe it
|
|
||||||
could get told when its window is obscured
|
|
||||||
|
|
||||||
4) rename Maps to soemthing that describes its role better. Cockpit?
|
|
||||||
HUD? (but it's actually H Down D) Head Unit? Navigate? Dashboard? Cluster?
|
|
||||||
Codriver? Satnav? Binnacle? Launch? Ride? Embark?
|
|
||||||
|
|
||||||
5) [all done]
|
|
||||||
Maps also needs to open the nmea port and parse data from it.
|
|
||||||
5a) Maps needs to open a fake nmea source for testing
|
|
||||||
5b) we need a generator of fake nmea data
|
|
||||||
|
|
||||||
6) Cockpit
|
|
||||||
- show [done] speed and [done] direction
|
|
||||||
- show speed limit
|
|
||||||
- [done] scroll and [not done] rotate map
|
|
||||||
- overlay planned route on map
|
|
||||||
- show next turn
|
|
||||||
- voice prompts
|
|
||||||
- when off-course, calculate route to nearest point on course
|
|
||||||
- fetch planned route from nominated url
|
|
||||||
(don't want to type the url in, is there a better way to have it check in
|
|
||||||
with a mothership?)
|
|
||||||
- save trail (maybe this could be a separate task entirely)
|
|
||||||
|
|
||||||
elapsed time: what should it actually show? moving time, I guess
|
|
||||||
- moving time since when?
|
|
||||||
|
|
||||||
should we rename bearing as course in nmea?
|
|
||||||
|
|
||||||
perhaps we need a server-side component for route planning
|
|
||||||
|
|
||||||
|
|
||||||
7) think about how to use nfc tags or something for profiles so that
|
|
||||||
it can recognise when it's attached to bicycle or motorbike
|
|
||||||
|
|
||||||
|
|
||||||
8) use OSM directly?
|
|
||||||
|
|
||||||
we can't rotate the map using OsmGpsMap widget because the labels will
|
|
||||||
be sideways or upside down, so we need something with vectors that we
|
|
||||||
can rotate
|
|
||||||
|
|
||||||
[done] a) we can get data from overpass api as json
|
|
||||||
|
|
||||||
[done badly] b) we would like to cache the results, which means some kind of
|
|
||||||
chunking or tiling so that the json for position a is the same as the
|
|
||||||
json for position b.
|
|
||||||
|
|
||||||
c) at coarser zoom levels, we need to query for fewer objects: either
|
|
||||||
do it by hand -
|
|
||||||
|
|
||||||
- houses
|
|
||||||
- minor roads
|
|
||||||
- major roads
|
|
||||||
|
|
||||||
or do something smart but complicated like "only return ways that
|
|
||||||
cover more than 1/16th the length of the tile"
|
|
||||||
|
|
||||||
d) render ways according to their type (road/cycleway/path/etc)
|
|
||||||
|
|
||||||
e) label the ways
|
|
||||||
|
|
||||||
f) async tile fetching
|
|
||||||
|
|
||||||
we don't want everything to stop when it's time to fetch a new
|
|
||||||
row of tiles, what are our options? lua-http is built on cqueues
|
|
||||||
which is async enough to make my head hurt, but we also need
|
|
||||||
to make it coexist with the gtk event loop
|
|
||||||
|
|
||||||
assumptions:
|
|
||||||
1) gtk stuff has to happen in the main thread (whatever that is...)
|
|
||||||
so we can't control it from cqueues because that has its own
|
|
||||||
threading stuff
|
|
||||||
2) there will be lots of fds from lua-http, do we really want the
|
|
||||||
housekeeping of making GLib.io_add_watch for each of them? it looks
|
|
||||||
like adding a glib source from lgi is not currently practical
|
|
||||||
https://github.com/lgi-devs/lgi/issues/111
|
|
||||||
|
|
||||||
3) if we put http calls inside cq:wrap, that make them background
|
|
||||||
provided that we call (cq:step 0)
|
|
||||||
periodically. we could do that in a glib idle function, perhaps.
|
|
||||||
|
|
||||||
- The tile fetcher would need to know where to write the data when
|
|
||||||
eventually it comes back
|
|
||||||
- need some say to not fetch the same tile 18 times if there's more than
|
|
||||||
one request for it while a previous request is in progress
|
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
https://git.syndicate-lang.org/tonyg/squeak-phone/raw/commit/474960ddc665ed445a1f5afb0164fe39057720f9/devices/pine64-pinephone/modem-docs/80545ST10798A_LM940_QMI_Command_Reference_Guide_r3.pdf
|
https://git.syndicate-lang.org/tonyg/squeak-phone/raw/commit/474960ddc665ed445a1f5afb0164fe39057720f9/devices/pine64-pinephone/modem-docs/80545ST10798A_LM940_QMI_Command_Reference_Guide_r3.pdf
|
||||||
|
@ -65,8 +65,9 @@ label.readout {
|
|||||||
:lat 49
|
:lat 49
|
||||||
:lon 0
|
:lon 0
|
||||||
:zoom 17
|
:zoom 17
|
||||||
:course 0
|
:course 0 ; direction of travel
|
||||||
:smooth-course 0
|
:orientation 0 ; map rotation angle from north
|
||||||
|
:tiles {}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -129,7 +130,11 @@ label.readout {
|
|||||||
(let [(tile-x tile-y) (tiles.latlon->tile app-state.lat app-state.lon app-state.zoom)]
|
(let [(tile-x tile-y) (tiles.latlon->tile app-state.lat app-state.lon app-state.zoom)]
|
||||||
(map-bounds-tile tile-x tile-y)))
|
(map-bounds-tile tile-x tile-y)))
|
||||||
|
|
||||||
|
(fn bounds= [a b]
|
||||||
|
(and (= a.min.x b.min.x)
|
||||||
|
(= a.min.y b.min.y)
|
||||||
|
(= a.max.x b.max.x)
|
||||||
|
(= a.max.y b.max.y)))
|
||||||
|
|
||||||
(local cq (cqueues.new))
|
(local cq (cqueues.new))
|
||||||
|
|
||||||
@ -194,6 +199,13 @@ label.readout {
|
|||||||
|
|
||||||
(var map-surface nil)
|
(var map-surface nil)
|
||||||
|
|
||||||
|
(fn fetch-tiles [bounds tbl zoom]
|
||||||
|
(for [x bounds.min.x bounds.max.x]
|
||||||
|
(for [y bounds.min.y bounds.max.y]
|
||||||
|
(let [k (tiles.name x y zoom)]
|
||||||
|
(when (not (. tbl k))
|
||||||
|
(tiles.fetch cq x y zoom #(tset tbl k $1)))))))
|
||||||
|
|
||||||
(fn draw-onto-map-surface [surface bounds zoom]
|
(fn draw-onto-map-surface [surface bounds zoom]
|
||||||
(let [{ : num-tiles-x : num-tiles-y } bounds
|
(let [{ : num-tiles-x : num-tiles-y } bounds
|
||||||
road-width 14
|
road-width 14
|
||||||
@ -201,9 +213,7 @@ label.readout {
|
|||||||
|
|
||||||
(for [x bounds.min.x bounds.max.x]
|
(for [x bounds.min.x bounds.max.x]
|
||||||
(for [y bounds.min.y bounds.max.y]
|
(for [y bounds.min.y bounds.max.y]
|
||||||
(merge lines (tiles.polylines cq x y zoom
|
(merge lines (or (. app-state.tiles (tiles.name x y zoom)) {}))))
|
||||||
#(set map-surface nil)
|
|
||||||
))))
|
|
||||||
|
|
||||||
(let [seen-road-names {}
|
(let [seen-road-names {}
|
||||||
g (cairo.Context.create surface)]
|
g (cairo.Context.create surface)]
|
||||||
@ -261,7 +271,7 @@ label.readout {
|
|||||||
(draw-onto-map-surface bounds app-state.zoom)))))
|
(draw-onto-map-surface bounds app-state.zoom)))))
|
||||||
|
|
||||||
(g:translate (+ (/ viewport-width 2)) (+ (/ viewport-height 2)))
|
(g:translate (+ (/ viewport-width 2)) (+ (/ viewport-height 2)))
|
||||||
(g:rotate (* (/ (- 360 app-state.smooth-course) 180) math.pi))
|
(g:rotate (* (/ (- 360 app-state.orientation) 180) math.pi))
|
||||||
(g:translate (- (/ viewport-width 2)) (- (/ viewport-height 2)))
|
(g:translate (- (/ viewport-width 2)) (- (/ viewport-height 2)))
|
||||||
|
|
||||||
(g:set_source_surface map-surface (- offset-x) (- offset-y))
|
(g:set_source_surface map-surface (- offset-x) (- offset-y))
|
||||||
@ -309,13 +319,12 @@ label.readout {
|
|||||||
(merge app-state new-vals)
|
(merge app-state new-vals)
|
||||||
(let [bounds
|
(let [bounds
|
||||||
(map-bounds app-state.lat app-state.lon app-state.zoom)]
|
(map-bounds app-state.lat app-state.lon app-state.zoom)]
|
||||||
(when (or
|
(when (not (bounds= old-bounds bounds))
|
||||||
(not (= old-bounds.min.x bounds.min.x))
|
(fetch-tiles bounds app-state.tiles app-state.zoom)
|
||||||
(not (= old-bounds.min.y bounds.min.y)))
|
|
||||||
(set map-surface nil)))
|
(set map-surface nil)))
|
||||||
(set app-state.smooth-course
|
(set app-state.orientation
|
||||||
(+ app-state.smooth-course
|
(+ app-state.orientation
|
||||||
(* 0.05 (- app-state.course app-state.smooth-course))))
|
(* 0.05 (- app-state.course app-state.orientation))))
|
||||||
(each [name widget (pairs state-widgets)]
|
(each [name widget (pairs state-widgets)]
|
||||||
(case name
|
(case name
|
||||||
:speed (widget:set_label
|
:speed (widget:set_label
|
||||||
@ -350,7 +359,7 @@ label.readout {
|
|||||||
(fn [self g]
|
(fn [self g]
|
||||||
(g:set_source_rgb 0.4 0.0 0.1)
|
(g:set_source_rgb 0.4 0.0 0.1)
|
||||||
(g:translate (// height 2) (// height 2))
|
(g:translate (// height 2) (// height 2))
|
||||||
(g:rotate (* (/ (- app-state.course app-state.smooth-course)
|
(g:rotate (* (/ (- app-state.course app-state.orientation)
|
||||||
180) math.pi))
|
180) math.pi))
|
||||||
(g:translate (// height -2) (// height -2))
|
(g:translate (// height -2) (// height -2))
|
||||||
(g:set_line_width 4)
|
(g:set_line_width 4)
|
||||||
|
@ -109,33 +109,29 @@
|
|||||||
;; we'd like to have a way for completed background fetch to signal
|
;; we'd like to have a way for completed background fetch to signal
|
||||||
;; so that the map can be redrawn
|
;; so that the map can be redrawn
|
||||||
|
|
||||||
(fn polylines [cq x y zoom cb]
|
(fn tile-name [x y zoom]
|
||||||
(let [k (.. x "_" y "_" zoom)
|
(.. x "_" y "_" zoom))
|
||||||
|
|
||||||
|
(fn fetch [cq x y zoom cb]
|
||||||
|
(let [k (tile-name x y zoom)
|
||||||
pathname (.. "/tmp/tiles/" k ".json")]
|
pathname (.. "/tmp/tiles/" k ".json")]
|
||||||
(if (file-exists? pathname)
|
(if (file-exists? pathname)
|
||||||
(let [data (with-open [i (io.open pathname :r)] (i:read "*a"))]
|
(let [payload (with-open [i (io.open pathname :r)] (i:read "*a"))]
|
||||||
(if (= data "")
|
(when (not (= payload ""))
|
||||||
[]
|
(cb (canvas (. (json.decode payload) :elements) zoom))))
|
||||||
(canvas (. (json.decode data) :elements) zoom)))
|
|
||||||
(let [out (io.open pathname :w)]
|
(let [out (io.open pathname :w)]
|
||||||
(cq:wrap (fn []
|
(cq:wrap (fn []
|
||||||
(print "getting " k)
|
(print "getting " k)
|
||||||
(var json nil)
|
(var payload nil)
|
||||||
(with-open [f out]
|
(with-open [f out]
|
||||||
(while (not json)
|
(while (not payload)
|
||||||
(set json (unparsed-for-xyz x y zoom))
|
(set payload (unparsed-for-xyz x y zoom))
|
||||||
(when (not json)
|
(when (not payload)
|
||||||
(print "sleeping " k)
|
(print "sleeping " k)
|
||||||
(cqueues.sleep (math.random 2 6))))
|
(cqueues.sleep (math.random 2 6))))
|
||||||
(print "got " k)
|
(print "got " k)
|
||||||
(f:write json)
|
(f:write payload)
|
||||||
(cb)
|
(cb (canvas (. (json.decode payload) :elements) zoom))
|
||||||
true)))
|
true)))))))
|
||||||
[] ; return no lines for now
|
|
||||||
))))
|
|
||||||
|
|
||||||
|
{ : fetch : latlon->tile :name tile-name }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{ : polylines : latlon->tile }
|
|
||||||
|
Loading…
Reference in New Issue
Block a user