nitaliano / react-native-mapbox-gl

A Mapbox GL react native module for creating custom maps
Other
2.16k stars 697 forks source link

Intermittent setCamera zoom issues on iOS #1466

Closed adamtootle closed 5 years ago

adamtootle commented 5 years ago

I'm going to try to offer as many details around what we're seeing.

We're using setCamera with these options:

this._map.setCamera({
    centerCoordinate: <coordinate>,
    zoom: 11,
    duration: 1400,
    mode: MapboxGL.CameraModes.Flight,
});

When this works as expected it actually zooms to 13.244271527738213. When it does not work it zooms to 22. I haven't been able to nail down what determines if it works or not after trying to comb through the native side of things, but it does seems to either work 100% of the time (one exception below) or break 100% of the time on a per-session/launch basis. I can navigate to a map, trigger the zoom, then back out and do it over again with repeatable results (either working or not working) consistently in a given app session. If I force quit the app and re-launch then I get consistent results again, either working or not working. I'm not really sure of a rate of when it works or doesn't. It seems to be a coin flip in my testing. I assume there's some setup stuff happening somewhere that impacts how this zoom works.

Working exception - On occasion, the "working" zoom will zoom to 10, but it's pretty rare. It's happened more than once so I don't think it was a random fluke. It may happen once per session, but then zoom to 13.244271527738213 every other time in that session. It's not easily repeatable.

Using MapboxGL.CameraModes.None or MapboxGL.CameraModes.Ease appears to always zoom to 11, which is what we actually pass to setCamera.

kristfal commented 5 years ago

Do you set this before the map has fully loaded or after? On Mon, 7 Jan 2019 at 19:39, Adam Tootle notifications@github.com wrote:

I'm going to try to offer as many details around what we're seeing.

We're using setCamera with these options:

this._map.setCamera({ centerCoordinate: , zoom: 11, duration: 1400, mode: MapboxGL.CameraModes.Flight, });

When this works as expected it actually zooms to 13.244271527738213. When it does not work it zooms to 22. I haven't been able to nail down what determines if it works or not after trying to comb through the native side of things, but it does seems to either work 100% of the time (one exception below) or break 100% of the time on a per-session/launch basis. I can navigate to a map, trigger the zoom, then back out and do it over again with repeatable results (either working or not working) consistently in a given app session. If I force quit the app and re-launch then I get consistent results again, either working or not working. I'm not really sure of a rate of when it works or doesn't. It seems to be a coin flip in my testing. I assume there's some setup stuff happening somewhere that impacts how this zoom works.

Working exception - On occasion, the "working" zoom will zoom to 10, but it's pretty rare. It's happened more than once so I don't think it was a random fluke. It may happen once per session, but then zoom to 13.244271527738213 every other time in that session. It's not easily repeatable.

Using MapboxGL.CameraModes.None or MapboxGL.CameraModes.Ease appears to always zoom to 11, which is what we actually pass to setCamera.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/mapbox/react-native-mapbox-gl/issues/1466, or mute the thread https://github.com/notifications/unsubscribe-auth/AFYH2xnIG3s_vjCul1prxa828ya5Jtskks5vA5RQgaJpZM4Z0BOj .

aprilzero commented 5 years ago

Do you set this before the map has fully loaded or after?

yep, whole thing is running after didFinishRenderingMapFully

some more details: this seems to happen when building with xcode 10 now, but works OK if built with xcode 9 (which won't be possible soon), everything else being the same. so we've just been building with an old machine for the last few months to work around the mapbox issue

atomheartother commented 5 years ago

We're also encountering odd behavior with the Flight mode on iOS. It never really zooms enough, if we ask it to zoom to 15 it zooms to what looks like 12, which is far from sufficient with the flight effect

This is our setCamera call:

      this._map.setCamera({
        centerCoordinate: [(site.zone.so.lon + site.zone.ne.lon) / 2, (site.zone.ne.lat + site.zone.so.lat) / 2],
        zoom: await this.getZoomFromBounds(site.zone.ne.lon - site.zone.so.lon, site.zone.ne.lat - site.zone.so.lat),
        duration: 5000,
        mode: Mapbox.CameraModes.Flight
     });

this.getZoomFromBounds simply returns the zoom level necessary to fit the given bounds. It is feeding the right value to zoom, that's been checked and re-checked, and confirmed by the fact that the Android version works perfectly.

Even worse, if we use:

      this._map.setCamera({
        bounds: {
          ne: [site.zone.ne.lon, site.zone.ne.lat],
          sw: [site.zone.so.lon, site.zone.so.lat],
        },
        mode: Mapbox.CameraModes.Flight,
      });

Then it still works on Android but the camera is totally wrong for iOS, it zooms in all the way first then translates to the correct bounds, it looks nothing like a flight.

aprilzero commented 5 years ago

Yes, this issue also happens for us in simulator always.

image

                        this._map.setCamera({
                            centerCoordinate: centerOn,
                            zoom: 11,
                            duration: 1400,
                            mode: MapboxGL.CameraModes.Flight,
                        });

(incorrectly zooms all the way in onload instead of the specified amount)

YousefED commented 5 years ago

Same issue here when trying to zoom in flight mode to specific bounds. @atomheartother, would you mind sharing your getZoomFromBounds code so I can use a similar workaround in the meantime?

olivierstern commented 5 years ago

It look like two issues in This file is causing the problem. If someone has a clue :

olivierstern commented 5 years ago

@YousefED Best is to use https://www.npmjs.com/package/@mapbox/geo-viewport and to use it like this :

      const viewport = geoViewport.viewport(
        [
          zone.so.lon,
          zone.so.lat,
          zone.ne.lon,
          zone.ne.lat,
        ],
        [viewportWidth, viewportHeight],
        minZoom,
        maxZoom,
        512,
        true
      );
      this.map.setCamera({
        centerCoordinate: viewport.center,
        zoom: viewport.zoom,
        duration: 5000,
        mode: Mapbox.CameraModes.Flight,
      });
kristfal commented 5 years ago

Fixed in master thanks to @mattijsf's PR.