maplibre-rs
maplibre-rs copied to clipboard
Restrict navigation to map bounds
Difficulty: Hard
Currently, there are no bounds when navigating (pan, zoom) the map. The goal of this task is to restrict the navigation such that users can not escape and see empty space.
🤔 Expected Behavior
In Y direction the navigation should be restricted such that one can not pan out from the map.
In X direction it should be possible to infinitely pan. When panning beyond the bounds then the world should should be wrapped. This is done in #74.
😯 Current Behavior
There are no bounds.
💁 Possible Solution
??
I'd love to take a stab at this and contribute, but I'm not really confident in my ability. Would it be possible to get a little mentorship if needed?
Sure thats my job :) feel free to join the matrix
As this seems a good and simple start, I had a look into it. In coords.rs for Zoom I added
pub fn limit(&mut self, min: f64, max: f64) {
if self.0 < min { self.0 = min }
else { if self.0 > max { self.0 = max } }
}
and in zoom_handler.rs in UpdateState for ZoomHandler I added
next_zoom.limit(0.0, 20.0);
The test runs well. Next I will look for panning / wrapping the world
What formal steps are needed, If I am done?
Hey @DerKarlos I think this is a good first task! Thanks for taking a look at it!
and in zoom_handler.rs in UpdateState for ZoomHandler I added
next_zoom.limit(0.0, 20.0);
That would temporarily allow to let the Zoom go above 20 or below 0. This might cause unexpected problems in the future. An implementation which does not use an additional &mut self
function would be preferable I think.
Implementing this in the ZoomHandler
is probably not what we want. The bounds will be a property of the style or map configuration in the maplibre
crate. ZoomHandler
is implemented in maplibre-winit
. So the bounds/min/max values should be enforced in the maplibre
core crate. Maybe a good place to implement this is the ViewState
which holds the current zoom value.
I need time and help to get used to such complex projects like maplibre-rs.
My 2nd atempt: I added min/maxzoom:f64 in Style&Default 0/20 (Mapstyle-Error if min>zoom or max<zoom) and addet both into InteractiveMapSchedule/ViewState. I impemented Zoom.clamp (no mod) and called it in ViewState::update_zoom. If clamped, oddly the map up-right corner shifts to the cursor or jumps to other coordinates! How to avoid or fix this? (No shift happens, if I clamp in zoom_handler) Without clamping, shifting the old position to the mouse works fine.
I need time and help to get used to such complex projects like maplibre-rs.
My 2nd atempt: I added min/maxzoom:f64 in Style&Default 0/20 (Mapstyle-Error if min>zoom or max<zoom) and addet both into InteractiveMapSchedule/ViewState. I impemented Zoom.clamp (no mod) and called it in ViewState::update_zoom. If clamped, oddly the map up-right corner shifts to the cursor or jumps to other coordinates! How to avoid or fix this? (No shift happens, if I clamp in zoom_handler) Without clamping, shifting the old position to the mouse works fine.
Can you open a PR with your changes? Then I can check them out :) Feel free to put it into "draft" mode
While my comments above should have been in #161, lets start with: Restrict navigation to map bounds - Nord/South Should thee map always fill the window or half of it or would 10 % do it? We could have an u8 as % parameter in the map style. I prefer 100% as default; but let's test it to feel it. The West/East would be the same, until #74 is done/used. What if the window is extrem small or flat? Take the longest side as relevant?
The map should probably fill the screen. It should never be possible to see the world "outside" of the map.