Learn how to perform and display a viewshed analysis in a 3D scene.
Viewshed analysis determines the visibility of terrain, buildings, and other 3D objects from an observer's location within a scene (using a specified field of view). The result indicates which areas are visible and which are obstructed when viewed from the observer's perspective.
In this tutorial, you will perform and display a viewshed analysis in a web scene. Your viewshed analysis will show visibility (visible or obstructed) and can be used to determine which hotspots in the Yosemite Valley are visible from a specified observer's perspective.
Prerequisites The following are required for this tutorial:
An ArcGIS account to access your API keys . If you don't have an account, sign up for free . Your system meets the system requirements . Steps Open the Xcode project To start this tutorial, first complete the Display a web scene tutorial or download and unzip the solution.
Open the .xcodeproj
file in Xcode .
If you downloaded the solution project, set your API key.
More info An API Key enables access to services , web maps , and web scenes hosted in ArcGIS Online .
Go to your developer dashboard to get your API key .
For these tutorials, use your default API key. It is scoped to include all of the services demonstrated in the tutorials.
In Xcode , in the Project Navigator , click AppDelegate.swift .
In the editor , set the APIKey
property on the AGSArcGISRuntime Environment
with your API key .
AppDelegate.swift
Expand
Use dark colors for code blocks
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
func application ( _ application : UIApplication ,
didFinishLaunchingWithOptions launchOptions : [ UIApplication . LaunchOptionsKey : Any ] ? ) -> Bool {
// Note: it is not best practice to store API keys in source code.
// The API key is referenced here for the convenience of this tutorial.
AGSArcGISRuntimeEnvironment .apiKey = "YOUR_API_KEY"
return true
}
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.
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. Make a note of the item ID at the end of the browser's URL. The item ID should be 7558ee942b2547019f66885c44d4f0b1 Update the scene In Xcode , in the Project Navigator , click ViewController.swift .
In the editor , modify the setup Scene()
method to create an AGSScene
for the web scene. To do this, create a portal item providing the web scene's item ID and an AGSPortal
referencing ArcGIS Online.
ViewController.swift
Expand
Use dark colors for code blocks 31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
30
29
28
27
27
27
27
27
28
29
30
31
32
33
34
35
36
37
36
35
36
36
36
36
35
34
33
32
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
15
14
13
12
11
10
9
8
7
7
7
6
5
4
3
2
1
0
-1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-24
-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
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
138
private func setupScene () {
let scene: AGSScene = {
let portal = AGSPortal .arcGISOnline(withLoginRequired: false )
let item = AGSPortalItem (portal: portal, itemID: "7558ee942b2547019f66885c44d4f0b1" )
return AGSScene (item: item)
}()
sceneView.scene = scene
}
Add a UI to control the viewshed analysis To control the viewshed analysis, some UI elements are required.
Create a private UISlider
named slider
. The slider changes the viewshed's maximum distance by expanding or contracting the size of the observer's field of view. The maximum Value
and minimum Value
properties define the range of values the user can select to calculate the viewshed. You set an action on the slider using a selector for a method that will be added in a later step.
ViewController.swift
Expand
Use dark colors for code blocks 47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
46
45
44
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
42
41
41
41
41
41
42
43
44
45
46
47
48
49
50
50
50
50
50
50
50
50
50
50
50
50
50
50
50
50
50
50
50
50
49
49
49
48
47
46
45
44
43
42
41
40
39
38
37
36
35
34
33
32
31
30
29
28
27
26
25
24
23
22
21
20
19
18
18
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
-1
-2
-3
-4
-5
-6
-7
-8
-9
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
138
private lazy var slider: UISlider = {
let slider = UISlider ()
slider.maximumValue = 12_000
slider.minimumValue = 1_000
slider.value = 3_000
slider.addTarget( self , action: #selector(sliderValueDidChange), for: .allTouchEvents)
return slider
}()
Define a private method named setup UI()
and assign the slider
as well as a "Clear"
button to the navigation bar. The clear button removes the viewshed from the sceneYou set an action on the clear button using a selector for a method that will be added in a later step.
ViewController.swift
Expand
Use dark colors for code blocks 47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
47
46
45
44
43
43
43
43
43
43
43
43
43
43
43
43
43
43
43
42
41
41
41
41
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
59
58
57
56
55
54
53
52
51
50
49
49
49
48
47
46
45
44
43
42
41
40
39
38
37
36
35
34
33
32
31
30
29
28
27
26
25
24
23
22
21
20
19
18
18
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
-1
-2
-3
-4
-5
-6
-7
-8
-9
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
138
private lazy var slider: UISlider = {
let slider = UISlider ()
slider.maximumValue = 12_000
slider.minimumValue = 1_000
slider.value = 3_000
slider.addTarget( self , action: #selector(sliderValueDidChange), for: .allTouchEvents)
return slider
}()
private func setupUI () {
navigationItem.titleView = slider
navigationItem.rightBarButtonItem = UIBarButtonItem (
title: "Clear" ,
style: .plain,
target: self ,
action: #selector(clearScene)
)
}
Define a method named slider Value D i d Change(_ : )
and assign it the @objc
keyword. This method updates the viewshed's max Distance
to a value specified by the slider. The @objc
method keyword exposes the method to Objective-C, a necessary step for using the UISlider
API.
ViewController.swift
Expand
Use dark colors for code blocks 56
56
56
56
56
56
56
56
56
56
56
56
56
56
56
56
56
56
56
56
56
56
56
55
54
53
52
52
52
52
52
52
52
52
52
52
52
52
52
52
52
51
50
50
50
50
50
50
50
50
50
50
50
50
50
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
64
63
62
61
60
59
59
59
58
57
56
55
54
53
52
51
50
49
48
47
46
45
44
43
42
41
40
39
38
37
36
35
34
33
32
31
30
29
28
28
28
27
26
25
24
23
22
21
20
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
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
138
private func setupUI () {
navigationItem.titleView = slider
navigationItem.rightBarButtonItem = UIBarButtonItem (
title: "Clear" ,
style: .plain,
target: self ,
action: #selector(clearScene)
)
}
@objc
func sliderValueDidChange ( _ sender : UISlider ) {
viewshed.maxDistance = Double (sender.value)
}
Define a method named clear Scene(_ : )
and assign it the @objc
keyword. This method hides the viewshed from the scene view. The @objc
method keyword exposes the method to Objective-C, a necessary step for using the UIBar Button Item
API.
ViewController.swift
Expand
Use dark colors for code blocks 66
66
66
66
66
66
66
66
66
66
66
66
66
66
66
66
66
66
66
66
66
66
66
65
64
63
62
62
62
62
62
62
62
62
62
62
62
62
62
62
62
61
60
60
60
60
60
60
60
60
60
60
60
60
60
60
60
60
60
60
60
60
60
60
60
60
61
62
63
64
65
66
67
68
69
69
69
69
68
67
66
65
64
63
62
61
60
59
58
57
56
55
54
53
52
51
50
49
48
47
46
45
44
43
42
41
40
39
38
38
38
37
36
35
34
33
32
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
15
14
13
12
11
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
138
@objc
func sliderValueDidChange ( _ sender : UISlider ) {
viewshed.maxDistance = Double (sender.value)
}
@objc
func clearScene ( _ sender : UIBarButtonItem ) {
clearViewshed()
}
In view D i d Load()
, call the method setup UI()
.
ViewController.swift
Expand
Use dark colors for code blocks 19
19
19
19
19
19
19
19
19
19
19
19
19
19
19
19
19
19
19
20
21
22
23
24
25
25
25
26
26
26
26
26
26
26
26
26
26
26
26
26
26
25
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
24
23
22
21
20
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
-1
-2
-3
-4
-5
-6
-7
-7
-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
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
138
override func viewDidLoad () {
super .viewDidLoad()
setupScene()
setupUI()
}
In Xcode , in the Project Navigator , click Main.storyboard .
In the editor , select View Controller
. In the menu bar , click Editor > Embed In > Navigation Controller .
More info Embedding View Controller
within a Navigation Controller places a navigation bar at the top of View Controller
. The navigation bar contains the UI elements.
To verify that your UI is set up properly, press <Command+R> to run the app. You should see a slider and a "Clear" button contained by the navigation bar and the app should load the Yosemite Valley Hotspots web scene .
Create a viewshed analysis Visual analyses are used to help you make sense of complex 3D data contained by a scene. Use a AGSLocation Viewshed
to perform and display a viewshed analysis using a 3D point to define the observer's location.
In Xcode , in the Project Navigator , click ViewController.swift .
In the editor , create a private lazy AGSLocation Viewshed
named viewshed
. Upon launch, the viewshed should not be visible.
ViewController.swift
Expand
Use dark colors for code blocks 78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
77
76
76
76
76
76
76
76
76
76
76
76
76
76
76
76
75
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
87
87
87
86
85
84
83
82
81
80
79
78
77
76
75
74
73
72
71
70
69
68
67
66
65
64
63
62
61
60
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
138
private lazy var viewshed: AGSLocationViewshed = {
let viewshed = AGSLocationViewshed (
location: AGSPointMake3D ( 0 , 0 , 0 , 0 , .wgs84()),
heading: 0 ,
pitch: 90 ,
horizontalAngle: 360 ,
verticalAngle: 180 ,
minDistance: 10 ,
maxDistance: Double (slider.value)
)
viewshed.isVisible = false
return viewshed
}()
Define a private method named setup Analysis Overlay()
to add the viewshed to the scene.
More info The viewshed analysis is added to a scene view using an analysis overlay. An analysis overlay is a container for analyses. It can be used to display visual analyses in a scene view. You can add more than one analysis overlay and they are displayed on top of all other layers .
ViewController.swift
Expand
Use dark colors for code blocks 78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
78
77
76
76
76
76
76
76
76
76
76
76
76
76
76
76
76
75
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
93
92
91
90
89
88
87
86
85
84
83
82
82
82
81
80
79
78
77
76
75
74
73
72
71
70
69
68
67
66
65
64
63
62
61
60
59
58
57
56
55
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
138
private lazy var viewshed: AGSLocationViewshed = {
let viewshed = AGSLocationViewshed (
location: AGSPointMake3D ( 0 , 0 , 0 , 0 , .wgs84()),
heading: 0 ,
pitch: 90 ,
horizontalAngle: 360 ,
verticalAngle: 180 ,
minDistance: 10 ,
maxDistance: Double (slider.value)
)
viewshed.isVisible = false
return viewshed
}()
private func setupAnalysisOverlay () {
let analysisOverlay = AGSAnalysisOverlay ()
sceneView.analysisOverlays.add(analysisOverlay)
analysisOverlay.analyses.add(viewshed)
}
Define a private method named set Viewshed Location(point: )
that receives a point as a parameter. This method is used to set the location of the viewshed and make it visible, if it is not visible already.
ViewController.swift
Expand
Use dark colors for code blocks 92
92
92
92
92
92
92
92
92
92
92
92
92
92
92
92
92
92
92
92
92
92
92
92
92
91
90
90
90
90
90
90
90
90
90
90
90
90
90
90
90
89
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
88
89
90
91
92
93
94
95
96
97
98
99
100
100
99
98
97
96
96
96
95
94
93
92
91
90
89
88
87
86
85
84
83
82
81
80
79
78
77
76
75
74
73
72
71
70
69
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
138
private func setupAnalysisOverlay () {
let analysisOverlay = AGSAnalysisOverlay ()
sceneView.analysisOverlays.add(analysisOverlay)
analysisOverlay.analyses.add(viewshed)
}
private func setViewshedLocation ( point : AGSPoint ) {
viewshed.location = point
if ! viewshed.isVisible {
viewshed.isVisible = true
}
}
Define a private method named clear Viewshed()
. This method is used to hide the viewshed.
ViewController.swift
Expand
Use dark colors for code blocks 98
98
98
98
98
98
98
98
98
98
98
98
98
98
98
98
98
98
98
98
98
98
98
98
98
97
96
96
96
96
96
96
96
96
96
96
96
96
96
96
96
95
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
94
95
96
97
98
99
100
101
102
103
104
104
104
104
103
102
101
100
99
98
97
96
95
94
93
92
91
90
89
88
87
86
85
84
83
82
81
80
79
78
77
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
138
private func setViewshedLocation ( point : AGSPoint ) {
viewshed.location = point
if ! viewshed.isVisible {
viewshed.isVisible = true
}
}
private func clearViewshed () {
viewshed.isVisible = false
}
In view D i d Load()
, call setup Analysis Overlay()
.
ViewController.swift
Expand
Use dark colors for code blocks 19
19
19
19
19
19
19
19
19
19
19
19
19
19
19
19
19
19
19
20
21
22
23
24
25
26
27
28
28
28
28
28
28
28
28
28
28
28
28
28
28
27
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
26
25
24
23
22
21
20
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
-1
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
138
override func viewDidLoad () {
super .viewDidLoad()
setupScene()
setupUI()
setupAnalysisOverlay()
}
Display the viewshed analysis with touch events Touch events determine where to place the observer for the viewshed analysis. A user will long-press and drag to reveal and move the observer's location.
Extend View Controller
to conform to the AGSGeo View Touch Delegate
protocol and include the four long-press geoview touch delegate methods.
ViewController.swift
Expand
Use dark colors for code blocks 111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
110
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
109
110
111
112
113
113
113
114
115
116
117
117
117
118
119
120
121
121
121
122
123
124
125
125
125
126
127
128
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
138
extension ViewController : AGSGeoViewTouchDelegate {
func geoView ( _ geoView : AGSGeoView , didLongPressAtScreenPoint screenPoint : CGPoint , mapPoint : AGSPoint ) {
}
func geoView ( _ geoView : AGSGeoView , didMoveLongPressToScreenPoint screenPoint : CGPoint , mapPoint : AGSPoint ) {
}
func geoView ( _ geoView : AGSGeoView , didEndLongPressAtScreenPoint screenPoint : CGPoint , mapPoint : AGSPoint ) {
}
func geoViewDidCancelLongPress ( _ geoView : AGSGeoView ) {
}
}
When the user begins, moves, and ends a long-press touch event, call set Viewshed Location(point: )
. Using all three touch delegate methods together allows the user to reveal the observer location with a long-press touch event and move the observer by dragging their finger around the screen.
ViewController.swift
Expand
Use dark colors for code blocks 111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
133
133
134
135
136
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
138
extension ViewController : AGSGeoViewTouchDelegate {
func geoView ( _ geoView : AGSGeoView , didLongPressAtScreenPoint screenPoint : CGPoint , mapPoint : AGSPoint ) {
setViewshedLocation(point: mapPoint)
}
func geoView ( _ geoView : AGSGeoView , didMoveLongPressToScreenPoint screenPoint : CGPoint , mapPoint : AGSPoint ) {
setViewshedLocation(point: mapPoint)
}
func geoView ( _ geoView : AGSGeoView , didEndLongPressAtScreenPoint screenPoint : CGPoint , mapPoint : AGSPoint ) {
setViewshedLocation(point: mapPoint)
}
func geoViewDidCancelLongPress ( _ geoView : AGSGeoView ) {
}
}
When the user cancels the long-press touch event, call clear Viewshed()
.
More info This may happen, for instance, when you have the magnifier visible and attempt to take a screenshot using the home/lock button combination.
ViewController.swift
Expand
Use dark colors for code blocks 111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
111
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
138
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
138
extension ViewController : AGSGeoViewTouchDelegate {
func geoView ( _ geoView : AGSGeoView , didLongPressAtScreenPoint screenPoint : CGPoint , mapPoint : AGSPoint ) {
setViewshedLocation(point: mapPoint)
}
func geoView ( _ geoView : AGSGeoView , didMoveLongPressToScreenPoint screenPoint : CGPoint , mapPoint : AGSPoint ) {
setViewshedLocation(point: mapPoint)
}
func geoView ( _ geoView : AGSGeoView , didEndLongPressAtScreenPoint screenPoint : CGPoint , mapPoint : AGSPoint ) {
setViewshedLocation(point: mapPoint)
}
func geoViewDidCancelLongPress ( _ geoView : AGSGeoView ) {
clearViewshed()
}
}
In the setup Scene()
method, assign View Controller
to scene View.touch Delegate
.
ViewController.swift
Expand
Use dark colors for code blocks 31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
31
32
33
34
35
36
37
38
39
40
41
42
43
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
44
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
138
private func setupScene () {
let scene: AGSScene = {
let portal = AGSPortal .arcGISOnline(withLoginRequired: false )
let item = AGSPortalItem (portal: portal, itemID: "7558ee942b2547019f66885c44d4f0b1" )
return AGSScene (item: item)
}()
sceneView.scene = scene
sceneView.touchDelegate = self
}
Run the app Press <Command+R> to run the app.
More info If you are using the Xcode simulator your system must meet these minimum requirements: macOS Big Sur 11.3, Xcode 13, iOS 13. If you are using a physical device, then refer to the system requirements .
You should see a scene of hotspots in the Yosemite Valley. Long-press and drag to display and move a viewshed analysis to explore the visibility of terrain from various locations.
What's next? Learn how to use additional API features , ArcGIS location services , and ArcGIS tools in these tutorials: