Custom styling of base layers is not currently supported, however it is possible to achieve using undocumented methods. Note that using these methods could break in the future (this recently happened with the major map style change that occurred these past few months). It's also worth noting that with the recent style changes, certain regions (China, Japan, and South Korea) are loaded as a raster tile layer due to legal reasons around map data for those countries, and can not be styled. This is also done for smaller roads when zoomed out for performance reasons.
That said, if you want to do this, here is how it can be done:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Custom map styles</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<!-- Add references to the Azure Maps Map control JavaScript and CSS files. -->
<link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css" rel="stylesheet" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js"></script>
<script>
var map, currentMapStyle;
//An object with the changes you want to make for each layer.
//This is a custom object I created for this example.
//The paint/layout properties are from MapLibre style specification as that is the underlying rendering framework: https://maplibre.org/maplibre-style-spec/layers/
var myCustomStyle = {
//Set the color of the background of the map area to green. (if you pitch the map, this is normally the white area above or below the map.
//Azure Maps makes the map canvas transparent so that the background can be set using regular old CSS.
backgroundColor: '#00ff00',
//Create custom styles for specific layer IDs.
layerStyles: {
//Make national parks purple. (Polygon/Fill area example)
"microsoft.bing.maps.baseFeature.park_national_fill": {
paint: {
"fill-color": "purple"
}
},
//Make lakes orange.
"microsoft.bing.maps.baseFeature.lake_fill-merged2": {
paint: {
"fill-color": "orange"
}
},
//Modify the style of ocean labels.
"microsoft.bing.maps.labels.ocean_fill_label-merged5": {
paint: {
"text-color": "black",
"text-halo-color": "white",
"text-halo-width": 1
},
layout: {
"text-size": 16,
"text-letter-spacing": 1.5
}
}
},
//Apply these to all layers that have a specific source layer in the vector tiles.
sourceLayerStyles: {
//Make all roads red. Note that some smaller roads are rendered as a tile layer when zoomed out and can't be styled.
//So they will stay their normal color until you zoom in.
//(LineString/Polyline/line example)
road: {
paint: {
"line-color": 'red'
}
},
//Hide all state/province data (borders and names).
admin_division1: {
layout: {
visibility: "none"
}
}
}
};
function GetMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
view: 'Auto',
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});
//Wait until the map resources are ready.
map.events.add('ready', function () {
//When the map style changes, the layers rendered will update, so you would likely need to reapply your changes.
//Monitor for when the map style changes.
map.events.add('styledata', styleChanged);
//Set the initial custom styles.
styleChanged();
//Add a style control to the map so we can test that the custom styles persist when the map style changes.
map.controls.add(new atlas.control.StyleControl(), {
position: 'top-right'
});
});
}
function styleChanged() {
//Get the basemap style.
var mapStyle = map.getStyle().style;
//Make sure the basemap style has changed.
//We need to do this as the style data event will fire every time any change is made to any layer style.
if(currentMapStyle !== mapStyle){
currentMapStyle = mapStyle;
applyCustomStyle(myCustomStyle);
//Optionally, you could look at what the new map style is and apply a different set of custom styles.
/*
switch (style) {
case 'road':
applyCustomStyle(myCustomStyle2);
break;
default:
applyCustomStyle(myCustomStyle);
break;
} */
}
}
function applyCustomStyle(style) {
//Access internal map object. Warning: undocumented/unsupported.
var innerMap = map.map;
//Check to see if the background color should be changed.
if(style.backgroundColor) {
//Set the background color of the map div.
map.getMapContainer().style.backgroundColor = style.backgroundColor;
}
//Loop through all layers in the inner map and apply the custom styles.
var layers = innerMap.getStyle().layers;
for (var i = 0; i < layers.length; i++) {
const l = layers[i];
//Check to see if there is a style for this specific layer ID.
const layerStyle = style.layerStyles[l.id];
if(layerStyle) {
applyStyle(innerMap, l.id, layerStyle);
}
//Check to see if the layer has a source layer in the vector tiles. Background doesn't.
const sourceLayer = l['source-layer'];
if(sourceLayer){
//Check to see if there is any source layer level custom styles.
const sourceLayerStyle = style.sourceLayerStyles[sourceLayer];
if(sourceLayerStyle) {
applyStyle(innerMap, l.id, sourceLayerStyle);
}
}
}
}
function applyStyle(innerMap, layerId, style) {
//Apply paint styles.
if(style.paint) {
Object.keys(style.paint).forEach(prop => {
try{
innerMap.setPaintProperty(layerId, prop, style.paint[prop]);
} catch{}
});
}
//Apply layout styles (these have more performance impact, thus why these are seperated in the inner maps styles).
if(style.layout) {
Object.keys(style.layout).forEach(prop => {
try{
innerMap.setLayoutProperty(layerId, prop, style.layout[prop]);
} catch{}
});
}
//Apply zoom range style. This can minimize the zoom range. Increasing the zoom range will only work if the data exists at those zoom levels in the data source.
if(style.zoomRange) {
try{
innerMap.setLayerZoomRange(layerId, style.zoomRange.minzoom, style.zoomRange.maxzoom);
} catch{}
}
}
</script>
<style>
html, body {
margin:0;
padding: 0;
width: 100%;
height: 100%;
}
#myMap {
position:relative;
width: 100%;
height: 100%;
}
</style>
</head>
<body onload="GetMap()">
<div id="myMap"></div>
</body>
</html>
This is also a good resource for inspecting the data/layers in the map: https://samples.azuremaps.com/?search=inspect&sample=inspect-features-under-the-mouse
And yes I know the custom styles in my example are ugly, lol :)