mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
wip multiple file uploads - geojson files
This commit is contained in:
parent
909ec06fd9
commit
e07277410f
5 changed files with 116 additions and 20 deletions
|
|
@ -31,7 +31,48 @@ class GeoJSONOverlayManager {
|
|||
return nil
|
||||
}
|
||||
|
||||
/// Load styled features for direct rendering
|
||||
/// Load styled features for specific enabled configs
|
||||
func loadStyledFeaturesForConfigs(_ enabledConfigs: Set<UUID>) -> [GeoJSONStyledFeature] {
|
||||
Logger.services.debug("🗺️ GeoJSONOverlayManager: loadStyledFeaturesForConfigs() called with \(enabledConfigs.count) configs")
|
||||
|
||||
// Get files that match the enabled configs
|
||||
let enabledFiles = MapDataManager.shared.getUploadedFiles().filter { enabledConfigs.contains($0.id) }
|
||||
|
||||
guard !enabledFiles.isEmpty else {
|
||||
Logger.services.debug("🗺️ GeoJSONOverlayManager: No enabled files found, returning empty array")
|
||||
return []
|
||||
}
|
||||
|
||||
// Load feature collection from enabled files only
|
||||
guard let collection = MapDataManager.shared.loadFeatureCollectionForFiles(enabledFiles) else {
|
||||
Logger.services.debug("🗺️ GeoJSONOverlayManager: No feature collection available for enabled files, returning empty array")
|
||||
return []
|
||||
}
|
||||
|
||||
var styledFeatures: [GeoJSONStyledFeature] = []
|
||||
|
||||
Logger.services.info("🗺️ GeoJSONOverlayManager: Processing \(collection.features.count) features from \(enabledFiles.count) enabled files")
|
||||
|
||||
for feature in collection.features {
|
||||
// Skip invisible features
|
||||
guard feature.isVisible else {
|
||||
Logger.services.debug("🗺️ GeoJSONOverlayManager: Skipping invisible feature")
|
||||
continue
|
||||
}
|
||||
|
||||
let layerId = feature.layerId ?? "default"
|
||||
let styledFeature = GeoJSONStyledFeature(
|
||||
feature: feature,
|
||||
overlayId: layerId
|
||||
)
|
||||
styledFeatures.append(styledFeature)
|
||||
}
|
||||
|
||||
Logger.services.info("🗺️ GeoJSONOverlayManager: Returning \(styledFeatures.count) styled features from enabled configs")
|
||||
return styledFeatures
|
||||
}
|
||||
|
||||
/// Load styled features for direct rendering (legacy method)
|
||||
func loadStyledFeatures() -> [GeoJSONStyledFeature] {
|
||||
Logger.services.debug("🗺️ GeoJSONOverlayManager: loadStyledFeatures() called")
|
||||
|
||||
|
|
@ -123,9 +164,10 @@ class GeoJSONOverlayManager {
|
|||
|
||||
/// Toggle the active state of an uploaded file
|
||||
func toggleFileActive(_ fileId: UUID) {
|
||||
Logger.services.debug("🗺️ GeoJSONOverlayManager: Toggling active state for file: \(fileId)")
|
||||
Logger.services.error("🚨 GeoJSONOverlayManager: ENTRY - Toggling active state for file: \(fileId)")
|
||||
MapDataManager.shared.toggleFileActive(fileId)
|
||||
// Clear cache to force reload with new file states
|
||||
clearCache()
|
||||
Logger.services.error("🚨 GeoJSONOverlayManager: EXIT - Completed toggle and cache clear for file: \(fileId)")
|
||||
}
|
||||
}
|
||||
|
|
@ -184,6 +184,38 @@ class MapDataManager {
|
|||
|
||||
// MARK: - Configuration Loading
|
||||
|
||||
/// Load combined feature collection from specific files
|
||||
func loadFeatureCollectionForFiles(_ files: [MapDataMetadata]) -> GeoJSONFeatureCollection? {
|
||||
Logger.services.debug("📁 MapDataManager: Loading feature collection for \(files.count) specific files")
|
||||
|
||||
guard !files.isEmpty else {
|
||||
Logger.services.debug("📁 MapDataManager: No files provided, returning nil")
|
||||
return nil
|
||||
}
|
||||
|
||||
var allFeatures: [GeoJSONFeature] = []
|
||||
|
||||
for file in files {
|
||||
do {
|
||||
if let featureCollection = try loadFeatureCollectionFromFile(file) {
|
||||
allFeatures.append(contentsOf: featureCollection.features)
|
||||
Logger.services.info("📁 MapDataManager: Successfully loaded \(featureCollection.features.count) features from \(file.filename, privacy: .public)")
|
||||
}
|
||||
} catch {
|
||||
Logger.services.error("📁 MapDataManager: Failed to load feature collection from \(file.filename, privacy: .public): \(error.localizedDescription, privacy: .public)")
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
guard !allFeatures.isEmpty else {
|
||||
Logger.services.debug("📁 MapDataManager: No features loaded from any files")
|
||||
return nil
|
||||
}
|
||||
|
||||
Logger.services.info("📁 MapDataManager: Successfully combined \(allFeatures.count) total features from \(files.count) files")
|
||||
return GeoJSONFeatureCollection(type: "FeatureCollection", features: allFeatures)
|
||||
}
|
||||
|
||||
/// Load and combine raw GeoJSON feature collections from all active files
|
||||
func loadFeatureCollection() -> GeoJSONFeatureCollection? {
|
||||
if let cached = activeFeatureCollection {
|
||||
|
|
@ -261,23 +293,27 @@ class MapDataManager {
|
|||
|
||||
/// Toggle the active state of an uploaded file
|
||||
func toggleFileActive(_ fileId: UUID) {
|
||||
Logger.services.debug("📁 MapDataManager: Toggling active state for file: \(fileId)")
|
||||
Logger.services.error("🚨 MapDataManager: ENTRY - Toggling active state for file: \(fileId)")
|
||||
|
||||
if let index = uploadedFiles.firstIndex(where: { $0.id == fileId }) {
|
||||
let oldState = uploadedFiles[index].isActive
|
||||
uploadedFiles[index].isActive.toggle()
|
||||
Logger.services.info("📁 MapDataManager: File '\(self.uploadedFiles[index].filename)' active state: \(self.uploadedFiles[index].isActive)")
|
||||
let newState = uploadedFiles[index].isActive
|
||||
Logger.services.error("🚨 MapDataManager: File '\(self.uploadedFiles[index].filename)' changed from \(oldState) to \(newState)")
|
||||
|
||||
// Save metadata changes
|
||||
do {
|
||||
try saveMetadata()
|
||||
// Clear cached data to force reload
|
||||
activeFeatureCollection = nil
|
||||
Logger.services.error("🚨 MapDataManager: Successfully saved metadata and cleared cache")
|
||||
} catch {
|
||||
Logger.services.error("📁 MapDataManager: Failed to save metadata after toggling file: \(error.localizedDescription)")
|
||||
Logger.services.error("🚨 MapDataManager: FAILED to save metadata after toggling file: \(error.localizedDescription)")
|
||||
}
|
||||
} else {
|
||||
Logger.services.error("📁 MapDataManager: Could not find file with ID: \(fileId)")
|
||||
Logger.services.error("🚨 MapDataManager: ERROR - Could not find file with ID: \(fileId)")
|
||||
}
|
||||
Logger.services.error("🚨 MapDataManager: EXIT - Completed toggle operation for file: \(fileId)")
|
||||
}
|
||||
|
||||
/// Delete uploaded file
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ struct MeshMapContent: MapContent {
|
|||
|
||||
// Map overlays
|
||||
@AppStorage("mapOverlaysEnabled") private var showMapOverlays = false
|
||||
@Binding var enabledOverlayConfigs: Set<UUID>
|
||||
|
||||
@FetchRequest(fetchRequest: PositionEntity.allPositionsFetchRequest(), animation: .easeIn)
|
||||
var positions: FetchedResults<PositionEntity>
|
||||
|
|
@ -244,11 +245,15 @@ struct MeshMapContent: MapContent {
|
|||
}
|
||||
|
||||
var overlayContent: some MapContent {
|
||||
let styledFeatures = GeoJSONOverlayManager.shared.loadStyledFeatures()
|
||||
// Get all features but filter by enabled configs
|
||||
let allStyledFeatures = GeoJSONOverlayManager.shared.loadStyledFeaturesForConfigs(enabledOverlayConfigs)
|
||||
|
||||
// Log with error level to make it visible
|
||||
print("🚨 MeshMapContent: overlayContent computed - \(enabledOverlayConfigs.count) enabled configs, \(allStyledFeatures.count) features")
|
||||
|
||||
return Group {
|
||||
ForEach(0..<styledFeatures.count, id: \.self) { index in
|
||||
let styledFeature = styledFeatures[index]
|
||||
ForEach(0..<allStyledFeatures.count, id: \.self) { index in
|
||||
let styledFeature = allStyledFeatures[index]
|
||||
let feature = styledFeature.feature
|
||||
let geometryType = feature.geometry.type
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ struct MapSettingsForm: View {
|
|||
@Binding var mapLayer: MapLayer
|
||||
@AppStorage("meshMapDistance") private var meshMapDistance: Double = 800000
|
||||
@Binding var meshMap: Bool
|
||||
@Binding var enabledOverlayConfigs: Set<UUID>
|
||||
|
||||
var body: some View {
|
||||
|
||||
|
|
@ -160,15 +161,18 @@ struct MapSettingsForm: View {
|
|||
ForEach(uploadedFiles) { file in
|
||||
Toggle(isOn: Binding(
|
||||
get: {
|
||||
Logger.services.debug("🔧 MapSettingsForm: File '\(file.originalName)' toggle getter - current state: \(file.isActive)")
|
||||
return file.isActive
|
||||
let isEnabled = enabledOverlayConfigs.contains(file.id)
|
||||
Logger.services.debug("🔧 MapSettingsForm: File '\(file.originalName)' toggle getter - enabled: \(isEnabled)")
|
||||
return isEnabled
|
||||
},
|
||||
set: { newValue in
|
||||
Logger.services.info("🔧 MapSettingsForm: File '\(file.originalName)' toggle setter - changing to: \(newValue)")
|
||||
GeoJSONOverlayManager.shared.toggleFileActive(file.id)
|
||||
// Update local state
|
||||
uploadedFiles = GeoJSONOverlayManager.shared.getUploadedFilesWithState()
|
||||
Logger.services.info("🔧 MapSettingsForm: Updated local uploadedFiles state after toggle")
|
||||
Logger.services.error("🚨 SETTER CALLED: File '\(file.originalName)' toggle setter - changing to: \(newValue)")
|
||||
if newValue {
|
||||
enabledOverlayConfigs.insert(file.id)
|
||||
} else {
|
||||
enabledOverlayConfigs.remove(file.id)
|
||||
}
|
||||
Logger.services.error("🚨 SETTER COMPLETED: enabledOverlayConfigs now has \(enabledOverlayConfigs.count) items")
|
||||
}
|
||||
)) {
|
||||
Label {
|
||||
|
|
@ -186,8 +190,9 @@ struct MapSettingsForm: View {
|
|||
}
|
||||
}
|
||||
} icon: {
|
||||
Image(systemName: file.isActive ? "doc.fill" : "doc")
|
||||
.foregroundColor(file.isActive ? .accentColor : .secondary)
|
||||
let isEnabled = enabledOverlayConfigs.contains(file.id)
|
||||
Image(systemName: isEnabled ? "doc.fill" : "doc")
|
||||
.foregroundColor(isEnabled ? .accentColor : .secondary)
|
||||
}
|
||||
}
|
||||
.tint(.accentColor)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ struct MeshMap: View {
|
|||
@AppStorage("enableMapTraffic") private var showTraffic: Bool = false
|
||||
@AppStorage("enableMapPointsOfInterest") private var showPointsOfInterest: Bool = false
|
||||
@AppStorage("mapLayer") private var selectedMapLayer: MapLayer = .standard
|
||||
/// Map overlay configs
|
||||
@State private var enabledOverlayConfigs: Set<UUID> = []
|
||||
// Map Configuration
|
||||
@Namespace var mapScope
|
||||
@State var mapStyle: MapStyle = MapStyle.standard(elevation: .flat, emphasis: MapStyle.StandardEmphasis.muted, pointsOfInterest: .excludingAll, showsTraffic: false)
|
||||
|
|
@ -70,7 +72,8 @@ struct MeshMap: View {
|
|||
showPointsOfInterest: $showPointsOfInterest,
|
||||
selectedMapLayer: $selectedMapLayer,
|
||||
selectedPosition: $selectedPosition,
|
||||
selectedWaypoint: $selectedWaypoint
|
||||
selectedWaypoint: $selectedWaypoint,
|
||||
enabledOverlayConfigs: $enabledOverlayConfigs
|
||||
)
|
||||
}
|
||||
.mapScope(mapScope)
|
||||
|
|
@ -134,7 +137,7 @@ struct MeshMap: View {
|
|||
.padding()
|
||||
}
|
||||
.sheet(isPresented: $editingSettings) {
|
||||
MapSettingsForm(traffic: $showTraffic, pointsOfInterest: $showPointsOfInterest, mapLayer: $selectedMapLayer, meshMap: $isMeshMap)
|
||||
MapSettingsForm(traffic: $showTraffic, pointsOfInterest: $showPointsOfInterest, mapLayer: $selectedMapLayer, meshMap: $isMeshMap, enabledOverlayConfigs: $enabledOverlayConfigs)
|
||||
}
|
||||
.onChange(of: router.navigationState) {
|
||||
guard case .map = router.navigationState.selectedTab else { return }
|
||||
|
|
@ -195,6 +198,11 @@ struct MeshMap: View {
|
|||
})
|
||||
.onFirstAppear {
|
||||
UIApplication.shared.isIdleTimerDisabled = true
|
||||
|
||||
// Initialize enabled overlay configs with all active files
|
||||
let activeFiles = GeoJSONOverlayManager.shared.getUploadedFilesWithState().filter { $0.isActive }
|
||||
enabledOverlayConfigs = Set(activeFiles.map { $0.id })
|
||||
print("🚨 MeshMap: Initialized with \(enabledOverlayConfigs.count) enabled overlay configs")
|
||||
|
||||
// let wayPointEntity = getWaypoint(id: Int64(deepLinkManager.waypointId) ?? -1, context: context)
|
||||
// if wayPointEntity.id > 0 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue