Reputation: 3488
I have a MapBox map and I'm drawing some lines on top.
First I create a geojson object. All my features are LineStrings. Some of my lines can have a left/right property, but it is not a mandatory parameter. So a feature looks like this:
const feature = {
'type': 'Feature',
'properties': {
'id': LINE_ID,
'color': LINE_COLOR,
'left_right': "LEFT", // can be "LEFT", "RIGHT", or ""
},
"geometry": {
'type': 'LineString',
"coordinates": [
[LINE_POINTS[0].lng, LINE_POINTS[0].lat],
[LINE_POINTS[1].lng, LINE_POINTS[1].lat],
]
}
}
After my geojson is ready, I add it as a source to the map:
map.addSource('geojson_lines', {type: 'geojson', data: LINE_FEATURES});
Now a need to add a layer to the map, from this source. No problem.
But I need my layer to meet these requirements:
I could make the color and line width work, but can't figure out the offset:
map.addLayer({
id: 'lines_layer', type: 'line', source: 'geojson_lines',
layout: {},
paint: {
'line-color': ['get', 'color'],
'line-width': {
stops: [[8, 4], [18, 10]]
},
'line-offset': [] // need help with this
}
});
The goal is to have an positive offset value for the "RIGHT" lines in the range for example from 2 to 6 for zoom levels 8 to 18 and a negative offset value for the "LEFT" lines.
Is it possible to achieve this with some kind of expression and the stops or interpolate array?
Upvotes: 1
Views: 1378
Reputation: 3488
After reading the documentation and trying out some tips found on stackoverflow I was able to solve this on my own
The key here is to first interpolate the values and then determine the direction using a case expression.
map.addLayer({
id: 'lines_layer', type: 'line', source: 'geojson_lines',
layout: {},
paint: {
'line-color': ['get', 'color'],
'line-width': {
stops: [[8, 4], [18, 10]]
},
'line-offset': ['interpolate', ['linear'], ['zoom'],
8
['case',
["==", ["get", "left_right"], "LEFT"],
-2,
["==", ["get", "left_right"], "RIGHT"],
2,
0
],
18,
['case',
["==", ["get", "left_right"], "LEFT"],
-6,
["==", ["get", "left_right"], "RIGHT"],
6,
0
],
],
}
});
Upvotes: 2