* Adapt `retrieve_image` to also return a timestamp based on the
CDN's last modified time; adapt other methods accordingly
* For the maps module, use `chrono::Utc` instead of
`tokio::time::Instant` and use `chrono::Duration` instead of
`tokio::time::Duration`
* Pass the maps timestamp to the `sample` function so it can use
that timestamp as base
This calculates which offset to use in the maps series with respect to
the instant of caching. It assumes the first map is current for the
instant it was retrieved.
* Rename `*_first` to `*_at` methods
* For convenience, change the types of `*_MAP_COUNT` to `u32`
* Introduce `*_MAP_INTERVAL` constants to indicate the number of
seconds each map in the series applies to
* Return `None` if the provided instant is too far in the future
* Use `Position` everywhere instead of latitude/longitude float values
* Implement `Partial`, `Eq` and `Hash` for `Position` so it can
part of a cache key
* Drop the `cache_key` helper function
* Rename the `address_position` function to `resolve_address`
* Add methods on `Position` for formatting latitude/longitude with
a given precision (used for URL parameters in providers)
* Also cache address geocoding requests to OSM Nomatim!
* Use the `cached` crate for an easy implementation
* Add the `cache_key` helper function to deal with floats being annoying
* Cache Buienradar get request for 5 minutes (per position/metric)
* Cache Luchtmeetnet get request for 5 minutes (per position/metric)
* Note the `Item` structs need to implement `Clone` now because
the cache will own them and Rocket will want a copy too
This makes the response time way more snappy when the maps thread
is updating its cache.
* Move the `MapsHandle` type to the `maps` module
* SWitch to using the standard library mutex
* Split refresh methods into retrieval methods that don't need the lock
and check timestamp & update methods that only need it shortly
* Introduce the `MapsRefresh` trait and implement it for `MapsHandle`
* Reorder some methods for clarity
* Small documentation fixes
* Replace the lazy `once_cell` by a maps handle type
* Use Rocket's managed state to manage a handle
* Ensure that the handlers have access to it
* Pass another handle to the maps updater loop
* Try to keep the lock as short as possible
Still, long downloads block the lock. Add a FIXME to refactor this
so the lock is only taken when updating the maps fields.