IdefixRC
IdefixRC

Reputation: 91

Mapbox gl js - Custom icons based on multiple criteria

I'm currently trying to build a customer web map with mapbox gl js and struggle how to best structure the code to display the geojson data on the map layer based on multiple properties.

Properties are as follows:

Type and name will define the icon type, nation the icon color (icons are in sdf format)

I have the following code now which works but without taking the name subclass for static objects into account. Any suggestion on how this subclass match can be included so I can show different icons for static+airport, static+building, static+bridge but not care about the name for the airplane and ship types?

map.addLayer({
        'id': 'marker',
        'type': 'symbol',
        'source': 'db-json',
        'layout': {
            'icon-image': [
                    'match', // Use the 'match' expression: https://docs.mapbox.com/mapbox-gl-js/style-spec/#expressions-match
                    ['get', 'type'], // Use the result 'coalition' property
                    'airplane', 'plane-icon',
                    'static', 'circle-stroked-15',
                    'ship', 'harbor-15',
                    'airfield-15' // any other type
                    ]
            },
            'paint': {
                'icon-color': [
                    'match', // Use the 'match' expression: https://docs.mapbox.com/mapbox-gl-js/style-spec/#expressions-match
                    ['get', 'nation'], // Use the result 'nation' property
                    0, '#808080',
                    1, '#FF0000',
                    2, '#0000FF',
                    '#00FF00' // any other nation
                    ]
                }
        });

Thanks a million !!

Upvotes: 4

Views: 2302

Answers (1)

IdefixRC
IdefixRC

Reputation: 91

To answer my own question. Multiple levels can be stacked of course. Might not be the most optimal solution (vs a query that checks and compares 2 variables at the same time) but it works.

Example:

map.addLayer({
        'id': 'marker',
        'type': 'symbol',
        'source': 'db-json',
        'layout': {
            'icon-image': [
                    'match', 
                    ['get', 'type'], // Use the result 'type' property
                    'airplane', 'plane-icon',
                    'static', [
                       'match', 
                        ['get', 'name'], // Use the result 'name' property
                        'airport', 'airport-icon',
                        'building', 'building-icon',
                        'bridge', 'bridge-icon',
                        '' // none for any other type
                         ],
                    'ship', 'harbor-15',
                    'airfield-15' // any other type
                    ]
            },
            'paint': {
                'icon-color': [
                    'match', 
                    ['get', 'nation'], // Use the result 'nation' property
                    0, '#808080',
                    1, '#FF0000',
                    2, '#0000FF',
                    '#00FF00' // any other nation
                    ]
                }
        });

Upvotes: 4

Related Questions