Skip to content

Commit b202a21

Browse files
authored
Merge branch 'v.next' into Caleb/New-FindAddressWithReverseGeocode
2 parents 3787ae0 + 0390d7a commit b202a21

File tree

8 files changed

+693
-0
lines changed

8 files changed

+693
-0
lines changed

Samples.xcodeproj/project.pbxproj

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@
187187
D7337C602ABD142D00A5D865 /* ShowMobileMapPackageExpirationDateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7337C5F2ABD142D00A5D865 /* ShowMobileMapPackageExpirationDateView.swift */; };
188188
D7337C612ABD166A00A5D865 /* ShowMobileMapPackageExpirationDateView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = D7337C5F2ABD142D00A5D865 /* ShowMobileMapPackageExpirationDateView.swift */; };
189189
D734FA0C2A183A5B00246D7E /* SetMaxExtentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D734FA092A183A5B00246D7E /* SetMaxExtentView.swift */; };
190+
D73723762AF5877500846884 /* FindRouteInMobileMapPackageView.Models.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73723742AF5877500846884 /* FindRouteInMobileMapPackageView.Models.swift */; };
191+
D73723792AF5ADD800846884 /* FindRouteInMobileMapPackageView.MobileMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73723782AF5ADD700846884 /* FindRouteInMobileMapPackageView.MobileMapView.swift */; };
192+
D737237A2AF5AE1600846884 /* FindRouteInMobileMapPackageView.MobileMapView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = D73723782AF5ADD700846884 /* FindRouteInMobileMapPackageView.MobileMapView.swift */; };
193+
D737237B2AF5AE1A00846884 /* FindRouteInMobileMapPackageView.Models.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = D73723742AF5877500846884 /* FindRouteInMobileMapPackageView.Models.swift */; };
190194
D73F8CF42AB1089900CD39DA /* Restaurant.stylx in Resources */ = {isa = PBXBuildFile; fileRef = D73F8CF32AB1089900CD39DA /* Restaurant.stylx */; settings = {ASSET_TAGS = (StyleFeaturesWithCustomDictionary, ); }; };
191195
D73FC0FD2AD4A18D0067A19B /* CreateMobileGeodatabaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73FC0FC2AD4A18D0067A19B /* CreateMobileGeodatabaseView.swift */; };
192196
D73FC0FE2AD4A19A0067A19B /* CreateMobileGeodatabaseView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = D73FC0FC2AD4A18D0067A19B /* CreateMobileGeodatabaseView.swift */; };
@@ -225,6 +229,9 @@
225229
D75B58522AAFB37C0038B3B4 /* StyleFeaturesWithCustomDictionaryView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = D75B58502AAFB3030038B3B4 /* StyleFeaturesWithCustomDictionaryView.swift */; };
226230
D75C35672AB50338003CD55F /* GroupLayersTogetherView.GroupLayerListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D75C35662AB50338003CD55F /* GroupLayersTogetherView.GroupLayerListView.swift */; };
227231
D76000A22AF18BAB00B3084D /* FindRouteInTransportNetworkView.Model.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = D7749AD52AF08BF50086632F /* FindRouteInTransportNetworkView.Model.swift */; };
232+
D76000AE2AF19C2300B3084D /* FindRouteInMobileMapPackageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76000AB2AF19C2300B3084D /* FindRouteInMobileMapPackageView.swift */; };
233+
D76000B12AF19C4600B3084D /* FindRouteInMobileMapPackageView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = D76000AB2AF19C2300B3084D /* FindRouteInMobileMapPackageView.swift */; };
234+
D76000B72AF19FCA00B3084D /* SanFrancisco.mmpk in Resources */ = {isa = PBXBuildFile; fileRef = D76000B62AF19FCA00B3084D /* SanFrancisco.mmpk */; settings = {ASSET_TAGS = (FindRouteInMobileMapPackage, ); }; };
228235
D7634FAF2A43B7AC00F8AEFB /* CreateConvexHullAroundGeometriesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7634FAE2A43B7AC00F8AEFB /* CreateConvexHullAroundGeometriesView.swift */; };
229236
D7634FB02A43B8B000F8AEFB /* CreateConvexHullAroundGeometriesView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = D7634FAE2A43B7AC00F8AEFB /* CreateConvexHullAroundGeometriesView.swift */; };
230237
D769C2122A29019B00030F61 /* SetUpLocationDrivenGeotriggersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D769C2112A29019B00030F61 /* SetUpLocationDrivenGeotriggersView.swift */; };
@@ -370,6 +377,9 @@
370377
dstSubfolderSpec = 7;
371378
files = (
372379
D73FCFFA2B02A3C50006360D /* FindAddressWithReverseGeocodeView.swift in Copy Source Code Files */,
380+
D737237B2AF5AE1A00846884 /* FindRouteInMobileMapPackageView.Models.swift in Copy Source Code Files */,
381+
D737237A2AF5AE1600846884 /* FindRouteInMobileMapPackageView.MobileMapView.swift in Copy Source Code Files */,
382+
D76000B12AF19C4600B3084D /* FindRouteInMobileMapPackageView.swift in Copy Source Code Files */,
373383
D7705D662AFC575000CC0335 /* FindClosestFacilityFromPointView.swift in Copy Source Code Files */,
374384
D73FD0002B02C9610006360D /* FindRouteAroundBarriersView.Views.swift in Copy Source Code Files */,
375385
D76EE6082AF9AFEC00DA0325 /* FindRouteAroundBarriersView.Model.swift in Copy Source Code Files */,
@@ -607,6 +617,8 @@
607617
D7337C592ABCFDB100A5D865 /* StyleSymbolsFromMobileStyleFileView.SymbolOptionsListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StyleSymbolsFromMobileStyleFileView.SymbolOptionsListView.swift; sourceTree = "<group>"; };
608618
D7337C5F2ABD142D00A5D865 /* ShowMobileMapPackageExpirationDateView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShowMobileMapPackageExpirationDateView.swift; sourceTree = "<group>"; };
609619
D734FA092A183A5B00246D7E /* SetMaxExtentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetMaxExtentView.swift; sourceTree = "<group>"; };
620+
D73723742AF5877500846884 /* FindRouteInMobileMapPackageView.Models.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FindRouteInMobileMapPackageView.Models.swift; sourceTree = "<group>"; };
621+
D73723782AF5ADD700846884 /* FindRouteInMobileMapPackageView.MobileMapView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FindRouteInMobileMapPackageView.MobileMapView.swift; sourceTree = "<group>"; };
610622
D73F8CF32AB1089900CD39DA /* Restaurant.stylx */ = {isa = PBXFileReference; lastKnownFileType = file; path = Restaurant.stylx; sourceTree = "<group>"; };
611623
D73FC0FC2AD4A18D0067A19B /* CreateMobileGeodatabaseView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateMobileGeodatabaseView.swift; sourceTree = "<group>"; };
612624
D73FCFF42B02A3AA0006360D /* FindAddressWithReverseGeocodeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FindAddressWithReverseGeocodeView.swift; sourceTree = "<group>"; };
@@ -628,6 +640,8 @@
628640
D7553CD82AE2DFEC00DC2A70 /* GeocodeOfflineView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeocodeOfflineView.swift; sourceTree = "<group>"; };
629641
D75B58502AAFB3030038B3B4 /* StyleFeaturesWithCustomDictionaryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StyleFeaturesWithCustomDictionaryView.swift; sourceTree = "<group>"; };
630642
D75C35662AB50338003CD55F /* GroupLayersTogetherView.GroupLayerListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GroupLayersTogetherView.GroupLayerListView.swift; sourceTree = "<group>"; };
643+
D76000AB2AF19C2300B3084D /* FindRouteInMobileMapPackageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FindRouteInMobileMapPackageView.swift; sourceTree = "<group>"; };
644+
D76000B62AF19FCA00B3084D /* SanFrancisco.mmpk */ = {isa = PBXFileReference; lastKnownFileType = file; path = SanFrancisco.mmpk; sourceTree = "<group>"; };
631645
D7634FAE2A43B7AC00F8AEFB /* CreateConvexHullAroundGeometriesView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateConvexHullAroundGeometriesView.swift; sourceTree = "<group>"; };
632646
D769C2112A29019B00030F61 /* SetUpLocationDrivenGeotriggersView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetUpLocationDrivenGeotriggersView.swift; sourceTree = "<group>"; };
633647
D76EE6062AF9AFE100DA0325 /* FindRouteAroundBarriersView.Model.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FindRouteAroundBarriersView.Model.swift; sourceTree = "<group>"; };
@@ -824,6 +838,7 @@
824838
D78666A92A21616D00C60110 /* Find nearest vertex */,
825839
E066DD33285CF3A0004D3D5B /* Find route */,
826840
D7DDF84F2AF47C6C004352D9 /* Find route around barriers */,
841+
D76000AA2AF19C2300B3084D /* Find route in mobile map package */,
827842
D7E7D0792AEB39BF003AAD02 /* Find route in transport network */,
828843
E088E1722863B5E600413100 /* Generate offline map */,
829844
D7553CD62AE2DFEC00DC2A70 /* Geocode offline */,
@@ -964,6 +979,7 @@
964979
00D4EF8328638BF100B9CC30 /* 15a7cbd3af1e47cfa5d2c6b93dc44fc2 */,
965980
D7CE9F992AE2F575008F7A5F /* 22c3083d4fa74e3e9b25adfc9f8c0496 */,
966981
00D4EF8E28638BF100B9CC30 /* 68ec42517cdd439e81b036210483e8e7 */,
982+
D76000B52AF19FC900B3084D /* 260eb6535c824209964cf281766ebe43 */,
967983
D7C16D202AC5FE9800689E89 /* 290f0c571c394461a8b58b6775d0bd63 */,
968984
1C965C4629DBA879002F8536 /* 681d6f7694644709a7c830ec57a2d72b */,
969985
D7CE9F9C2AE2F585008F7A5F /* 3424d442ebe54f3cbf34462382d3aebe */,
@@ -1521,6 +1537,24 @@
15211537
path = "Style features with custom dictionary";
15221538
sourceTree = "<group>";
15231539
};
1540+
D76000AA2AF19C2300B3084D /* Find route in mobile map package */ = {
1541+
isa = PBXGroup;
1542+
children = (
1543+
D73723782AF5ADD700846884 /* FindRouteInMobileMapPackageView.MobileMapView.swift */,
1544+
D73723742AF5877500846884 /* FindRouteInMobileMapPackageView.Models.swift */,
1545+
D76000AB2AF19C2300B3084D /* FindRouteInMobileMapPackageView.swift */,
1546+
);
1547+
path = "Find route in mobile map package";
1548+
sourceTree = "<group>";
1549+
};
1550+
D76000B52AF19FC900B3084D /* 260eb6535c824209964cf281766ebe43 */ = {
1551+
isa = PBXGroup;
1552+
children = (
1553+
D76000B62AF19FCA00B3084D /* SanFrancisco.mmpk */,
1554+
);
1555+
path = 260eb6535c824209964cf281766ebe43;
1556+
sourceTree = "<group>";
1557+
};
15241558
D769C20D2A28FF8600030F61 /* Set up location-driven geotriggers */ = {
15251559
isa = PBXGroup;
15261560
children = (
@@ -1987,6 +2021,7 @@
19872021
ChangeCameraController,
19882022
DisplayDimensions,
19892023
DisplayMapFromMobileMapPackage,
2024+
FindRouteInMobileMapPackage,
19902025
FindRouteInTransportNetwork,
19912026
GeocodeOffline,
19922027
IdentifyRasterCell,
@@ -2046,6 +2081,7 @@
20462081
D73F8CF42AB1089900CD39DA /* Restaurant.stylx in Resources */,
20472082
D74C8C022ABA6202007C76B8 /* emoji-mobile.stylx in Resources */,
20482083
D7CE9FA32AE2F595008F7A5F /* san-diego-eagle-locator in Resources */,
2084+
D76000B72AF19FCA00B3084D /* SanFrancisco.mmpk in Resources */,
20492085
792222DD2A81AA5D00619FFE /* AIS_MarineCadastre_SelectedVessels_CustomDataSource.jsonl in Resources */,
20502086
E041AC20288077B90056009B /* xcode.css in Resources */,
20512087
00D4EF9028638BF100B9CC30 /* LA_Trails.geodatabase in Resources */,
@@ -2166,6 +2202,7 @@
21662202
1C3B7DC82A5F64FC00907443 /* AnalyzeNetworkWithSubnetworkTraceView.Model.swift in Sources */,
21672203
D752D9402A39154C003EB25E /* ManageOperationalLayersView.swift in Sources */,
21682204
D7ABA2F92A32579C0021822B /* MeasureDistanceInSceneView.swift in Sources */,
2205+
D73723792AF5ADD800846884 /* FindRouteInMobileMapPackageView.MobileMapView.swift in Sources */,
21692206
E004A6E028466279002A1FE6 /* ShowCalloutView.swift in Sources */,
21702207
E000E763286A0B18005D87C5 /* CutGeometryView.swift in Sources */,
21712208
D7705D582AFC244E00CC0335 /* FindClosestFacilityToMultiplePointsView.swift in Sources */,
@@ -2284,10 +2321,12 @@
22842321
0042E24528E4F82C001F33D6 /* ShowViewshedFromPointInSceneView.ViewshedSettingsView.swift in Sources */,
22852322
D7DDF8532AF47C6C004352D9 /* FindRouteAroundBarriersView.swift in Sources */,
22862323
1C9B74D929DB54560038B06F /* ChangeCameraControllerView.swift in Sources */,
2324+
D76000AE2AF19C2300B3084D /* FindRouteInMobileMapPackageView.swift in Sources */,
22872325
00273CF42A82AB5900A7A77D /* SamplesSearchView.swift in Sources */,
22882326
D78666AD2A2161F100C60110 /* FindNearestVertexView.swift in Sources */,
22892327
D7C16D1B2AC5F95300689E89 /* Animate3DGraphicView.swift in Sources */,
22902328
D744FD172A2112D90084A66C /* CreateConvexHullAroundPointsView.swift in Sources */,
2329+
D73723762AF5877500846884 /* FindRouteInMobileMapPackageView.Models.swift in Sources */,
22912330
00CB9138284814A4005C2C5D /* SearchWithGeocodeView.swift in Sources */,
22922331
1C43BC7F2A43781200509BF8 /* SetVisibilityOfSubtypeSublayerView.Views.swift in Sources */,
22932332
D754E3232A1D66820006C5F1 /* StylePointWithPictureMarkerSymbolsView.swift in Sources */,
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
// Copyright 2023 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+
extension FindRouteInMobileMapPackageView {
19+
/// The map view for a mobile map package map.
20+
struct MobileMapView: View {
21+
/// The view model for the view.
22+
@StateObject private var model: Model
23+
24+
/// The placement of the address callout on the map.
25+
@State private var calloutPlacement: CalloutPlacement?
26+
27+
/// The text address shown in the callout.
28+
@State private var calloutText: String = ""
29+
30+
/// The point on the screen where the user tapped.
31+
@State private var tapScreenPoint: CGPoint?
32+
33+
/// A Boolean value indicating whether the reset button is disabled.
34+
@State private var resetDisabled = true
35+
36+
/// A Boolean value indicating whether the error alert is showing.
37+
@State private var errorAlertIsShowing = false
38+
39+
/// The error shown in the error alert.
40+
@State private var error: Error? {
41+
didSet { errorAlertIsShowing = error != nil }
42+
}
43+
44+
init(map: Map, locatorTask: LocatorTask) {
45+
let model = Model(map: map, locatorTask: locatorTask)
46+
_model = StateObject(wrappedValue: model)
47+
}
48+
49+
var body: some View {
50+
MapViewReader { mapViewProxy in
51+
MapView(map: model.map, graphicsOverlays: model.graphicsOverlays)
52+
.callout(placement: $calloutPlacement) { _ in
53+
Text(calloutText)
54+
.font(.callout)
55+
.padding(8)
56+
}
57+
.onSingleTapGesture { screenPoint, _ in
58+
tapScreenPoint = screenPoint
59+
}
60+
.task(id: tapScreenPoint) {
61+
guard let tapScreenPoint else { return }
62+
63+
do {
64+
// Check to see if the tap was on a marker.
65+
let identifyResult = try await mapViewProxy.identify(
66+
on: model.markerGraphicsOverlay,
67+
screenPoint: tapScreenPoint,
68+
tolerance: 12
69+
)
70+
71+
if let graphic = identifyResult.graphics.first,
72+
let graphicPoint = graphic.geometry as? Point {
73+
// Update the callout to the identified marker.
74+
await updateCallout(point: graphicPoint, graphic: graphic)
75+
} else {
76+
// Add a graphic at the tapped map point.
77+
guard let location = mapViewProxy.location(
78+
fromScreenPoint: tapScreenPoint
79+
) else { return }
80+
await addGraphic(at: location)
81+
}
82+
} catch {
83+
self.error = error
84+
}
85+
}
86+
}
87+
.toolbar {
88+
ToolbarItemGroup(placement: .bottomBar) {
89+
Spacer()
90+
Button("Reset") {
91+
resetGraphics()
92+
}
93+
.disabled(resetDisabled)
94+
}
95+
}
96+
.task {
97+
// Load the route parameters sample loads.
98+
do {
99+
try await model.loadRouteParameters()
100+
} catch {
101+
self.error = error
102+
}
103+
}
104+
.alert(isPresented: $errorAlertIsShowing, presentingError: error)
105+
}
106+
107+
/// Updates the placement and text of the callout using a given point and graphic.
108+
/// - Parameters:
109+
/// - point: The point to reverse geocode and set the callout placement to.
110+
/// - graphic: The graphic at the point.
111+
private func updateCallout(point: Point, graphic: Graphic) async {
112+
// Update the callout text with the address from a reverse geocode.
113+
do {
114+
calloutText = try await model.reverseGeocode(point: point)
115+
} catch {
116+
self.error = error
117+
calloutText = "No address found"
118+
}
119+
120+
// Update the callout placement with the graphic and point.
121+
calloutPlacement = .geoElement(graphic, tapLocation: point)
122+
}
123+
124+
/// Adds a marker or route stop with a callout at a given point.
125+
/// - Parameter point: The point to add the graphic at.
126+
private func addGraphic(at point: Point) async {
127+
// Normalize the tap location.
128+
guard let point = GeometryEngine.normalizeCentralMeridian(of: point) as? Point else { return }
129+
130+
// Add a route stop if the map has routing. Otherwise, update the marker.
131+
if model.routeTask != nil {
132+
do {
133+
try await model.addRouteStop(at: point)
134+
} catch {
135+
self.error = error
136+
}
137+
} else {
138+
model.updateMarker(to: point)
139+
}
140+
141+
// Update the callout with the last marker.
142+
guard let lastMarker = model.lastMarker else { return }
143+
await updateCallout(point: point, graphic: lastMarker)
144+
145+
resetDisabled = false
146+
}
147+
148+
/// Resets the graphics on the map view.
149+
private func resetGraphics() {
150+
// Reset the view properties.
151+
calloutPlacement = nil
152+
resetDisabled = true
153+
154+
// Reset the graphics.
155+
if model.routeTask != nil {
156+
model.markerGraphicsOverlay.removeAllGraphics()
157+
model.routeGraphicsOverlay?.removeAllGraphics()
158+
} else {
159+
model.lastMarker?.geometry = nil
160+
}
161+
}
162+
}
163+
}

0 commit comments

Comments
 (0)