Skip to content

Commit 7052581

Browse files
authored
Merge pull request #271 from TaskarCenterAtUW/bug-1990-GiG-User-Interactions-Are-Slow
improved pins rendering on map with cluster
2 parents b69afb5 + 803bca1 commit 7052581

File tree

15 files changed

+362
-228
lines changed

15 files changed

+362
-228
lines changed

GoInfoGame/GoInfoGame.xcodeproj/project.pbxproj

Lines changed: 28 additions & 72 deletions
Large diffs are not rendered by default.

GoInfoGame/GoInfoGame.xcodeproj/xcshareddata/xcschemes/GoInfoGame.xcscheme

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,18 @@
7878
ReferencedContainer = "container:GoInfoGame.xcodeproj">
7979
</BuildableReference>
8080
</BuildableProductRunnable>
81+
<AdditionalOptions>
82+
<AdditionalOption
83+
key = "MallocStackLogging"
84+
value = ""
85+
isEnabled = "YES">
86+
</AdditionalOption>
87+
<AdditionalOption
88+
key = "PrefersMallocStackLoggingLite"
89+
value = ""
90+
isEnabled = "YES">
91+
</AdditionalOption>
92+
</AdditionalOptions>
8193
</LaunchAction>
8294
<ProfileAction
8395
buildConfiguration = "Release"

GoInfoGame/GoInfoGame.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

