From d16708b337f01591d0f0722d00f0552af92d5c2e Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 7 May 2023 08:01:16 -0700 Subject: [PATCH] Add tiles above labels setting, add delete cached tiles button --- Meshtastic.xcodeproj/project.pbxproj | 4 ++ Meshtastic/Extensions/UserDefaults.swift | 11 +++++ .../Views/Map/Custom/MapViewSwiftUI.swift | 2 +- Meshtastic/Views/Map/Custom/TilesView.swift | 48 +++++++++++++++++++ Meshtastic/Views/Nodes/NodeMap.swift | 27 +++++++++-- de.lproj/Localizable.strings | 4 +- en.lproj/Localizable.strings | 4 +- zh-Hans.lproj/Localizable.strings | 4 +- 8 files changed, 90 insertions(+), 14 deletions(-) create mode 100644 Meshtastic/Views/Map/Custom/TilesView.swift diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 3367b256..49095803 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -103,6 +103,7 @@ DDB75A142A0593E2006ED576 /* OfflineTileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB75A132A0593E2006ED576 /* OfflineTileManager.swift */; }; DDB75A162A0594AD006ED576 /* TileOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB75A152A0594AD006ED576 /* TileOverlay.swift */; }; DDB75A1A2A05EB67006ED576 /* alpha.png in Resources */ = {isa = PBXBuildFile; fileRef = DDB75A192A05EB67006ED576 /* alpha.png */; }; + DDB75A1C2A076DFA006ED576 /* TilesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB75A1B2A076DFA006ED576 /* TilesView.swift */; }; DDC2E15826CE248E0042C5E4 /* MeshtasticApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E15726CE248E0042C5E4 /* MeshtasticApp.swift */; }; DDC2E15C26CE248F0042C5E4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */; }; DDC2E15F26CE248F0042C5E4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDC2E15E26CE248F0042C5E4 /* Preview Assets.xcassets */; }; @@ -291,6 +292,7 @@ DDB75A132A0593E2006ED576 /* OfflineTileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfflineTileManager.swift; sourceTree = ""; }; DDB75A152A0594AD006ED576 /* TileOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileOverlay.swift; sourceTree = ""; }; DDB75A192A05EB67006ED576 /* alpha.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = alpha.png; sourceTree = ""; }; + DDB75A1B2A076DFA006ED576 /* TilesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TilesView.swift; sourceTree = ""; }; DDBA45EC299ED78100DEEDDC /* MeshtasticDataModelV8.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV8.xcdatamodel; sourceTree = ""; }; DDC2E15426CE248E0042C5E4 /* Meshtastic.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Meshtastic.app; sourceTree = BUILT_PRODUCTS_DIR; }; DDC2E15726CE248E0042C5E4 /* MeshtasticApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshtasticApp.swift; sourceTree = ""; }; @@ -399,6 +401,7 @@ DD964FC32974767D007C176F /* MapViewFitExtension.swift */, DD2AD8A7296D2DF9001FF0E7 /* MapViewSwiftUI.swift */, DDDB443529F6287000EE2349 /* MapButtons.swift */, + DDB75A1B2A076DFA006ED576 /* TilesView.swift */, ); path = Custom; sourceTree = ""; @@ -1004,6 +1007,7 @@ DD2160AF28C5552500C17253 /* MQTTConfig.swift in Sources */, DDDB444229F8A88700EE2349 /* Double.swift in Sources */, DD5E520F298EE33B00D21B61 /* cannedmessages.pb.swift in Sources */, + DDB75A1C2A076DFA006ED576 /* TilesView.swift in Sources */, DDB75A162A0594AD006ED576 /* TileOverlay.swift in Sources */, DDF924CA26FBB953009FE055 /* ConnectedDevice.swift in Sources */, DD3CC6BE28E4CD9800FA9159 /* BatteryGauge.swift in Sources */, diff --git a/Meshtastic/Extensions/UserDefaults.swift b/Meshtastic/Extensions/UserDefaults.swift index c0751635..49a2bf4c 100644 --- a/Meshtastic/Extensions/UserDefaults.swift +++ b/Meshtastic/Extensions/UserDefaults.swift @@ -14,11 +14,13 @@ extension UserDefaults { case preferredPeripheralId case provideLocation case provideLocationInterval + case mapLayer case meshMapRecentering case meshMapShowNodeHistory case meshMapShowRouteLines case enableOfflineMaps case mapTileServer + case mapTilesAboveLabels } func reset() { @@ -121,4 +123,13 @@ extension UserDefaults { UserDefaults.standard.set(newValue, forKey: "mapTileServer") } } + + static var mapTilesAboveLabels: Bool { + get { + UserDefaults.standard.bool(forKey: "mapTilesAboveLabels") + } + set { + UserDefaults.standard.set(newValue, forKey: "mapTilesAboveLabels") + } + } } diff --git a/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift b/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift index d2927f70..ce96e651 100644 --- a/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift +++ b/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift @@ -105,7 +105,7 @@ struct MapViewSwiftUI: UIViewRepresentable { if !UserDefaults.enableOfflineMapsMBTiles { let overlay = TileOverlay() overlay.canReplaceMapContent = false - mapView.addOverlay(overlay, level: .aboveLabels) + mapView.addOverlay(overlay, level: UserDefaults.mapTilesAboveLabels ? .aboveLabels : .aboveRoads) } case .satellite: mapView.mapType = .satellite diff --git a/Meshtastic/Views/Map/Custom/TilesView.swift b/Meshtastic/Views/Map/Custom/TilesView.swift new file mode 100644 index 00000000..77127d40 --- /dev/null +++ b/Meshtastic/Views/Map/Custom/TilesView.swift @@ -0,0 +1,48 @@ +// +// TilesView.swift +// Meshtastic +// +// Copyright(c) Garth Vander Houwen on 5/6/23. +// + +import SwiftUI +import MapKit + +struct TilesView: View { + + @ObservedObject var tileManager = OfflineTileManager.shared + @State var totalDownloadedTileSize = "" + + var body: some View { + + Button(action: { + tileManager.removeAll() + totalDownloadedTileSize = tileManager.getAllDownloadedSize() + print("delete all tiles") + }) { + + HStack { + Image(systemName: "trash") + .foregroundColor(.red) + Text("\("map.tiles.delete".localized) (\(totalDownloadedTileSize))") + .foregroundColor(.red) + Spacer() + } + } + .onAppear(perform: { + totalDownloadedTileSize = tileManager.getAllDownloadedSize() + }) + Divider() + } +} + +// MARK: Previews +struct TilesView_Previews: PreviewProvider { + + static var previews: some View { + + TilesView() + .previewLayout(.fixed(width: 300, height: 80)) + .environment(\.colorScheme, .light) + } +} diff --git a/Meshtastic/Views/Nodes/NodeMap.swift b/Meshtastic/Views/Nodes/NodeMap.swift index 38daa2ac..068201ff 100644 --- a/Meshtastic/Views/Nodes/NodeMap.swift +++ b/Meshtastic/Views/Nodes/NodeMap.swift @@ -22,6 +22,7 @@ struct NodeMap: View { @State var enableOfflineMaps: Bool = UserDefaults.enableOfflineMaps @State var mapTileServer: String = UserDefaults.mapTileServer @State var enableOfflineMapsMBTiles: Bool = UserDefaults.enableOfflineMapsMBTiles + @State var mapTilesAboveLabels: Bool = UserDefaults.mapTilesAboveLabels @FetchRequest(sortDescriptors: [NSSortDescriptor(key: "time", ascending: true)], predicate: NSPredicate(format: "time >= %@ && nodePosition != nil", Calendar.current.startOfDay(for: Date()) as NSDate), animation: .none) @@ -143,11 +144,12 @@ struct NodeMap: View { .onTapGesture { self.enableOfflineMaps.toggle() UserDefaults.enableOfflineMaps = self.enableOfflineMaps + if !self.enableOfflineMaps { + if self.selectedMapLayer == .offline { + self.selectedMapLayer = .standard + } + } } -// Text("If you have shared a MBTiles file with meshtastic it will be loaded.") -// .font(.caption) -// .foregroundColor(.gray) - if UserDefaults.enableOfflineMaps { VStack { @@ -168,6 +170,20 @@ struct NodeMap: View { UserDefaults.mapTileServer = newMapTileServer } } + Text("A tile server will be used (defaults to wikimedia OSM) to load and cache map tiles as you browse the Offline map type.") + .font(.caption) + .foregroundColor(.gray) + Divider() + Toggle(isOn: $mapTilesAboveLabels) { + Text("Tiles above Labels") + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + .onTapGesture { + self.mapTilesAboveLabels.toggle() + UserDefaults.mapTilesAboveLabels = self.mapTilesAboveLabels + } + Divider() + TilesView() } Toggle(isOn: $enableOfflineMapsMBTiles) { Text("Enable MB Tiles") @@ -177,6 +193,9 @@ struct NodeMap: View { self.enableOfflineMapsMBTiles.toggle() UserDefaults.enableOfflineMapsMBTiles = self.enableOfflineMapsMBTiles } + Text("The latest MBTiles file shared with meshtastic will be loaded into the map.") + .font(.caption) + .foregroundColor(.gray) } } } diff --git a/de.lproj/Localizable.strings b/de.lproj/Localizable.strings index 243b8015..cc289015 100644 --- a/de.lproj/Localizable.strings +++ b/de.lproj/Localizable.strings @@ -138,9 +138,7 @@ "lora.config"="LoRa Einstellungen"; "map"="Mesh Karte"; "map.centering"="Centering"; -"map.tiles.download"="Download Tiles"; -"map.tiles.delete"="Delete Tiles"; -"map.tiles.downloading"="Downloading Tiles"; +"map.tiles.delete"="Delete Cached Tiles"; "map.recentering"="Automatic Re-centering"; "map.type"="kartentyp"; "map.usertrackingmode"="User tracking mode"; diff --git a/en.lproj/Localizable.strings b/en.lproj/Localizable.strings index 87ab586b..04841901 100644 --- a/en.lproj/Localizable.strings +++ b/en.lproj/Localizable.strings @@ -139,9 +139,7 @@ "map"="Mesh Map"; "map.type"="Default Type"; "map.centering"="Centering Mode"; -"map.tiles.download"="Download Tiles"; -"map.tiles.delete"="Delete Tiles"; -"map.tiles.downloading"="Downloading Tiles"; +"map.tiles.delete"="Delete Cached Tiles"; "map.recentering"="Automatic Re-centering"; "map.usertrackingmode"="User tracking mode"; "map.usertrackingmode.follow"="Follow"; diff --git a/zh-Hans.lproj/Localizable.strings b/zh-Hans.lproj/Localizable.strings index 974693bc..cf4e6b3b 100644 --- a/zh-Hans.lproj/Localizable.strings +++ b/zh-Hans.lproj/Localizable.strings @@ -138,9 +138,7 @@ "lora.config"="LoRa 配置"; "map"="Mesh 地图"; "map.centering"="Centering"; -"map.tiles.download"="Download Tiles"; -"map.tiles.delete"="Delete Tiles"; -"map.tiles.downloading"="Downloading Tiles"; +"map.tiles.delete"="Delete Cached Tiles"; "map.recentering"="Automatic Re-centering"; "map.type"="地图类型"; "map.usertrackingmode"="User tracking mode";