Tutorial: Change the static basemap tiles style

Learn how to change a basemap style in a scene using the static basemap tiles service (beta).

You can display a scene with raster basemap tiles using the static basemap tiles service (beta). The service supports a number of ArcGIS styles such as navigation, streets, outdoor, and light-gray. The tiles are returned as PNG files.

In this tutorial, you customize the BaseLayerPicker widget to display the different basemap layer styles and display them as raster tiles on your scene.

Prerequisites

This tutorial requires an ArcGIS Location Platform account.

Steps

Create a new pen

  1. To get started, you can complete the Display a scene tutorial or use the .

Get a Cesium ion access token

All Cesium applications must use an access token provided through Cesium ion. This token allows you to access assets such as Cesium World Terrain in your application.

  1. Go to your Cesium ion dashboard to generate an access token. Copy the key and store it somewhere safe.

Get an access token

You need an access token with the correct privileges to access the resources used in this tutorial.

  1. Go to the Create an API key tutorial and create an API key with the following privilege(s):
    • Privileges
      • Location services > Basemaps
  2. Copy the API key access token as it will be used in the next step.

To learn about other ways to get an access token, go to Types of authentication.

Set the access tokens

  1. In CodePen, update the accessToken and cesiumAccessToken variables to use the access tokens you have obtained.

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
        const accessToken = "YOUR_ACCESS_TOKEN"
    
        const cesiumAccessToken = "YOUR_CESIUM_ACCESS_TOKEN";
    
        Cesium.Ion.defaultAccessToken = cesiumAccessToken;
    

Update the camera's viewpoint

  1. Change the camera's destination to -91.2996, 37.1174, 4622324.434309. This will focus the camera on the United States of America.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
        viewer.camera.setView({
    
          destination: Cesium.Cartesian3.fromDegrees(-91.2996, 37.1174, 4622324.434309),
    
          orientation: {
            heading: Cesium.Math.toRadians(0.0),
            pitch: Cesium.Math.toRadians(-90.0),
          }
        });
    
    Expand

Remove base layer references

  1. Remove arcGisImagery, terrain, and the baseLayer properties from the viewer. ss
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
          const arcGisImagery = Cesium.ArcGisMapServerImageryProvider.fromBasemapType(Cesium.ArcGisBaseMapType.SATELLITE);
    
          const viewer = new Cesium.Viewer("cesiumContainer", {
    
            baseLayer: Cesium.ImageryLayer.fromProviderAsync(arcGisImagery),
    
            terrain: Cesium.Terrain.fromWorldTerrain(),
    
            timeline: false,
            animation: false,
            geocoder:false
    
          });
    

Load the basemaps

  1. Create a variable called viewModel to obtain the BaseLayerPicker widget. You will be able to customize the widget through this variable.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
        const accessToken = "YOUR_ACCESS_TOKEN"
    
        const cesiumAccessToken = "YOUR_CESIUM_ACCESS_TOKEN";
    
        Cesium.Ion.defaultAccessToken = cesiumAccessToken;
    
        const viewer = new Cesium.Viewer("cesiumContainer", {
          timeline: false,
          animation: false,
          geocoder: false,
        });
    
        const viewModel = viewer.baseLayerPicker.viewModel;
    
        viewer.camera.setView({
    
          destination: Cesium.Cartesian3.fromDegrees(-91.2996, 37.1174, 4622324.434309),
    
          orientation: {
            heading: Cesium.Math.toRadians(0.0),
            pitch: Cesium.Math.toRadians(-90.0),
          }
        });
    
    Expand
  2. Create an async function called loadBasemaps.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
        const accessToken = "YOUR_ACCESS_TOKEN"
    
        const cesiumAccessToken = "YOUR_CESIUM_ACCESS_TOKEN";
    
        Cesium.Ion.defaultAccessToken = cesiumAccessToken;
    
        const viewer = new Cesium.Viewer("cesiumContainer", {
          timeline: false,
          animation: false,
          geocoder: false,
        });
    
        const viewModel = viewer.baseLayerPicker.viewModel;
    
        async function loadBasemaps() {
    
        }
    
        viewer.camera.setView({
    
          destination: Cesium.Cartesian3.fromDegrees(-91.2996, 37.1174, 4622324.434309),
    
          orientation: {
            heading: Cesium.Math.toRadians(0.0),
            pitch: Cesium.Math.toRadians(-90.0),
          }
        });
    
    Expand
  3. Inside the function, use the fetch method to call the service URL and pass in the accessToken. Store the JSON-formatted response in a variable called data.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
        async function loadBasemaps() {
    
          const response = await fetch(`https://static-map-tiles-api.arcgis.com/arcgis/rest/services/static-basemap-tiles-service/beta/self?token=${accessToken}`);
          const data = await response.json();
    
        }
    
    Expand
  4. Create an empty list of imageryProviders. We will use this list to store the basemap styles that will be displayed in the base layer picker.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
        async function loadBasemaps() {
    
          const response = await fetch(`https://static-map-tiles-api.arcgis.com/arcgis/rest/services/static-basemap-tiles-service/beta/self?token=${accessToken}`);
          const data = await response.json();
    
          const imageryProviders = []
    
        }
    
    Expand
  5. For each basemap style returned by the service, create a new Cesium.ProviderViewModel and push it into our imageryProviders list.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
        async function loadBasemaps() {
    
          const response = await fetch(`https://static-map-tiles-api.arcgis.com/arcgis/rest/services/static-basemap-tiles-service/beta/self?token=${accessToken}`);
          const data = await response.json();
    
          const imageryProviders = []
    
          for (const style of data.styles) {
    
            imageryProviders.push(new Cesium.ProviderViewModel({
              name: style.name,
              iconUrl: style.thumbnailUrl,
              creationFunction: () => {
                return new Cesium.UrlTemplateImageryProvider({
                  url: style.templateUrl + "?token=" + accessToken,
                  tileWidth: 512,
                  tileHeight: 512,
    
                });
              }
            }));
          }
    
        }
    
    Expand
  6. Apply the imageryProviders list into the viewModel and use the first basemap style as the default basemap.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
        async function loadBasemaps() {
    
          const response = await fetch(`https://static-map-tiles-api.arcgis.com/arcgis/rest/services/static-basemap-tiles-service/beta/self?token=${accessToken}`);
          const data = await response.json();
    
          const imageryProviders = []
    
          for (const style of data.styles) {
    
            imageryProviders.push(new Cesium.ProviderViewModel({
              name: style.name,
              iconUrl: style.thumbnailUrl,
              creationFunction: () => {
                return new Cesium.UrlTemplateImageryProvider({
                  url: style.templateUrl + "?token=" + accessToken,
                  tileWidth: 512,
                  tileHeight: 512,
    
                });
              }
            }));
          }
    
          viewModel.imageryProviderViewModels = imageryProviders;
          viewModel.selectedImagery = imageryProviders[0]; // set the first basemap style as the default style
    
        }
    
    Expand

