@@ -16,10 +16,95 @@ import ArcGIS
1616import SwiftUI
1717
1818struct ApplyRasterRenderingRuleView : View {
19- @State private var map = Map ( basemapStyle: . arcGISTopographic)
19+ /// A map with a streets basemap.
20+ @State private var map = Map ( basemapStyle: . arcGISStreets)
21+
22+ /// An array of raster layers, each with a different rendering rule.
23+ @State private var rasterLayers : [ RasterLayer ] = [ ]
24+
25+ /// The name of rendering rule selected by the picker.
26+ @State private var selectedRenderingRule = " None "
27+
28+ /// The viewpoint for zooming the map view to a layer's extent.
29+ @State private var viewpoint : Viewpoint ?
30+
31+ /// The error shown in the error alert.
32+ @State private var error : Error ?
2033
2134 var body : some View {
22- MapView ( map: map)
35+ MapView ( map: map, viewpoint: viewpoint)
36+ . toolbar {
37+ ToolbarItem ( placement: . bottomBar) {
38+ Picker ( " Rendering Rule " , selection: $selectedRenderingRule) {
39+ ForEach ( rasterLayers, id: \. name) { rasterLayer in
40+ Text ( rasterLayer. name)
41+ }
42+ }
43+ . onChange ( of: selectedRenderingRule) { newRule in
44+ if let rasterLayer = rasterLayers. first ( where: { $0. name == newRule } ) {
45+ setLayer ( rasterLayer)
46+ }
47+ }
48+ }
49+ }
50+ . task {
51+ // Sets up the raster layers when the sample opens.
52+ do {
53+ rasterLayers = try await makeRasterLayers ( )
54+ await rasterLayers. load ( )
55+
56+ if let rasterLayer = rasterLayers. first {
57+ setLayer ( rasterLayer)
58+ }
59+ } catch {
60+ self . error = error
61+ }
62+ }
63+ . errorAlert ( presentingError: $error)
64+ }
65+
66+ /// Sets a given layer on the map and zooms the viewpoint the layer's extent.
67+ /// - Parameter layer: The layer to set.
68+ private func setLayer( _ layer: Layer ) {
69+ map. removeAllOperationalLayers ( )
70+ map. addOperationalLayer ( layer)
71+
72+ if let layerExtent = layer. fullExtent {
73+ viewpoint = Viewpoint ( boundingGeometry: layerExtent)
74+ }
75+ }
76+
77+ /// Creates raster layers for all the rendering rules from an image service raster.
78+ /// - Returns: An array of new `RasterLayer` objects.
79+ private func makeRasterLayers( ) async throws -> [ RasterLayer ] {
80+ // Creates and loads an image service raster using an image service URL.
81+ let imageServiceRaster = ImageServiceRaster ( url: . charlotteLASImageService)
82+ try await imageServiceRaster. load ( )
83+
84+ // Gets the rendering rule infos from the raster's service info.
85+ guard let renderingRuleInfos = imageServiceRaster. serviceInfo? . renderingRuleInfos else {
86+ return [ ]
87+ }
88+
89+ return renderingRuleInfos. map { renderingRuleInfo in
90+ // Creates another image service raster and sets its rendering rule using the info.
91+ // This is required since the raster can't be loaded when setting its rendering rule.
92+ let imageServiceRaster = ImageServiceRaster ( url: . charlotteLASImageService)
93+ imageServiceRaster. renderingRule = RenderingRule ( info: renderingRuleInfo)
94+
95+ // Creates a layer using the raster.
96+ let rasterLayer = RasterLayer ( raster: imageServiceRaster)
97+ rasterLayer. name = renderingRuleInfo. name
98+
99+ return rasterLayer
100+ }
101+ }
102+ }
103+
104+ private extension URL {
105+ /// The web URL to the "CharlotteLAS" image service containing LAS files for Charlotte, NC downtown area.
106+ static var charlotteLASImageService : URL {
107+ URL ( string: " https://sampleserver6.arcgisonline.com/arcgis/rest/services/CharlotteLAS/ImageServer " ) !
23108 }
24109}
25110
0 commit comments