javascriptmapboxmapbox-gl-jsmapbox-gl

mapbox expressions combining of 'match' and 'interpolate'


I need help with mapbox expressions in react js.

I need to customize the line-width of line on layer depending on a 'type' parameter, And i need a special 'line-width' behavior for each of four road types. When I try to use "interpolate" with "match":

<Layer
    id='roads'
    type='line'
    source='roads'
    source-layer={SOURCE_LAYER}
    layout={{
        'line-join': 'round',
        'line-cap': 'round'
    }}
    paint={{
        'line-color': '#444444',
        'line-width': ["match", ["get", "type"],
            "primary", ["interpolate", ["exponential", 1.5], ["zoom"], 6, 0.3, 18, 32],
            "secondary", ["interpolate", ["exponential", 1.5], ["zoom"], 5, 0.1, 18, 26],
            "street", ["interpolate", ["exponential", 1.5], ["zoom"], 13, 1, 18, 19],
            "minor", ["interpolate", ["exponential", 1.5], ["zoom"], 14, 0.5, 19, 12],
            1]
    }}/>

I got an error: Error: layers.roads.paint.line-width: Only one zoom-based "step" or "interpolate" subexpression may be used in an expression.

When i revert interpolate and match,

<Layer
    id='roads'
    type='line'
    source='roads'
    source-layer={SOURCE_LAYER}
    layout={{
        'line-join': 'round',
        'line-cap': 'round'
    }}
    paint={{
        'line-color': '#43815b',
        'line-width': [
            "interpolate", ["exponential", 1.5], ["zoom"],
            [
                "match", ["get", "type"],
                "primary", [5, 0.75, 18, 32],
                "secondary", [5, 0.1, 18, 26],
                "street", [14, 2, 18, 18],
                "minor", [14, 0.5, 18, 12],
                1
            ], 2 // for 4 args
        ]
    }}/>

the error is: Input/output pairs for "interpolate" expressions must be defined using literal numeric values (not computed expressions) for the input values.

also I can't understand how to add stop_input and stop_output properly.

Can you please explain how to set stops depending on a road type and zoom?


Solution

  • I think you need to have one overriding zoom expression, with different data-driven expressions at each zoom level:

    'line-width': [
        "interpolate", ["exponential", 1.5], ["zoom"],
        5, 
            ["match", ["get", "type"],
                "primary", 0.75,
                "secondary", 0.1
                "street", 2, // note this meaning has changed
                "minor", 0.5
            ],
        18,
            ["match", ["get", "type"],
                "primary", 0.32,
                "secondary", 26
                "street", 18,
                "minor", 12
            ],
        ]
    ]