Custom Styles
The SDK supports flexible map style customization, allowing you to modify map appearance through various methods, including layer style overrides, theme switching, etc.
Style Override
Using setStyle Method
The setStyle method allows you to override styles for specific layers:
javascript
sdk.setStyle({
// Single layer style
"airport-label": {
paint: {
"text-color": "#ff0000",
"text-size": 14,
},
},
// Multiple layer styles
"airline": {
paint: {
"line-color": "#00ff00",
"line-width": 2,
},
},
});Array Type Layer Styles
For array-type layers (such as amm, controlled, restricted, airspace, airline), you need to use array format:
javascript
sdk.setStyle({
amm: [
{
"amm-layer-1": {
paint: {
"fill-color": "#ff0000",
},
},
},
{
"amm-layer-2": {
paint: {
"fill-color": "#00ff00",
},
},
},
],
controlled: [
{
"controlled-layer-1": {
paint: {
"fill-color": "#0000ff",
},
},
},
],
});Using Theme Class
The SDK internally uses the Theme class to manage styles, which you can also use directly:
javascript
// Theme class automatically handles style application
const theme = sdk.theme;
// Apply styles
theme.setStyle({
"airport-label": {
paint: {
"text-color": "#ff0000",
},
},
});Layer Style Updates
Update Single Layer Style
javascript
sdk.updateLayerStyle("airport-label", {
paint: {
"text-color": "#ff0000",
"text-size": 16,
},
layout: {
"text-field": ["get", "name"],
"text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
},
});Batch Update Layer Styles
javascript
// Update multiple layers
const styles = {
"airport-label": {
paint: { "text-color": "#ff0000" },
},
"airline": {
paint: { "line-color": "#00ff00" },
},
};
Object.entries(styles).forEach(([layerId, style]) => {
sdk.updateLayerStyle(layerId, style);
});Dynamic Style Switching
Switch Styles Based on Zoom Level
javascript
sdk.on("zoom", () => {
const zoom = sdk.getZoom();
if (zoom < 10) {
// Low zoom level: simplified style
sdk.setStyle({
"airport-label": {
layout: {
visibility: "none",
},
},
});
} else {
// High zoom level: detailed style
sdk.setStyle({
"airport-label": {
layout: {
visibility: "visible",
},
paint: {
"text-size": 14,
},
},
});
}
});Switch Styles Based on Time (Night Mode)
javascript
function toggleNightMode(isNight) {
if (isNight) {
sdk.setStyle({
"airport-label": {
paint: {
"text-color": "#ffffff",
},
},
"airline": {
paint: {
"line-color": "#ffff00",
},
},
});
} else {
sdk.setStyle({
"airport-label": {
paint: {
"text-color": "#000000",
},
},
"airline": {
paint: {
"line-color": "#0000ff",
},
},
});
}
}
// Auto-switch based on time
const hour = new Date().getHours();
toggleNightMode(hour >= 18 || hour < 6);Theme Configuration
Using Predefined Themes
The SDK provides predefined theme style files:
javascript
// Load dark theme
const darkTheme = await fetch("/styles/dark.json").then(r => r.json());
sdk.setMapStyle(darkTheme);
// Load light theme
const lightTheme = await fetch("/styles/light.json").then(r => r.json());
sdk.setMapStyle(lightTheme);Custom Theme Configuration
Create a custom theme configuration file:
json
{
"airport-label": {
"paint": {
"text-color": "#ff0000",
"text-size": 14
}
},
"airline": {
"paint": {
"line-color": "#00ff00",
"line-width": 2
}
},
"amm": [
{
"amm-layer-1": {
"paint": {
"fill-color": "#0000ff"
}
}
}
]
}Load custom theme:
javascript
async function loadCustomTheme(themePath) {
const theme = await fetch(themePath).then(r => r.json());
sdk.setStyle(theme);
}
loadCustomTheme("/styles/custom-theme.json");Style Properties
Paint Properties
paint properties control the visual appearance of layers:
javascript
sdk.setStyle({
"airport-label": {
paint: {
// Text color
"text-color": "#ff0000",
// Text size
"text-size": 14,
// Text stroke color
"text-halo-color": "#ffffff",
// Text stroke width
"text-halo-width": 2,
},
},
"airline": {
paint: {
// Line color
"line-color": "#00ff00",
// Line width
"line-width": 2,
// Line opacity
"line-opacity": 0.8,
// Dash pattern
"line-dasharray": [2, 2],
},
},
});Layout Properties
layout properties control layer layout and visibility:
javascript
sdk.setStyle({
"airport-label": {
layout: {
// Visibility
visibility: "visible", // "visible" | "none"
// Text field
"text-field": ["get", "name"],
// Text font
"text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
// Text anchor
"text-anchor": "center",
// Text offset
"text-offset": [0, 1],
},
},
});Style Expressions
The SDK supports MapBox style expressions for dynamic styles:
javascript
sdk.setStyle({
"airport-label": {
paint: {
// Set color based on property value
"text-color": [
"case",
["==", ["get", "type"], "civil"],
"#0000ff", // Civil airport: blue
"#ff0000", // Military airport: red
],
// Set size based on zoom level
"text-size": [
"interpolate",
["linear"],
["zoom"],
10, 12, // Size 12 at zoom level 10
15, 16, // Size 16 at zoom level 15
],
},
},
});Complete Example
javascript
let sdk;
async function initMap() {
sdk = new navMap.MapSDK({
container: "map",
center: [116.39, 39.9],
zoom: 10,
});
sdk.on("loadComplete", () => {
setupCustomStyles();
});
}
function setupCustomStyles() {
// 1. Basic style override
sdk.setStyle({
"airport-label": {
paint: {
"text-color": "#ff0000",
"text-size": 14,
},
},
});
// 2. Dynamic style switching
sdk.on("zoom", () => {
const zoom = sdk.getZoom();
sdk.setStyle({
"airport-label": {
paint: {
"text-size": zoom < 12 ? 12 : 16,
},
},
});
});
// 3. Theme switch buttons
document.getElementById("dark-theme-btn").addEventListener("click", () => {
loadTheme("/styles/dark.json");
});
document.getElementById("light-theme-btn").addEventListener("click", () => {
loadTheme("/styles/light.json");
});
}
async function loadTheme(themePath) {
const theme = await fetch(themePath).then(r => r.json());
sdk.setStyle(theme);
}
initMap();Notes
- Layer ID: Ensure the layer IDs used are correct, incorrect IDs will be ignored
- Style Timing: Apply styles after map
loadComplete - Performance Considerations: Frequent style updates may affect performance, consider batch updates
- Style Priority: Later applied styles will override earlier ones
- Array Layers: For array-type layers like
amm,controlled, etc., array format must be used
