Skip to content

Commit 2c397a1

Browse files
authored
Merge pull request #536 from Esri/Caleb/New-AddKMLLayerWithNetworkLinks
[New] Add KML layer with network links
2 parents 2da1dc8 + 4780b28 commit 2c397a1

File tree

5 files changed

+180
-0
lines changed

5 files changed

+180
-0
lines changed

Samples.xcodeproj/project.pbxproj

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@
332332
D75101822A2E497F00B8FA48 /* ShowLabelsOnLayerView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = D75101802A2E493600B8FA48 /* ShowLabelsOnLayerView.swift */; };
333333
D751018E2A2E962D00B8FA48 /* IdentifyLayerFeaturesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751018D2A2E962D00B8FA48 /* IdentifyLayerFeaturesView.swift */; };
334334
D751018F2A2E966C00B8FA48 /* IdentifyLayerFeaturesView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = D751018D2A2E962D00B8FA48 /* IdentifyLayerFeaturesView.swift */; };
335+
D751B4C82CD3E572005CE750 /* AddKMLLayerWithNetworkLinksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751B4C42CD3E572005CE750 /* AddKMLLayerWithNetworkLinksView.swift */; };
336+
D751B4CB2CD3E598005CE750 /* AddKMLLayerWithNetworkLinksView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = D751B4C42CD3E572005CE750 /* AddKMLLayerWithNetworkLinksView.swift */; };
335337
D752D9402A39154C003EB25E /* ManageOperationalLayersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D752D93F2A39154C003EB25E /* ManageOperationalLayersView.swift */; };
336338
D752D9412A39162F003EB25E /* ManageOperationalLayersView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = D752D93F2A39154C003EB25E /* ManageOperationalLayersView.swift */; };
337339
D752D9462A3A6F80003EB25E /* MonitorChangesToMapLoadStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D752D9452A3A6F7F003EB25E /* MonitorChangesToMapLoadStatusView.swift */; };
@@ -579,6 +581,7 @@
579581
dstPath = "";
580582
dstSubfolderSpec = 7;
581583
files = (
584+
D751B4CB2CD3E598005CE750 /* AddKMLLayerWithNetworkLinksView.swift in Copy Source Code Files */,
582585
D70789952CD1611E000DF215 /* ApplyDictionaryRendererToGraphicsOverlayView.swift in Copy Source Code Files */,
583586
D7F2A0302CD00F400008D981 /* ApplyDictionaryRendererToFeatureLayerView.swift in Copy Source Code Files */,
584587
D75E5EF42CC04A0C00252595 /* EditFeaturesUsingFeatureFormsView.swift in Copy Source Code Files */,
@@ -990,6 +993,7 @@
990993
D74F03EF2B609A7D00E83688 /* AddFeaturesWithContingentValuesView.Model.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddFeaturesWithContingentValuesView.Model.swift; sourceTree = "<group>"; };
991994
D75101802A2E493600B8FA48 /* ShowLabelsOnLayerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShowLabelsOnLayerView.swift; sourceTree = "<group>"; };
992995
D751018D2A2E962D00B8FA48 /* IdentifyLayerFeaturesView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdentifyLayerFeaturesView.swift; sourceTree = "<group>"; };
996+
D751B4C42CD3E572005CE750 /* AddKMLLayerWithNetworkLinksView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddKMLLayerWithNetworkLinksView.swift; sourceTree = "<group>"; };
993997
D752D93F2A39154C003EB25E /* ManageOperationalLayersView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManageOperationalLayersView.swift; sourceTree = "<group>"; };
994998
D752D9452A3A6F7F003EB25E /* MonitorChangesToMapLoadStatusView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MonitorChangesToMapLoadStatusView.swift; sourceTree = "<group>"; };
995999
D752D95E2A3BCE06003EB25E /* DisplayMapFromPortalItemView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayMapFromPortalItemView.swift; sourceTree = "<group>"; };
@@ -1238,6 +1242,7 @@
12381242
00D4EF7E2863840D00B9CC30 /* Add feature layers */,
12391243
D7F8C0342B60564D0072BFA7 /* Add features with contingent values */,
12401244
D713C6D42CB990600073AA72 /* Add KML layer */,
1245+
D751B4C72CD3E572005CE750 /* Add KML layer with network links */,
12411246
D7DFA0E92CBA0242007C31F2 /* Add map image layer */,
12421247
D7CDD3882CB86F0A00DE9766 /* Add point cloud layer from file */,
12431248
D7848ED72CBD85A300F6F546 /* Add point scene layer */,
@@ -2376,6 +2381,14 @@
23762381
path = "Identify layer features";
23772382
sourceTree = "<group>";
23782383
};
2384+
D751B4C72CD3E572005CE750 /* Add KML layer with network links */ = {
2385+
isa = PBXGroup;
2386+
children = (
2387+
D751B4C42CD3E572005CE750 /* AddKMLLayerWithNetworkLinksView.swift */,
2388+
);
2389+
path = "Add KML layer with network links";
2390+
sourceTree = "<group>";
2391+
};
23792392
D752D93C2A3914E5003EB25E /* Manage operational layers */ = {
23802393
isa = PBXGroup;
23812394
children = (
@@ -3424,6 +3437,7 @@
34243437
4D2ADC6729C50BD6003B367F /* AddDynamicEntityLayerView.Model.swift in Sources */,
34253438
E004A6E928493BCE002A1FE6 /* ShowDeviceLocationView.swift in Sources */,
34263439
1C26ED192A859525009B7721 /* FilterFeaturesInSceneView.swift in Sources */,
3440+
D751B4C82CD3E572005CE750 /* AddKMLLayerWithNetworkLinksView.swift in Sources */,
34273441
D75E5EF12CC049D500252595 /* EditFeaturesUsingFeatureFormsView.swift in Sources */,
34283442
D7352F8E2BD992C40013FFEF /* MonitorChangesToDrawStatusView.swift in Sources */,
34293443
F111CCC1288B5D5600205358 /* DisplayMapFromMobileMapPackageView.swift in Sources */,
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright 2024 Esri
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import ArcGIS
16+
import SwiftUI
17+
18+
struct AddKMLLayerWithNetworkLinksView: View {
19+
/// A scene with the current air traffic in parts of Europe.
20+
@State private var scene: ArcGIS.Scene = {
21+
let scene = Scene(basemapStyle: .arcGISImagery)
22+
23+
// Creates a KML dataset from a remote KMZ file.
24+
let kmlDataset = KMLDataset(url: .radarKMZFile)
25+
26+
// Creates a KML layer from the dataset and adds it to the scene's operational layers.
27+
let kmlLayer = KMLLayer(dataset: kmlDataset)
28+
scene.addOperationalLayer(kmlLayer)
29+
30+
// Sets the viewpoint to be initially centered on the data coverage.
31+
scene.initialViewpoint = Viewpoint(latitude: 50.472421, longitude: 8.150526, scale: 1e7)
32+
33+
return scene
34+
}()
35+
36+
/// The messages from the KML dataset's network links.
37+
@State private var networkLinkMessages: [String] = []
38+
39+
/// A Boolean value indicating whether network link messages popover is showing.
40+
@State private var isShowingMessages = false
41+
42+
var body: some View {
43+
SceneView(scene: scene)
44+
.toolbar {
45+
ToolbarItem(placement: .bottomBar) {
46+
Button("Network Link Messages") {
47+
isShowingMessages = true
48+
}
49+
.popover(isPresented: $isShowingMessages) { [networkLinkMessages] in
50+
MessagesList(messages: networkLinkMessages)
51+
.presentationDetents([.fraction(0.5), .large])
52+
.frame(idealWidth: 320, idealHeight: 380)
53+
}
54+
}
55+
}
56+
.task {
57+
// Listens for new KML network link messages.
58+
let kmlLayer = scene.operationalLayers.first as! KMLLayer
59+
60+
for await (_, message) in kmlLayer.dataset.networkLinkMessages {
61+
networkLinkMessages.append(message)
62+
}
63+
}
64+
}
65+
66+
/// A list of KML network link messages.
67+
private struct MessagesList: View {
68+
/// The messages to show in the list.
69+
let messages: [String]
70+
71+
/// The action to dismiss the view.
72+
@Environment(\.dismiss) private var dismiss
73+
74+
var body: some View {
75+
NavigationStack {
76+
List(messages, id: \.self) { message in
77+
Text(message)
78+
}
79+
.navigationTitle("Network Link Messages")
80+
.navigationBarTitleDisplayMode(.inline)
81+
.toolbar {
82+
ToolbarItem(placement: .confirmationAction) {
83+
Button("Done") { dismiss() }
84+
}
85+
}
86+
}
87+
}
88+
}
89+
}
90+
91+
private extension URL {
92+
/// The web URL to the "radar" KMZ file containing network links for the current air traffic in parts of Europe.
93+
static var radarKMZFile: URL {
94+
URL(string: "https://www.arcgis.com/sharing/rest/content/items/600748d4464442288f6db8a4ba27dc95/data")!
95+
}
96+
}
97+
98+
#Preview {
99+
AddKMLLayerWithNetworkLinksView()
100+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Add KML layer with network links
2+
3+
Display a file with a KML network link, including displaying any network link control messages at launch.
4+
5+
![Image of Add KML layer with network links sample](add-kml-layer-with-network-links.png)
6+
7+
## Use case
8+
9+
KML files can reference other KML files on the network and support automatically refreshing content. For example, survey workers will benefit from KML data shown on their devices automatically refreshing to show the most up-to-date state. Additionally, discovering KML files linked to the data they are currently viewing provides additional information to make better decisions in the field.
10+
11+
## How to use the sample
12+
13+
The sample will load the KML file automatically. The data shown should refresh automatically every few seconds. Tap the "Network Link Messages" button to view the messages. Pan and zoom to explore the map.
14+
15+
## How it works
16+
17+
1. Create a `KMLDataset` from a KML source that has network links.
18+
2. Construct a `KMLLayer` with the dataset and add the layer to the scene as an operational layer.
19+
3. To listen for network messages, use the KML dataset's `networkLinkMessages`.
20+
21+
## Relevant API
22+
23+
* KMLDataset
24+
* KMLDataset.networkLinkMessages
25+
* KMLLayer
26+
27+
## Offline data
28+
29+
This sample uses the "radar.kmz" file, which can be found on [ArcGIS Online](https://arcgisruntime.maps.arcgis.com/home/item.html?id=600748d4464442288f6db8a4ba27dc95).
30+
31+
## About the data
32+
33+
This map shows the current air traffic in parts of Europe with heading, altitude, and ground speed. Additionally, noise levels from ground monitoring stations are shown.
34+
35+
## Tags
36+
37+
keyhole, KML, KMZ, network link, network link control, OGC
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"category": "Layers",
3+
"description": "Display a file with a KML network link, including displaying any network link control messages at launch.",
4+
"ignore": false,
5+
"images": [
6+
"add-kml-layer-with-network-links.png"
7+
],
8+
"keywords": [
9+
"KML",
10+
"KMZ",
11+
"OGC",
12+
"keyhole",
13+
"network link",
14+
"network link control",
15+
"KMLDataset",
16+
"KMLDataset.networkLinkMessages",
17+
"KMLLayer"
18+
],
19+
"redirect_from": [],
20+
"relevant_apis": [
21+
"KMLDataset",
22+
"KMLDataset.networkLinkMessages",
23+
"KMLLayer"
24+
],
25+
"snippets": [
26+
"AddKMLLayerWithNetworkLinksView.swift"
27+
],
28+
"title": "Add KML layer with network links"
29+
}
234 KB
Loading

0 commit comments

Comments
 (0)