Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Features added to a mapView through addAnnotation appear below raster tyle sources #6774

Closed
Jmaguerre opened this issue Oct 20, 2016 · 6 comments
Labels
bug iOS Mapbox Maps SDK for iOS runtime styling

Comments

@Jmaguerre
Copy link

Platform:
iOS
Mapbox SDK version:
https://github.com/mapbox/mapbox-gl-native/releases/tag/ios-v3.4.0-beta.1

Steps to trigger behavior

Using the new styles API adding a raster source to the map style makes any annotation appear below the tiles

  1. Create a new MGLRasterSource with an URL
  2. Create a new MGLRasterStyleLayer with the previously created source
  3. Add annotations to mapView

Expected behavior

Annotations should appear on top of the raster layers

Actual behavior

I have a glimpse of the annotations appearing on the map before the tiles load. After tiles finish loading annotations do not show.

It happens either adding annotations conforming to MGLAnnotation protocol or MGLPointFeatures.

I don't know if there's anything I'm doing wrong or it is a bug. We have an app using the old RMTileSources and RMMapLayer where it works as expected.

Thanks

@cammace cammace added the iOS Mapbox Maps SDK for iOS label Oct 20, 2016
@incanus
Copy link
Contributor

incanus commented Oct 20, 2016

@Jmaguerre To speed this along, could you whip up a quick code demo? Based on the loading behavior, it does sound like a possible bug.

@Jmaguerre
Copy link
Author

@Icanus Okay so while trying to reproduce I think I know what's happening but don't know why.
Basically what I'm doing is the following:
In the viewDidLoad I have a network call and in the callback I add a raster source and layer to the map.
As the mapView initializes before the call finishes it is loaded with the default mapbox streets base layer.
Once the call finishes I add the new source and layer (mapbox streets satellite) and also any annotation and I can see the annotation drawn over the mapbox street default layer and afterwards , when the other source loads the annotation is covered.

  @IBOutlet var mapView: MGLMapView!

  override func viewDidLoad() {

    self.client.doSomeNetworkCall(completion: { () -> Void in 
      let source = MGLRasterSource(identifier: "base", url: URL(string: "mapbox://mapbox.streets-satellite")!, tileSize: 256)
    mapView.style().add(source)

      let layer = MGLRasterStyleLayer(identifier: "base", source: source)
    mapView.style().add(layer)

      mapView.setCenter(CLLocationCoordinate2D(latitude: 40.7326808, longitude: -73.9843407), zoomLevel: 12, animated: false)
    view.addSubview(mapView)

      // Declare the marker `hello` and set its coordinates, title, and subtitle.
      let hello = MGLPointAnnotation()
      hello.coordinate = CLLocationCoordinate2D(latitude: 40.7326808, longitude: -73.9843407)
      hello.title = "Hello world!"
      hello.subtitle = "Welcome to my marker"

      // Add marker `hello` to the map.
      mapView.addAnnotation(hello)
    }
  }

Result:

mapboxsatellitewcall 1

So here comes another posible bug. If I do the same thing without having the network call the source added is never loaded.

  @IBOutlet var mapView: MGLMapView!

  override func viewDidLoad() {
    let source = MGLRasterSource(identifier: "base", url: URL(string: "mapbox://mapbox.streets-satellite")!, tileSize: 256)
    mapView.style().add(source)

    let layer = MGLRasterStyleLayer(identifier: "base", source: source)
    mapView.style().add(layer)

    mapView.setCenter(CLLocationCoordinate2D(latitude: 40.7326808, longitude: -73.9843407), zoomLevel: 12, animated: false)
    view.addSubview(mapView)

    // Declare the marker `hello` and set its coordinates, title, and subtitle.
    let hello = MGLPointAnnotation()
    hello.coordinate = CLLocationCoordinate2D(latitude: 40.7326808, longitude: -73.9843407)
    hello.title = "Hello world!"
    hello.subtitle = "Welcome to my marker"

    // Add marker `hello` to the map.
    mapView.addAnnotation(hello)
  }

Result:

mapboxsatellite 1

@lilykaiser
Copy link

Closing due to ticket age. If this is still a problem, please re-open

@amphib
Copy link

amphib commented Nov 23, 2017

this is still a problem. I am running the IOS SDK version 3.7.0 B1. I have several MGLPointAnnotation added to my MGLMapView. They are visible on top of the default streetmap. I use the following code to add a raster layer to the map and the raster layer appears over top of the MGLPointAnnotations. The MGLPointAnnotations are no longer visible. This is also true of MGLPolyline that I have added to the map. The raster layer also hides them.

MGLRasterSource *source = [[MGLRasterSource alloc] initWithIdentifier:@"onlinemapssource" tileURLTemplates:tileSources options:nil];
MGLRasterStyleLayer *layer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"onlinemapslayer" source:source];
[_map.style addSource:source];
[_map.style addLayer:layer];

@1ec5
Copy link
Contributor

1ec5 commented Nov 29, 2017

An implementation detail worth mentioning is that annotations are backed by a built-in symbol style layer that gets added to the style in after -mapView:didFinishLoadingStyle: gets called but before -mapView:didFinishLoadingMap: gets called.

Until we implement either #6181 or #1734 (comment), the annotation and runtime styling APIs don’t always interact intuitively when used together with the same map view, but MGLMapViewDelegate and MGLStyle do provide hooks for avoiding these conflicts.

Okay so while trying to reproduce I think I know what's happening but don't know why.
Basically what I'm doing is the following:
In the viewDidLoad I have a network call and in the callback I add a raster source and layer to the map.
As the mapView initializes before the call finishes it is loaded with the default mapbox streets base layer.
Once the call finishes I add the new source and layer (mapbox streets satellite) and also any annotation and I can see the annotation drawn over the mapbox street default layer and afterwards , when the other source loads the annotation is covered.

@Jmaguerre, the network request in your code most likely finishes at some point after the annotation layer is added. A little advertised behavior of the SDK is that you can add arbitrary layers to the top of the style in -mapView:didFinishLoadingMap: or at any time thereafter. #7707 (comment) proposes to remove this “feature”.

So here comes another posible bug. If I do the same thing without having the network call the source added is never loaded.

In fact, anything you do to an MGLStyle before -mapView:didFinishLoadingStyle: gets called is ignored. For this reason, we changed MGLMapView.style in #7664 to be optional: this property is now nil up until the call to -mapView:didFinishLoadingStyle:. This change shipped in v3.4.0. Now your code will sometimes fail to display the raster layers, depending on the speed of the network response.

this is still a problem. I am running the IOS SDK version 3.7.0 B1. I have several MGLPointAnnotation added to my MGLMapView. They are visible on top of the default streetmap. I use the following code to add a raster layer to the map and the raster layer appears over top of the MGLPointAnnotations. The MGLPointAnnotations are no longer visible. This is also true of MGLPolyline that I have added to the map. The raster layer also hides them.

@amphib, you can avoid this issue by adding the style layers in -mapView:styleDidFinishLoading:. If that’s too early for your needs, you can get the style’s ordered list of layers in MGLStyle.layers, then insert your layers below any layers used for point or shape annotations. (They all have identifiers beginning with com.mapbox..) I think this would be a solution for @Jmaguerre as well.

@Jmaguerre
Copy link
Author

Perfectly understood, thanks for the details of the explanation.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug iOS Mapbox Maps SDK for iOS runtime styling
Projects
None yet
Development

No branches or pull requests

6 participants