Display a line of sight

Learn how to perform and display a line of sight analysis in a 3D scene.

display a line of sight

A line of sight analysis is a type of visibility analysis that calculates visibility (visible or obstructed) between a designated observer and target. It calculates whether the target is visible to the observer based on the environment and renders a line indicating visibility on the map.

In this tutorial, you will perform and display a line of sight analysis in a web scene. Your line of sight analysis will show which targets (hot spots) are visible, based on the terrain, from specified observation points in the Yosemite Valley.

Prerequisites

Before starting this tutorial:

  1. You need an ArcGIS Location Platform or ArcGIS Online account.

  2. Your system meets the system requirements.

Steps

Open the Xcode project

  1. To start this tutorial, first complete the Display a web scene tutorial or download and unzip the solution.

  2. Open the .xcodeproj file in Xcode.

  3. If you downloaded the solution, get an access token and set the API key.

Get the web scene item ID

You can use ArcGIS tools to create and view web scenes. Use the Scene Viewer to identify the web scene item ID. This item ID will be used later in the tutorial.

  1. Go to the Yosemite Valley Hotspots web scene in the Scene Viewer in ArcGIS Online. This web scene displays terrain and hotspots in the Yosemite Valley.
  2. Make a note of the item ID at the end of the browser's URL. The item ID should be 7558ee942b2547019f66885c44d4f0b1.

Update the scene

  1. In Xcode, in the Project Navigator, click ContentView.swift.

  2. In the editor, modify the scene variable to create a Scene for the web scene. To do this, create a portal item providing the web scene's item ID and a Portal referencing ArcGIS Online.

    ContentView.swift
    Use dark colors for code blocks
    105 106 107 108 109 110 111 112 113 114
    Change lineChange lineChange lineChange line
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
        // The Yosemite Valley hotspots scene.
        @State private var scene: ArcGIS.Scene = {
    
            let portalItem = PortalItem(
                portal: .arcGISOnline(connection: .anonymous),
                id: Item.ID("7558ee942b2547019f66885c44d4f0b1")!
            )
    
            return Scene(item: portalItem)
        }()
    

Set observer and target symbols

Your app will use graphics to depict the locations of the analyses observer and targets.

  1. Create a private class named Model of type ObservableObject. See the programming patterns page for more information on how to manage states.

  2. Create a GraphicsOverlay named graphicsOverlay and set some of its properties to display the observer and targets graphics.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    18 19 20 21 22 23 24 25 26 27 28 29 30 31
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
    private class Model: ObservableObject {
        // MARK: Graphics
    
        // The graphics overlay to add graphics to.
        let graphicsOverlay: GraphicsOverlay = {
            let graphicsOverlay = GraphicsOverlay()
            graphicsOverlay.sceneProperties.surfacePlacement = .absolute
            graphicsOverlay.sceneProperties.altitudeOffset = 5
            return graphicsOverlay
        }()
    
    
    
    }
    
    Expand
  3. Create a private Symbol named observerSymbol with a black fill color and white outline. Create another private symbol named targetSymbol with a white fill color and black outline. These symbols are used to depict the location of the line of sight analyses observer and target respectively. Both symbols will be used to make graphics when the locations are determined.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    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
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
    private class Model: ObservableObject {
        // MARK: Graphics
    
        // The graphics overlay to add graphics to.
        let graphicsOverlay: GraphicsOverlay = {
            let graphicsOverlay = GraphicsOverlay()
            graphicsOverlay.sceneProperties.surfacePlacement = .absolute
            graphicsOverlay.sceneProperties.altitudeOffset = 5
            return graphicsOverlay
        }()
    
        // The symbol to indicate the observer.
        private let observerSymbol: Symbol = {
            let symbol = SimpleMarkerSymbol(
                style: .circle,
                color: .black,
                size: 20
            )
            symbol.outline = SimpleLineSymbol(
                style: .solid,
                color: .white,
                width: 2
            )
            return symbol
        }()
    
        // The symbol to indicate the target.
        private var targetSymbol: Symbol = {
            let symbol = SimpleMarkerSymbol(
                style: .circle,
                color: .white,
                size: 20
            )
            symbol.outline = SimpleLineSymbol(
                style: .solid,
                color: .black,
                width: 2
            )
            return symbol
        }()
    
    
    
    }
    
    Expand

