mapbox-maps-ios icon indicating copy to clipboard operation
mapbox-maps-ios copied to clipboard

Setting camera bounds with padding fails [v11]

Open naftalibeder opened this issue 11 months ago • 9 comments

Environment

  • Xcode version: 15.2
  • iOS version: 17.0
  • Devices affected: iOS Simulator
  • Maps SDK Version: Reproduced on 11.2.0-rc1 and 11.1.0

Observed behavior and steps to reproduce

When setting the camera to a coordinate bounds with padding, the camera does not zoom out to encompass the provided bounds.

To reproduce, run this example with Mapbox >= 11.0.0 and click the Change button repeatedly:

CameraAnimationExample.swift

import UIKit
import MapboxMaps

final class CameraAnimationExample: UIViewController, ExampleProtocol {
  private var mapView: MapView!
  private var cameraOptions: CameraOptions!
  private var flag = 0
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    mapView = MapView(frame: view.bounds)
    mapView.ornaments.scaleBarView.isHidden = true
    try? mapView.mapboxMap.setProjection(.init(name: .mercator))
    mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    view.addSubview(mapView)
    
    let button = UIButton(type: .roundedRect)
    button.backgroundColor = .white
    button.setTitle("Change", for: .normal)
    button.layer.position = .init(x: 100, y: 100)
    button.frame.size = .init(width: 200, height: 40)
    button.addTarget(self, action: #selector(onClick), for: .touchUpInside)
    view.addSubview(button)
    
    mapView.mapboxMap.onMapLoaded.observeNext { _ in
      self.onClick()
    }
  }
  
  @objc func onClick() {
    switch flag {
    case 0:
      let padding = UIEdgeInsets(
        top: 0,
        left: 0,
        bottom: 500,
        right: 0
      )
      cameraOptions = CameraOptions(
        center: CLLocationCoordinate2D(
          latitude: 41.888579,
          longitude: -87.804039
        ),
        padding: padding,
        zoom: 14,
        bearing: 0,
        pitch: 0
      )
      print("Camera 1 | Padding \(padding.top + padding.bottom), map height \(mapView.bounds.height)")
    case 1:
      let padding = UIEdgeInsets(
        top: 0,
        left: 0,
        bottom: 500,
        right: 0
      )
      cameraOptions = mapView.mapboxMap.camera(
        for: CoordinateBounds(
          southwest: CLLocationCoordinate2D(
            latitude: 41.87726211032818,
            longitude: -87.80420963106079
          ),
          northeast: CLLocationCoordinate2D(
            latitude: 41.880369537640505,
            longitude: -87.80199949078224
          )
        ),
        padding: padding,
        bearing: nil,
        pitch: nil,
        maxZoom: nil,
        offset: nil
      )
      print("Camera 2 | Padding \(padding.top + padding.bottom), map height \(mapView.bounds.height)")
    default:
      break
    }
    
    mapView.camera.ease(to: cameraOptions, duration: 1)
    
    flag += 1
    if flag == 2 {
      flag = 0
    }
  }
}

Expected behavior

On repeat click, the camera should alternatively ease between a center coordinate and a slightly zoomed out bounds, both bottom-padded.

Actual behavior

The camera moves laterally to the approximate bounding box, but the zoom does not change. The following seemingly contradictory data prints to the console:

Camera 1 | Padding 500.0, map height 852.0 Camera 2 | Padding 500.0, map height 852.0 [Warning, maps-core]: {}[General]: Unable to calculate camera for given bounds/geometry, padding is greater than map's width or height.

Notes / preliminary analysis

  • This bug appears to happen on all v11. On v10, it works correctly.
  • Using try camera(for:camera:coordinatesPadding:maxZoom:offset:) has the same issue, but it throws instead of quietly logging to the console.
  • Lowering the padding to total a smaller amount produces a strange set of bounds:
    • >=353: Zoom does not change, as shown in the v11 video.
    • =352: Suddenly zooms way out to bound around a very large area.
    • <=351: As padding gets closer to zero, zoom increases until eventually settles at the correct value when padding is 0.

Additional links and references

The above example behaves correctly on v10:

https://github.com/mapbox/mapbox-maps-ios/assets/2423291/d2e935cd-d6f5-4ee4-952f-b00a0858f08f

but fails on v11:

https://github.com/mapbox/mapbox-maps-ios/assets/2423291/4ca88720-6bae-4ca4-8ad5-7f824ed2fa57

naftalibeder avatar Feb 27 '24 16:02 naftalibeder