iOS: camera.zoom calculates smaller zoom for camera(for:) initially
Environment
- Xcode version: 15.3
- iOS version: iOS 17.4 Simulator
- Devices affected: iPhone 15 Pro - iOS 17.4 Simulator
- Maps SDK Version: v11.4.0, #32bb4e4766b7434dcf0f50fd6728aa5765faa5b9
Observed behavior and steps to reproduce
CameraOptions calculated for camera(for: coordinates) just after map is added to a view is smaller than when calculated from onStyleDataLoaded
When calculated just after map added to a view the zoom is less than the ideal (:
When calculated from onStyleDataLoaded the zoom is correct:
To reproduce use the code snippet at the end of the report to replace BasicMapExample in the Apps/Examples Xcode project.
Observe the zoom values printed and uncomment the setCamera in onStyleDataLoaded handler to verify that that the zoom value is correct there.
=> zoom: Optional(3.535590091035326)
=> zoom(styleDataLoaded): Optional(3.9738550186157227)
Expected behaviour
Either camera(for:) should return an error, so signal that it's not in the state to calculate CameraOption correctly or return the correct camera settings (zoom!) for the actual bounds. I don't think any map loading is needed for that calculation.
Notes / preliminary analysis
Additional links and references
import UIKit
import MapboxMaps
final class BasicMapExample: UIViewController, ExampleProtocol {
private var mapView: MapView!
var handlers: [AnyCancelable] = [];
override func viewDidLoad() {
super.viewDidLoad()
mapView = MapView(frame: view.bounds)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.ornaments.options.scaleBar.visibility = .visible
let coordinates = [
CLLocationCoordinate2D(latitude: -74.41429582091831, longitude: -105.02738295071447),
CLLocationCoordinate2D(latitude: -82.41571395310365, longitude: -108.67784207799926),
CLLocationCoordinate2D(latitude: -71.45151781686236, longitude: -117.5641615804278),
CLLocationCoordinate2D(latitude: -74.41429582091831, longitude: -105.02738295071447)
]
view.addSubview(mapView)
let camera = try! mapView.mapboxMap.camera(for: coordinates, camera:
CameraOptions(), coordinatesPadding: nil,
maxZoom: nil,
offset: nil
)
print("=> zoom: \(String(describing: camera.zoom))")
mapView.mapboxMap.setCamera(to: camera)
handlers.append(mapView.mapboxMap.onStyleDataLoaded.observe {
event in
let camera1 = try! self.mapView.mapboxMap.camera(for: coordinates, camera:
CameraOptions(), coordinatesPadding: nil,
maxZoom: nil,
offset: nil
)
print("=> zoom(styleDataLoaded): \(String(describing: camera1.zoom))")
// uncomment this next line to see the correct zoom
// self.mapView.mapboxMap.setCamera(to: camera1)
})
handlers.append(mapView.mapboxMap.onMapLoaded.observe {
event in
let sourceData = GeoJSONSourceData.geometry(.lineString(LineString(coordinates)))
var source = GeoJSONSource(id: "poly")
source.data = sourceData
try! self.mapView.mapboxMap.addSource(source)
var layer = LineLayer(id: "poly-l", source: "poly")
layer.lineWidth = .constant(2.0)
layer.lineColor = .constant(StyleColor(UIColor.red))
try! self.mapView.mapboxMap.addLayer(layer)
})
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// The below line is used for internal testing purposes only.
finish()
}
}
https://github.com/rnmapbox/sponsors/issues/3
Hey, @mfazekas I'm currently working on the issues with camera(for:) and will take a look at this too. Thank you, for the reproduction steps!
Hi @aleksproger - any updates on findings for this issue?
@mfazekas hey! do you observe similar problem in Android in v11.4.0-rc.1 when using async overload of cameraForCoordinates which makes sure that viewport is set properly.
@kiryldz sorry, I cannot comment on that, this was reported as an iOS only issue, so this might not have surfaced on android beacuse timing or other
+1 on this
camera(for coordinates:camera:coordinatesPadding:maxZoom:offset:) behaves inconsistently in my app.
The zoom is smaller than expected in some scenarios.
SDK Version (iOS): v11.5.1
I have to stay on v10.x until it's fixed :( Hope a fix can be found soon.
v11.6.0, ios Same problem
Hello @aleksproger any update on this? thx
@aleksproger any updates? it is really unpleasant bug
I found solution:
func updateCameraBounds(coordinates: [CLLocationCoordinate2D], padding: UIEdgeInsets, animated: Bool = true) {
do {
let referenceCamera = CameraOptions(padding: padding, bearing: 0, pitch: 0)
let camera = try mapboxMap.camera(for: coordinates, camera: referenceCamera, coordinatesPadding: nil, maxZoom: nil, offset: nil)
setCameraOptions(cameraOptions: camera, animated: animated)
} catch {
debug("\(error)")
}
}