Add features and graphics to a scene view

Add features to a scene view when you want to:

  • Display data with a common attribute schema (for example, census data)
  • Display geographical data of a common geometry type (point, line, or polygon)
  • Persist or store the data beyond the current app session

Add graphics to a scene view when:

  • You want to display temporary data, such as fast-changing, fast-moving data (for example, a fleet of airliners, or voluminous data.
  • You want to display data that doesn't share a common geometry type (such as point, line, or polygon) and doesn't share a common set of attribute fields
  • The data is required only for the current app session

Both features and graphics can be:

The way you add features and graphics to scenes follows the same steps required to add them to maps, with these additional considerations:

Add features to a scene view

Feature layers can contain any number of features of a single geometry type (point, polyline or polygon). Adding features to a scenes is the same as adding features to a map:

  1. Add features to a feature layer
  2. If you want to include features' attributes (to run queries, for example), make sure to use LOAD_ALL if building your feature layer from a service feature table
  3. Add the feature layer to the scene's operational layers

// add feature layer(s)
final FeatureLayer featureLayer = new FeatureLayer(serviceFeatureTable);
// load all attributes in the service feature table
final QueryParameters queryParams = new QueryParameters();
queryParams.setWhereClause("1=1");
serviceFeatureTable.queryFeaturesAsync(queryParams, ServiceFeatureTable.QueryFeatureFields.LOAD_ALL);
// add the feature layer to the scene
scene.getOperationalLayers().add(featureLayer);

Add graphics to a scene view

Adding graphics to scenes is the same as adding graphics to maps:

  1. Add graphics to a graphics overlay
  2. Set the graphic overlays surface placement, if you prefer a surface placement other than the default DRAPED
  3. Add the graphics overlay to the scene view's graphic overlays
Note:

Any graphic you add to a scene view must be constructed from a geometry with a spatial reference.

In 3D, you can add graphics such as points, polylines, polygons, and 3D marker symbols, all into the same graphics overlay or into multiple graphics overlays.

For additional details on adding graphic overlays to a map or scene, see Add graphic overlays to your app. For details on adding graphics to a graphics overlay, see Add graphics and text to graphics overlays.

// add graphics overlay(s)
GraphicsOverlay graphicsOverlay = new GraphicsOverlay();
graphicsOverlay.getSceneProperties().setSurfacePlacement(LayerSceneProperties.SurfacePlacement.ABSOLUTE);
sceneView.getGraphicsOverlays().add(graphicsOverlay);

Surface placement modes

For both feature layers and graphics overlays, you can specify a surface placement mode or use the default mode of DRAPED. These modes control how the z-value of your geometry is used when features and graphics are drawn.

  • DRAPED—(default) Features and graphics are drawn on the surface. The z-value has no effect.
  • ABSOLUTE—Features and graphics are drawn at a height using the z-value referenced from above the globe skin (sea level).
  • RELATIVE—Features and graphics are drawn at a height using the z-value referenced from above the surface layer.

The following code shows the same data loaded into three different feature layers with different surface placement modes.

// create overlays with elevation modes

FeatureLayer drapedFeatureLayer = featureLayer.copy();
// feature layers are set to SurfacePlacement.DRAPED by default, though it can be set explicitly as below:
drapedFeatureLayer.getSceneProperties().setSurfacePlacement(LayerSceneProperties.SurfacePlacement.DRAPED);
scene.getOperationalLayers().add(drapedFeatureLayer);

FeatureLayer relativeFeatureLayer = featureLayer.copy();
drapedFeatureLayer.getSceneProperties().setSurfacePlacement(LayerSceneProperties.SurfacePlacement.RELATIVE);
scene.getOperationalLayers().add(relativeFeatureLayer);

FeatureLayer absoluteFeatureLayer = featureLayer.copy();
absoluteFeatureLayer.getSceneProperties()
    .setSurfacePlacement(LayerSceneProperties.SurfacePlacement.ABSOLUTE);
scene.getOperationalLayers().add(absoluteFeatureLayer);

The following code shows three points drawn in graphics overlays in the three different surface placement modes. The red graphic is draped on the surface, the blue graphic is drawn in absolute mode, and the green in relative mode

// create overlays with elevation modes
GraphicsOverlay drapedOverlay = new GraphicsOverlay();
drapedOverlay.getSceneProperties().setSurfacePlacement(SurfacePlacement.DRAPED);
sceneView.getGraphicsOverlays().add(drapedOverlay);
GraphicsOverlay relativeOverlay = new GraphicsOverlay();
relativeOverlay.getSceneProperties().setSurfacePlacement(SurfacePlacement.RELATIVE);
sceneView.getGraphicsOverlays().add(relativeOverlay);
GraphicsOverlay absoluteOverlay = new GraphicsOverlay();
absoluteOverlay.getSceneProperties().setSurfacePlacement(SurfacePlacement.ABSOLUTE);
sceneView.getGraphicsOverlays().add(absoluteOverlay);


// create a text symbol for each elevation mode
TextSymbol drapedText = new TextSymbol(10, "DRAPED", 0xFFFFFFFF, HorizontalAlignment.LEFT,
  VerticalAlignment.MIDDLE);
TextSymbol relativeText = new TextSymbol(10, "RELATIVE", 0xFFFFFFFF, HorizontalAlignment.LEFT,
  VerticalAlignment.MIDDLE);
TextSymbol absoluteText = new TextSymbol(10, "ABSOLUTE", 0xFFFFFFFF, HorizontalAlignment.LEFT,
  VerticalAlignment.MIDDLE);


// create point for graphic location
Point point = new Point(-4.04, 53.06, 1000, sceneView.getSpatialReference());
SimpleMarkerSymbol redSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, 0xFFFF0000, 10);
SimpleMarkerSymbol greenSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, 0xFF00FF00, 10);
SimpleMarkerSymbol blueSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, 0xFF0000FF, 10);


