rnmapbox / rnmapbox/maps

Zoom level not applied correctly when switching from setting camera with `centerCoordinate` to `bounds`

Open
#3,488 8 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug 🪲
Dominant language
Kotlin
Stars
2.9k
Forks
947
Avg merge
6d 37m
Merged PRs (30d)
1

Description

Mapbox Implementation

Mapbox

Mapbox Version

11.3.0

React Native Version

0.72.4

Platform

iOS, Android

@rnmapbox/maps version

10.1.19

Standalone component to reproduce
import React, { useRef } from "react";
import { Button, StyleSheet, TouchableOpacity, View, Text } from "react-native";
import Mapbox from "@rnmapbox/maps";
import { ShapeSource, CircleLayer, Camera } from "@rnmapbox/maps";


const App = () => {
const realMapRef = useRef<Mapbox.MapView>(null);
const realCameraRef = useRef<Mapbox.Camera>(null);

const currentZoom = 16;
const sheetHeight = 374;

const padding = {
      paddingTop: 60,
      paddingLeft: 24,
      paddingRight: 24,
      paddingBottom: sheetHeight ? sheetHeight - 30 : 30,
    };

// this function is called in the parent component. Left for the reference
const zoomToBounds = (bounds) => {
        realCameraRef.current.camera?.setCamera({
          bounds: {
            ne: [ 10.6701055, 59.9111846 ],
            sw:  [ 10.6270699, 59.9008117 ],
          },
          padding: padding,
          heading: 0.0, // reset to north
          animationMode: 'easeTo',
        });
      };
// this function is called in the parent component. Left for the reference
      const zoomToPosition = (pos) => {
        realCameraRef.current.setCamera({
          centerCoordinate: [ 10.6701055, 59.9008117 ],
          padding: padding,
          zoomLevel: currentZoom < 17 ? 17 : undefined,
          heading: 0.0,
          animationMode: 'easeTo',
        });
      };

  return (
  <Mapbox.MapView
  ref={realMapRef}
          styleURL="mapbox://styles/123"
          projection="globe"
          rotateEnabled={true}
          scaleBarEnabled={false}
          logoEnabled={false}
        >
           <Camera ref={realCameraRef} animationDuration={0} />
       {/*Rest of the code*/}
        </Mapbox.MapView>
  );
}

export default App;
Observed behavior and steps to reproduce

I see warning in Xcode when the bug happens: [Warning, maps-core]: {}[General]: Unable to calculate camera for given bounds/geometry, padding is greater than map's width or height.

We set the camera position and zoom level by using two methods, depends on what the user click.
If user click a marker in the map, we call zoomToPosition function where we set centerCoordinate with the marker position and the padding.

If user click on the fence we call zoomToBounds function where we use bounds param to set the camera in the center with the correct zoom.

The problem is that when we call zoomToPosition and the camera zoom in to the marker and later we call zoomToBounds the camera centers correctly but the zoom level is not applied to show all the markers within the bounds.

https://github.com/rnmapbox/maps/assets/13038459/ebb1df5a-201a-4501-b248-9e596c6d1563


const padding = {
  paddingTop: topSafeArea + 10,
  paddingLeft: 24,
  paddingRight: 24,
  paddingBottom: sheetHeight ? sheetHeight - 30 : 30,
};
      
 const zoomToPosition = (pos) => {
        realCameraRef.current.setCamera({
          centerCoordinate: [ 10.6701055, 59.9008117 ],
          padding: padding,
          zoomLevel: currentZoom < 17 ? 17 : undefined,
          heading: 0.0,
          animationMode: 'easeTo',
        });
      };
      
const zoomToBounds = (bounds) => {
        realCameraRef.current.camera?.setCamera({
          bounds: {
            ne: [ 10.6701055, 59.9111846 ],
            sw:  [ 10.6270699, 59.9008117 ],
          },
          padding: padding,
          heading: 0.0, // reset to north
          animationMode: 'easeTo',
        });
      };

Screen recording. Here we can see that clicking on the marker zoom in the camera, when we navigate back the zoomToBounds is called and it should zoom out the camera to show all the markers, but instead the zoom level don't change.
https://github.com/rnmapbox/maps/assets/13038459/bc2d5116-047d-49f7-b33b-d01ca54c2ae0

Expected behavior

Zoom level should be applied correctly to show all the markers within the bounds when calling first

  camera?.setCamera({
    centerCoordinate: pos,
    padding: padding,
    zoomLevel: currentZoom < 17 ? 17 : undefined,
    heading: 0.0,
    animationMode: 'easeTo',
  });

and calling after that setCamera with bounds

realCameraRef.current.camera?.setCamera({
          bounds: {
            ne: [ 10.6701055, 59.9111846 ],
            sw:  [ 10.6270699, 59.9008117 ],
          },
          padding: padding,
          heading: 0.0, // reset to north
          animationMode: 'easeTo',
        });
      };

Zoom level is not applied correctly when we use

Notes / preliminary analysis

We render the bottom sheet on the map. We use the bottom sheet height to calculate bottom padding, to make sure we center the camera in the visible part of the map.

It appears that this zoom issue is gone when we set the padding to the static value example: 30, but this will not center the camera in the visible part of the map.

Additional links and references

No response

Related issue #3354

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Camera.setCamera calls in the reproduction and compare bounds handling with the dynamically calculated bottom-sheet padding; review related issue #3354. Done means switching from centerCoordinate to bounds applies a zoom that displays all markers while preserving visible-map centering on both iOS and Android.

Written by the indexing model from the issue text.

Assessment

Tech stack
react-native, typescript
Domain
mobile-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.