Skip to content

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

  1. Layer ID: Ensure the layer IDs used are correct, incorrect IDs will be ignored
  2. Style Timing: Apply styles after map loadComplete
  3. Performance Considerations: Frequent style updates may affect performance, consider batch updates
  4. Style Priority: Later applied styles will override earlier ones
  5. Array Layers: For array-type layers like amm, controlled, etc., array format must be used