Skip to content

Commit a98c05e

Browse files
committed
optimised saveOSMElements in DatabaseConnector
- removed unnecessary enumerations, loops and duplicate operations - improved realm write operations
1 parent 4410fda commit a98c05e

File tree

1 file changed

+62
-73
lines changed

1 file changed

+62
-73
lines changed

GoInfoGame/GoInfoGame/DataBase/DatabaseConnector.swift

Lines changed: 62 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -24,89 +24,78 @@ class DatabaseConnector {
2424
@param elements List of OPElement
2525
*/
2626
func saveOSMElements(_ elements: [OSMElement]) {
27-
// Save the elements appropriately
28-
// Get the ways and nodes out
2927
let realm = try! Realm(configuration: RealmConfig.configuration)
30-
let nodes = elements.filter({$0 is OSMNode})
31-
let nodesOnly = elements.filter({$0 is OSMNode})
32-
// Create a dictionary out of this like [id : osmnode]
33-
var nodesDict: [String:OSMNode] = [:]
34-
nodesOnly.forEach { element in
35-
nodesDict[String(element.id)] = element as? OSMNode
28+
print("Realm path: \(realm.configuration.fileURL?.path ?? "No file URL")")
29+
30+
// Build lookup and filter nodes
31+
var nodesDict: [Int: OSMNode] = [:]
32+
let nodes = elements.compactMap { element -> OSMNode? in
33+
guard let node = element as? OSMNode else { return nil }
34+
nodesDict[node.id] = node
35+
return node
3636
}
37-
38-
let ways = elements.filter { element in
39-
guard let way = element as? OSMWay else {
40-
return false
37+
38+
let ways = elements.compactMap { element -> OSMWay? in
39+
guard let way = element as? OSMWay,
40+
!way.tags.isEmpty,
41+
way.tags["ext:link"] != "true" else {
42+
return nil
4143
}
42-
return !way.tags.isEmpty && !(way.tags["ext:link"] == "true")
44+
return way
4345
}
44-
45-
do {
46-
try realm.write {
47-
for node in nodes {
48-
let storedElement = StoredNode()
49-
storedElement.id = Int64(node.id)
50-
storedElement.tags.removeAll()
51-
node.tags.forEach { key, value in
52-
storedElement.tags[key] = value
53-
}
54-
// if let meta = node {
55-
storedElement.version = node.version
56-
storedElement.timestamp = node.timestamp
57-
// }
58-
if let asNode = node as? OSMNode{
59-
// coordinate from lat long
60-
storedElement.point = CLLocationCoordinate2D(latitude: asNode.lat, longitude: asNode.lon)
61-
// switch asNode.geometry {
62-
// case .center(let coordinate):
63-
// storedElement.point = coordinate
64-
// default:
65-
// continue
66-
// }
67-
}
68-
realm.add(storedElement, update: .all)
46+
47+
// Prepare Realm objects outside write block
48+
let storedNodes: [StoredNode] = nodes.map { node in
49+
let stored = StoredNode()
50+
stored.id = Int64(node.id)
51+
let map = Map<String, String>()
52+
node.tags.forEach { key, value in
53+
map[key] = value
54+
}
55+
stored.tags = map
56+
stored.version = node.version
57+
stored.timestamp = node.timestamp
58+
stored.point = CLLocationCoordinate2D(latitude: node.lat, longitude: node.lon)
59+
return stored
60+
}
61+
62+
let storedWays: [StoredWay] = ways.map { way in
63+
let stored = StoredWay()
64+
stored.id = Int64(way.id)
65+
let map = Map<String, String>()
66+
way.tags.forEach { key, value in
67+
if !key.contains(".") {
68+
map[key] = value
6969
}
70-
// Store the ways
71-
for way in ways {
72-
let storedWay = StoredWay()
73-
storedWay.id = Int64(way.id)
74-
storedWay.tags.removeAll()
75-
way.tags.forEach { key, value in
76-
if !key.contains(".") {
77-
storedWay.tags[key] = value
78-
}
79-
}
80-
storedWay.version = way.version
81-
storedWay.timestamp = way.timestamp
82-
if let asWay = way as? OSMWay {
83-
storedWay.nodes.append(objectsIn: asWay.nodes.map({Int64($0)}))
84-
// Get all the points for the p
85-
let nodesInWay = List<CLLocationCoordinate2D>()
86-
asWay.nodes.forEach { nodeId in
87-
if let actualNode = nodesDict[String(nodeId)] {
88-
nodesInWay.append(CLLocationCoordinate2D(latitude: actualNode.lat, longitude: actualNode.lon))
89-
}
90-
91-
}
92-
storedWay.polyline = nodesInWay
93-
// print("STORED POLYLINES --->>>\(storedWay.polyline)")
94-
// Store the coordinates
95-
//MARK: TBD polylines
96-
// switch asWay.geometry {
97-
// case .polygon(let coordinates):
98-
// storedWay.polyline.append(objectsIn: coordinates)
99-
// default:
100-
// print("Ignoring geometry")
101-
// }
102-
}
103-
realm.add(storedWay, update: .all)
70+
}
71+
stored.tags = map
72+
stored.version = way.version
73+
stored.timestamp = way.timestamp
74+
stored.nodes.append(objectsIn: way.nodes.map(Int64.init))
75+
76+
let polyline = List<CLLocationCoordinate2D>()
77+
for nodeId in way.nodes {
78+
if let node = nodesDict[nodeId] {
79+
polyline.append(CLLocationCoordinate2D(latitude: node.lat, longitude: node.lon))
10480
}
10581
}
82+
stored.polyline = polyline
83+
return stored
84+
}
85+
86+
// Persist to Realm
87+
do {
88+
realm.autorefresh = false
89+
try realm.write {
90+
realm.add(storedNodes, update: .all)
91+
realm.add(storedWays, update: .all)
92+
}
93+
realm.autorefresh = true
10694
} catch {
107-
print("Elements to be skipped or something happened")
95+
print("❌ Realm write failed: \(error)")
10896
}
10997
}
98+
11099

111100
func clearDB() {
112101
do {

0 commit comments

Comments
 (0)