first attempts to pull local data from offline areas

This commit is contained in:
stopflock
2025-08-10 16:42:31 -05:00
parent 167f3cc0a0
commit 20bd04e338
4 changed files with 181 additions and 23 deletions
+69 -18
View File
@@ -6,6 +6,8 @@ import '../models/osm_camera_node.dart';
import '../app_state.dart';
import 'map_data_submodules/cameras_from_overpass.dart';
import 'map_data_submodules/tiles_from_osm.dart';
import 'map_data_submodules/cameras_from_local.dart';
import 'map_data_submodules/tiles_from_local.dart';
enum MapSource { local, remote, auto } // For future use
@@ -28,7 +30,8 @@ class MapDataProvider {
AppState.instance.setOfflineMode(enabled);
}
/// Fetch cameras from OSM/Overpass or local storage, depending on source/offline mode.
/// Fetch cameras from OSM/Overpass or local storage.
/// Remote is default. If source is MapSource.auto, remote is tried first unless offline.
Future<List<OsmCameraNode>> getCameras({
required LatLngBounds bounds,
required List<CameraProfile> profiles,
@@ -37,16 +40,13 @@ class MapDataProvider {
}) async {
final offline = AppState.instance.offlineMode;
print('[MapDataProvider] getCameras called, source=$source, offlineMode=$offline');
// Resolve source:
if (offline && source != MapSource.local) {
print('[MapDataProvider] BLOCKED by offlineMode for getCameras');
throw OfflineModeException("Cannot fetch remote cameras in offline mode.");
}
if (source == MapSource.local) {
// TODO: implement local camera loading
throw UnimplementedError('Local camera loading not yet implemented.');
} else {
// Use Overpass remote fetch, from submodule:
// Explicit remote request: error if offline, else always remote
if (source == MapSource.remote) {
if (offline) {
print('[MapDataProvider] BLOCKED by offlineMode for remote camera fetch');
throw OfflineModeException("Cannot fetch remote cameras in offline mode.");
}
return camerasFromOverpass(
bounds: bounds,
profiles: profiles,
@@ -54,21 +54,72 @@ class MapDataProvider {
maxCameras: AppState.instance.maxCameras,
);
}
// Explicit local request: always use local
if (source == MapSource.local) {
return fetchLocalCameras(
bounds: bounds,
profiles: profiles,
);
}
// AUTO: default = remote first, fallback to local only if offline
if (offline) {
return fetchLocalCameras(
bounds: bounds,
profiles: profiles,
);
} else {
// Try remote, fallback to local ONLY if remote throws (optional, could be removed for stricter behavior)
try {
return await camerasFromOverpass(
bounds: bounds,
profiles: profiles,
uploadMode: uploadMode,
maxCameras: AppState.instance.maxCameras,
);
} catch (e) {
print('[MapDataProvider] Remote camera fetch failed, error: $e. Falling back to local.');
return fetchLocalCameras(
bounds: bounds,
profiles: profiles,
);
}
}
}
/// Fetch tile image bytes from OSM or local (future). Only fetches, does not save!
/// Fetch tile image bytes. Default is to try local first, then remote if not offline. Honors explicit source.
Future<List<int>> getTile({
required int z,
required int x,
required int y,
MapSource source = MapSource.auto,
}) async {
print('[MapDataProvider] getTile called for $z/$x/$y, source=$source');
if (source == MapSource.local) {
// TODO: implement local tile loading
throw UnimplementedError('Local tile loading not yet implemented.');
} else {
// Use OSM remote fetch from submodule:
final offline = AppState.instance.offlineMode;
print('[MapDataProvider] getTile called for $z/$x/$y, source=$source, offlineMode=$offline');
// Explicitly remote
if (source == MapSource.remote) {
if (offline) {
print('[MapDataProvider] BLOCKED by offlineMode for remote tile fetch');
throw OfflineModeException("Cannot fetch remote tiles in offline mode.");
}
return fetchOSMTile(z: z, x: x, y: y);
}
// Explicitly local
if (source == MapSource.local) {
return fetchLocalTile(z: z, x: x, y: y);
}
// AUTO (default): try local first, then remote if not offline
try {
return await fetchLocalTile(z: z, x: x, y: y);
} catch (_) {
if (!offline) {
return fetchOSMTile(z: z, x: x, y: y);
} else {
throw OfflineModeException("Tile $z/$x/$y not found in offline areas and offline mode is enabled.");
}
}
}
}