Perform a line of sight analysis between two points in real time.
Use case
A line of sight analysis can be used to assess whether a view is obstructed between an observer and a target. Obstructing features could either be natural, like topography, or man-made, like buildings. Consider an events planning company wanting to commemorate a national event by lighting sequential beacons across hill summits or roof tops. To guarantee a successful event, ensuring an unobstructed line of sight between neighboring beacons would allow each beacon to be activated as intended.
How to use the sample
Tap on the map to set the observer location. Tap and hold to drag the line of sight target. A red segment on the line means the view between observer and target is obstructed, whereas green means the view is unobstructed.
How it works
Create an AGSAnalysisOverlay and add it to the scene view.
Track the screen taps using the AGSGeoViewTouchDelegate.
Create an AGSLocationLineOfSight with the map points.
Update the target location when needed.
Relevant API
AGSAnalysisOverlay
AGSLocationLineOfSight
AGSSceneView
Tags
3D, line of sight, visibility, visibility analysis
Sample Code
LineOfSightLocationViewController.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
// Copyright 2018 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//// http://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 UIKit
import ArcGIS
classLineOfSightLocationViewController: UIViewController, AGSGeoViewTouchDelegate{
@IBOutletweakvar sceneView: AGSSceneView!
@IBOutletweakvar observerInstructionLabel: UILabel!
@IBOutletweakvar targetInstructionLabel: UILabel!
privatevar lineOfSight: AGSLocationLineOfSight? {
willSet {
sceneView.analysisOverlays.removeAllObjects()
}
didSet {
guardlet lineOfSight = lineOfSight else {
targetInstructionLabel.isHidden =truereturn }
targetInstructionLabel.isHidden =false// create an analysis overlay using a single Line of Sight and add it to the scene viewlet analysisOverlay =AGSAnalysisOverlay()
analysisOverlay.analyses.add(lineOfSight)
sceneView.analysisOverlays.add(analysisOverlay)
}
}
overridefuncviewDidLoad() {
super.viewDidLoad()
// add the source code button item to the right of navigation bar (navigationItem.rightBarButtonItem as!SourceCodeBarButtonItem).filenames = ["LineOfSightLocationViewController"]
// Initialize the scene with an imagery basemap style.let scene =AGSScene(basemapStyle: .arcGISImagery)
// assign the scene to the scene view sceneView.scene = scene
/// The url of the Terrain 3D ArcGIS REST Service.let worldElevationServiceURL =URL(string: "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer")!// initialize the elevation source with the service URL and add it to the base surface of the scenelet elevationSrc =AGSArcGISTiledElevationSource(url: worldElevationServiceURL)
scene.baseSurface?.elevationSources.append(elevationSrc)
// set the viewpoint specified by the camera positionlet camera =AGSCamera(location: AGSPoint(x: -73.0815, y: -49.3272, z: 4059, spatialReference: .wgs84()), heading: 11, pitch: 62, roll: 0)
sceneView.setViewpointCamera(camera)
// set touch delegate on scene view as self sceneView.touchDelegate =self// set the line width (default 1.0). This setting is applied to all line of sight analysis in the viewAGSLineOfSight.setLineWidth(2.0)
}
// MARK: - AGSGeoViewTouchDelegatefuncgeoView(_geoView: AGSGeoView, didTapAtScreenPointscreenPoint: CGPoint, mapPoint: AGSPoint) {
// user tapped to place Line of Sight observer. Create Line of Sight analysis if need beif lineOfSight ==nil {
// set initial Line of Sight analysis with tapped point lineOfSight =AGSLocationLineOfSight(observerLocation: mapPoint, targetLocation: mapPoint)
} else {
// update the observer location lineOfSight?.observerLocation = mapPoint
}
}
funcgeoView(_geoView: AGSGeoView, didLongPressAtScreenPointscreenPoint: CGPoint, mapPoint: AGSPoint) {
// update the target location lineOfSight?.targetLocation = mapPoint
}
funcgeoView(_geoView: AGSGeoView, didMoveLongPressToScreenPointscreenPoint: CGPoint, mapPoint: AGSPoint) {
// update the target location lineOfSight?.targetLocation = mapPoint
}
}