Skip to content

Commit ece7d4c

Browse files
authored
Merge branch 'v.next' into Ting/FixTearDownBranch
2 parents 3498710 + 50c00e1 commit ece7d4c

File tree

5 files changed

+257
-1
lines changed

5 files changed

+257
-1
lines changed

Samples.xcodeproj/project.pbxproj

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,13 +305,15 @@
305305
88F93CC229C4D3480006B28E /* CreateAndEditGeometriesView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = 88F93CC029C3D59C0006B28E /* CreateAndEditGeometriesView.swift */; };
306306
88FB70392DCC207B00EB76E3 /* ApplySymbologyToShapefileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88FB70382DCC207B00EB76E3 /* ApplySymbologyToShapefileView.swift */; };
307307
88FB703C2DCC22E900EB76E3 /* ApplySymbologyToShapefileView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = 88FB70382DCC207B00EB76E3 /* ApplySymbologyToShapefileView.swift */; };
308-
88FB70D12DCC248400EB76E3 /* Aurora_CO_shp in Resources */ = {isa = PBXBuildFile; fileRef = 88FB70D02DCC247B00EB76E3 /* Aurora_CO_shp */; settings = {ASSET_TAGS = (ApplySymbologyToShapefile, ); }; };
308+
88FB70D12DCC248400EB76E3 /* Aurora_CO_shp in Resources */ = {isa = PBXBuildFile; fileRef = 88FB70D02DCC247B00EB76E3 /* Aurora_CO_shp */; settings = {ASSET_TAGS = (ApplySymbologyToShapefile, ShowShapefileMetadata, ); }; };
309309
88FB70D42DCD10B600EB76E3 /* AuthenticateWithIntegratedWindowsAuthenticationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88FB70D32DCD10B600EB76E3 /* AuthenticateWithIntegratedWindowsAuthenticationView.swift */; };
310310
88FB70D52DD3C2E000EB76E3 /* AuthenticateWithIntegratedWindowsAuthenticationView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = 88FB70D32DCD10B600EB76E3 /* AuthenticateWithIntegratedWindowsAuthenticationView.swift */; };
311311
88FB70D82DD3DF3700EB76E3 /* AddOpenStreetMapLayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88FB70D72DD3DF3700EB76E3 /* AddOpenStreetMapLayerView.swift */; };
312312
88FB70D92DD3DFA800EB76E3 /* AddOpenStreetMapLayerView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = 88FB70D72DD3DF3700EB76E3 /* AddOpenStreetMapLayerView.swift */; };
313313
9501BBEF2DF39DAB0054F4BD /* SetFeatureLayerRenderingModeOnSceneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9501BBEE2DF39DA50054F4BD /* SetFeatureLayerRenderingModeOnSceneView.swift */; };
314314
9503056E2C46ECB70091B32D /* ShowDeviceLocationUsingIndoorPositioningView.Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9503056D2C46ECB70091B32D /* ShowDeviceLocationUsingIndoorPositioningView.Model.swift */; };
315+
951896BB2E29B15A00144F9B /* ShowShapefileMetadataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 951896BA2E29B15600144F9B /* ShowShapefileMetadataView.swift */; };
316+
951896BD2E29B20500144F9B /* ShowShapefileMetadataView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = 951896BA2E29B15600144F9B /* ShowShapefileMetadataView.swift */; };
315317
951961AC2E00BC420088B0C2 /* ShowGeodesicSectorAndEllipseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 951961AB2E00BC3C0088B0C2 /* ShowGeodesicSectorAndEllipseView.swift */; };
316318
951961AE2E00BD430088B0C2 /* SetMapImageLayerSublayerVisibilityView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = 95813E382DF88FD000342CBF /* SetMapImageLayerSublayerVisibilityView.swift */; };
317319
9520B2B52E135AD800B3BEF9 /* ShowLineOfSightBetweenGeoelementsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9520B2B42E135AD800B3BEF9 /* ShowLineOfSightBetweenGeoelementsView.swift */; };
@@ -741,6 +743,7 @@
741743
1C17E1CA2DDFB6FB00A012CB /* GenerateGeodatabaseReplicaFromFeatureServiceView.swift in Copy Source Code Files */,
742744
000B75702E33F67600C4B257 /* ControlAnnotationSublayerVisibilityView.Model.swift in Copy Source Code Files */,
743745
1C8438F92DDBDE1F005CCBC7 /* ControlAnnotationSublayerVisibilityView.swift in Copy Source Code Files */,
746+
951896BD2E29B20500144F9B /* ShowShapefileMetadataView.swift in Copy Source Code Files */,
744747
95A86A5D2E1C51A9000BF570 /* ShowPortalUserInfoView.swift in Copy Source Code Files */,
745748
9520B2B62E135AEE00B3BEF9 /* ShowLineOfSightBetweenGeoelementsView.swift in Copy Source Code Files */,
746749
95FFEB442E06211B00543993 /* ShowGeodesicSectorAndEllipseView.swift in Copy Source Code Files */,
@@ -1206,6 +1209,7 @@
12061209
88FB70D72DD3DF3700EB76E3 /* AddOpenStreetMapLayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddOpenStreetMapLayerView.swift; sourceTree = "<group>"; };
12071210
9501BBEE2DF39DA50054F4BD /* SetFeatureLayerRenderingModeOnSceneView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetFeatureLayerRenderingModeOnSceneView.swift; sourceTree = "<group>"; };
12081211
9503056D2C46ECB70091B32D /* ShowDeviceLocationUsingIndoorPositioningView.Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowDeviceLocationUsingIndoorPositioningView.Model.swift; sourceTree = "<group>"; };
1212+
951896BA2E29B15600144F9B /* ShowShapefileMetadataView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowShapefileMetadataView.swift; sourceTree = "<group>"; };
12091213
951961AB2E00BC3C0088B0C2 /* ShowGeodesicSectorAndEllipseView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowGeodesicSectorAndEllipseView.swift; sourceTree = "<group>"; };
12101214
9520B2B42E135AD800B3BEF9 /* ShowLineOfSightBetweenGeoelementsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowLineOfSightBetweenGeoelementsView.swift; sourceTree = "<group>"; };
12111215
9537AFD62C220EF0000923C5 /* ExchangeSetwithoutUpdates */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ExchangeSetwithoutUpdates; sourceTree = "<group>"; };
@@ -1822,6 +1826,7 @@
18221826
95A5721A2C0FDCCE006E8B48 /* Show scale bar */,
18231827
95D2EE102C334D1D00683D53 /* Show service area */,
18241828
88AF55282DD68753003F146E /* Show service areas for multiple facilities */,
1829+
951896BF2E29B21900144F9B /* Show shapefile metadata */,
18251830
1CAF831A2A20305F000E1E60 /* Show utility associations */,
18261831
D7ABA2FB2A3287C10021822B /* Show viewshed from geoelement in scene */,
18271832
0086F3FC28E3770900974721 /* Show viewshed from point in scene */,
@@ -2746,6 +2751,14 @@
27462751
path = "Set feature layer rendering mode on scene";
27472752
sourceTree = "<group>";
27482753
};
2754+
951896BF2E29B21900144F9B /* Show shapefile metadata */ = {
2755+
isa = PBXGroup;
2756+
children = (
2757+
951896BA2E29B15600144F9B /* ShowShapefileMetadataView.swift */,
2758+
);
2759+
path = "Show shapefile metadata";
2760+
sourceTree = "<group>";
2761+
};
27492762
951961AD2E00BC760088B0C2 /* Show geodesic sector and ellipse */ = {
27502763
isa = PBXGroup;
27512764
children = (
@@ -4224,6 +4237,7 @@
42244237
ShowDeviceLocationWithNmeaDataSources,
42254238
ShowLineOfSightBetweenGeoelements,
42264239
ShowMobileMapPackageExpirationDate,
4240+
ShowShapefileMetadata,
42274241
ShowViewshedFromGeoelementInScene,
42284242
SnapGeometryEditsWithUtilityNetworkRules,
42294243
StyleFeaturesWithCustomDictionary,
@@ -4692,6 +4706,7 @@
46924706
D7635FFB2B9277DC0044AB97 /* ConfigureClustersView.Model.swift in Sources */,
46934707
D7EAF35A2A1C023800D822C4 /* SetMinAndMaxScaleView.swift in Sources */,
46944708
1C19B4F52A578E46001D2506 /* CreateLoadReportView.Model.swift in Sources */,
4709+
951896BB2E29B15A00144F9B /* ShowShapefileMetadataView.swift in Sources */,
46954710
88C5E0EB2DCBC1E20091D271 /* ApplyScenePropertyExpressionsView.swift in Sources */,
46964711
9547085C2C3C719800CA8579 /* EditFeatureAttachmentsView.Model.swift in Sources */,
46974712
D71C90A22C6C249B0018C63E /* StyleGeometryTypesWithSymbolsView.swift in Sources */,
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Show shapefile metadata
2+
3+
Read a shapefile and display its metadata.
4+
5+
![Image of show shapefile metadata sample](show-shapefile-metadata.png)
6+
7+
## Use case
8+
9+
Display metadata for the shapefile currently being viewed—such as tags, credits, and a summary.
10+
11+
## How to use the sample
12+
13+
Open the sample to automatically view the shapefile’s metadata.
14+
15+
## How it works
16+
17+
1. Load the shapefile using the `ShapefileFeatureTable` with the assets URL.
18+
2. Access the shapefile metadata through the `info` property of the feature table.
19+
3. Retrieve and display the thumbnail image from `fileInfo.thumbnail`.
20+
4. Display the shapefile's `summary`, `credits`, and `tags` from the metadata.
21+
22+
## Relevant API
23+
24+
* ShapefileFeatureTable
25+
* ShapefileFeatureTable.info
26+
* ShapefileInfo
27+
* ShapefileInfo.credits
28+
* ShapefileInfo.summary
29+
* ShapefileInfo.tags
30+
* ShapefileInfo.thumbnail
31+
32+
## Offline data
33+
34+
[Aurora Colorado Shapefiles](https://www.arcgis.com/home/item.html?id=d98b3e5293834c5f852f13c569930caa) is available as an item hosted on ArcGIS Online.
35+
36+
## About the data
37+
38+
This sample uses a shapefile showing bike trails in Aurora, CO. The [Aurora Colorado Shapefiles](https://www.arcgis.com/home/item.html?id=d98b3e5293834c5f852f13c569930caa) are available as an item on ArcGIS Online.
39+
40+
## Tags
41+
42+
credits, description, metadata, package, shape file, shapefile, summary, symbology, tags, visualization
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"category": "Visualization",
3+
"description": "Read a shapefile and display its metadata.",
4+
"ignore": false,
5+
"images": [
6+
"show-shapefile-metadata.png"
7+
],
8+
"keywords": [
9+
"credits",
10+
"description",
11+
"metadata",
12+
"package",
13+
"shape file",
14+
"shapefile",
15+
"summary",
16+
"symbology",
17+
"tags",
18+
"visualization",
19+
"ShapefileFeatureTable",
20+
"ShapefileFeatureTable.info",
21+
"ShapefileInfo",
22+
"ShapefileInfo.credits",
23+
"ShapefileInfo.summary",
24+
"ShapefileInfo.tags",
25+
"ShapefileInfo.thumbnail"
26+
],
27+
"redirect_from": [],
28+
"relevant_apis": [
29+
"ShapefileFeatureTable",
30+
"ShapefileFeatureTable.info",
31+
"ShapefileInfo",
32+
"ShapefileInfo.credits",
33+
"ShapefileInfo.summary",
34+
"ShapefileInfo.tags",
35+
"ShapefileInfo.thumbnail"
36+
],
37+
"offline_data": [
38+
"d98b3e5293834c5f852f13c569930caa"
39+
],
40+
"snippets": [
41+
"ShowShapefileMetadataView.swift"
42+
],
43+
"title": "Show shapefile metadata"
44+
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// Copyright 2025 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 ShowShapefileMetadataView: View {
19+
/// Model which contains the logic for loading and setting the data.
20+
@State private var model = Model()
21+
/// The error that occurred, if any, when trying to load the shapefile or display its metadata.
22+
@State private var error: Error?
23+
/// A Boolean value specifying whether the metadata view should be shown
24+
@State private var showMetadata: Bool = false
25+
26+
var body: some View {
27+
MapViewReader { mapView in
28+
MapView(map: model.map)
29+
.onAppear {
30+
Task {
31+
do {
32+
// Attempt to asynchronously load the
33+
// feature layer from the model.
34+
try await model.loadShapefile()
35+
// If the feature layer has a full extent,
36+
// use it to set the map's viewpoint.
37+
if let fullExtent = model.featureLayer?.fullExtent {
38+
await mapView.setViewpointGeometry(
39+
fullExtent,
40+
padding: 50
41+
)
42+
}
43+
} catch {
44+
self.error = error
45+
}
46+
}
47+
}
48+
.toolbar {
49+
ToolbarItem(placement: .bottomBar) {
50+
Button("Show Shapefile Metadata") {
51+
showMetadata.toggle()
52+
}
53+
.popover(isPresented: $showMetadata) {
54+
metadataPopover
55+
}
56+
}
57+
}
58+
.errorAlert(presentingError: $error)
59+
}
60+
}
61+
62+
@ViewBuilder var metadataPopover: some View {
63+
NavigationStack {
64+
MetadataPanel(model: $model)
65+
.navigationTitle("Shapefile Metadata")
66+
.navigationBarTitleDisplayMode(.inline)
67+
.toolbar {
68+
ToolbarItem(placement: .confirmationAction) {
69+
Button("Done") {
70+
showMetadata = false
71+
}
72+
}
73+
}
74+
}
75+
.presentationDetents([.fraction(0.55)])
76+
.frame(idealWidth: 320, idealHeight: 380)
77+
}
78+
}
79+
80+
private extension ShowShapefileMetadataView {
81+
@MainActor
82+
@Observable
83+
class Model {
84+
/// Create a map with a topographic basemap.
85+
@ObservationIgnored var map = Map(basemapStyle: .arcGISTopographic)
86+
87+
/// Declare a FeatureLayer to display the shapefile features on the map.
88+
@ObservationIgnored var featureLayer: FeatureLayer?
89+
90+
/// Holds metadata information about the shapefile, such as name, description, etc.
91+
var shapefileInfo: ShapefileInfo?
92+
93+
/// Holds the thumbnail image associated with the shapefile, if available.
94+
var thumbnailImage: UIImage?
95+
96+
/// Asynchronous function to load the feature layer from the shapefile.
97+
func loadShapefile() async throws {
98+
let featureTable = ShapefileFeatureTable(fileURL: .auroraShapefile)
99+
let layer = FeatureLayer(featureTable: featureTable)
100+
101+
try await layer.featureTable?.load()
102+
103+
map.addOperationalLayer(layer)
104+
featureLayer = layer
105+
shapefileInfo = featureTable.info
106+
thumbnailImage = featureTable.info?.thumbnail
107+
}
108+
}
109+
110+
struct MetadataPanel: View {
111+
/// Binding to the model to reflect changes in the UI.
112+
@Binding var model: ShowShapefileMetadataView.Model
113+
114+
var body: some View {
115+
VStack(alignment: .center, spacing: 16) {
116+
if let info = model.shapefileInfo {
117+
Text(info.credits)
118+
.bold()
119+
Text(info.summary)
120+
.font(.caption)
121+
.multilineTextAlignment(.leading)
122+
}
123+
if let image = model.thumbnailImage {
124+
Image(uiImage: image)
125+
.resizable()
126+
.scaledToFit()
127+
.frame(maxHeight: 150)
128+
}
129+
130+
if let tags = model.shapefileInfo?.tags {
131+
Text("Tags: \(tags.joined(separator: ", "))")
132+
.font(.caption2)
133+
.foregroundColor(.secondary)
134+
}
135+
}
136+
.padding()
137+
.cornerRadius(8)
138+
.padding(.horizontal)
139+
}
140+
}
141+
}
142+
143+
private extension URL {
144+
static var auroraShapefile: URL {
145+
Bundle.main.url(
146+
forResource: "TrailBikeNetwork",
147+
withExtension: "shp",
148+
subdirectory: "Aurora_CO_shp"
149+
)!
150+
}
151+
}
152+
153+
#Preview {
154+
ShowShapefileMetadataView()
155+
}
131 KB
Loading

0 commit comments

Comments
 (0)