Load the new base layer picker

  1. Call the loadBasemaps function to load the new base layer picker with the static basemap styles.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
        loadBasemaps();
    
        viewer.camera.setView({
    
          destination: Cesium.Cartesian3.fromDegrees(-91.2996, 37.1174, 4622324.434309),
    
          orientation: {
            heading: Cesium.Math.toRadians(0.0),
            pitch: Cesium.Math.toRadians(-90.0),
          }
        });
    
    Expand

Add attribution

You are required to provide data attribution to the static basemap tiles service. CesiumJS does not add the attribution automatically. Therefore, you are required to add it manually. To do this, you make another call to the service to retrieve the basemap style's metadata, then attach the copyrightText attribute to the imagery provider's credit.

  1. Inside the for loop, make a call to the style's URL to retrieve its metadata. Store the JSON response into a variable called attributionData.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
        async function loadBasemaps() {
    
          const response = await fetch(`https://static-map-tiles-api.arcgis.com/arcgis/rest/services/static-basemap-tiles-service/beta/self?token=${accessToken}`);
          const data = await response.json();
    
          const imageryProviders = []
    
          for (const style of data.styles) {
    
            const attributionResponse = await fetch(`${style.url}?token=${accessToken}`);
            const attributionData = await attributionResponse.json();
    
            imageryProviders.push(new Cesium.ProviderViewModel({
              name: style.name,
              iconUrl: style.thumbnailUrl,
              creationFunction: () => {
                return new Cesium.UrlTemplateImageryProvider({
                  url: style.templateUrl + "?token=" + accessToken,
                  tileWidth: 512,
                  tileHeight: 512,
    
                });
              }
            }));
          }
    
          viewModel.imageryProviderViewModels = imageryProviders;
          viewModel.selectedImagery = imageryProviders[0]; // set the first basemap style as the default style
    
        }
    
    Expand
  2. In the creationFunction of the style, use the copyrightText from the attributionData in the credit attribute.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
        async function loadBasemaps() {
    
          const response = await fetch(`https://static-map-tiles-api.arcgis.com/arcgis/rest/services/static-basemap-tiles-service/beta/self?token=${accessToken}`);
          const data = await response.json();
    
          const imageryProviders = []
    
          for (const style of data.styles) {
    
            const attributionResponse = await fetch(`${style.url}?token=${accessToken}`);
            const attributionData = await attributionResponse.json();
    
            imageryProviders.push(new Cesium.ProviderViewModel({
              name: style.name,
              iconUrl: style.thumbnailUrl,
              creationFunction: () => {
                return new Cesium.UrlTemplateImageryProvider({
                  url: style.templateUrl + "?token=" + accessToken,
                  tileWidth: 512,
                  tileHeight: 512,
    
                  credit: new Cesium.Credit(attributionData.copyrightText)
    
                });
              }
            }));
          }
    
          viewModel.imageryProviderViewModels = imageryProviders;
          viewModel.selectedImagery = imageryProviders[0]; // set the first basemap style as the default style
    
        }
    
    Expand

Run the app

In CodePen, run your code to display the map.

The scene should display an area of the United States of America with a customized base layer picker.

What's next?

Learn how to use additional ArcGIS location services in these tutorials:

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.