wip multiple file uploads - geojson files

This commit is contained in:
Jacob Powers 2025-07-22 02:03:36 +00:00
parent 909ec06fd9
commit e07277410f
5 changed files with 116 additions and 20 deletions

View file

@ -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)")
}
}

View file

@ -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

View 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

View file

@ -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)

View file

@ -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 {