Scenes (3D)

Scene with the imagery basemap layer, scene view camera set to 7.65, 46.63, height 4500 meters

What is a scene?

A scene is a container for layers. You use a scene together with a scene view to display layers of geographic data in 3D. Most applications contain a basemap layer to display geographic data with streets or satellite imagery, but you can also use data layers and graphics to display additional data.

You can use a scene and a scene view to:

  • Display basemap layers such as streets, topographic, light gray canvas, or satellite imagery.
  • Display basemap layers with custom styles.
  • Display data layers that contain feature, vector tile, or tile layer data.
  • Display temporary points, lines, polygons, or text as graphics.
  • Display terrain with elevation.
  • Display real-world objects such as buildings, cars, and trees.
  • Display 3D visualizations of 2D objects.
  • Provide an interface with which your users can zoom, pan, and interact.
  • Inspect layers and display attribute information.
  • Display layers in a web scene.

How a scene works

A scene and a scene view work together to display layers in 3D. A scene manages layers and a scene view displays layer data. A scene typically contains a basemap layer that references an elevation layer (or service), and one or more data layers. A scene view combines all of the layers (and graphics) into a single display.

Data sources

Each layer in a scene references a data source. A layer's data source provides the geographic data that is displayed in the scene view. The main data source for a basemap layer is the basemap layer service. The data source for a data layer can be a file, collection of local data, or a data service. Learn more about data sources in Basemap layer service and Data layers.

Scene layers

Scenes can also contain scene layers to provide more advanced 3D visualizations. Scene services provide high-resolution 3D data of landscapes, cities, buildings, and other 3D object types. To learn more about publishing scene services, visit Scene services in the ArcGIS Enterprise documentation.

Layer order

When a scene view displays a scene, the layers and graphics are displayed from the bottom up, therefore, it is important to add a basemap layer and elevation layer (or service) first, then data layers, and then graphics.

Figure 1: A scene and scene view work together to display layers and graphics.

Scene

A scene contains a collection of layers for a mapping application. You use it to add, remove, order, and set the visibility for all layers you would like to display. For a simple application, you can just add a basemap layer, and optionally, reference an elevation layer (or service). Scenes use values in an elevation layer to determine the ground height (surface). In most cases, all other layers are draped on top of a basemap layer that has elevation defined. Layers can also have a relative position above or below the surface.

A basemap layer is the most important layer in a scene as it provides the overall visual context for the scene. Most APIs provide an enumeration to make it easier to access a basemap layer's data source. Other APIs require you to reference the service URL and style for the desired basemap.

ArcGIS JS APIArcGIS .NET APIArcGIS Android APIArcGIS iOS APIArcGIS Java APIArcGIS Qt API (C++)ArcGIS Qt API (QML)
                     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Fix line

esriConfig.apiKey = "YOUR_API_KEY";
const scene = new Map({
  basemap: "arcgis-topographic", // Basemap layer
  ground: "world-elevation" // Elevation service
});