Create line of sight analyses

Visual analyses help you make sense of complex 3D data contained by a scene. Use a LocationLineOfSight to perform and display a line of sight analysis using observer and target locations.

  1. Create an AnalysisOverlay named analysisOverlay to contain and display the line of sight analyses.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    61 62 63 64
    Add line.Add line.Add line.
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
        // MARK: Analysis
        // The analysis overlay to be added to the scene.
        let analysisOverlay = AnalysisOverlay()
    
    
    Expand
  2. Create a private variable named observerLocation of type Point.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    61 62 63 64 65 66 67
    Add line.Add line.
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
        // MARK: Analysis
        // The analysis overlay to be added to the scene.
        let analysisOverlay = AnalysisOverlay()
    
        // The location of the observer.
        private var observerLocation: Point?
    
    
    Expand
  3. Define a private method named createLineOfSight(scenePoint:) that accepts a Point as a parameter. This method creates a LocationLineOfSight analysis, adds it to the scene view analysis overlay, and adds the observer and target graphics to the graphics overlay.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    61 62 63 64 65 66 67 68 69 70 71 72
    Add line.Add line.Add line.Add line.
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
        // MARK: Analysis
        // The analysis overlay to be added to the scene.
        let analysisOverlay = AnalysisOverlay()
    
        // The location of the observer.
        private var observerLocation: Point?
    
        // Creates the line of sight with the scene point.
        func createLineOfSight(scenePoint: Point) {
    
        }
    
    
    Expand
  4. If the observerLocation has no value, set it equal to scenePoint. Create and display a graphic for the observer using the observer symbol previously created.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
        // MARK: Analysis
        // The analysis overlay to be added to the scene.
        let analysisOverlay = AnalysisOverlay()
    
        // The location of the observer.
        private var observerLocation: Point?
    
        // Creates the line of sight with the scene point.
        func createLineOfSight(scenePoint: Point) {
    
            if observerLocation == nil {
                // Updates the observer location.
                observerLocation = scenePoint
                // Adds the observer graphic to the graphics overlay.
                let observerGraphic = Graphic(geometry: scenePoint, symbol: observerSymbol)
                graphicsOverlay.addGraphic(observerGraphic)
            }
    
        }
    
    
    Expand
  5. If observerLocation has a value, create a new LocationLineOfSight analysis using the observerLocation and scenePoint. Add the line of sight analysis to the analysis overlay using addAnalysis(_:). Create the target graphic and add it to the graphics overlay to show the target point.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
        // Creates the line of sight with the scene point.
        func createLineOfSight(scenePoint: Point) {
    
            if observerLocation == nil {
                // Updates the observer location.
                observerLocation = scenePoint
                // Adds the observer graphic to the graphics overlay.
                let observerGraphic = Graphic(geometry: scenePoint, symbol: observerSymbol)
                graphicsOverlay.addGraphic(observerGraphic)
            }
    
            else if let observerLocation {
                // Creates and sets the line of sight analysis with the tapped scene point.
                let lineOfSight = LocationLineOfSight(observerLocation: observerLocation, targetLocation: scenePoint)
                // Adds the line of sight to the analysis overlay.
                analysisOverlay.addAnalysis(lineOfSight)
                // Creates a target graphic and adds it to the graphics overlay.
                let targetGraphic = Graphic(geometry: scenePoint, symbol: targetSymbol)
                graphicsOverlay.addGraphic(targetGraphic)
            }
    
        }
    
    Expand
  6. Define a private method named clearAnalyses() to remove all line of sight analyses from the scene view, remove all graphics from the graphics overlay, and set the lineOfSight variable to nil.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
    Add line.Add line.Add line.Add line.Add line.Add line.
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
            else if let observerLocation {
                // Creates and sets the line of sight analysis with the tapped scene point.
                let lineOfSight = LocationLineOfSight(observerLocation: observerLocation, targetLocation: scenePoint)
                // Adds the line of sight to the analysis overlay.
                analysisOverlay.addAnalysis(lineOfSight)
                // Creates a target graphic and adds it to the graphics overlay.
                let targetGraphic = Graphic(geometry: scenePoint, symbol: targetSymbol)
                graphicsOverlay.addGraphic(targetGraphic)
            }
    
        }
    
        // Resets the observer location and clears all graphics and analyses.
        func clearAnalyses() {
            analysisOverlay.removeAllAnalyses()
            graphicsOverlay.removeAllGraphics()
            observerLocation = nil
        }
    
    Expand

