Switch view from 2D to 3D

This sample demonstrates how you can switch a map's view from 2D to 3D. This can be done with the same Map instance or with separate WebMap and WebScene instances. Working with WebMaps and WebScenes reduces the amount of code needed to check for differences between 2D and 3D that aren't supported in both views, such as 2D and 3D symbology. Click the 3D button in the top-left corner of the view to switch the view from 2D to 3D and vice versa.

To implement this behavior, set the container in the starting view to the container of the destination view. Likewise, set the map instance and the viewpoint on the destination view.

While Camera is the preferred object for setting a SceneView's visible extent and extent is preferred for MapView, the viewpoint property on each view is convenient because it persists the extent and rotation from one view type to the next. Some properties, such as tilt and elevation layers, will be ignored in 2D MapViews.

The function below demonstrates how to accomplish this.

Use dark colors for code blocksCopy
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
// Switches the view from 2D to 3D and vice versa
function switchView() {
  const is3D = appConfig.activeView.type === "3d";
  const activeViewpoint = appConfig.activeView.viewpoint.clone();

  // Compute scale conversion factor with cosine of latitude to account for distance distortion as latitude moves away from the equator
  const latitude = appConfig.activeView.center.latitude;
  const scaleConversionFactor = Math.cos((latitude * Math.PI) / 180.0);

  // remove the reference to the container for the previous view
  appConfig.activeView.container = null;

  if (is3D) {
    activeViewpoint.scale /= scaleConversionFactor;

    // if the input view is a SceneView, set the viewpoint on the
    // mapView instance. Set the container on the mapView and flag
    // it as the active view
    appConfig.mapView.viewpoint = activeViewpoint;
    appConfig.mapView.container = appConfig.container;
    appConfig.activeView = appConfig.mapView;
    switchButton.value = "3D";
  } else {
    activeViewpoint.scale *= scaleConversionFactor;

    appConfig.sceneView.viewpoint = activeViewpoint;
    appConfig.sceneView.container = appConfig.container;
    appConfig.activeView = appConfig.sceneView;
    switchButton.value = "2D";
  }
}

Limitations about switching between 2D and 3D

Keep in mind that switching from a MapView to a SceneView requires careful consideration for a number of factors. See the list below for some of the factors of consideration. This list is not comprehensive.

  • Data types - Some layers aren't supported in 2D because of their 3D nature. These include SceneLayer, IntegratedMeshLayer, and PointCloudLayer. They will need to be removed from the map instance altogether, or replaced with 2D counterparts. For example, you could switch a SceneLayer representing buildings with a polygon FeatureLayer representing building footprints. ElevationLayer doesn't need to be considered as closely as the other layers mentioned above since the Map's ground is ignored in MapViews.
  • Symbols - While most 2D symbols are usable in SceneView, all 3D symbols are not supported in MapViews. Renderers may need to be reconfigured if 3D symbols are used.
  • UI components - If adding widgets and other UI components using view.ui.add(), then keep in mind that these components need extra logic for persisting from one view to the next.
  • Widgets - All widgets in the API are tied to a specific view. If persisting widgets from a 2D to 3D view is desired then extra logic will need to be included for switching the view referenced by each widget. This includes a view's popup instance.

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