Measure a distance in 3D

Learn how to evaluate the horizontal, vertical, and direct distances between two points in a 3D Scene.

measure a distance in 3d

A distance measurement analysis is a type of measurement analysis that calculates and displays the distance between start point and end point locations. The analysis evaluates the vertical, horizontal, and direct distances between the two 3D points and renders a measurement visualization on-screen.

In this tutorial you will perform and display a distance measurement analysis in a web scene. Using the distance measurement analysis you will measure distances between hotspots 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.

Develop or Download

You have two options for completing this tutorial:

  1. Option 1: Develop the code or
  2. Option 2: Download the completed solution

Option 1: Develop the code

To start the tutorial, complete the Display a web scene tutorial. This creates a scene to display the trails, trailheads, and parks in the Santa Monica Mountains.

Continue with the following instructions to evaluate the horizontal, vertical, and direct distances between two points in a 3D Scene.

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
    58 59 60 61 62 63 64 65 66 67
    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
        // 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)
        }()
    

Create a distance measurement analysis

Use a LocationDistanceMeasurement to perform and display a distance measurement analysis using 3D points to define the start and end locations.

  1. Create a private class named Model of type ObservableObject and an accompanying State Object reference in the ContentView struct. See the programming patterns page for more information on how to manage states.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    18 19 20 21 22 23 24 25 26
    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
    private class Model: ObservableObject {
    
    }
    
    struct ContentView: View {
    
        // An ObservableObject containing the scene, and analysis overlay.
        @StateObject private var model = Model()
    
    
    Expand
  2. Create an AnalysisOverlay named analysisOverlay to contain and display the distance measurement analyses.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    18 19 20 21 22 23
    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
    private class Model: ObservableObject {
    
        // The analysis overlay to be added to the scene.
        let analysisOverlay = AnalysisOverlay()
    
    }
    
    Expand
  3. Create a LocationDistanceMeasurement named measurement. Upon launch, the distance measurement visualization should not be visible.

    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
    private class Model: ObservableObject {
    
        // The analysis overlay to be added to the scene.
        let analysisOverlay = AnalysisOverlay()
    
        let measurement: LocationDistanceMeasurement = {
            let point = Point(x: -119.5968, y: 37.7567, z: 58.5011, spatialReference: .wgs84)
            let measurement = LocationDistanceMeasurement(startLocation: point, endLocation: point)
            measurement.isVisible = false
            measurement.unitSystem = .metric
            return measurement
        }()
    
    }
    
    Expand
  4. In init(), add the distance measurement to the analysis overlay.

    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
    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
    private class Model: ObservableObject {
    
        // The analysis overlay to be added to the scene.
        let analysisOverlay = AnalysisOverlay()
    
        let measurement: LocationDistanceMeasurement = {
            let point = Point(x: -119.5968, y: 37.7567, z: 58.5011, spatialReference: .wgs84)
            let measurement = LocationDistanceMeasurement(startLocation: point, endLocation: point)
            measurement.isVisible = false
            measurement.unitSystem = .metric
            return measurement
        }()
    
        init() {
            analysisOverlay.addAnalysis(measurement)
        }
    
        func moveDistanceMeasurement(point: Point) {
            if measurement.startLocation == measurement.endLocation {
                measurement.startLocation = point
            } else {
                measurement.endLocation = point
            }
            measurement.isVisible = true
        }
    
        func clearMeasurement() {
            measurement.isVisible = false
            let point = Point(x: 0, y: 0, z: 0, m: 0, spatialReference: .wgs84)
            measurement.startLocation = point
            measurement.endLocation = point
        }
    
    }
    
    Expand
  5. Define a method named moveDistanceMeasurement(point:) that receives a point as a parameter. This method is used to set the distance measurement analysis and make it visible, if it's not visible already.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    35 36 37 38 39 40 41 42 43
    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
        func moveDistanceMeasurement(point: Point) {
            if measurement.startLocation == measurement.endLocation {
                measurement.startLocation = point
            } else {
                measurement.endLocation = point
            }
            measurement.isVisible = true
        }
    
    
    Expand
  6. Define a private method named clearMeasurement(). This method is used to hide and clear the distance measurement analysis. Set the measurement's visibility to false and reset the start and end locations to allow new measurements.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
    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
        func moveDistanceMeasurement(point: Point) {
            if measurement.startLocation == measurement.endLocation {
                measurement.startLocation = point
            } else {
                measurement.endLocation = point
            }
            measurement.isVisible = true
        }
    
        func clearMeasurement() {
            measurement.isVisible = false
            let point = Point(x: 0, y: 0, z: 0, m: 0, spatialReference: .wgs84)
            measurement.startLocation = point
            measurement.endLocation = point
        }
    
    Expand

Display the distance measurement analysis with touch events

Touch events determine where to perform and display the distance measurement analysis. A user can tap to add start and end points or long-press and drag to move the distance measurement analysis' location around the screen.

  1. The first step to displaying the analyses is to add the analysis to the scene view. Modify the scene view to add the analysis overlay.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    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
    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
    struct ContentView: View {
    
        // An ObservableObject containing the scene, 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 {
            VStack {
    
                SceneView(scene: scene, analysisOverlays: [model.analysisOverlay])
    
            }
        }
    
    }
    
    Expand
  2. When a user performs a single touch or a long-press touch event, call moveDistanceMeasurement(point:).

    ContentView.swift
    Expand
    Use dark colors for code blocks
    69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
    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
        var body: some View {
            VStack {
    
                SceneView(scene: scene, analysisOverlays: [model.analysisOverlay])
    
                    .onSingleTapGesture { _, scenePoint in
                        guard let scenePoint else { return }
                        model.moveDistanceMeasurement(point: scenePoint)
                    }
                    .onLongPressGesture { _, scenePoint in
                        guard let scenePoint else { return }
                        model.moveDistanceMeasurement(point: scenePoint)
                    }
    
            }
        }
    
    Expand