Display the line of sight analyses with touch events

Touch events determine where to place the observer and targets as well as display line of sight analyses. A user taps to place targets and then long-press and drags to place the observer and display line of sight analyses.

  1. The first step to displaying the analyses and graphics is to add the analysis and graphics overlays to the scene view. In the ContentView struct, create a variable of type Model with a @StateObject property wrapper and add the overlays to the scene view.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
    Add line.Add line.Change line
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
    struct ContentView: View {
    
        // An ObservableObject containing the scene, graphics overlay, and analysis overlay.
        @StateObject private var model = Model()
    
        // The Yosemite Valley hotspots scene.
        @State private var scene: ArcGIS.Scene = {
    
            let portalItem = PortalItem(
                portal: .arcGISOnline(connection: .anonymous),
                id: Item.ID("7558ee942b2547019f66885c44d4f0b1")!
            )
    
            return Scene(item: portalItem)
        }()
    
        var body: some View {
    
            SceneView(scene: scene, graphicsOverlays: [model.graphicsOverlay], analysisOverlays: [model.analysisOverlay])
    
        }
    
    }
  2. To add a new line of sight with each tap, add the onSingleTapGesture(perform:) method to the SceneView. In the closure, call the previously created createLineOfSight(scenePoint:) method, passing in the scenePoint.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    116 117 118 119 120 121 122 123 124 125 126
    Add line.Add line.Add line.Add line.Add line.
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
        var body: some View {
    
            SceneView(scene: scene, graphicsOverlays: [model.graphicsOverlay], analysisOverlays: [model.analysisOverlay])
    
                .onSingleTapGesture { _, scenePoint in
                    // Places an observer point upon single touch.
                    guard let scenePoint else { return }
                    model.createLineOfSight(scenePoint: scenePoint)
                }
    
        }
    
    Expand

Add a UI to control the line of sight analyses

To control the line of sight analyses, some UI is required.

  1. Lastly, create a toolbar and add a "Clear" button to reset the analysis and graphics overlays. The "Clear" button calls the previously created clearAnalyses() method. This will allow users a fresh start to make more analyses.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
        var body: some View {
    
            SceneView(scene: scene, graphicsOverlays: [model.graphicsOverlay], analysisOverlays: [model.analysisOverlay])
    
                .onSingleTapGesture { _, scenePoint in
                    // Places an observer point upon single touch.
                    guard let scenePoint else { return }
                    model.createLineOfSight(scenePoint: scenePoint)
                }
    
                .toolbar {
                    ToolbarItemGroup(placement: .bottomBar) {
                        Button("Clear") {
                            // Resets the line of sight.
                            model.clearAnalyses()
                        }
                    }
                }
    
        }
    
    Expand

Run the app

Press Command + R to run the app.

You should see a scene of hotspots in the Yosemite Valley. Long-press and drag to set the location of the observer and tap to add target locations. The application performs and displays line of sight analyses between the observer and its targets.

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