const view = new SceneView({
  map: scene,
  camera: {
    position: {
      x: -118.808,
      y: 33.961,
      z: 2000 // meters
    tilt: 75
  container: "viewDiv"
});

Scene view

A scene view is a user interface that displays layers in a scene and graphics in 3D. Its primary role is to display all of the geographic data for a specific area of the scene. The visible area is known as the extent.

A scene view also provides a user interface for the scene and its layers. It supports user interactions such as click, tap, swipe, and pinch. You can use these events to access data in layers or graphics. Click events are typically used to access feature attributes and display them in a pop-up.

To create a scene view, you typically set the scene and the camera position. Unlike a map, a scene uses a camera to define the viewer's perspective and determine the visible extent. The perspective is defined by setting the camera's position, location, altitude (height), heading and tilt. You also set the container to connect the view to a visible component in the application.

ArcGIS JS APIArcGIS .NET APIArcGIS Android APIArcGIS iOS APIArcGIS Java APIArcGIS Qt API (C++)ArcGIS Qt API (QML)
                     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Fix line

esriConfig.apiKey = "YOUR_API_KEY";
const scene = new Map({
  basemap: "arcgis-topographic", // Basemap layer
  ground: "world-elevation" // Elevation service
});


const view = new SceneView({
  map: scene,
  camera: {
    position: {
      x: -118.808,
      y: 33.961,
      z: 2000 // meters
    },
    tilt: 75
  },
  container: "viewDiv"
});

Examples

Display a scene with elevation

This example uses a scene and scene view to displays the topographic basemap layer. The basemap layer is draped on the elevation layer to create a 3D view. The camera for the scene is set to -118.808, 33.961 (longitude, latitude) at an altitude of 2000 meters. The tilt is set to 75 degrees. The second example displays the same scene with the satellite imagery basemap layer.

Steps

  1. Create a map or scene and add a basemap layer and elevation layer (or service).
  2. Create a scene view and set the camera position.

Topographic basemap layer

ArcGIS JS APIArcGIS .NET APIArcGIS Android APIArcGIS iOS APIArcGIS Java APIArcGIS Qt API (C++)ArcGIS Qt API (QML)
                                                   
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
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
  <title>ArcGIS Developer Guide: Display a scene</title>
  <style>
    html, body, #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
  </style>

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

  <script>
    require([
        "esri/config",
        "esri/Map",
        "esri/views/SceneView"
    ],(esriConfig, Map, SceneView)=> {
      esriConfig.apiKey = "YOUR-API-KEY";
      const map = new Map({
        basemap: "arcgis-topographic",
        ground: "world-elevation"
      });

      const view = new SceneView({
        map: map,
        camera: {
          position: {
            x: -118.808,
            y: 33.961,
            z: 2000 // meters
          },
          tilt: 75
        },
        container: "viewDiv"
      });
  </script>
</head>
<body>
  <div id="viewDiv"></div>
</body>
</html>

Satellite imagery basemap layer

ArcGIS JS APIArcGIS .NET APIArcGIS Android APIArcGIS iOS APIArcGIS Java APIArcGIS Qt API (C++)ArcGIS Qt API (QML)
                                                  
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
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
  <title>ArcGIS Developer Guide: Satellite basemap layer</title>
  <style>
    html, body, #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
  </style>

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

  <script>
    require([
        "esri/config",
        "esri/Map",
        "esri/views/SceneView"
    ],(esriConfig, Map, SceneView)=> {
      esriConfig.apiKey = "YOUR-API-KEY";
      const map = new Map({
        basemap: "arcgis-imagery", //Basemap layer service
        ground: "world-elevation" //Elevation service
      });

      const view = new SceneView({
        container: "viewDiv",
        map: map,
        camera: {
          position: {
            x: -118.808, //Longitude
            y: 33.961, //Latitude
            z: 2000 // Meters
          },
          tilt: 75
        }
      });
  </script>
</head>
<body>
  <div id="viewDiv"></div>
</body>
</html>

Display 2D data in 3D

This example illustrates how to use a renderer to display 2D features in 3D with a scene view.

Steps

  1. Create a map or scene and add a basemap layer and reference an elevation layer (or service).
  2. Add a data layer or graphics with points, lines, or polygons.
  3. Set a layer renderer style the points with 3D symbols.
  4. Set the scene to the scene view.
  5. Set the camera position.
ArcGIS JS APIArcGIS .NET APIArcGIS Android APIArcGIS iOS APIArcGIS Java APIArcGIS Qt API (C++)ArcGIS Qt API (QML)
                                                                                                                                                                                                                                           
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
<html>
  <head>
    <meta charset="utf-8" />
<title>
  ArcGIS Developer Guide: Display 2D data in 3D
    </title>
     <!-- ArcGIS Mapping APIs and Location Services Developer Guide
    Learn more: https://developers.arcgis.com/documentation/mapping-apis-and-services/maps
    -->

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

    <style>
      html,
      body,
      #viewDiv {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
      #menu {
        padding: 1em;
      #menu > div {
        padding: 0.4em;
        font-family: "Avenir Next W00", "Helvetica Neue", Helvetica, Arial,
    </style>

    <script>
      require([
        "esri/config",
        "esri/WebScene",
        "esri/views/SceneView",
        "esri/layers/FeatureLayer",
        "esri/renderers/UniqueValueRenderer"
      ],(esriConfig, WebScene, SceneView, FeatureLayer, UniqueValueRenderer)=> {
        esriConfig.apiKey = "YOUR-API-KEY";
        const webscene = new WebScene({
          portalItem: {
            id: "4a711462369c4334972dcd39b064d214"
        const view = new SceneView({
          container: "viewDiv",
          map: webscene,
          qualityProfile: "high",
          environment: {
            lighting: {
              directShadowsEnabled: true,
              ambientOcclusionEnabled: true
            atmosphere: {
              quality: "high"
         //These options can be set on a PathSymbol3DLayer
        const options = {
          profile: "quad", //Shape
          cap: "round",
          join: "miter",
          width: 5,
          height: 30,
          color: [200, 200, 200],
          profileRotation: "all"
        //For transit lines
        const colors = {
          A: [255, 0, 16],
          B: [0, 170, 227],
          C: [248, 150, 29],
          D: [0, 166, 63],
          F1: [189, 239, 133],
          F2: [189, 239, 133]
        const transitLayer = new FeatureLayer({
          url:
            "http://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/subway_tcl_stations_lines_wgs84/FeatureServer/0",
          copyright:
            "Data from <a href='https://data.beta.grandlyon.com/en/datasets/lignes-metro-funiculaire-reseau-transports-commun-lyonnais/info'>Data Grand Lyon - Sytral</a>",
          elevationInfo: {
            mode: "relative-to-ground",
            offset: 10
          },
          title: "Transit lines in Lyon",
          definitionExpression: "sens='Aller'",
          outFields: ["*"]
        });
        webscene.add(transitLayer);

        //Render unique path symbol for each transit line
        function renderTransitLayer() {
          const renderer = new UniqueValueRenderer({
            field: "ligne"
          });

          for (let property in colors) {
            if (colors.hasOwnProperty(property)) {
              renderer.addUniqueValueInfo({
                value: property,
                symbol: {
                  type: "line-3d",
                  symbolLayers: [
                    {
                      type: "path",
                      profile: options.profile,
                      material: {
                        color: colors[property]
                      },
                      width: options.width,
                      height: options.height,
                      join: options.join,
                      cap: options.cap,
                      anchor: "bottom",
                      profileRotation: options.profileRotation
                    }
                  ]
                }
              });
            }
          }

          transitLayer.renderer = renderer;
        }
        //Add event listeners to modify path properties from options
        const styleSelect = document.getElementById("style");
        styleSelect.addEventListener("change", (event)=> {
          const value = event.target.value;
          switch (value) {
            case "round-tube":
              options.profile = "circle";
              options.height = 30;
              options.width = 30;
              break;
            case "square-tube":
              options.profile = "quad";
              options.height = 30;
              options.width = 30;
              break;
            case "wall":
              options.profile = "quad";
              options.height = 30;
              options.width = 5;
              break;
            case "strip":
              options.profile = "quad";
              options.height = 5;
              options.width = 30;
              break;
          renderTransitLayer(); //re-render the layer
        const capSelect = document.getElementById("cap");
        capSelect.addEventListener("change", (event)=> {
        const joinSelect = document.getElementById("join");
        joinSelect.addEventListener("change", (event)=> {
          console.log(event.target.value);
        const rotationSelect = document.getElementById("profileRotation");
        rotationSelect.addEventListener("change", (event)=> {
        view.ui.add("menu", "top-right");
    </script>
  </head>

  <body>
    <div id="viewDiv" class="esri-widget"></div>
    <div id="menu" class="esri-widget">
      <p>Choose path properties:</p>
      <div>
        <label for="style">Style</label>
        <select id="style">
          <option value="wall">Wall</option>
          <option value="square-tube">Square tube</option>
          <option value="round-tube">Round tube</option>
          <option value="strip">Strip</option>
        </select>
      </div>
      <div>
        <label for="cap">Cap</label>
        <select id="cap">
          <option value="round">Round</option>
          <option value="butt">Butt</option>
          <option value="square">Square</option>
          <option value="none">None</option>
        </select>
      </div>
      <div>
        <label for="join">Join</label>
        <select id="join">
          <option value="miter">Miter</option>
          <option value="round">Round</option>
          <option value="bevel">Bevel</option>
        </select>
      </div>
      <div>
        <label for="profileRotation">Profile rotation</label>
        <select id="profileRotation">
          <option value="all">All</option>
          <option value="heading">Heading</option>
        </select>
      </div>
    </div>
  </body>
</html>

Display a scene service with textured buildings

This example shows to display 3D objects such as building, trees, and cars using a scene layer that references a scene service data source. The scene service must be created and published with ArcGIS prior to creating the application. Once created, the service can be referenced by URL or by its item ID.

Steps

  1. Create a map or scene and add a basemap layer and reference an elevation layer (or service).
  2. Add a scene layer that references a scene service with textured buildings.
  3. Set the scene to the scene view.
  4. Set the camera position.
ArcGIS JS APIArcGIS .NET APIArcGIS Android APIArcGIS iOS APIArcGIS Java APIArcGIS Qt API (C++)ArcGIS Qt API (QML)
                                                                          
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
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
     <!-- ArcGIS Mapping APIs and Location Services Developer Guide
    Learn more: https://developers.arcgis.com/documentation/mapping-apis-and-services/maps
    -->
<title>
  ArcGIS Developer Guide: Scene service buildings
    </title>
    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
    </style>

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

    <script>
      require([
        "esri/config",
        "esri/Map",
        "esri/views/SceneView",
        "esri/layers/SceneLayer"
      ],(esriConfig, Map, SceneView, SceneLayer)=> {
        // Create SceneLayer and add to the map
        esriConfig.apiKey = "YOUR-API-KEY";
        const sceneLayer = new SceneLayer({
          portalItem: {
            id: "2342ab7928834076a1240fb93c60e978"
          },
          elevationInfo: {
            mode: "absolute-height",
            offset: 6
          }
        });

        // Create Map
        const map = new Map({
          basemap: "hybrid", //Basemap layer service
          ground: "world-elevation", //Elevation service
          layers: [sceneLayer]
        });

        // Create the SceneView
        const view = new SceneView({
          container: "viewDiv",
          map: map,
          camera: {
            position: [4.84361, 45.75561, 270],
            tilt: 82,
            heading: 304
          }
        });

    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
  </body>
</html>

Display a scene service with an integrated mesh

This example displays a 3D integrated mesh surface by using a scene layer that references a scene service data source. The scene service must be created and published with ArcGIS prior to creating the application. Once created, the service can be referenced by URL or by its item ID.

Steps

  1. Create a scene and add an elevation layer and a basemap layer.
  2. Add a scene layer that references a scene service with an integrated mesh.
  3. Set the scene to the scene view.
  4. Set the camera position.
ArcGIS JS APIArcGIS .NET APIArcGIS Android APIArcGIS iOS APIArcGIS Java APIArcGIS Qt API (C++)ArcGIS Qt API (QML)
                                                                                                                                                               
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
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>
      ArcGIS Developer Guide: Realistic city visualization- Integrated mesh
    </title>
    <link rel="stylesheet" href="https://js.arcgis.com/4.19/esri/themes/light/main.css">
    <script src="https://js.arcgis.com/4.19/"></script>

    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      #menu {
        padding: 1em;
    </style>

    <script>
      require([
        "esri/config",
        "esri/Map",
        "esri/views/SceneView",
        "esri/layers/IntegratedMeshLayer",
        "esri/widgets/LayerList",
        "esri/layers/FeatureLayer",
        "esri/widgets/Legend"
      ],(
        Map,
      )=> {
        esriConfig.apiKey = "YOUR-API-KEY";
        const map = new Map({
          basemap: "arcgis-imagery",
          ground: "world-elevation"
        const meshLayer = new IntegratedMeshLayer({
          url: "https://tiles.arcgis.com/tiles/u0sSNqDXr7puKJrF/arcgis/rest/services/Frankfurt2017_v17/SceneServer/layers/0",
          copyright: "nFrames - Aerowest",
          title: "Integrated Mesh Frankfurt"
        });
        const color = [235, 171, 52];
        const poiLayer = new FeatureLayer({
          url: "https://services.arcgis.com/5xC5Wrapp1gUAl2r/arcgis/rest/services/Frankfurt_POIs/FeatureServer/0",
          title: "Points of interest",
          renderer: {
            type: "simple",
            symbol: {
              type: "point-3d", // autocasts as new PointSymbol3D()
              symbolLayers: [
                  type: "icon", // autocasts as new IconSymbol3DLayer()
                  resource: {
                    primitive: "circle"
                  size: 10,
                  material: {
                    color: color
                  outline: {
                    color: "white",
                    size: 1
              verticalOffset: {
                screenLength: 40,
                maxWorldLength: 200,
                minWorldLength: 35
              callout: {
                type: "line", // autocasts as new LineCallout3D()
                color: color,
                size: 1,
                border: {
                  color: "white"
          elevationInfo: {
            // elevation mode that will place points on top of the buildings or other SceneLayer 3D objects
            mode: "relative-to-scene"
          labelingInfo: [
              labelExpressionInfo: {
                value: "{name}"
              symbol: {
                type: "label-3d",
                symbolLayers: [
                    type: "text",
                    material: {
                      color: color
                    // we set a halo on the font to make the labels more visible with any kind of background
                    halo: {
                      size: 1,
                      color: "black"
                    size: 10
        const view = new SceneView({
          container: "viewDiv",
          map: map,
          qualityProfile: "high",
          camera: {
            position: [
              8.69370363,
              50.10533415,
              284.73511
            heading: 295.75,
            tilt: 76.80
        const layerList = new LayerList({
          view: view
        view.ui.add(layerList, "top-right");
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
  </body>
</html>

Tutorials

Services

Basemap layer service

Access streets, satellite, and other basemap styles for maps and scenes.

API support

2D Display3D DisplayBasemap layersData layersGraphicsWeb mapsWeb scenes
ArcGIS API for JavaScriptFully supportedFully supportedFully supportedFully supportedFully supportedFully supportedFully supported
ArcGIS Runtime API for AndroidFully supportedFully supportedFully supportedFully supportedFully supportedFully supportedFully supported
ArcGIS Runtime API for iOSFully supportedFully supportedFully supportedFully supportedFully supportedFully supportedFully supported
ArcGIS Runtime API for JavaFully supportedFully supportedFully supportedFully supportedFully supportedFully supportedFully supported
ArcGIS Runtime API for .NETFully supportedFully supportedFully supportedFully supportedFully supportedFully supportedFully supported
ArcGIS Runtime API for QtFully supportedFully supportedFully supportedFully supportedFully supportedFully supportedFully supported
ArcGIS API for PythonFully supportedNot supportedFully supportedFully supportedFully supportedFully supportedFully supported
Esri LeafletFully supportedNot supportedFully supportedFeature layer, Image tile layerLeaflet LayersNot supportedNot supported
MapBox GL JSFully supportedNot supportedFully supportedFeature layer, Image tile layerMapbox LayersNot supportedNot supported
OpenLayersFully supportedNot supportedFully supportedFeature layer, Image tile layerOpenSource LayersNot supportedNot supported
ArcGIS REST JSNot supportedNot supportedDirect access and authenticationDirect access and authenticationNot supportedDirect access and authenticationDirect access and authentication
Full supportPartial support (see notes)Not supported

Tools

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