Point styles for cities

Visualizing points of interest in cities poses the following challenges:

  • Icons can be mostly hidden by buildings
  • Distinguishing the actual position of each point can be difficult
  • The screen can easily become cluttered in tilted views or small-scale views

This sample shows the features that help solve these problems: relative-to-scene, callout, verticalOffset, decluttering and screenSizePerspectiveEnabled.

In this sample we visualize 700 points of interest (museums, restaurants etc.) in Lyon, France. This is how the city would look like by just visualizing all the points without any enhancement:

city-points-initial

You can't see points in the center of the city because they are hidden by buildings. Labels and icons overlap, making it hard to understand which label belongs to which icon. All icons have the same size, so it's difficult to distinguish which icons are closer to the camera. We can solve these problems in 4 simple steps:

Step 1: Points located within a building should be aligned with the roof of the building

In 3D city visualizations it's important that points located within the building are displayed on top of the building so they are visible. The relative-to-scene elevation mode aligns points to the height of their corresponding building.

city-points-relative-to-scene
Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
// feature layer representing points of interest as icons
const pointsLayer = new FeatureLayer({
  ...
  elevationInfo: {
    // this elevation mode will place points on top of
    // buildings or other SceneLayer 3D objects
    mode: "relative-to-scene"
  },
  ...
});

Step 2: Add callout lines to clearly understand the position of the points

For some points it's difficult to identify their location. Moreover, some points are located on the ground and hidden by buildings. To solve this, we set a vertical offset on the points; that way points on the ground can still be visible even if they are located behind a building. Adding a callout line helps to see the actual position of the points.

city-points-callout
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
// symbol representing a point of interest
const symbol = {
  type: "point-3d", // autocasts as new PointSymbol3D()
  symbolLayers: [
    {
      type: "icon" // autocasts as new IconSymbol3DLayer()
      // add properties for the IconSymbol3DLayer here
    }
  ],

  verticalOffset: {
    screenLength: 40,
    maxWorldLength: 200,
    minWorldLength: 35
  },

  callout: {
    type: "line", // autocasts as new LineCallout3D()
    color: "white",
    size: 2,
    border: {
      color: [50, 50, 50]
    }
  }
};

Step 3: Improve distance perception by making icons that are further away smaller

A problem with visualizing features in screen space like icons in 3D tilted views is that depth perception is not very clear. All icons have the same size, so users are not sure which icons are closer or further away from the camera.

The screenSizePerspectiveEnabled property on FeatureLayer helps to better interpret distances in 3D space by making the icons further away from the camera appear smaller than icons that are closer. This setting is enabled by default.

city-points-perspective
Use dark colors for code blocksCopy
1
2
3
4
5
6
7
const pointsLayer = new FeatureLayer({
  ...
  // we recommend turning this feature off when
  // working with size visual variables
  screenSizePerspectiveEnabled: false,
  ...
});

Step 4: Declutter the webscene by removing overlapping icons

In this view we now see all the icons within the given area. However, this makes the view a bit cluttered at smaller scales. With declutter, we can choose to hide some of the icons that conflict with others. Icons that are closer to the camera remain visible and other distant icons are hidden.

city-points-declutter
Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
// feature layer representing points of interest
const pointsLayer = new FeatureLayer({
  ...
  featureReduction: {
    type: "selection"
  },
  ...
});

See also Using callout lines with labels sample to see how to set callouts of type line on labels.

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