mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Local MBTiles source
This commit is contained in:
parent
f2a333b5df
commit
fae46080c7
9 changed files with 188 additions and 17 deletions
|
|
@ -8,6 +8,10 @@
|
|||
|
||||
/* Begin PBXBuildFile section */
|
||||
C9483F6D2773017500998F6B /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9483F6C2773017500998F6B /* MapView.swift */; };
|
||||
C9697F9B2793366500250207 /* offline_map.mbtiles in Resources */ = {isa = PBXBuildFile; fileRef = C9697F9A2793366500250207 /* offline_map.mbtiles */; };
|
||||
C9697F9D279336B700250207 /* LocalMBTileOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9697F9C279336B700250207 /* LocalMBTileOverlay.swift */; };
|
||||
C9697FA527933B8C00250207 /* SQLite in Frameworks */ = {isa = PBXBuildFile; productRef = C9697FA427933B8C00250207 /* SQLite */; };
|
||||
C9697FA72793F9FB00250207 /* MTAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9697FA62793F9FB00250207 /* MTAppDelegate.swift */; };
|
||||
C9A7BC1027759A9600760B50 /* PositionAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A7BC0F27759A9600760B50 /* PositionAnnotationView.swift */; };
|
||||
C9A88B55278B503C00BD810A /* MapViewModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A88B54278B503C00BD810A /* MapViewModule.swift */; };
|
||||
C9A88B57278B559900BD810A /* apponly.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A88B56278B559900BD810A /* apponly.pb.swift */; };
|
||||
|
|
@ -74,6 +78,9 @@
|
|||
|
||||
/* Begin PBXFileReference section */
|
||||
C9483F6C2773017500998F6B /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = "<group>"; };
|
||||
C9697F9A2793366500250207 /* offline_map.mbtiles */ = {isa = PBXFileReference; lastKnownFileType = file; path = offline_map.mbtiles; sourceTree = "<group>"; };
|
||||
C9697F9C279336B700250207 /* LocalMBTileOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalMBTileOverlay.swift; sourceTree = "<group>"; };
|
||||
C9697FA62793F9FB00250207 /* MTAppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MTAppDelegate.swift; sourceTree = "<group>"; };
|
||||
C9A7BC0F27759A9600760B50 /* PositionAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionAnnotationView.swift; sourceTree = "<group>"; };
|
||||
C9A88B54278B503C00BD810A /* MapViewModule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MapViewModule.swift; sourceTree = "<group>"; };
|
||||
C9A88B56278B559900BD810A /* apponly.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = apponly.pb.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -132,6 +139,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C9697FA527933B8C00250207 /* SQLite in Frameworks */,
|
||||
DD5394FC276993AD00AD86B1 /* SwiftProtobuf in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
@ -159,6 +167,7 @@
|
|||
C9A7BC0E27759A6800760B50 /* Custom */,
|
||||
C9483F6C2773017500998F6B /* MapView.swift */,
|
||||
C9A88B54278B503C00BD810A /* MapViewModule.swift */,
|
||||
C9697F9C279336B700250207 /* LocalMBTileOverlay.swift */,
|
||||
);
|
||||
path = Map;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -258,6 +267,7 @@
|
|||
DDC2E18826CE24EE0042C5E4 /* Model */,
|
||||
DDC2E18926CE24F70042C5E4 /* Resources */,
|
||||
DDC2E15726CE248E0042C5E4 /* MeshtasticClientApp.swift */,
|
||||
C9697FA62793F9FB00250207 /* MTAppDelegate.swift */,
|
||||
DDC2E16526CE248F0042C5E4 /* Info.plist */,
|
||||
DDC2E15D26CE248F0042C5E4 /* Preview Content */,
|
||||
);
|
||||
|
|
@ -316,6 +326,7 @@
|
|||
DDC2E18926CE24F70042C5E4 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C9697F9A2793366500250207 /* offline_map.mbtiles */,
|
||||
DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */,
|
||||
);
|
||||
path = Resources;
|
||||
|
|
@ -383,6 +394,7 @@
|
|||
name = MeshtasticClient;
|
||||
packageProductDependencies = (
|
||||
DD5394FB276993AD00AD86B1 /* SwiftProtobuf */,
|
||||
C9697FA427933B8C00250207 /* SQLite */,
|
||||
);
|
||||
productName = MeshtasticClient;
|
||||
productReference = DDC2E15426CE248E0042C5E4 /* MeshtasticClient.app */;
|
||||
|
|
@ -435,6 +447,7 @@
|
|||
TargetAttributes = {
|
||||
DDC2E15326CE248E0042C5E4 = {
|
||||
CreatedOnToolsVersion = 12.5.1;
|
||||
LastSwiftMigration = 1320;
|
||||
};
|
||||
DDC2E16926CE248F0042C5E4 = {
|
||||
CreatedOnToolsVersion = 12.5.1;
|
||||
|
|
@ -457,6 +470,7 @@
|
|||
mainGroup = DDC2E14B26CE248E0042C5E4;
|
||||
packageReferences = (
|
||||
DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */,
|
||||
C9697FA327933B8C00250207 /* XCRemoteSwiftPackageReference "SQLite.swift" */,
|
||||
);
|
||||
productRefGroup = DDC2E15526CE248E0042C5E4 /* Products */;
|
||||
projectDirPath = "";
|
||||
|
|
@ -476,6 +490,7 @@
|
|||
files = (
|
||||
DDC2E15F26CE248F0042C5E4 /* Preview Assets.xcassets in Resources */,
|
||||
DDC2E15C26CE248F0042C5E4 /* Assets.xcassets in Resources */,
|
||||
C9697F9B2793366500250207 /* offline_map.mbtiles in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -551,10 +566,12 @@
|
|||
DDAF8C6326ED0A230058C060 /* admin.pb.swift in Sources */,
|
||||
C9483F6D2773017500998F6B /* MapView.swift in Sources */,
|
||||
DDAF8C5826ED07FD0058C060 /* mesh.pb.swift in Sources */,
|
||||
C9697FA72793F9FB00250207 /* MTAppDelegate.swift in Sources */,
|
||||
DD8169FB271F1F3A00F4AB02 /* MeshLog.swift in Sources */,
|
||||
DD2E65262767A01F00E45FC5 /* NodeDetail.swift in Sources */,
|
||||
C9A88B57278B559900BD810A /* apponly.pb.swift in Sources */,
|
||||
DD47E3D926F3093800029299 /* MessageBubble.swift in Sources */,
|
||||
C9697F9D279336B700250207 /* LocalMBTileOverlay.swift in Sources */,
|
||||
DD8169F9271F1A6100F4AB02 /* MeshLogger.swift in Sources */,
|
||||
DD539502276DAA6A00AD86B1 /* MapLocation.swift in Sources */,
|
||||
DDAF8C6726ED0C8C0058C060 /* remote_hardware.pb.swift in Sources */,
|
||||
|
|
@ -720,6 +737,7 @@
|
|||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 15;
|
||||
|
|
@ -737,6 +755,7 @@
|
|||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2,6";
|
||||
};
|
||||
|
|
@ -748,6 +767,7 @@
|
|||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 15;
|
||||
|
|
@ -896,6 +916,14 @@
|
|||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
C9697FA327933B8C00250207 /* XCRemoteSwiftPackageReference "SQLite.swift" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/stephencelis/SQLite.swift.git";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 0.9.2;
|
||||
};
|
||||
};
|
||||
DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/apple/swift-protobuf.git";
|
||||
|
|
@ -907,6 +935,11 @@
|
|||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
C9697FA427933B8C00250207 /* SQLite */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = C9697FA327933B8C00250207 /* XCRemoteSwiftPackageReference "SQLite.swift" */;
|
||||
productName = SQLite;
|
||||
};
|
||||
DD5394FB276993AD00AD86B1 /* SwiftProtobuf */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,15 @@
|
|||
{
|
||||
"object": {
|
||||
"pins": [
|
||||
{
|
||||
"package": "SQLite.swift",
|
||||
"repositoryURL": "https://github.com/stephencelis/SQLite.swift.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "60a65015f6402b7c34b9a924f755ca0a73afeeaa",
|
||||
"version": "0.13.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "SwiftProtobuf",
|
||||
"repositoryURL": "https://github.com/apple/swift-protobuf.git",
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -2,10 +2,27 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>UISupportsDocumentBrowser</key>
|
||||
<false/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<false/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Meshtastic</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>MBTiles Map</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Default</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>gvh.MeshtasticClient.mbtiles</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
|
|
@ -29,7 +46,7 @@
|
|||
<key>NSBluetoothAlwaysUsageDescription</key>
|
||||
<string>We use bluetooth to connect to nearby Meshtastic Devices</string>
|
||||
<key>NSBluetoothPeripheralUsageDescription</key>
|
||||
<string>Bluetooth is used to connect an iPhone to a user's meshtastic device to allow text messaging and location data for the mesh network.</string>
|
||||
<string>Bluetooth is used to connect an iPhone to a user's meshtastic device to allow text messaging and location data for the mesh network.</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string>We use your location to center maps of the mesh</string>
|
||||
<key>Privacy – Bluetooth Always Usage Description</key>
|
||||
|
|
@ -65,5 +82,27 @@
|
|||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UTImportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>MBTiles Map</string>
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>gvh.MeshtasticClient.mbtiles</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>mbtiles</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
|||
28
MeshtasticClient/MTAppDelegate.swift
Normal file
28
MeshtasticClient/MTAppDelegate.swift
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
//
|
||||
// AppDelegate.swift
|
||||
// MeshtasticClient
|
||||
//
|
||||
// Created by Joshua Pirihi on 16/01/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
class MTAppDelegate: NSObject, UIApplicationDelegate {
|
||||
|
||||
func applicationDidFinishLaunching(_ application: UIApplication) {
|
||||
}
|
||||
|
||||
func application(
|
||||
_ application: UIApplication,
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
|
||||
) -> Bool {
|
||||
// ...
|
||||
return true
|
||||
}
|
||||
|
||||
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
|
||||
print("We received a file")
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@ import CoreData
|
|||
@main
|
||||
struct MeshtasticClientApp: App {
|
||||
|
||||
@UIApplicationDelegateAdaptor var delegate: MTAppDelegate
|
||||
|
||||
let persistenceController = PersistenceController.shared
|
||||
|
||||
@ObservedObject private var bleManager: BLEManager = BLEManager.shared
|
||||
|
|
|
|||
72
MeshtasticClient/Views/Map/LocalMBTileOverlay.swift
Normal file
72
MeshtasticClient/Views/Map/LocalMBTileOverlay.swift
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
//
|
||||
// LocalMBTileOverlay.swift
|
||||
// MeshtasticClient
|
||||
//
|
||||
// Created by Joshua Pirihi on 16/01/22.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MapKit
|
||||
import SQLite
|
||||
|
||||
class LocalMBTileOverlay: MKTileOverlay {
|
||||
|
||||
var path: String!
|
||||
|
||||
var mb: Connection!
|
||||
|
||||
init(mbTilePath path: String) {
|
||||
|
||||
super.init(urlTemplate: nil)
|
||||
self.path = path
|
||||
|
||||
do {
|
||||
self.mb = try Connection(self.path, readonly: true)
|
||||
let metadata = Table("metadata")
|
||||
|
||||
let name = Expression<String>("name")
|
||||
let value = Expression<String>("value")
|
||||
|
||||
let minZQuery = try mb.pluck(metadata.select(value).filter(name == "minzoom"))
|
||||
self.minimumZ = Int(minZQuery![value])!
|
||||
|
||||
let maxZQuery = try mb.pluck(metadata.select(value).filter(name == "maxzoom"))
|
||||
self.maximumZ = Int(maxZQuery![value])!
|
||||
|
||||
self.isGeometryFlipped = true
|
||||
|
||||
//let boundingBoxString = try mb.pluck(metadata.select(value).filter(name == "bounds"))
|
||||
//let boundCoords = boundingBoxString![value].split(separator: ",")
|
||||
//self.boundingMapRect = MKMapRect(coordinates: [CLLocationCoordinate2D(latitude: Double(boundCoords[0]) ?? 0, longitude: Double(boundCoords[1]) ?? 0), CLLocationCoordinate2D(latitude: Double(boundCoords[2]) ?? 0, longitude: Double(boundCoords[3]) ?? 0)])
|
||||
|
||||
|
||||
} catch {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override func loadTile(at path: MKTileOverlayPath) async throws -> Data {
|
||||
|
||||
let tileX = Int64(path.x)
|
||||
let tileY = Int64(path.y)
|
||||
let tileZ = Int64(path.z)
|
||||
|
||||
let tileData = Expression<SQLite.Blob>("tile_data")
|
||||
let zoomLevel = Expression<Int64>("zoom_level")
|
||||
let tileColumn = Expression<Int64>("tile_column")
|
||||
let tileRow = Expression<Int64>("tile_row")
|
||||
|
||||
if let dataQuery = try self.mb.pluck(Table("tiles").select(tileData).filter(zoomLevel == tileZ).filter(tileColumn == tileX).filter(tileRow == tileY)) {
|
||||
|
||||
let data = Data(bytes: dataQuery[tileData].bytes, count: dataQuery[tileData].bytes.count)//dataQuery![tileData].bytes
|
||||
|
||||
return data
|
||||
|
||||
} else {
|
||||
return Data()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -97,7 +97,7 @@ public struct MapView: UIViewRepresentable {
|
|||
|
||||
//self.annotations = annotations
|
||||
|
||||
self.locationNodes = locationNodes
|
||||
//self.locationNodes = locationNodes
|
||||
|
||||
self.overlays = overlays
|
||||
|
||||
|
|
@ -135,22 +135,10 @@ public struct MapView: UIViewRepresentable {
|
|||
if self.customMapOverlay != self.presentCustomMapOverlayHash {
|
||||
mapView.removeOverlays(mapView.overlays)
|
||||
if let customMapOverlay = self.customMapOverlay {
|
||||
let overlay = CustomMapOverlaySource(
|
||||
parent: self,
|
||||
mapName: customMapOverlay.mapName,
|
||||
tileType: customMapOverlay.tileType,
|
||||
defaultTile: customMapOverlay.defaultTile
|
||||
)
|
||||
|
||||
if let minZ = customMapOverlay.minimumZoomLevel {
|
||||
overlay.minimumZ = minZ
|
||||
}
|
||||
let overlay = LocalMBTileOverlay(mbTilePath: Bundle.main.path(forResource: "offline_map", ofType: "mbtiles")!)
|
||||
|
||||
if let maxZ = customMapOverlay.maximumZoomLevel {
|
||||
overlay.maximumZ = maxZ
|
||||
}
|
||||
|
||||
overlay.canReplaceMapContent = customMapOverlay.canReplaceMapContent
|
||||
overlay.canReplaceMapContent = false//customMapOverlay.canReplaceMapContent
|
||||
|
||||
mapView.addOverlay(overlay)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ struct NodeMap: View {
|
|||
)*/
|
||||
|
||||
@State private var customMapOverlay: MapView.CustomMapOverlay? = MapView.CustomMapOverlay(
|
||||
mapName: UserDefaults.standard.string(forKey: "meshMapCustomTileServer"),
|
||||
mapName: "offlinemap",
|
||||
tileType: "png",
|
||||
canReplaceMapContent: true
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue