mapbox / mapbox/mapbox-maps-ios

iOS: camera.zoom calculates smaller zoom for camera(for:) initially

Open
#2,170 9 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

auto-triaged bug :beetle:
Dominant language
Swift
Stars
601
Forks
196
PR merge metrics
No merged PRs in 30d

Description

## 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)`](https://docs.mapbox.com/ios/maps/api/11.2.0/documentation/mapboxmaps/mapboxmap/camera(for:camera:coordinatespadding:maxzoom:offset:)/) 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 (:
image

When calculated from `onStyleDataLoaded` the zoom is correct:
image

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.

```log
=> zoom: Optional(3.535590091035326)
=> zoom(styleDataLoaded): Optional(3.9738550186157227)
```

## Expected behaviour

Either [`camera(for:)`](https://docs.mapbox.com/ios/maps/api/11.2.0/documentation/mapboxmaps/mapboxmap/camera(for:camera:coordinatespadding:maxzoom:offset:)/) 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

```swift
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

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

Reproduce the issue by replacing BasicMapExample in Apps/Examples and compare camera(for:) immediately after adding the map with the value from onStyleDataLoaded. Trace the camera calculation entry point and lifecycle state, then verify that the initial result is either correctly calculated or reports an error when it cannot be calculated reliably.

Written by the indexing model from the issue text.

Assessment

Tech stack
ios, swift
Domain
mobile-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.