Skip to content

Adding linePattern image after render doesn't shows on initial zoom level #1751

@mfazekas

Description

@mfazekas

Environment

  • Xcode version: 14.1
  • iOS version: Simulator iOS 16.1
  • Devices affected: Simulator iOS 16.1/iPhone 14 Pro
  • Maps SDK Version: 10.10.0-rc.1, 10.9.0

Observed behavior and steps to reproduce

Adding image of linePatter after the line already rendered, doesn't apply the pattern on the current zoom level, just on smaller and larger zooms.

layer.linePattern = Value.constant(.name(imageUrl))
map.style.addLayer(layer)
...

URLSession.shared.dataTask(with: URL(string: imageUrl)!) { data,response,error in
   ...
   DispatchQueue.main.async { try! map.style.addImage(image, id: imageUrl) }
}
mapbox-line-pattern.mov
class ViewControllerFillPattern : UIViewController {
  internal var mapView: MapView!
  
  let center = LocationCoordinate2D(latitude: 43.610, longitude: -116.395)
  
  func addLineLayer(_ map: MapboxMap, center: LocationCoordinate2D) {
    var source = GeoJSONSource()
    source.data = .geometry(Geometry.lineString(LineString([center, LocationCoordinate2D(latitude: center.latitude+0.2, longitude: center.longitude+0.2)])))
    
    try! map.style.addSource(source, id: "line-source")
    var layer = LineLayer(id: "line-with-pattern")
    layer.source = "line-source"
    layer.lineColor = .constant(StyleColor(.red))
    layer.lineWidth = .constant(32.0)

    let imageUrl = "https://docs.mapbox.com/mapbox-gl-js/assets/colorado_flag.png?\(Int.random(in: 0..<10000))"
    layer.linePattern = Value.constant(.name(imageUrl))

    
    try! map.style.addLayer(layer)
    URLSession.shared.dataTask(with: URL(string: imageUrl)!) { data,response,error in
      guard let data = data else  {
        print("=> download failed: \(error) \(response)")
        return
      }
      
      DispatchQueue.main.async {
        let image = UIImage(data: data)!
        
        try! map.style.addImage(image, id: imageUrl)
      }
    }.resume()
  }
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    let accessToken = MY_ACCESS_TOKEN;

    let mapUri = StyleURI.streets
    let myResourceOptions = ResourceOptions(accessToken:accessToken)
    let myMapInitOptions = MapInitOptions(resourceOptions: myResourceOptions, styleURI: mapUri)

    mapView = MapView(frame: view.bounds, mapInitOptions: myMapInitOptions)
    mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    self.view.addSubview(mapView)
    
    mapView.mapboxMap.setCamera(to:
      CameraOptions(center: self.center, zoom: 15.0))
    
    mapView.mapboxMap.onNext(event: .styleLoaded) { _ in
      let mapboxMap = self.mapView.mapboxMap!
      self.addLineLayer(mapboxMap, center: self.center)
   }
  }
}

Note that I see the same thing if set linePattern after addImage.

class ViewController : UIViewController {
  internal var mapView: MapView!
  
  let center = LocationCoordinate2D(latitude: 43.610, longitude: -116.395)
  
  func addLineLayer(_ map: MapboxMap, center: LocationCoordinate2D) {
    var source = GeoJSONSource()
    source.data = .geometry(Geometry.lineString(LineString([center, LocationCoordinate2D(latitude: center.latitude+0.2, longitude: center.longitude+0.2)])))
    
    try! map.style.addSource(source, id: "line-source")
    var layer = LineLayer(id: "line-with-pattern")
    layer.source = "line-source"
    layer.lineColor = .constant(StyleColor(.red))
    layer.lineWidth = .constant(32.0)
    try! map.style.addLayer(layer)

    let imageUrl = "https://docs.mapbox.com/mapbox-gl-js/assets/colorado_flag.png"
    URLSession.shared.dataTask(with: URL(string: imageUrl)!) { data,response,error in
      guard let data = data else  {
        print("download failed: \(error) \(response)")
        return
      }
      
      DispatchQueue.main.async {
        let image = UIImage(data: data)!
        
        try! map.style.addImage(image, id: imageUrl)
        try! map.style.updateLayer(withId: "line-with-pattern", type: LineLayer.self) { lineLayer in
          lineLayer.linePattern = Value.constant(.name(imageUrl))
        }
      }
    }.resume()
  }
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    let accessToken = MY_ACCESS_TOKEN;

    let mapUri = StyleURI.streets
    let myResourceOptions = ResourceOptions(accessToken:accessToken)
    let myMapInitOptions = MapInitOptions(resourceOptions: myResourceOptions, styleURI: mapUri)

    mapView = MapView(frame: view.bounds, mapInitOptions: myMapInitOptions)
    mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    self.view.addSubview(mapView)
    
    mapView.mapboxMap.setCamera(to:
      CameraOptions(center: self.center, zoom: 15.0))
    
    mapView.mapboxMap.onNext(event: .styleLoaded) { _ in
      let mapboxMap = self.mapView.mapboxMap!
      self.addLineLayer(mapboxMap, center: self.center)
   }
  }
}

Expected behavior

Update line layer on current zoom to render the linePattern

Notes / preliminary analysis

Additional links and references

rnmapbox/maps#2408

Metadata

Metadata

Assignees

No one assigned

    Labels

    auto-triagedAutomatically triaged by AIbug 🪲Something is broken!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions