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.