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

Complicated layerID level hierarchy/overlapping management #970

Closed
EricPKerr opened this issue Jan 19, 2018 · 6 comments
Closed

Complicated layerID level hierarchy/overlapping management #970

EricPKerr opened this issue Jan 19, 2018 · 6 comments

Comments

@EricPKerr
Copy link
Contributor

EricPKerr commented Jan 19, 2018

I'm having trouble understanding how to correctly order the hierarchy of layers and getting things to correctly be on the right "level" and overlap correctly - especially when things are dynamically added and removed from the hierarchy. Is there a zIndex-like system for this or do you have to maintain everything with aboveLayerID and belowLayerID?

The app has many dynamic MyComponent -> ShapeSource -> LineLayer, and OtherComponent-> ShapeSource -> (CircleLayer & SymbolLayer) type combinations. What is the recommended way of doing this?

We have separate wrapper components for these common elements that get added as children to the main MapboxGL.MapView map, but I keep running into layer cannot be placed above (null) in the style. Make sure sibling was obtained using... type errors.

Thanks in advance!

@EricPKerr EricPKerr changed the title Complicated layer/level management Complicated layerID level hierarchy/overlapping management Jan 19, 2018
@nitaliano
Copy link
Owner

nitaliano commented Jan 19, 2018

Z-index in the application is ordered similar to how html elements get there z indexes, so without providing any ids, the bottom most layers in your render methods will always have a higher z index

<MapboxGL.ShapeSource ...>
  <MapboxGL.LineLayer id='polyline' />
</MapboxGL.ShapeSource>

<MapboxGL.ShapeSource ...>
   <MapboxGL.CircleLayer id='vertices' />
</MapboxGL.ShapeSource>

in the example above since vertices is rendered last it will be given the higher z index over polyline.

One thing you can do also do is keep also the layers rendered in the view tree but have them visisble or invisible

I'm going to close this out but we can continue the conversation in here, if you also wanted to make an example repo I can help you out there as well

@karlguillotte
Copy link

karlguillotte commented Jan 20, 2018

Thanks @nitaliano for your answer here!

I use this setup to order my layers (physical order with source and layer compoenents, see below). However, the order is not kept whenever I change my layer visibility (using the visibility style property). Any ideas how I can keep my layers order?

<Mapview>
  <Source id='S1'>
    <Layer id='L1' style={dynamic} />
    <Layer id='L2' style={dynamic} />
    <Layer id='L3' style={dynamic} />
    <Layer id='L4' style={dynamic} />
  </Source>
  <Source id='S2'>
    <Layer id='L5' style={dynamic} />
    <Layer id='L6' style={dynamic} />
    <Layer id='L7' style={dynamic} />
    <Layer id='L8' style={dynamic} />
  </Source>
</Mapview>

Thanks!

@ClayChristmas
Copy link

@nitaliano - My team seems to be running into this in our deployed app. We have not seen it locally, but Crashlytics is reporting it for some of our users. We are trying to run it down but haven't had much luck yet. We are using aboveLayerID plus the z-index ordering. Is it possible that there is some race condition with rendering layers that causes this to happen? Here is the code example and some crash data:

<Mapbox.RasterSource key='d' id='mySource' url={url} tileSize={512}>
  <Mapbox.RasterLayer id='myLayer' sourceID='mySource' style={{rasterOpacity:0.7}} />
</Mapbox.RasterSource>
<Mapbox.ShapeSource id='currentLocationMarkerSource' shape={this.state.featureCollection}>
  <Mapbox.SymbolLayer id='currentLocationMarkerSymbols'
    style={[mapStyles.icon, {textField:this.state.markerText, iconSize: this.state.iconSize ? 0.5 : 1 }]}
    aboveLayerID='myLayer' />
</Mapbox.ShapeSource>

Fatal Exception: NSInvalidArgumentException
A style layer cannot be placed above (null) in the style. Make sure sibling was obtained using -[MGLStyle layerWithIdentifier:].

I have stack traces and other Crashlytics data if that helps in resolving this.

@nitaliano
Copy link
Owner

nitaliano commented Apr 3, 2018

yes it's totally possible, could you post more of the stack traces and devices here or send me a message on Gitter with them.

I think this is more so likely with the RasterSource then other sources since it's going out and fetching tile data

@cglacet
Copy link

cglacet commented Apr 10, 2018

Z-index in the application is ordered similar to how html elements get there z indexes, so without providing any ids, the bottom most layers in your render methods will always have a higher z index

Is that the only rule? It seems like there is something else because I have this:

<Mapbox.MapView>
    { (this.state.trip.geojsonRoutes.features.length > 1) &&
        <Mapbox.ShapeSource id="route" shape={this.state.trip.geojsonRoutes}>
            <Mapbox.LineLayer id="route" style={mapStyle.route} />
        </Mapbox.ShapeSource>
    }
    <Mapbox.ShapeSource id="test" shape={this.state.coordinates}>
        <Mapbox.SymbolLayer ... />
              
     </Mapbox.ShapeSource>
</Mapbox.MapView>

And the route still shows under the test layer (maybe its due to the fact that the condition is false the first time I load the map, then the state change and the condition becomes true, thus rendering new Shape/Layer for the route?).

Anyway, to make it work (the route is under the test layer) I had to do that:

<Mapbox.MapView>
    <Mapbox.ShapeSource id="test" shape={this.state.coordinates}>
        <Mapbox.SymbolLayer ... />
              
     </Mapbox.ShapeSource>

    { (this.state.trip.geojsonRoutes.features.length > 1) &&
        <Mapbox.ShapeSource id="route" shape={this.state.trip.geojsonRoutes}>
            <Mapbox.LineLayer belowLayerID="test" id="route"  style={mapStyle.route} />
        </Mapbox.ShapeSource>
    }
</Mapbox.MapView>

@ClayChristmas
Copy link

I experienced something similar. I was waiting on an API call to give me data for one layer and had a shape source that was rendering underneath it even though it came as a later z-index.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants