This sample demonstrates how to visualize 2D point features based on real-world sizes or measurements in a 3D SceneView. The layer in this app contains point data representing tree locations. This data has multiple fields for measurements of each tree, including canopy diameters along semi-major and semi-minor axes, canopy height, trunk width, and trunk height. We'll use the data in these fields to create symbols that represent the real-world sizes and shapes of each tree in relation to other map features, regardless of scale.
In this case, we'll use a SimpleRenderer with three size visual variables and one color visual variable to model the size and shape of each tree based as it exists in the real world.
Prior to completing the following steps, you should be familiar with views, Map, and FeatureLayer. If necessary, complete the following tutorials first:
The basic components of this app, such as creating instances of the Map and SceneView classes and understanding HTML and CSS structure will not be reviewed. See the tutorials listed above if you need to familiarize yourself with those components in this application. As a general rule the introductory principles discussed in the tutorials above apply to most samples in the documentation.
1. Create a SimpleRenderer for trees and assign it a default symbol
Create a SimpleRenderer and set a default symbol on the symbol property of the renderer. In this case, we'll create a WebStyleSymbol depicting a realistic tree. ArcGIS Online provides many realistic 3D symbols out of the box. In this case we select a generic tree from the esri
style group.
const trunkRenderer = {
type: "simple", // autocasts as new SimpleRenderer()
symbol: {
type: "web-style", // autocasts as new WebStyleSymbol()
styleName: "esriRealisticTreesStyle",
name: "Other"
}
};
To read more in depth about WebStyleSymbols and their relationship to PointSymbol3D, see the Visualize features with realistic WebStyleSymbols sample.
2. Set three size visual variables on the renderer
When defining the size of any WebStyleSymbol or ObjectSymbol3DLayer, there are three axes that need to be considered: height, width (length/diameter from east to west), and depth (length/diameter from north to south). Each axis can be set base on field values with a separate size visual variable. If the values of each axis are equal, then only one size visual variable is required.
The tree data happens to have three fields storing three dimensions of each crown: Crown
(height in feet), Width
(diameter in feet from east to west), and Width
(diameter in feet from north to south). Since each of these values can be different, we'll see some tree crowns that more closely resemble their actual shape rather than perfect spheres.
const crownRenderer = {
type: "simple", // autocasts as new SimpleRenderer()
symbol: sym, // set from the code snippet in step 3
visualVariables: [
{
type: "size",
axis: "height", // specify which axis to apply the data values to
field: "Crown_Height",
valueUnit: "feet"
},
{
type: "size",
axis: "width", // specify which axis to apply the data values to
field: "Width_EW",
valueUnit: "feet"
},
{
type: "size",
axis: "depth", // specify which axis to apply the data values to
field: "Width_NS",
valueUnit: "feet"
}
]
};
3. Add a color visual variable to the renderer
Adding a color visual variable can add a nice thematic touch to the tree visualization. Since the service contains carbon storage data for each tree, we'll assign each tree crown a color ranging from pale yellow to a deeper green based on the amount of carbon storage measured at a particular point. This same concept is discussed in the Scale feature sizes based on real world sizes (2D) sample.
const visualVariables = crownRenderer.visualVariables.splice(0);
visualVariables.push({
type: "color",
field: "C_Storage", // Carbon storage
stops: [
{ value: 0, color: "#f7fcb9" }, // features with zero carbon
{ value: 10000, color: "#31a354" } // features with 8000 carbon
]
});
crownRenderer.visualVariables = visualVariables;
4. Apply the renderer to the layer
Once the renderer is defined, set it on the layer.
const treesLayer = new FeatureLayer({
url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Landscape_Trees/FeatureServer/0",
renderer: renderer, // set renderer on layer
outFields: ["*"],
popupTemplate: {
// autocasts as new PopupTemplate()
title: "{Cmn_Name}",
content:
"<i>{Sci_Name}</i><br>" +
"This tree is in {Condition} condition and is {Height} feet in height."
}
});
Once the renderer is defined, you can set it on the layer and the view will automatically update. Click the sandbox button below to see the full code of this app.
While the main purpose of this sample is to demonstrate how to scale the size of features based on their real-world sizes, it also demonstrates how to incorporate multivariate elements of thematic mapping through other visual means, such as color or various dimensions of size.
5. Additional visualization tutorials and samples
- Visualizing points with 3D symbols
- Visualize features with realistic WebStyleSymbols
- Scale feature sizes based on real world sizes (2D)
- Extrude building footprints based on real world heights
- Data-driven continuous color
- Data-driven continuous size
- Data-driven extrusion
- Thematic multivariate visualization (2D)
- Thematic multivariate visualization (3D)
- ArcGIS blog - Using attributes to represent real-world sizes of features