Hosted ImageryTileLayer

Explore in the sandboxView live

This sample shows how to add an instance of a hosted ImageryTileLayer to a Map in a MapView. The ImageryTileLayer in this sample has a multidimensionalInfo containing ocean salinity and water temperature information at different depths as recorded on 3/17/2013. Users can choose to display ocean salinity or water temperature variables at the specified depth dimension.

See Publish hosted imagery layers document for more information on hosting your raster data.

How it works

When the application starts, the UI displays options for user input. Here, specify the variable you want to display and the depth dimension. When the user chooses a variable name, we will update the layer's multidimensionalDefinition property to display the data for the selected variable. Then we update the statistics for the layer's stretch renderer to match the statistics associated with the chosen variable as shown below:

                                                                                                                                                                           
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no" />
    <title>Hosted ImageryTileLayer | Sample | ArcGIS API for JavaScript 4.20</title>

    <link rel="stylesheet" href="https://js.arcgis.com/4.20/esri/themes/light/main.css" />
    <script src="https://js.arcgis.com/4.20/"></script>

    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      #rendererDiv {
        padding: 10px;
        width: 200px;
        height: 360px;
      .slider {
        height: 160px;
        width: 100%;
      .esri-slider__content{
        padding: 5px;
    </style>

    <script>
      require([
        "esri/Map",
        "esri/views/MapView",
        "esri/layers/ImageryTileLayer",
        "esri/layers/support/DimensionalDefinition",
        "esri/widgets/Slider",
        "esri/core/promiseUtils"
      ], (Map, MapView, ImageryTileLayer, DimensionalDefinition, Slider, promiseUtils) => {
        // variable names are salinity or water temperature for this HYCOM layer
        let variableName = "salinity";
        const url = "https://tiledimageservices.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/HYCOM20130317/ImageServer";
        const layer = new ImageryTileLayer({
          url: url
        const map = new Map({
          basemap: "gray-vector",
          layers: [layer]
        const view = new MapView({
          container: "viewDiv",
          map: map,
          zoom: 3,
          center: [-149, 35]
        // add UI controls to the app
        view.ui.add("rendererDiv", "top-right");
        // this function will be called as user adjusts the slider thumb to change the
        // ocean depth. Layer's stdZ dimension will be updated on the map.
        const updateRenderer = promiseUtils.debounce((dimensionName, sliderData) => {
          if (!sliderData || !layer.loaded) {
            return;
          // set the depth or StdZ dimension of the layer corresponding to the slider's thumb location
          const multidimensionalDefinition = layer.multidimensionalDefinition;
          const depthDef = multidimensionalDefinition.find((def) => def.dimensionName === "StdZ");
          if (dimensionName === "StdZ") {
            if (depthDef.values[0] === sliderData.value) {
              return;
            depthDef.values[0] = sliderData.value;
        // listen to variable dropdown change event and update layer's
        // multidimensionalDefinition and renderer properties
        // to reflect the variable selected.
        const variableNameSelect = document.getElementById("variableName");
        variableNameSelect.addEventListener("change", () => {
          if (!layer.loaded) {
            return;
        // Change the layer's variable name corresponding the selected variable in the drop down
        // variable name in this case are salinity or temperature
        function changeVariableName(variableName) {
          const multidimensionalDefinition = layer.multidimensionalDefinition;

          // filter the data by the variable that user selected
          // it is either salinity or water temperature for this data
          multidimensionalDefinition.forEach(
            (def) => (def.variableName = variableName)
          );
          layer.multidimensionalDefinition = multidimensionalDefinition;

          // update statistics for the layer's stretch renderer to match
          // statistics associated with the chosen variable
          // layer.rasterInfo.multidimensionalInfo - returns the multidimensional info
          // from the image service
          const renderer = layer.renderer.clone();
          const dimensions = layer.rasterInfo.multidimensionalInfo;
          const variable = dimensions.variables.find(
            (variable) => variable.name === variableName
          );
          renderer.statistics = variable.statistics;
          layer.renderer = renderer;
        }
        // listen to temporal slider's thumb change and drag events
        const depthSlider = new Slider({
          container: "depth-slider",
          min: -5000,
          max: 0,
          values: [-5000],
          steps: 1000,
          layout: "vertical",
          snapOnClickEnabled: true,
          labelFormatFunction: (value, type) => {
            if (type === "value") {
              return value + "m";
            return (type === "min") ? "-5000 m" : "Sea level"
          visibleElements: {
            labels: true,
            rangeLabels: true
        depthSlider.on(["thumb-change", "thumb-drag"], (delta) => updateRenderer("StdZ", delta));
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
    <div id="rendererDiv" class="esri-widget">
      <h3 class="esri-widget__heading">Multidimensional data filter</h3>
      <label style="text-align:center; font-size: 10px;" class="esri-feature-form__label">Showing data from 3/17/2013</label>
      <label class="esri-feature-form__label">Select a variable:</label>
      <select id="variableName" class="esri-input esri-select">
        <option value="salinity" selected>Salinity</option>
        <option value="water_temp">Water temperature</option>
      </select>
      <br/>
      <div>
        <label id="depthLabel" class="esri-feature-form__label">Depth:</label>
        <div id="depth-slider" class="slider"></div>
      </div>
    </div>
  </body>
  </html>

The layer will be updated to display salinity or water temperature information at the given depth whenever the depth slider thumb is changed. The following function is called whenever the depth slider thumb is moved.

                                                                                                                                                                           
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no" />
    <title>Hosted ImageryTileLayer | Sample | ArcGIS API for JavaScript 4.20</title>

    <link rel="stylesheet" href="https://js.arcgis.com/4.20/esri/themes/light/main.css" />
    <script src="https://js.arcgis.com/4.20/"></script>

    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      #rendererDiv {
        padding: 10px;
        width: 200px;
        height: 360px;
      .slider {
        height: 160px;
        width: 100%;
      .esri-slider__content{
        padding: 5px;
    </style>

    <script>
      require([
        "esri/Map",
        "esri/views/MapView",
        "esri/layers/ImageryTileLayer",
        "esri/layers/support/DimensionalDefinition",
        "esri/widgets/Slider",
        "esri/core/promiseUtils"
      ], (Map, MapView, ImageryTileLayer, DimensionalDefinition, Slider, promiseUtils) => {
        // variable names are salinity or water temperature for this HYCOM layer
        let variableName = "salinity";
        const url = "https://tiledimageservices.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/HYCOM20130317/ImageServer";
        const layer = new ImageryTileLayer({
          url: url
        const map = new Map({
          basemap: "gray-vector",
          layers: [layer]
        const view = new MapView({
          container: "viewDiv",
          map: map,
          zoom: 3,
          center: [-149, 35]
        // add UI controls to the app
        view.ui.add("rendererDiv", "top-right");
        // this function will be called as user adjusts the slider thumb to change the
        // ocean depth. Layer's stdZ dimension will be updated on the map.
        const updateRenderer = promiseUtils.debounce((dimensionName, sliderData) => {
          if (!sliderData || !layer.loaded) {
            return;
          }
          // set the depth or StdZ dimension of the layer corresponding to the slider's thumb location
          const multidimensionalDefinition = layer.multidimensionalDefinition;
          const depthDef = multidimensionalDefinition.find((def) => def.dimensionName === "StdZ");
          if (dimensionName === "StdZ") {
            if (depthDef.values[0] === sliderData.value) {
              return;
            }
            depthDef.values[0] = sliderData.value;
          }
          layer.multidimensionalDefinition = multidimensionalDefinition;
        });
        // listen to variable dropdown change event and update layer's
        // multidimensionalDefinition and renderer properties
        // to reflect the variable selected.
        const variableNameSelect = document.getElementById("variableName");
        variableNameSelect.addEventListener("change", () => {
          if (!layer.loaded) {
            return;
        // Change the layer's variable name corresponding the selected variable in the drop down
        // variable name in this case are salinity or temperature
        function changeVariableName(variableName) {
          const multidimensionalDefinition = layer.multidimensionalDefinition;
          // filter the data by the variable that user selected
          // it is either salinity or water temperature for this data
            (def) => (def.variableName = variableName)
          // update statistics for the layer's stretch renderer to match
          // statistics associated with the chosen variable
          // layer.rasterInfo.multidimensionalInfo - returns the multidimensional info
          // from the image service
          const renderer = layer.renderer.clone();
          const dimensions = layer.rasterInfo.multidimensionalInfo;
          const variable = dimensions.variables.find(
            (variable) => variable.name === variableName
        // listen to temporal slider's thumb change and drag events
        const depthSlider = new Slider({
          container: "depth-slider",
          min: -5000,
          max: 0,
          values: [-5000],
          steps: 1000,
          layout: "vertical",
          snapOnClickEnabled: true,
          labelFormatFunction: (value, type) => {
            if (type === "value") {
              return value + "m";
            return (type === "min") ? "-5000 m" : "Sea level"
          visibleElements: {
            labels: true,
            rangeLabels: true
        depthSlider.on(["thumb-change", "thumb-drag"], (delta) => updateRenderer("StdZ", delta));
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
    <div id="rendererDiv" class="esri-widget">
      <h3 class="esri-widget__heading">Multidimensional data filter</h3>
      <label style="text-align:center; font-size: 10px;" class="esri-feature-form__label">Showing data from 3/17/2013</label>
      <label class="esri-feature-form__label">Select a variable:</label>
      <select id="variableName" class="esri-input esri-select">
        <option value="salinity" selected>Salinity</option>
        <option value="water_temp">Water temperature</option>
      </select>
      <br/>
      <div>
        <label id="depthLabel" class="esri-feature-form__label">Depth:</label>
        <div id="depth-slider" class="slider"></div>
      </div>
    </div>
  </body>
  </html>

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