Learn how to add a raster tile layer to a map .
A raster tile layer, also known as an image tile layer , displays imagery such as satellite photography or hillshading. You can combine raster 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 raster 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 raster tile layer, which is a basemap layer composed of JPEG images, on top of a street basemap layer.
Prerequisites You need an ArcGIS account to access the developer dashboard and create an API key .
Steps Create a new pen To get started, either complete the Display a map tutorial or use this pen . 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.
Go to your dashboard to get an API key. The API key must be scoped to access the services used in this tutorial.
In CodePen , update apiKey
to use your key.
Use dark colors for code blocks
Change line
1
2
3
4
5
6
7
8
9
10
//
const apiKey = "YOUR_API_KEY" ;
const basemapEnum = "ArcGIS:Streets" ;
const map = new mapboxgl.Map({
container : "map" , // the id of the div element
style : `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/ ${basemapEnum} ?type=style&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.
Add an event handler for the load
event.
Use dark colors for code blocks
Show more lines
Add line. Add line. Add line. Add line.
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
<!DOCTYPE html >
< html >
< head >
< meta charset = "utf-8" />
< meta name = "viewport" content = "initial-scale=1,maximum-scale=1,user-scalable=no" />
< script src = "https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js" > </ script >
< link href = "https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel = "stylesheet" />
< style >
html ,
body ,
#map {
padding : 0 ;
margin : 0 ;
height : 100% ;
width : 100% ;
font-family : Arial, Helvetica, sans-serif;
font-size : 14px ;
color : #323232 ;
}
</ style >
</ head >
< body >
< div id = "map" > </ div >
< script >
const apiKey = "YOUR_API_KEY" ;
const basemapEnum = "ArcGIS:Streets" ;
const map = new mapboxgl.Map({
container : "map" , // the id of the div element
style : `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/ ${basemapEnum} ?type=style&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.
map.addSource( "hillshade" , {
type : "raster" ,
tiles : [
"https://server.arcgisonline.com/arcgis/rest/services/Elevation/World_Hillshade/MapServer/tile/{z}/{y}/{x}.jpeg?token=" + apiKey
]
});
// 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
);
layers.forEach( ( layer ) => {
if (layer.type === "fill" && !layer.id.match( /(Water area|Marine area|Bathymetry|Building)/ )) {
map.setPaintProperty(layer.id, "fill-opacity" , 0.5 );
}
});
});
</ script >
</ body >
</ html >
Show more lines
Add a raster source You need to define a source for the raster tiles. This tells the Map
how to access the data for the layer, but does not display it.
Inside the load event handler, add a raster source with id hillshade
.
Use dark colors for code blocks
Show more lines
Add line. Add line. Add line. Add line. Add line. Add line.
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
<!DOCTYPE html >
< html >
< head >
< meta charset = "utf-8" />
< meta name = "viewport" content = "initial-scale=1,maximum-scale=1,user-scalable=no" />
< script src = "https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js" > </ script >
< link href = "https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel = "stylesheet" />
< style >
html ,
body ,
#map {
padding : 0 ;
margin : 0 ;
height : 100% ;
width : 100% ;
font-family : Arial, Helvetica, sans-serif;
font-size : 14px ;
color : #323232 ;
}
</ style >
</ head >
< body >
< div id = "map" > </ div >
< script >
const apiKey = "YOUR_API_KEY" ;
const basemapEnum = "ArcGIS:Streets" ;
const map = new mapboxgl.Map({
container : "map" , // the id of the div element
style : `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/ ${basemapEnum} ?type=style&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.
map.addSource( "hillshade" , {
type : "raster" ,
tiles : [
"https://server.arcgisonline.com/arcgis/rest/services/Elevation/World_Hillshade/MapServer/tile/{z}/{y}/{x}.jpeg?token=" + apiKey
]
});
// 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
);
layers.forEach( ( layer ) => {
if (layer.type === "fill" && !layer.id.match( /(Water area|Marine area|Bathymetry|Building)/ )) {
map.setPaintProperty(layer.id, "fill-opacity" , 0.5 );
}
});
});
</ script >
</ body >
</ html >
Show more lines
Add a raster layer To display the raster tiles, add a layer of type raster
.
Add a raster layer with id hillshade-raster
, connected to the hillshade
source.
Use dark colors for code blocks
Show more lines
Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line.
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
<!DOCTYPE html >
< html >
< head >
< meta charset = "utf-8" />
< meta name = "viewport" content = "initial-scale=1,maximum-scale=1,user-scalable=no" />
< script src = "https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js" > </ script >
< link href = "https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel = "stylesheet" />
< style >
html ,
body ,
#map {
padding : 0 ;
margin : 0 ;
height : 100% ;
width : 100% ;
font-family : Arial, Helvetica, sans-serif;
font-size : 14px ;
color : #323232 ;
}
</ style >
</ head >
< body >
< div id = "map" > </ div >
< script >
const apiKey = "YOUR_API_KEY" ;
const basemapEnum = "ArcGIS:Streets" ;
const map = new mapboxgl.Map({
container : "map" , // the id of the div element
style : `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/ ${basemapEnum} ?type=style&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.
map.addSource( "hillshade" , {
type : "raster" ,
tiles : [
"https://server.arcgisonline.com/arcgis/rest/services/Elevation/World_Hillshade/MapServer/tile/{z}/{y}/{x}.jpeg?token=" + apiKey
]
});
// 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
);
layers.forEach( ( layer ) => {
if (layer.type === "fill" && !layer.id.match( /(Water area|Marine area|Bathymetry|Building)/ )) {
map.setPaintProperty(layer.id, "fill-opacity" , 0.5 );
}
});
});
</ script >
</ body >
</ html >
Show more lines
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.
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
.
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.
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.
Use dark colors for code blocks
Show more lines
Add line. Add line. Add line. Add line.
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
<!DOCTYPE html >
< html >
< head >
< meta charset = "utf-8" />
< meta name = "viewport" content = "initial-scale=1,maximum-scale=1,user-scalable=no" />
< script src = "https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js" > </ script >
< link href = "https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel = "stylesheet" />
< style >
html ,
body ,
#map {
padding : 0 ;
margin : 0 ;
height : 100% ;
width : 100% ;
font-family : Arial, Helvetica, sans-serif;
font-size : 14px ;
color : #323232 ;
}
</ style >
</ head >
< body >
< div id = "map" > </ div >
< script >
const apiKey = "YOUR_API_KEY" ;
const basemapEnum = "ArcGIS:Streets" ;
const map = new mapboxgl.Map({
container : "map" , // the id of the div element
style : `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/ ${basemapEnum} ?type=style&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.
map.addSource( "hillshade" , {
type : "raster" ,
tiles : [
"https://server.arcgisonline.com/arcgis/rest/services/Elevation/World_Hillshade/MapServer/tile/{z}/{y}/{x}.jpeg?token=" + apiKey
]
});
// 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
);
layers.forEach( ( layer ) => {
if (layer.type === "fill" && !layer.id.match( /(Water area|Marine area|Bathymetry|Building)/ )) {
map.setPaintProperty(layer.id, "fill-opacity" , 0.5 );
}
});
});
</ script >
</ body >
</ html >
Show more lines
Set 50% fill-opacity
for every fill layer except water and building layers.
Use dark colors for code blocks
Show more lines
Add line. Add line. Add line. Add line. Add line.
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
<!DOCTYPE html >
< html >
< head >
< meta charset = "utf-8" />
< meta name = "viewport" content = "initial-scale=1,maximum-scale=1,user-scalable=no" />
< script src = "https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js" > </ script >
< link href = "https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel = "stylesheet" />
< style >
html ,
body ,
#map {
padding : 0 ;
margin : 0 ;
height : 100% ;
width : 100% ;
font-family : Arial, Helvetica, sans-serif;
font-size : 14px ;
color : #323232 ;
}
</ style >
</ head >
< body >
< div id = "map" > </ div >
< script >
const apiKey = "YOUR_API_KEY" ;
const basemapEnum = "ArcGIS:Streets" ;
const map = new mapboxgl.Map({
container : "map" , // the id of the div element
style : `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/ ${basemapEnum} ?type=style&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.
map.addSource( "hillshade" , {
type : "raster" ,
tiles : [
"https://server.arcgisonline.com/arcgis/rest/services/Elevation/World_Hillshade/MapServer/tile/{z}/{y}/{x}.jpeg?token=" + apiKey
]
});
// 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
);
layers.forEach( ( layer ) => {
if (layer.type === "fill" && !layer.id.match( /(Water area|Marine area|Bathymetry|Building)/ )) {
map.setPaintProperty(layer.id, "fill-opacity" , 0.5 );
}
});
});
</ script >
</ body >
</ html >
Show more lines
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: