Skip to content

Show extruded graphics

View on GitHub

Extrude graphics based on an attribute value.

Image of Show extruded graphics sample

Use case

Graphics representing features can be vertically extruded to represent properties of the data that might otherwise go unseen. Extrusion can add visual prominence to data beyond what may be offered by varying the color, size, or shape of symbol alone. For example, graphics representing wind turbines in a wind farm application can be extruded by a real-world "height" attribute so that they can be visualized in a landscape. Likewise, census data can be extruded by a thematic "population" attribute to visually convey population levels across a country.

How to use the sample

Run the sample. Note that the graphics are extruded to the level set in their height property.

How it works

  1. Create a GraphicsOverlay and SimpleRenderer.
  2. Set the extrusion mode for the renderer with renderer.sceneProperties.extrusionMode = .baseHeight.
  3. Specify the attribute name of the graphic that the extrusion mode will use, RendererSceneProperties.extrusionExpression = "[height]".
  4. Set the renderer on the graphics overlay using, GraphicsOverlay.renderer = renderer.
  5. Create graphics with their attribute set, graphic.setAttributeValue(ZValue, forKey: "height").

Relevant API

  • RendererSceneProperties
  • RendererSceneProperties.ExtrusionMode
  • SimpleRenderer

About the data

Data is hard coded in this sample as a demonstration of how to create and set an attribute to a graphic. To extrude graphics based on pre-existing attributes (e.g. from a feature layer) see the "Show extruded features" sample.

Tags

3D, extrude, extrusion, height, scene, visualization

Sample Code

ShowExtrudedGraphicsView.swift
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright 2025 Esri
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import ArcGIS
import SwiftUI

struct ShowExtrudedGraphicsView: View {
    /// A scene with a topographic basemap style.
    @State private var scene: ArcGIS.Scene = {
        let scene = Scene(basemapStyle: .arcGISTopographic)
        // Creates the elevation source.
        let elevationSource = ArcGISTiledElevationSource(url: .worldElevationService)

        // Add the elevation source to the scene base surface.
        scene.baseSurface.addElevationSource(elevationSource)

        let camera = Camera(
            location: .initialLocation,
            heading: 10,
            pitch: 70,
            roll: 0
        )
        scene.initialViewpoint = Viewpoint(boundingGeometry: camera.location, camera: camera)

        return scene
    }()

    /// The scene view graphics overlay.
    @State private var graphicsOverlay: GraphicsOverlay = {
        // Create a graphics overlay.
        let graphicsOverlay = GraphicsOverlay()
        graphicsOverlay.sceneProperties.surfacePlacement = .drapedBillboarded

        // Create a renderer and set its extrusion properties.
        let renderer = SimpleRenderer()
        let lineSymbol = SimpleLineSymbol(style: .solid, color: .white, width: 1)
        renderer.symbol = SimpleFillSymbol(style: .solid, color: .red, outline: lineSymbol)
        renderer.sceneProperties.extrusionMode = .baseHeight
        renderer.sceneProperties.extrusionExpression = "[height]"
        graphicsOverlay.renderer = renderer

        return graphicsOverlay
    }()

    init() {
        addGraphics()
    }

    var body: some View {
        SceneView(scene: scene, graphicsOverlays: [graphicsOverlay])
    }

    /// Adds extruded polygon graphics the graphics overlays.
    private func addGraphics() {
        let x = Point.initialLocation.x - 0.01
        let y = Point.initialLocation.y + 0.25

        let spacing = 0.01

        for column in stride(from: 0, to: 6, by: 1.0) {
            for row in stride(from: 0, to: 4, by: 1.0) {
                let startingX: Double = x + column * (.squareSize + spacing)
                let startingY: Double = y + row * (.squareSize + spacing)
                let startingPoint = Point(x: startingX, y: startingY)
                let polygon = polygon(for: startingPoint)
                let graphic = extrudedGraphic(for: polygon)
                graphicsOverlay.addGraphic(graphic)
            }
        }
    }

    /// An extruded graphic created from a given polygon with a random height.
    /// - Parameter polygon: The polygon.
    /// - Returns: A graphic.
    private func extrudedGraphic(for polygon: ArcGIS.Polygon) -> Graphic {
        let maxHeight = 10_000
        let height = Int.random(in: 0...maxHeight)
        let graphic = Graphic(geometry: polygon)
        graphic.setAttributeValue(height, forKey: "height")
        return graphic
    }

    /// A square polygon created from a given point.
    /// - Parameter point: The point.
    /// - Returns: A polygon.
    private func polygon(for point: Point) -> ArcGIS.Polygon {
        let polygon = PolygonBuilder()
        polygon.add(Point(x: point.x, y: point.y))
        polygon.add(Point(x: point.x, y: point.y + .squareSize))
        polygon.add(Point(x: point.x + .squareSize, y: point.y + .squareSize))
        polygon.add(Point(x: point.x + .squareSize, y: point.y))
        return polygon.toGeometry()
    }
}

private extension Double {
    /// The square size of the extruded graphics.
    static var squareSize: Double { 0.01 }
}

private extension Point {
    /// The initial location.
    static var initialLocation: Point {
        Point(x: 83, y: 28.4, z: 20_000)
    }
}

private extension URL {
    /// The URL of the Terrain 3D ArcGIS REST Service.
    static var worldElevationService: URL {
        URL(string: "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer")!
    }
}

#Preview {
    ShowExtrudedGraphicsView()
}

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