// add the point graphic and text graphic to the corresponding graphics
// overlay
drapedOverlay.getGraphics().add(new Graphic(point, redSymbol));
drapedOverlay.getGraphics().add(new Graphic(point, drapedText));


relativeOverlay.getGraphics().add(new Graphic(point, greenSymbol));
relativeOverlay.getGraphics().add(new Graphic(point, relativeText));


absoluteOverlay.getGraphics().add(new Graphic(point, blueSymbol));
absoluteOverlay.getGraphics().add(new Graphic(point, absoluteText));

Graphics rendered at different heights, despite all having the same z-value.

Graphics drawn with different surface placement options

Renderers: Controlling symbology with attributes

Just as in 2D, both feature layers and graphic overlays can use various renderers, such as simple renderers and unique value renderers, to control symbology with attributes. For details, see Symbols and renderers.

When using renderers in 3D, you can set properties to define extrusion expressions for both features and graphics. However, only graphics can have rotation expressions.

To apply extrusion to a feature layer:

  1. Set the feature layer to rendering in DYNAMIC mode
  2. Define a renderer which will be used to render the feature layer
  3. Set the renderer's scene property extrusion mode
  4. Set the renderer's scene property extrusion expression
  5. Set the renderer to the feature layer
  6. Add the feature layer to the scene

// set the feature layer to render dynamically to allow extrusion
featureLayer.setRenderingMode(FeatureLayer.RenderingMode.DYNAMIC);

// define line and fill symbols for a simple renderer
SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLACK, 1.0f);
SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, Color.BLUE, lineSymbol);
final SimpleRenderer renderer = new SimpleRenderer(fillSymbol);

// set renderer extrusion mode to base height, which includes base height of each vertex in calculating z values
renderer.getSceneProperties().setExtrusionMode(Renderer.SceneProperties.ExtrusionMode.BASE_HEIGHT);
// set the attribute used for extrusion (if, for example, the feature layer has an attribute called 'pop2000')
renderer.getSceneProperties().setExtrusionExpression("[pop2000]");

// set the simple renderer to the feature layer
featureLayer.setRenderer(renderer);

// add the feature layer to the scene
scene.getOperationalLayers().add(featureLayer);

Extrusion can also be applied to graphics overlays:

  1. Define a renderer which will be used to render the graphics overlay
  2. Set the renderer's scene property extrusion mode
  3. Set the renderer's scene property extrusion expression
  4. Set the renderer to the graphics overlay

// set renderer with extrusion property
SimpleRenderer renderer = new SimpleRenderer();
SceneProperties renderProperties = renderer.getSceneProperties();
renderProperties.setExtrusionMode(SceneProperties.ExtrusionMode.BASE_HEIGHT);
renderProperties.setExtrusionExpression("[HEIGHT]");
graphicsOverlay.setRenderer(renderer);

In the image below, a graphic overlay is being extruded based on a population attribute: pop2000.

County polygons extruded on population

Only graphics overlays can have rotation expressions--used to change the heading, pitch and roll of the graphics in the graphics overlay. To set rotation expressions:

  1. Define a renderer which will be used to render the graphics overlay
  2. Set the rotation type
  3. Set the renderer's scene property heading expression
  4. Set the renderer's scene property pitch expression
  5. Set the renderer's scene property roll expression
  6. Set the renderer to the graphics overlay

// create renderer to handle updating plane rotation using the GPU
SimpleRenderer renderer3D = new SimpleRenderer();
renderer3D.setRotationType(RotationType.GEOGRAPHIC);
Renderer.SceneProperties renderProperties = renderer3D.getSceneProperties();
renderProperties.setHeadingExpression("[HEADING]");
renderProperties.setPitchExpression("[PITCH]");
renderProperties.setRollExpression("[ROLL]");
graphicsOverlay.setRenderer(renderer3D);

3D-specific symbols for graphics

Graphics in a 3D graphics overlay can use any of the symbols discussed in Add graphics and text to graphics overlays. You can also add:

3D symbols

Add shape-based symbols

3D shapes, such as a cone, floating on the earth's surface.

The following code snippet shows how to create a sphere symbol and render it using a point geometry in a graphic.

// sphere symbol
SimpleMarkerSceneSymbol sphere = new SimpleMarkerSceneSymbol(SimpleMarkerSceneSymbol.Style.SPHERE, 0xCC880000, 3000,
  3000, 3000, SceneSymbol.AnchorPosition.CENTER);


// sphere point
Point spherePoint = new Point(-4.04, 53.16, 1000);


// add graphic
Graphic sphereGraphic = new Graphic(spherePoint, sphere);
graphicsOverlay.getGraphics().add(sphereGraphic);

Add model symbols

A model symbol provides a realistic three-dimensional visualization to symbolize scene features. These models define the geometry and surface textures of real-world items such as aircraft. Create a ModelMarkerSymbol using a 3D model file, passing the path to the file and a scale factor to the model symbol constructor. The supported model file types include Collada (.dae), 3D Max (.3ds), Blender 3d (.blend), and the formats listed in the Open Asset Import Library (Assimp). Depending on the model file's default orientation, you may have to rotate the symbol to get your model in the desired orientation.

Model symbol representing a helicopter

Create these model symbols using the ModelSceneSymbol class.

// load the plane's 3D model symbol
String modelURI = new File("path/to/folder", "file.dae").getAbsolutePath();
ModelSceneSymbol plane3DSymbol = new ModelSceneSymbol(modelURI, scaleOfPlane);
plane3DSymbol.loadAsync();


// create the graphic
graphicsOverlay.getGraphics().add(new Graphic(new Point(0, 0, 0, SpatialReferences.getWgs84()), plane3DSymbol));

Distance composite symbols

While model symbols closely resemble the real-world object they represent when viewed close up, when you zoom away from them, the symbols gets smaller until they're no longer visible. If you want to see the location of your graphics at any distance from the camera, use distance composite symbols. These symbols allow you to use different symbols depending on the distance the graphic is from the camera.

The code snippet below the following images shows how to set up a distance composite symbol similar to the one shown in the images.

When the camera is far away from the point, a red simple marker symbol displays.

A simple point is displayed when the camera is far away

As you zoom closer to the point, the symbol renders as a cone pointing in the aircraft's direction of travel.

A cone symbol shows heading at intermediate camera distance

When viewed even closer, the point displays as a model symbol, which is appropriate at this distance from the camera.

A model symbol displays at the nearest camera distance

// set up the different symbols
int red = 0xFFFF0000;
SimpleMarkerSymbol circleSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, red, 10);
SimpleMarkerSceneSymbol coneSymbol = SimpleMarkerSceneSymbol.createCone(red, 10, 10);
coneSymbol.setPitch(-90);
String modelURI = new File("path/to/file.dae").getAbsolutePath();
ModelSceneSymbol modelSymbol = new ModelSceneSymbol(modelURI, 1.0);
modelSymbol.loadAsync();


// set up the distance composite symbol
DistanceCompositeSceneSymbol compositeSymbol = new DistanceCompositeSceneSymbol();
compositeSymbol.getRangeCollection().add(new DistanceCompositeSceneSymbol.Range(modelSymbol, 0, 100));
compositeSymbol.getRangeCollection().add(new DistanceCompositeSceneSymbol.Range(coneSymbol, 100, 1000));
compositeSymbol.getRangeCollection().add(new DistanceCompositeSceneSymbol.Range(circleSymbol, 1000, 0));


// create graphic
Point aircraftPosition = new Point(-2.708471, 56.096575, 5000, SpatialReferences.getWgs84());
Graphic aircraftGraphic = new Graphic(aircraftPosition, compositeSymbol);
// add graphic to graphics overlay
graphicsOverlay.getGraphics().add(aircraftGraphic);