Add a map tile layer

Learn how to add a map tile layer to a map.

A map tile layer, also known as an image tile layer, displays raster imagery such as satellite photography or hillshading. You can combine map tile layers to enhance the display of a street basemap layer, position the layer on top of existing layers, or position it under existing layers. When positioned above other layers, you need to give the map tile layer a level of transparency so that users can see through it to the basemap. This combined basemap layer technique is used to enhance overall visualization.

In this tutorial, you add a Hillshade map tile layer, which is a basemap layer composed of JPEG images, on top of a street basemap layer.

Prerequisites

You need an ArcGIS Developer or ArcGIS Online account to access the developer dashboard and create an API key.

Steps

Create a new pen

  1. To get started, either complete the Display a map tutorial or .

Set the API key

To access location services, you need an API key or OAuth 2.0 access token. To learn how to create and scope your key, visit the Create an API key tutorial.

  1. Go to your dashboard to get an API key. The API key must be scoped to access the services used in this tutorial.

  2. In CodePen, update apiKey to use your key.

    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
    const apiKey = "YOUR_API_KEY";
    const basemapEnum = "arcgis/streets";
    const map = new maplibregl.Map({
      container: "map", // the id of the div element
      style: `https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/styles/${basemapEnum}?token=${apiKey}`,
      zoom: 12, // starting zoom
      center: [-118.805, 34.027] // starting location [longitude, latitude]
    });
    

Add a load event handler

To add layers to the map, you need to use the load event to ensure the map is fully loaded.

  1. Add an event handler for the load event.

    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
        <script>
          const apiKey = "YOUR_API_KEY";
          const basemapEnum = "arcgis/streets";
          const map = new maplibregl.Map({
            container: "map", // the id of the div element
            style: `https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/styles/${basemapEnum}?token=${apiKey}`,
            zoom: 12, // starting zoom
            center: [-118.805, 34.027] // starting location [longitude, latitude]
          });
    
          map.once("load", () => {
            // This code runs once the base style has finished loading.
    
          });
    
        </script>
    
    Expand

Add a raster source

You need to define a source for the map tiles. This tells the Map how to access the data for the layer, but does not display it.

  1. Inside the load event handler, add a raster source with id hillshade.

    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
          map.once("load", () => {
            // This code runs once the base style has finished loading.
    
            map.addSource("hillshade", {
              type: "raster",
              tiles: [
                "https://server.arcgisonline.com/arcgis/rest/services/Elevation/World_Hillshade/MapServer/tile/{z}/{y}/{x}.jpeg?token=" + apiKey
              ]
            });
    
          });
    
    Expand

Add a raster layer

To display the map tiles, add a layer of type raster.

  1. Add a raster layer with id hillshade-raster, connected to the hillshade source.

    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
          map.once("load", () => {
            // This code runs once the base style has finished loading.
    
            map.addSource("hillshade", {
              type: "raster",
              tiles: [
                "https://server.arcgisonline.com/arcgis/rest/services/Elevation/World_Hillshade/MapServer/tile/{z}/{y}/{x}.jpeg?token=" + apiKey
              ]
            });
    
            map.addLayer(
              {
                id: "hillshade-raster",
                type: "raster",
                source: "hillshade"
              },
    
            );
    
          });
    
    Expand
  2. At the top right, click Run. You should see the hillshade layer only.

Adjust the basemap

By default, the hillshade layer is added on top of all the basemap layers. To visually combine hillshading with roads and park layers, you need to make two changes.

  1. Move the hillshade layer below every layer except the background layer. You do this by passing the id of the next layer as an extra argument to map.addLayer.

  2. Reduce the opacity of most fill layers so the hillshade layer can be seen through them. In the ArcGIS:Streets basemap, this includes several layers whose ids begin with Water area, Marine area, Bathymetry or Building. You can use map.getStyle to get the current style, and its layers property to access all layers. Use map.setPaintProperty to change the fill-opacity for each layer.

  3. In the load handler, find the id of the first non-background layer. Modify your addLayer call to insert the raster layer before that layer.

    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
            // Find the first non-background layer in order to add our raster layer before it.
            const layers = map.getStyle().layers;
            const bottomLayer = layers.find((layer) => layer.type !== "background");
    
            map.addLayer(
              {
                id: "hillshade-raster",
                type: "raster",
                source: "hillshade"
              },
    
              bottomLayer.id
    
            );
    
    Expand
  4. Set 50% fill-opacity for every fill layer except water and building layers.

    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
              bottomLayer.id
    
            );
    
            layers.forEach((layer) => {
              if (layer.type === "fill" && !layer.id.match(/(Water area|Marine area|Bathymetry|Building)/)) {
                map.setPaintProperty(layer.id, "fill-opacity", 0.5);
              }
            });
    
    Expand

Run the app

In CodePen, run your code to display the map.

Your map should display a semi-transparent hillshade layer overlaid over a basemap. You should see the hillshade layer combined with other layers, with labels, roads, buildings and water areas clearly visible over the top.

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.