All docsMapbox GL JSExamplesChange worldview of administrative boundaries

Change worldview of administrative boundaries

This example uses the worldview value to adjust administrative boundaries based on the map's audience. Read more about worldviews.

<!DOCTYPE html>
<meta charset="utf-8">
<title>Change worldview of administrative boundaries</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link href="" rel="stylesheet">
<script src=""></script>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
#menu {
position: absolute;
background: #fff;
padding: 20px;
margin: 20px;
font-family: 'Open Sans', sans-serif;
max-width: 180px;
#worldview-options {
margin-top: 10px;
<div id="map"></div>
<div id="menu">
Display administrative boundaries consistent with the following
<!-- The worldview options will be built dynamically using JavaScript (below). -->
<div id="worldview-options"></div>
mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN';
const map = new mapboxgl.Map({
container: 'map',
// The worldview data field is only available in styles
// that use the Mapbox Streets v8 tileset
// or Mapbox Boundaries v3 tileset
// Choose from Mapbox's core styles, or make your own style with Mapbox Studio
style: 'mapbox://styles/mapbox/light-v10',
center: [88, 26],
zoom: 4
// List the worldviews options you want users to select from. For
// available worldviews, see
const availableWorldViews = [
code: 'CN',
name: 'China'
code: 'IN',
name: 'India'
code: 'JP',
name: 'Japan'
code: 'US',
name: 'United States'
// Choose a worldview you want to use when the map is first loaded.
// Styles created by Mapbox default to "US" as the initial worldview.
const worldViewOnMapLoad = 'US';
// Build the menu.
// Alternatively, you could hard code the menu in your HTML directly.
const worldViewOptions = document.getElementById('worldview-options');
for (const worldView of availableWorldViews) {
// Create three new elements for each worldview.
const radioItem = document.createElement('div');
const radioInput = document.createElement('input');
const radioLabel = document.createElement('label');
// Assign attributes based on the worldview.
radioInput.type = 'radio'; = 'toggle-worldview'; = worldView.code;
radioInput.value = worldView.code;
radioInput.checked = worldView.code === worldViewOnMapLoad;
radioLabel.htmlFor = worldView.code;
radioLabel.innerText = `${worldView.code} (${})`;
// Append the input and label elements to the radioItem div.
// Append the radioItem div to the worldViewOptions div that
// will contain all the radio buttons.
// Wait for the map to finish loading.
map.on('load', () => {
// Filter the "admin-0-*" layers to display
// administrative boundaries consistent with the
// initial worldview defined above ("CN").
// Get all the worldview option inputs and loop through them.
const inputs = worldViewOptions.getElementsByTagName('input');
for (const input of inputs) {
// Specify that the switchWorldview function
// (defined below) should run every time an input
// is clicked.
input.onclick = (option) => {
// Create a function that will identify which worldview
// is currently selected and run the filterLayers function
// with that worldview as an argument.
// Update the filter for each "admin-0-*" layer, which contain
// administrative boundaries at the country level.
// These are the same filters used in the Mapbox Light
// style except that the worldview is based on user input.
function filterLayers(worldview) {
// The "admin-0-boundary-disputed" layer shows boundaries
// at this level that are known to be disputed.
map.setFilter('admin-0-boundary-disputed', [
['==', ['get', 'disputed'], 'true'],
['==', ['get', 'admin_level'], 0],
['==', ['get', 'maritime'], 'false'],
['match', ['get', 'worldview'], ['all', worldview], true, false]
// The "admin-0-boundary" layer shows all boundaries at
// this level that are not disputed.
map.setFilter('admin-0-boundary', [
['==', ['get', 'admin_level'], 0],
['==', ['get', 'disputed'], 'false'],
['==', ['get', 'maritime'], 'false'],
['match', ['get', 'worldview'], ['all', worldview], true, false]
// The "admin-0-boundary-bg" layer helps features in both
// "admin-0-boundary" and "admin-0-boundary-disputed" stand
// out visually.
map.setFilter('admin-0-boundary-bg', [
['==', ['get', 'admin_level'], 0],
['==', ['get', 'maritime'], 'false'],
['match', ['get', 'worldview'], ['all', worldview], true, false]