strokeDashArray
does not support data driven styling. There is a feedback item being tracked here.
If you need to have different styles of dash arrays, one way around this limitation is to use multiple layers with filters. For example, using your code as a starting point, if we limit the dash arrays to a specific set of allowed values, we can do something like the following:
//A list of all allowed/supported dash arrays.
private supportedDashArray: number[][] = [
[4,4],
[2,4],
[4, 4, 2, 4]
];
private createLineLayers(source: atlas.surce.DataSource, lineStyle: ILineStyle){
const layers = [];
//Loop through the list of supported dash arrays and create a layer for each.
supportedDashArray.forEach(dashArray => {
layers.push(new atlas.layer.LineLayer(source, null, createLineLayerOptions(lineStyle, dashArray)));
});
//Add a default layer to handle undefined or unsupported dash arrays.
layers.push(new atlas.layer.LineLayer(source, null, createLineLayerOptions(lineStyle)));
return layers;
}
private createLineLayerOptions(lineStyle: ILineStyle, dashArray: number[] | undefined): atlas.LineLayerOptions {
return {
strokeColor: [
'case',
['has', 'lineStyle'],
['get', 'color', ['get', 'lineStyle']],
lineStyle.color
],
// This works for the entire layer:
//strokeDashArray: lineStyle.dashArray.length ? lineStyle.dashArray : undefined
strokeDashArray: dashArray,
strokeOpacity: [
'case',
['has', 'lineStyle'],
['get', 'opacity', ['get', 'lineStyle']],
lineStyle.opacity
],
strokeWidth: [
'case',
['has', 'lineStyle'],
['get', 'width', ['get', 'lineStyle']],
lineStyle.width
],
filter: createDashArrayFilter(dashArray)
}
}
private createDashArrayFilter(dashArray: number[] | undefined) {
if(dashArray) {
//Note that a match/comparison can't be done on an array directly in a style expression since an array is seen as an expression.
//Converting the array to a string makes for easier comparison.
const dashArrayString = `[${dashArray.toString()}]`; //Will create a string like '[1,2,3]'
return [
//AND comparison of conditions.
'all',
//Ensure the shape has a lineStyle.dashArray property.
['has', 'linestyle'],
['has', 'dashArray', ['get', 'lineStyle']],
//Compare the string versions of the dashArray values.
[
'==',
//Convert the shapes dashArray porperty to string.
['to-string', ['get', 'dashArray', ['get', 'lineStyle']]], //Will create a string like '[1,2,3]'
dashArrayString
]
];
} else {
//Convert the list of supported dash arrays to a list of strings we can compare against.
const stringDashArrays = [];
//Loop through the list of supported dash arrays and create a layer for each.
supportedDashArray.forEach(dash => {
stringDashArrays.push(`[${dash.toString()}]`);
});
//Check that it doesn't have a dash array property.
return [
//Do the opposite of the following check.
'!',
//Check to see if the shape has a valid dash array property and allowed value.
[
//AND comparison of conditions.
'all',
//Ensure the shape has a lineStyle.dashArray property.
['has', 'linestyle'],
['has', 'dashArray', ['get', 'lineStyle']],
//Optionally, also handle any dash arrays that aren't supported.
//Check to see if the dash array pattern is an allowed/supported one.
['in', ['to-string', ['get', 'dashArray', ['get', 'lineStyle']]], ['literal', stringDashArrays]]
]
];
}
}
Note that Azure Maps wraps MapLibre (fork of Mapbox) and adds a layer to the API that makes it easier to develop applications, and create /maintain common scenarios. However, when it comes to style expression support, Azure Maps will only support as much as MapLibre does. Also note that the Azure Maps team is involved in the MapLibre developer community and does help add improvements at that level.