diff --git a/Meshtastic Client.xcodeproj/project.xcworkspace/xcuserdata/joshuapirihi.xcuserdatad/UserInterfaceState.xcuserstate b/Meshtastic Client.xcodeproj/project.xcworkspace/xcuserdata/joshuapirihi.xcuserdatad/UserInterfaceState.xcuserstate index 423ac35f..8bcb5868 100644 Binary files a/Meshtastic Client.xcodeproj/project.xcworkspace/xcuserdata/joshuapirihi.xcuserdatad/UserInterfaceState.xcuserstate and b/Meshtastic Client.xcodeproj/project.xcworkspace/xcuserdata/joshuapirihi.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/MeshtasticClient/MeshtasticClientApp.swift b/MeshtasticClient/MeshtasticClientApp.swift index e72b1713..10879c8b 100644 --- a/MeshtasticClient/MeshtasticClientApp.swift +++ b/MeshtasticClient/MeshtasticClientApp.swift @@ -23,10 +23,21 @@ struct MeshtasticClientApp: App { let fileManager = FileManager.default let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first! let destination = documentsDirectory.appendingPathComponent("offline_map.mbtiles", isDirectory: false) + + //do we need to delete an old one? + if (fileManager.fileExists(atPath: destination.path)) { + print("ℹ️ Found an old map file. Deleting it") + try? fileManager.removeItem(atPath: destination.path) + } + try? fileManager.copyItem(at: url, to: destination) if (fileManager.fileExists(atPath: destination.path)) { print("ℹ️ Saved the map file") + + //need to tell the map view that it needs to update and try loading the new overlay + UserDefaults.standard.set(Date().timeIntervalSince1970, forKey: "lastUpdatedLocalMapFile") + } else { print("💥 Didn't save the map file") } diff --git a/MeshtasticClient/Views/Map/LocalMBTileOverlay.swift b/MeshtasticClient/Views/Map/LocalMBTileOverlay.swift index 088f6365..ed3f4022 100644 --- a/MeshtasticClient/Views/Map/LocalMBTileOverlay.swift +++ b/MeshtasticClient/Views/Map/LocalMBTileOverlay.swift @@ -33,6 +33,11 @@ extension MKMapRect { } } +enum MapTileError: Error { + case invalidFormat + case other +} + class LocalMBTileOverlay: MKTileOverlay { var path: String! @@ -46,7 +51,7 @@ class LocalMBTileOverlay: MKTileOverlay { } } - init(mbTilePath path: String) { + init?(mbTilePath path: String) { super.init(urlTemplate: nil) self.path = path @@ -58,6 +63,12 @@ class LocalMBTileOverlay: MKTileOverlay { let name = Expression("name") let value = Expression("value") + //make sure it's raster + let formatQuery = try mb.pluck(metadata.select(value).filter(name == "format")) + if formatQuery?[value] == nil || (formatQuery![value] != "jpg" && formatQuery![value] != "png") { + throw MapTileError.invalidFormat + } + let minZQuery = try mb.pluck(metadata.select(value).filter(name == "minzoom")) self.minimumZ = Int(minZQuery![value])! @@ -78,7 +89,8 @@ class LocalMBTileOverlay: MKTileOverlay { } catch { - //print("MAP ERROR \(error)") + print("💥 Map tile error: \(error)") + return nil } diff --git a/MeshtasticClient/Views/Map/MapViewModule.swift b/MeshtasticClient/Views/Map/MapViewModule.swift index 28fc41b4..0bebbc20 100644 --- a/MeshtasticClient/Views/Map/MapViewModule.swift +++ b/MeshtasticClient/Views/Map/MapViewModule.swift @@ -17,6 +17,10 @@ public struct MapView: UIViewRepresentable { //@Binding private var region: MKCoordinateRegion + //make this view dependent on the UserDefault that is updated when importing a new map file + @AppStorage("lastUpdatedLocalMapFile") private var lastUpdatedLocalMapFile = 0 + @State private var loadedLastUpdatedLocalMapFile = 0 + private var customMapOverlay: CustomMapOverlay? @State private var presentCustomMapOverlayHash: CustomMapOverlay? @@ -138,7 +142,7 @@ public struct MapView: UIViewRepresentable { //mapView.region = self.region //} - if self.customMapOverlay != self.presentCustomMapOverlayHash { + if self.customMapOverlay != self.presentCustomMapOverlayHash || self.loadedLastUpdatedLocalMapFile != self.lastUpdatedLocalMapFile { mapView.removeOverlays(mapView.overlays) if let customMapOverlay = self.customMapOverlay { @@ -150,17 +154,19 @@ public struct MapView: UIViewRepresentable { print("Loading local map file") - let overlay = LocalMBTileOverlay(mbTilePath: tilePath) + if let overlay = LocalMBTileOverlay(mbTilePath: tilePath) { - overlay.canReplaceMapContent = false//customMapOverlay.canReplaceMapContent + overlay.canReplaceMapContent = false//customMapOverlay.canReplaceMapContent - mapView.addOverlay(overlay) + mapView.addOverlay(overlay) + } } else { print("Couldn't find a local map file to load") } } DispatchQueue.main.async { self.presentCustomMapOverlayHash = self.customMapOverlay + self.loadedLastUpdatedLocalMapFile = self.lastUpdatedLocalMapFile } }