Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
mfazekas opened this issue Apr 25, 2024 · 4 comments
Open

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

mfazekas opened this issue Apr 25, 2024 · 4 comments
Labels
bug 🪲 Something is broken!

Comments

@mfazekas
Copy link
Contributor

mfazekas commented Apr 25, 2024

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 (:
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.

=> 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

@mfazekas mfazekas added the bug 🪲 Something is broken! label Apr 25, 2024
@aleksproger
Copy link
Contributor

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!

@benjamin-sweney
Copy link

Hi @aleksproger - any updates on findings for this issue?

@kiryldz
Copy link
Contributor

kiryldz commented May 13, 2024

@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.

@mfazekas
Copy link
Contributor Author

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🪲 Something is broken!
Projects
None yet
Development

No branches or pull requests

4 participants