'Variable line offset in MapBox
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:
- all the lines can have a different color, set by the color property
- the width of the line changes according to zoom level
- if there's is a left_right value, the line should be offset to the direction set by this value and the amount of the offset should change according to zoom level
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?
Solution 1:[1]
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
],
],
}
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Dusan |
