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
139
140
141
142
143
144
145
146
147
148
149
150
151
// 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.
using Esri.ArcGISRuntime.Data;
using Esri.ArcGISRuntime.Mapping;
using Esri.ArcGISRuntime.UI.Controls;
using Foundation;
using System;
using System.Collections.Generic;
using System.Linq;
using Esri.ArcGISRuntime.Geometry;
using UIKit;
namespace ArcGISRuntime.Samples.SceneLayerSelection
{
[Register("SceneLayerSelection")]
[ArcGISRuntime.Samples.Shared.Attributes.Sample(
name: "Scene layer selection",
category: "Layers",
description: "Identify features in a scene to select.",
instructions: "Tap on a building in the scene layer to select it. Deselect buildings by clicking away from the buildings.",
tags: new[] { "3D", "Berlin", "buildings", "identify", "model", "query", "search", "select" })]
public class SceneLayerSelection : UIViewController
{
// Hold references to UI controls.
private SceneView _mySceneView;
public SceneLayerSelection()
{
Title = "Scene layer selection";
}
private async void Initialize()
{
// Create a new Scene with an imagery basemap.
Scene scene = new Scene(BasemapStyle.ArcGISImageryStandard);
// Add a base surface with elevation data.
Surface elevationSurface = new Surface();
Uri elevationService = new Uri("https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer");
elevationSurface.ElevationSources.Add(new ArcGISTiledElevationSource(elevationService));
scene.BaseSurface = elevationSurface;
// Add a scene layer.
Uri buildingsService = new Uri("https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/Buildings_Berlin/SceneServer");
ArcGISSceneLayer buildingsLayer = new ArcGISSceneLayer(buildingsService);
scene.OperationalLayers.Add(buildingsLayer);
// Assign the Scene to the SceneView.
_mySceneView.Scene = scene;
try
{
// Create a camera with an interesting view.
await buildingsLayer.LoadAsync();
MapPoint center = (MapPoint) GeometryEngine.Project(buildingsLayer.FullExtent.GetCenter(), SpatialReferences.Wgs84);
Camera viewCamera = new Camera(center.Y, center.X, 600, 120, 60, 0);
// Set the viewpoint with the camera.
_mySceneView.SetViewpointCamera(viewCamera);
}
catch (Exception e)
{
new UIAlertView("Error", e.ToString(), (IUIAlertViewDelegate) null, "OK", null).Show();
}
}
private async void SceneViewTapped(object sender, GeoViewInputEventArgs e)
{
// Get the scene layer from the scene (first and only operational layer).
ArcGISSceneLayer sceneLayer = (ArcGISSceneLayer) _mySceneView.Scene.OperationalLayers.First();
// Clear any existing selection.
sceneLayer.ClearSelection();
try
{
// Identify the layer at the tap point.
// Use a 10-pixel tolerance around the point and return a maximum of one feature.
IdentifyLayerResult result = await _mySceneView.IdentifyLayerAsync(sceneLayer, e.Position, 10, false, 1);
// Get the GeoElements that were identified (will be 0 or 1 element).
IReadOnlyList<GeoElement> geoElements = result.GeoElements;
// If a GeoElement was identified, select it in the scene.
if (geoElements.Any())
{
GeoElement geoElement = geoElements.FirstOrDefault();
if (geoElement != null)
{
// Select the feature to highlight it in the scene view.
sceneLayer.SelectFeature((Feature) geoElement);
}
}
}
catch (Exception ex)
{
new UIAlertView("Error", ex.ToString(), (IUIAlertViewDelegate) null, "OK", null).Show();
}
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
Initialize();
}
public override void LoadView()
{
// Create the views.
View = new UIView() { BackgroundColor = ApplicationTheme.BackgroundColor };
_mySceneView = new SceneView();
_mySceneView.TranslatesAutoresizingMaskIntoConstraints = false;
// Add the views.
View.AddSubviews(_mySceneView);
// Lay out the views.
NSLayoutConstraint.ActivateConstraints(new[]
{
_mySceneView.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor),
_mySceneView.BottomAnchor.ConstraintEqualTo(View.BottomAnchor),
_mySceneView.LeadingAnchor.ConstraintEqualTo(View.LeadingAnchor),
_mySceneView.TrailingAnchor.ConstraintEqualTo(View.TrailingAnchor)
});
}
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
// Subscribe to events.
_mySceneView.GeoViewTapped += SceneViewTapped;
}
public override void ViewDidDisappear(bool animated)
{
base.ViewDidDisappear(animated);
// Unsubscribe from events, per best practice.
_mySceneView.GeoViewTapped -= SceneViewTapped;
}
}
}