Add a UI to control the distance measurement analysis

To control the distance measurement analysis, some UI is required.

  1. Add a toolbar and create a "Clear" button. The button hides and clears the distance measurement analysis from the scene. When the button is selected, call the ClearMeasurement method.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    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
    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
        var body: some View {
            VStack {
    
                SceneView(scene: scene, analysisOverlays: [model.analysisOverlay])
    
                    .onSingleTapGesture { _, scenePoint in
                        guard let scenePoint else { return }
                        model.moveDistanceMeasurement(point: scenePoint)
                    }
                    .onLongPressGesture { _, scenePoint in
                        guard let scenePoint else { return }
                        model.moveDistanceMeasurement(point: scenePoint)
                    }
    
                .toolbar {
                    ToolbarItemGroup(placement: .bottomBar) {
                        Button("Clear") {
                            // Resets the distance measurement.
                            model.clearMeasurement()
                        }
                    }
                }
    
            }
        }
    
    Expand

Format measurements for readability

Display the distance measurement results in a reader-friendly format.

  1. In the ContentView, add three @State variables to contain the text measurements.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
    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
        // 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)
        }()
    
        @State private var directDistanceText = "--"
        @State private var horizontalDistanceText = "--"
        @State private var verticalDistanceText = "--"
    
        var body: some View {
            VStack {
    
                SceneView(scene: scene, analysisOverlays: [model.analysisOverlay])
    
    Expand
  2. Create a private extension outside of the ContentView struct named FormatStyle. Create a variable named distance and set the format style to abbreviated, used as provided, and 2 decimal places.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    101 102 103 104 105 106
    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
    private extension FormatStyle where Self == Measurement<UnitLength>.FormatStyle {
        /// The format style for the distances.
        static var distance: Self {
            .measurement(width: .abbreviated, usage: .asProvided, numberFormatStyle: .number.precision(.fractionLength(2)))
        }
    }
  3. Add a task function to the SceneView that produces formatted measurements as the values change.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
    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
                SceneView(scene: scene, analysisOverlays: [model.analysisOverlay])
    
                    .onSingleTapGesture { _, scenePoint in
                        guard let scenePoint else { return }
                        model.moveDistanceMeasurement(point: scenePoint)
                    }
                    .onLongPressGesture { _, scenePoint in
                        guard let scenePoint else { return }
                        model.moveDistanceMeasurement(point: scenePoint)
                    }
    
                    .task {
                        for await measurements in model.measurement.measurements {
                            directDistanceText = measurements.directDistance.formatted(.distance)
                            horizontalDistanceText = measurements.horizontalDistance.formatted(.distance)
                            verticalDistanceText = measurements.verticalDistance.formatted(.distance)
                        }
                    }
    
    Expand
  4. Add text above the toolbar to display the measurements.

    ContentView.swift
    Expand
    Use dark colors for code blocks
    95 96 97 98 99 100 101 102 103 104 105 106 107
    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
                Text("Direct: \(directDistanceText)")
                Text("Horizontal: \(horizontalDistanceText)")
                Text("Vertical: \(verticalDistanceText)")
                Spacer()
    
                .toolbar {
                    ToolbarItemGroup(placement: .bottomBar) {
                        Button("Clear") {
                            // Resets the distance measurement.
                            model.clearMeasurement()
                        }
                    }
                }
    
    Expand
  5. In the Project Navigator, click MainApp.swift. Change the ignoresSafeArea(_:edges:) method to specify the top edge. This will make the text visible.

    MainApp.swift
    Use dark colors for code blocks
    58 59 60 61 62 63 64 65
    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
        var body: some SwiftUI.Scene {
            WindowGroup {
                ContentView()
    
                    .ignoresSafeArea(edges: .top)
    
            }
        }
    

Run the app

Press Command + R to run the app.

You should see a scene of hotspots in the Yosemite Valley. Tap to set start and end locations. Long-press and drag to display and move a distance measurement analysis to evaluate the horizontal, vertical, and direct distances between two park locations.

Alternatively, you can download the tutorial solution, as follows.

Option 2: Download the solution

  1. Click the Download solution link under Solution and unzip the file to a location on your machine.

  2. Open the .xcodeproj file in Xcode.

Since the downloaded solution does not contain authentication credentials, you must first set up authentication to create credentials, and then add the developer credentials to the solution.

Set up authentication

To access the secure ArcGIS location services used in this tutorial, you must implement API key authentication or user authentication using an ArcGIS Location Platform or an ArcGIS Online account.

Create a new API key access token with privileges to access the secure resources used in this tutorial.

  1. Complete the Create an API key tutorial and create an API key with the following privilege(s):

    • Privileges
      • Location services > Basemaps
  2. Copy and paste the API key access token into a safe location. It will be used in a later step.

Set developer credentials in the solution

To allow your app users to access ArcGIS location services, use the developer credentials that you created in the Set up authentication step to authenticate requests for resources.

Pass your API Key access token to the ArcGISEnvironment.

  1. In the Project Navigator, click MainApp.swift.

  2. Set the AuthenticationMode to .apiKey.

    MainApp.swift
    Use dark colors for code blocks
    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
        // Change the `AuthenticationMode` to `.apiKey` if your application uses API key authentication.
    
        private var authenticationMode: AuthenticationMode { .apiKey }
    
    
  3. Set the apiKey property with your API key access token.

    MainApp.swift
    Expand
    Use dark colors for code blocks
    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
        // Please enter an API key access token if your application uses API key authentication.
    
        private let apiKey = APIKey("<#YOUR-ACCESS-TOKEN#>")
    
    
    Expand

Best Practice: The access token is stored directly in the code as a convenience for this tutorial. Do not store credentials directly in source code in a production environment.

Run the solution

Press Command + R to run the app.

You should see a scene of hotspots in the Yosemite Valley. Tap to set start and end locations. Long-press and drag to display and move a distance measurement analysis to evaluate the horizontal, vertical, and direct distances between two park locations.

What's next?

Learn how to use additional API features, ArcGIS location services, and ArcGIS tools in these tutorials:

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