Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Moving the map does not allow to override newCamera #14686

Open
natalia-osa opened this issue May 16, 2019 · 4 comments · May be fixed by mapbox/mapbox-gl-native-ios#284
Open

Moving the map does not allow to override newCamera #14686

natalia-osa opened this issue May 16, 2019 · 4 comments · May be fixed by mapbox/mapbox-gl-native-ios#284
Assignees
Labels
archived Archived because of inactivity feature iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS

Comments

@natalia-osa
Copy link

I would like to highlight a point, which could be improved in the current MapBox implementation. As the user of MapBox library, I am not able to edit the position to which the camera is going to.

Probably the best place to edit it would be method shouldChangeFromCamera:toCamera:reason:.
You could be passing newCamera as a reference - so it'd be editable for those who want it, or not, for those who don't want it. Or make another delegate method to eventually edit it - if you want to keep in sync with the old version.

2 examples why it's so useful to edit newCamera:

Scenario 1:
When someone wants to handle restricting map panning to an area in a better way, than just prohibiting any movement when you're close to the map border. In reality, when bounds are eg set to US, one would rather prefer not to stop the movement from New York to Pekin, but allow to move it behind California, to the border of US. Returning NO in this method, as you do in the sample (https://docs.mapbox.com/ios/maps/examples/constraining-gestures/), works far from perfect. There's a possibility to do the whole movement or no movement at all. It's impossible to swipe in such way, that you set the camera exactly next to the bounds. In reality, you'd rather prefer to be able to move to the point behind which you can't move. I'm attaching 2 drawings to demonstrate this scenario.

Scenario 2:
If you open Google Maps at zoom 6, centre to UK and scroll right/left you will see the map gets rotated as well. In this scenario, they're doing the rotation to mimic north pole. A simple change of heading in newCamera would be sufficient to do it.

Steps to reproduce

Repro steps for scenario 1:

  1. Implement the example from https://docs.mapbox.com/ios/maps/examples/constraining-gestures/
  2. Set the bounds to eg USA
  3. Launch the app, set camera position to New York and make a very quick gesture right. The camera shouldn't move at all. You'd expect it to swipe a bit, to let you see area next to the bounds.
    Another scenario is to set your centre position in New York. Then try to zoom out to see the whole USA. Impossible without changing the centre point. I don't think any user will think it's so complicated and he needs to change the centre point.

Expected behaviour

The camera should allow you to pan to be exactly next to the border without constraining touches previously.

Actual behaviour

The camera with a quick swipe will not move at all.

Configuration

Mapbox SDK versions: 4.10.0 (previous as well)
iOS/macOS versions: all
Device/simulator models: all
Xcode version: 10.1

Bounding box
Pan movement

@julianrex julianrex added feature iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS labels May 16, 2019
@julianrex
Copy link
Contributor

@natalia-osa Thanks for the detailed issue - the team will discuss.

Please note that the "reason" APIs e.g. shouldChangeFromCamera:toCamera:reason: are currently undocumented and signifies that they are likely to change in the future.

/cc @chloekraw

See also @natalia-osa's comment: #14680 (comment)

@stale stale bot added the archived Archived because of inactivity label Feb 19, 2020
@stale
Copy link

stale bot commented Feb 19, 2020

This issue has been automatically detected as stale because it has not had recent activity and will be archived. Thank you for your contributions.

@stale stale bot closed this as completed Feb 19, 2020
@chloekraw chloekraw reopened this Feb 29, 2020
@stale stale bot removed the archived Archived because of inactivity label Feb 29, 2020
@knov knov added this to the release-water milestone Apr 27, 2020
@1ec5
Copy link
Contributor

1ec5 commented Apr 30, 2020

There’s no way to allow movement to the border, so to expected camera position.

If I understand correctly, the request is ultimately that returning NO from -shouldChangeFromCamera:toCamera: or -shouldChangeFromCamera:toCamera:reason: should still result in an animated camera change for a drifting effect, but that the drifting animation should stop at the boundary of the viewable area. We already stop the gesture at the boundary when the user pans slowly, but not when they flick the map and trigger that drifting animation.

Unfortunately, there’s no way for the application to specify the boundary of the viewable area. The only data points we get from the application are the before and after coordinates in increments as the gesture takes place, and the before and after coordinates of a drifting animation. If the boundary happens to lie between the before and after coordinates of a drifting animation, we have no way to know what it would be.

from ------||------> to
        boundary
        (target)

There are two ways to address this gap:

  • An option to declare the viewable bounds upfront, before any gesture takes place
  • A way to truncate a camera change in response to a particular gesture

What’s been proposed in mapbox/mapbox-gl-native-ios#284 is a way to redirect a camera change, or possibly do other things instead of changing the camera, which could in theory be a way to truncate the default camera change. The problem is that it’s pretty difficult for the application to calculate that boundary’s location. It requires Turf’s Turf.intersection(_:_:) method, but that can be inconvenient for Objective-C applications. It doesn’t matter if we animate to a delegate-specified coordinate or let the delegate perform the animation itself; it’s still unfairly difficult for the delegate to calculate that coordinate.

Since #2457, I’ve warmed to the idea of a declarative viewable area option, as long as it can be nonrectangular (since there are no rectangular countries) and we have a way to keep a tilted map from peering beyond that viewable area – that’s the hard part, something that probably deserves a cross-platform implementation.

In the meantime, assuming the developer has figured out how to calculate the boundary camera for a given gesture, mapbox/mapbox-gl-native-ios#284 would require them to implement an -[MGLMapViewDelegate mapView:didCancelGestureForCamera:] that sets the camera using -[MGLMapView setCamera:animated:], whereas the suggestion in mapbox/mapbox-gl-native-ios#284 (comment) would be for MGLMapView to set the camera automatically using a similar but differently named method.

Why -[MGLMapView setCamera:animated:] and not -[MGLMapView flyToCamera:completionHandler:]? Because the use case above requires keeping the camera in motion along the same course, never reversing course to some distant coordinate.

Reversing course would be part of a “rubber band” effect, but flight animation would be overkill whereas the point of a rubber band animation is to be subtle. A rubber band animation would entail buffering the viewable area before calculating the target camera, but it would still be jarring to do anything to the map other than an ease transition at that point.

Still, if some developer wanted a jarring effect, mapbox/mapbox-gl-native-ios#284 (comment) would still allow them to fly in either -shouldChangeFromCamera:toCamera: (to replace an incremental camera change) or -mapViewWillEndPanning:targetCamera: (to replace the drifting animation).

@1ec5
Copy link
Contributor

1ec5 commented Apr 30, 2020

If you open Google Maps at zoom 6, centre to UK and scroll right/left you will see the map gets rotated as well. In this scenario, they're doing the rotation to mimic north pole. A simple change of heading in newCamera would be sufficient to do it.

These days you have to enable “globe view” in Google Maps to see it, but it’s a real globe view, not merely mimicking a globe by rotating the map. Rotating the map about a pole results in distortions because you can only rotate the map in one direction at a time. In our implementation, it’d also be easy to wind up with blank tiles on the screen because the tile system only extends to a certain latitude, not quite to the poles. mapbox/mapbox-gl-js#3184 tracks projecting the map according to a projection other than Web Mercator.

@nishant-karajgikar nishant-karajgikar removed this from the release-water milestone May 6, 2020
@stale stale bot added the archived Archived because of inactivity label Nov 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
archived Archived because of inactivity feature iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants