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 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 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
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 a graphics overlay to the scene view
let graphicsOverlay = AGSGraphicsOverlay()
sceneView.graphicsOverlays.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 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

var drapedGraphicsOverlay: AGSGraphicsOverlay!
var absoluteGraphicsOverlay: AGSGraphicsOverlay!
var relativeGraphicsOverlay: AGSGraphicsOverlay!
// create a draped graphics overlay
drapedGraphicsOverlay = AGSGraphicsOverlay()
drapedGraphicsOverlay.sceneProperties?.surfacePlacement = AGSSurfacePlacement.draped
sceneView.graphicsOverlays.add(drapedGraphicsOverlay)
// create a absolute graphics overlay
absoluteGraphicsOverlay = AGSGraphicsOverlay()
absoluteGraphicsOverlay.sceneProperties?.surfacePlacement = AGSSurfacePlacement.absolute
sceneView.graphicsOverlays.add(absoluteGraphicsOverlay)
// create a relative graphics overlay
relativeGraphicsOverlay = AGSGraphicsOverlay()
relativeGraphicsOverlay.sceneProperties?.surfacePlacement = AGSSurfacePlacement.relative
sceneView.graphicsOverlays.add(relativeGraphicsOverlay)
//create a point and marker symbols
let point = AGSPointMake3D(-4.04, 53.06, 1000, 0, sceneView.spatialReference)
let redMarker = AGSSimpleMarkerSymbol(style: .circle, color: .red, size: 10)
let blueMarker = AGSSimpleMarkerSymbol(style: .circle, color: .blue, size: 10)
let greenMarker = AGSSimpleMarkerSymbol(style: .circle, color: .green, size: 10)
//create the graphics
let drapedGraphic = AGSGraphic(geometry: point, symbol: redMarker)
let absoluteGraphic = AGSGraphic(geometry: point, symbol: blueMarker)
let relativeGraphic = AGSGraphic(geometry: point, symbol: greenMarker)
//add the graphics in the overlays
drapedGraphicsOverlay.graphics.add(drapedGraphic)
absoluteGraphicsOverlay.graphics.add(absoluteGraphic)
relativeGraphicsOverlay.graphics.add(relativeGraphic)
//set the camera to look at the points
let camera = AGSCamera(latitude: 53.02, longitude: -4.04, altitude: 1600, heading: 0, pitch: 70, roll: 0)
sceneView.setViewpointCamera(camera)
sceneView.currentViewpointCamera()

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 DYNAMICmode
  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

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

// define fill and outline for symbol       
let line = AGSSimpleLineSymbol(style: .Solid, color: blackColor, width: 1)
let fill = AGSSimpleFillSymbol(style: .Solid, color: greenColor, outline: line)

// create a simple renderer
let renderer = AGSSimpleRenderer(symbol: fill)
 
// define the extrusion mode and expression       
renderer.sceneProperties?.extrusionMode = .AbsoluteHeight
renderer.sceneProperties?.extrusionExpression = "pop2000"
        
graphicsOverlay.renderer(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 the plane rotation
let renderer = AGSSimpleRenderer(symbol: coneSymbol)
renderer.rotationType = .geographic
renderer.sceneProperties?.headingExpression = "heading"
renderer.sceneProperties?.pitchExpression = "pitch"
renderer.sceneProperties?.rollExpression = "roll"
self.graphicsOverlay.renderer = renderer

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.

//create a sphere symbol
let sphereSymbol = AGSSimpleMarkerSceneSymbol(style: .sphere, color: .red, height: 1000, width: 1000, depth: 1000, anchorPosition: .center)
//create a point
let point = AGSPointMake3D(-4.04, 53.16, 1000, 0, self.sceneView.spatialReference)
//create a graohic
let graphic = AGSGraphic(geometry: point, symbol: sphereSymbol)
//add the graphic to the relative graphics overlay
relativeGraphicsOverlay.graphics.add(graphic)

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.

modelSymbol = AGSModelSceneSymbol(url: filePathURL, scale: 3000)
modelSymbol.load(completion: { [weak self] (error) in
    if let error = error {
        print(error)
        return
    }
    let modelPoint = AGSPointMake3D(-4.04, 53.16, 5000, 0, self?.sceneView.spatialReference)
    let modelGraphic = AGSGraphic(geometry: modelPoint, symbol: self?.modelSymbol, attributes: nil)
    self?.graphicsOverlay.graphics.add(modelGraphic)
})

Note:
When you add a model symbol file of type .dae into your project you must ensure that the file is of type Data. For each file in your project go to the File Inspector. Find the Type property and change it from Default = Digital Asset Exchange to Data. This will ensure that Xcode does not compress the file and it will be read correctly.

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

modelSymbol = AGSModelSceneSymbol(url: filePathURL, scale: 100)
modelSymbol.load(completion: { [weak self] (error) in
    if let error = error {
        print(error)
        return
    }
    //create a cone symbol for medium range viewing
    let coneSymbol = AGSSimpleMarkerSceneSymbol(style: .cone, color: .red, height: 1000, width: 500, depth: 500, anchorPosition: .center)
    coneSymbol.pitch = 90
    //create a simple marker symbol for far range viewing
    let pointSymbol = AGSSimpleMarkerSymbol(style: .circle, color: .red, size: 20)
    //create a distance composite symbol with viewing ranges for each symbol
    let compositeSymbol = AGSDistanceCompositeSceneSymbol()
    compositeSymbol.ranges.append(AGSDistanceSymbolRange(symbol: self!.modelSymbol, minDistance: 0, maxDistance: 25000))
    compositeSymbol.ranges.append(AGSDistanceSymbolRange(symbol: coneSymbol, minDistance: 25000, maxDistance: 100000))
    compositeSymbol.ranges.append(AGSDistanceSymbolRange(symbol: pointSymbol, minDistance: 100000, maxDistance: 0))
    //display the aircraft with a composite symbol
    let aircraftPoint = AGSPointMake3D(-4.04, 53.16, 10000, 0, self?.sceneView.spatialReference)
    let aircraftGraphic = AGSGraphic(geometry: aircraftPoint, symbol: compositeSymbol)
    self?.graphicsOverlay.graphics.add(aircraftGraphic)
})