GoInfoGame/GoInfoGame/AppQuestManager.swift

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,44 @@ class AppQuestManager {
6969
// Fetches all the available quests from Database
7070
func fetchQuestsFromDB() -> [DisplayUnitWithCoordinate] {
7171

72-
let allOriginalNodes = dbInstance.getNodes().filter {$0.tags.count != 0 }
72+
let allOriginalNodes = dbInstance.getNodes().filter {$0.tags.count != 0 && ($0.point.latitude != 0.0 || $0.point.longitude != 0.0)}
7373

7474

75-
let nodesFromStorage: [StoredNode] = allOriginalNodes.compactMap { original in
76-
original.tags["ext:gig_complete"] == "yes" ? nil : original
75+
var nodesFromStorage: [StoredNode] = []
76+
for node in allOriginalNodes {
77+
autoreleasepool {
78+
if node.tags["ext:gig_complete"] != "yes" {
79+
nodesFromStorage.append(node)
80+
}
81+
}
7782
}
7883

7984
let allOriginalWays = dbInstance.getWays().filter {
80-
$0.tags.count != 0
85+
$0.tags.count != 0 && !$0.polyline.isEmpty
8186
}
8287

83-
let waysFromStorage: [StoredWay] = allOriginalWays.compactMap { original in
84-
original.tags["ext:gig_complete"] == "yes" ? nil : original
88+
var waysFromStorage: [StoredWay] = []
89+
90+
for way in allOriginalWays {
91+
autoreleasepool {
92+
if way.tags["ext:gig_complete"] != "yes" {
93+
waysFromStorage.append(way)
94+
}
95+
}
8596
}
8697

8798

88-
let nodeElements = nodesFromStorage.map({$0.asNode()})
89-
let wayElements = waysFromStorage.map({$0.asWay()})
99+
let nodeElements = nodesFromStorage.map({ node in
100+
autoreleasepool {
101+
node.asNode()
102+
}
103+
})
104+
let wayElements = waysFromStorage.map({ way in
105+
autoreleasepool {
106+
way.asWay()
107+
}
108+
109+
})
90110

91111
// Get the quests for nodes
92112
var nodeQuests: [any Quest] = []

GoInfoGame/GoInfoGame/UI/CustomComponents/RadioItem.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77

88
import SwiftUI
99

10+
struct TextItem<T> {
11+
let value: T
12+
let titleId: String
13+
}
14+
1015
struct RadioItem<T>: View {
1116
let textItem: TextItem<T>
1217
let isSelected: Bool

GoInfoGame/GoInfoGame/UI/InitialView/InitialViewModel.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ class InitialViewModel: ObservableObject {
9292

9393
isLoading = true
9494

95-
ApiManager.shared.performRequest(to: .fetchLongQuests(workspaceId), setupType: .workspace, modelType: LongFormResponse.self) { result in
96-
DispatchQueue.main.async {
95+
ApiManager.shared.performRequest(to: .fetchLongQuests(workspaceId), setupType: .workspace, modelType: LongFormResponse.self) { [unowned self] result in
96+
DispatchQueue.main.async { [unowned self] in
9797
switch result {
9898
case .success(let longQuestsResponse):
9999

GoInfoGame/GoInfoGame/UI/Map/CustomMap.swift

Lines changed: 124 additions & 97 deletions
Large diffs are not rendered by default.

GoInfoGame/GoInfoGame/UI/Map/MapView.swift

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ struct MapView: View {
7777
selectedQuest: $viewModel.selectedQuest,
7878
shouldShowPolyline: $shouldShowPolyline,
7979

80-
isPresented: $isPresented, isUserSettingsPresented: $showUserSettingsSheet, selectedAnnotations: $viewModel.selectedAnnotaions, isMultiSelectModeEnabled: $viewModel.isMultiSelectModeEnabled, selectedAnnotationType: $viewModel.selectedAnnotationType, showMultiSelectionBottomSheet: $showMultiSelectionBottomSheet,
80+
isPresented: $isPresented, isUserSettingsPresented: $showUserSettingsSheet, selectedAnnotations: $viewModel.selectedAnnotaions, isMultiSelectModeEnabled: $viewModel.isMultiSelectModeEnabled, selectedAnnotationType: $viewModel.selectedAnnotationType, showMultiSelectionBottomSheet: $showMultiSelectionBottomSheet ,
8181
onMapViewCreated: { map in
8282
self.mapViewRef = map
83-
},
83+
} ,
8484
contextualInfo: { contextualInfo in
8585
print(contextualInfo)
8686
selectedDetent = .fraction(0.8)
@@ -162,7 +162,7 @@ struct MapView: View {
162162

163163
if !viewModel.selectedAnnotaions.isEmpty,
164164
let selectedAnnotationType = viewModel.selectedAnnotationType,
165-
let image = viewModel.selectedAnnotaions.first?.displayUnit.parent?.icon {
165+
let image = UIImage(named: viewModel.selectedAnnotaions.first?.displayUnit?.parent?.iconName ?? "notes") {
166166

167167
MultiQuestSelectionBottomSheet(
168168
selectedAnnotationType: selectedAnnotationType,
@@ -427,9 +427,34 @@ struct MapView: View {
427427
}
428428

429429
func isBBoxValid(_ bbox: BBox) -> Bool {
430-
let latDelta = bbox.maxLat - bbox.minLat
431-
let lonDelta = bbox.maxLon - bbox.minLon
432-
return latDelta * lonDelta <= 1.0
430+
return isBBoxValid(minLat: bbox.minLat, minLon: bbox.minLon, maxLat: bbox.maxLat, maxLon: bbox.maxLon)
431+
}
432+
433+
private func isBBoxValid(minLat: Double, minLon: Double, maxLat: Double, maxLon: Double) -> Bool {
434+
let latDistanceKm = haversineDistance(lat1: minLat, lon1: minLon, lat2: maxLat, lon2: minLon)
435+
let lonDistanceKm = haversineDistance(lat1: minLat, lon1: minLon, lat2: minLat, lon2: maxLon)
436+
437+
let areaKm2 = latDistanceKm * lonDistanceKm
438+
print("Area: \(areaKm2) km²")
439+
440+
return areaKm2 < 12.0 // allow small tolerance
441+
}
442+
443+
private func haversineDistance(lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> Double {
444+
let earthRadiusKm = 6371.0
445+
let dLat = degreesToRadians(lat2 - lat1)
446+
let dLon = degreesToRadians(lon2 - lon1)
447+
448+
let a = sin(dLat / 2) * sin(dLat / 2) +
449+
cos(degreesToRadians(lat1)) * cos(degreesToRadians(lat2)) *
450+
sin(dLon / 2) * sin(dLon / 2)
451+
let c = 2 * atan2(sqrt(a), sqrt(1 - a))
452+
453+
return earthRadiusKm * c
454+
}
455+
456+
private func degreesToRadians(_ degrees: Double) -> Double {
457+
return degrees * .pi / 180.0
433458
}
434459
}
435460

GoInfoGame/GoInfoGame/UI/Map/MapViewModel.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ class MapViewModel: ObservableObject {
6565
}
6666

6767
for quest in self.selectedAnnotaions {
68-
print("Quest ID: \(quest.displayUnit.id) Tags: \(tags)")
69-
if let longElementQuest = quest.displayUnit.parent as? LongElementQuest {
68+
print("Quest ID: \(quest.id) Tags: \(tags)")
69+
if let longElementQuest = quest.displayUnit?.parent as? LongElementQuest {
7070
longElementQuest.onAnswer(answer: tags)
7171
}
7272
}
@@ -99,6 +99,9 @@ class MapViewModel: ObservableObject {
9999
}
100100

101101
func fetchOSMDataFor(from bboxSource: BBoxSource) {
102+
if isLoading {
103+
return
104+
}
102105
isLoading = true
103106
let bBox: BBox
104107
switch bboxSource {
@@ -115,7 +118,7 @@ class MapViewModel: ObservableObject {
115118

116119
if let workspaceID = KeychainManager.load(key: "workspaceID") {
117120

118-
ApiManager.shared.performRequest(to: .fetchOSMElements(bBox.minLon, bBox.minLat, bBox.maxLon, bBox.maxLat, workspaceID), setupType: .osm, modelType: OSMMapDataResponse.self) { result in
121+
ApiManager.shared.performRequest(to: .fetchOSMElements(bBox.minLon, bBox.minLat, bBox.maxLon, bBox.maxLat, workspaceID), setupType: .osm, modelType: OSMMapDataResponse.self) { [unowned self] result in
119122
switch result {
120123
case .success(let success):
121124
let osmElements = success.getOSMElements()
@@ -124,9 +127,11 @@ class MapViewModel: ObservableObject {
124127
let response = Array(osmElements.values)
125128
let allValues = response
126129

127-
DispatchQueue.main.async {
130+
DispatchQueue.main.async { [unowned self, allValues] in
128131
self.dbInstance.saveOSMElements(allValues) // Save all where there are tags
129-
self.items = AppQuestManager.shared.fetchQuestsFromDB()
132+
autoreleasepool { [unowned self] in
133+
self.items = AppQuestManager.shared.fetchQuestsFromDB()
134+
}
130135
self.isLoading = false
131136
if self.items.count == 0 {self.refreshMap = UUID()}
132137
}

GoInfoGame/GoInfoGame/quests/CrossingMarking/CrossMarking.swift

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,3 @@ enum CrossingAnswer: String {
6565
case no = "No"
6666
case none = "none"
6767
}
68-
69-
struct TextItem<T> {
70-
let value: T
71-
let titleId: String
72-
}

0 commit comments

Comments
 (0)