nitaliano / react-native-mapbox-gl

A Mapbox GL react native module for creating custom maps
Other
2.16k stars 697 forks source link

dynamic color of symbol layer #1516

Closed KasparasGud closed 5 years ago

KasparasGud commented 5 years ago

I am trying to implement a SymbolLayer where the icons have some data driven colour. The docs state that one can achieve this using sdf icons, however I can't quite seem to find any resources on how this should be done in practice.

The only examples I could find online are for the Mapbox gl js web library. If anyone could share some knowledge, that would be greatly appreciated.

onitzschke commented 5 years ago

You can't tint SymbolLayer png icons. It's not supported but you add your icons in different color into your assets.

Here is an example how i've done this.

      <MapboxGL.ShapeSource
        id={'poiShapeSource'}
        aboveLayerID={'locomotionRouteLineShapeSource'}
        shape={{
          type: 'FeatureCollection',
          features: this.state.poiShapeSource
        }}
        onPress={(event: MapboxGL.RCTMGLShapeSource) => {
          const id = event.nativeEvent.payload.properties.id;
          onPress(id);
        }}>
        <MapboxGL.SymbolLayer
          id={'poi'}
          filter={['all', ['==', 'isFav', false], ['==', 'isSelected', false]]}
          style={layerStyles.poi}
        />

        <MapboxGL.SymbolLayer
          id={'fav'}
          aboveLayerID={'poi'}
          filter={['all', ['==', 'isFav', true], ['==', 'isSelected', false]]}
          style={layerStyles.favoritePoi}
        />

        <MapboxGL.SymbolLayer
          id={'selected'}
          aboveLayerID={'fav'}
          filter={['all', ['==', 'isFav', false], ['==', 'isSelected', true]]}
          style={layerStyles.selectedPoi}
        />

        <MapboxGL.SymbolLayer
          id={'selectedAndFav'}
          aboveLayerID={'selected'}
          filter={['all', ['==', 'isFav', true], ['==', 'isSelected', true]]}
          style={layerStyles.selectedAndFavPoi}
        />
      </MapboxGL.ShapeSource>

and here the objects

    return data.map(poi => {
      return {
        type: 'Feature',
        properties: { id: poi.id, isSelected: poi.id === selectedId, isFav: poi.isFav },
        geometry: { type: 'Point', coordinates: [poi.longitude, poi.latitude] }
      };
    });
kristfal commented 5 years ago

If you need fine grained control of colors, I’d recommend building your own font stack and render your icons as text.