mirror of
https://github.com/azaion/gps-denied-desktop.git
synced 2026-04-22 22:06:36 +00:00
name components correctly
update tutorial with 3. implementation phase add implementation commands
This commit is contained in:
@@ -1,41 +0,0 @@
|
||||
# Feature: Tile Cache Management
|
||||
|
||||
## Description
|
||||
Manages persistent disk-based caching of satellite tiles with flight-specific organization. Provides storage, retrieval, and cleanup of cached tiles to minimize redundant API calls and enable offline access to prefetched data.
|
||||
|
||||
## Component APIs Implemented
|
||||
- `cache_tile(flight_id: str, tile_coords: TileCoords, tile_data: np.ndarray) -> bool`
|
||||
- `get_cached_tile(flight_id: str, tile_coords: TileCoords) -> Optional[np.ndarray]`
|
||||
- `clear_flight_cache(flight_id: str) -> bool`
|
||||
|
||||
## External Tools and Services
|
||||
- **diskcache**: Persistent cache library for disk storage management
|
||||
- **opencv-python**: Image serialization (PNG encoding/decoding)
|
||||
- **numpy**: Image array handling
|
||||
|
||||
## Internal Methods
|
||||
- `_generate_cache_path(flight_id: str, tile_coords: TileCoords) -> Path`: Generates cache file path following pattern `/satellite_cache/{flight_id}/{zoom}/{tile_x}_{tile_y}.png`
|
||||
- `_ensure_cache_directory(flight_id: str, zoom: int) -> bool`: Creates cache directory structure if not exists
|
||||
- `_serialize_tile(tile_data: np.ndarray) -> bytes`: Encodes tile array to PNG bytes
|
||||
- `_deserialize_tile(data: bytes) -> Optional[np.ndarray]`: Decodes PNG bytes to tile array
|
||||
- `_update_cache_index(flight_id: str, tile_coords: TileCoords, action: str) -> None`: Updates cache index for tracking
|
||||
- `_check_global_cache(tile_coords: TileCoords) -> Optional[np.ndarray]`: Fallback lookup in shared cache
|
||||
|
||||
## Unit Tests
|
||||
1. **cache_tile_success**: Cache new tile → file created at correct path
|
||||
2. **cache_tile_overwrite**: Cache existing tile → file updated
|
||||
3. **cache_tile_disk_error**: Simulate disk full → returns False
|
||||
4. **get_cached_tile_hit**: Tile exists → returns np.ndarray
|
||||
5. **get_cached_tile_miss**: Tile not exists → returns None
|
||||
6. **get_cached_tile_corrupted**: Invalid file → returns None, logs warning
|
||||
7. **get_cached_tile_global_fallback**: Not in flight cache, found in global → returns tile
|
||||
8. **clear_flight_cache_success**: Flight with tiles → all files removed
|
||||
9. **clear_flight_cache_nonexistent**: No such flight → returns True (no-op)
|
||||
10. **cache_path_generation**: Various tile coords → correct paths generated
|
||||
|
||||
## Integration Tests
|
||||
1. **cache_round_trip**: cache_tile() then get_cached_tile() → returns identical data
|
||||
2. **multi_flight_isolation**: Cache tiles for flight A and B → each retrieves only own tiles
|
||||
3. **clear_does_not_affect_others**: Clear flight A → flight B cache intact
|
||||
4. **large_cache_handling**: Cache 1000 tiles → all retrievable
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
# Feature: Tile Coordinate Operations
|
||||
|
||||
## Description
|
||||
Handles all tile coordinate calculations including GPS-to-tile conversion, tile grid computation, and grid expansion for progressive search. Delegates core Web Mercator projection math to H06 Web Mercator Utils to maintain single source of truth.
|
||||
|
||||
## Component APIs Implemented
|
||||
- `compute_tile_coords(lat: float, lon: float, zoom: int) -> TileCoords`
|
||||
- `compute_tile_bounds(tile_coords: TileCoords) -> TileBounds`
|
||||
- `get_tile_grid(center: TileCoords, grid_size: int) -> List[TileCoords]`
|
||||
- `expand_search_grid(center: TileCoords, current_size: int, new_size: int) -> List[TileCoords]`
|
||||
|
||||
## External Tools and Services
|
||||
None (pure computation, delegates to H06)
|
||||
|
||||
## Internal Dependencies
|
||||
- **H06 Web Mercator Utils**: Core projection calculations
|
||||
- `H06.latlon_to_tile()` for coordinate conversion
|
||||
- `H06.compute_tile_bounds()` for bounding box calculation
|
||||
|
||||
## Internal Methods
|
||||
- `_compute_grid_offset(grid_size: int) -> int`: Calculates offset from center for symmetric grid (e.g., 3×3 → offset 1)
|
||||
- `_grid_size_to_dimensions(grid_size: int) -> Tuple[int, int]`: Maps grid_size (1,4,9,16,25) to (rows, cols)
|
||||
- `_generate_grid_tiles(center: TileCoords, rows: int, cols: int) -> List[TileCoords]`: Generates all tile coords in grid
|
||||
|
||||
## Unit Tests
|
||||
1. **compute_tile_coords_ukraine**: Ukraine GPS coords at zoom 19 → valid tile coords
|
||||
2. **compute_tile_coords_origin**: lat=0, lon=0 → correct center tile
|
||||
3. **compute_tile_coords_edge_cases**: lat=90, lon=180, lon=-180 → handled correctly
|
||||
4. **compute_tile_bounds_zoom19**: Zoom 19 tile → GSD ≈ 0.3 m/pixel
|
||||
5. **compute_tile_bounds_corners**: Returns valid GPS for all 4 corners
|
||||
6. **get_tile_grid_1**: grid_size=1 → returns [center]
|
||||
7. **get_tile_grid_4**: grid_size=4 → returns 4 tiles (2×2)
|
||||
8. **get_tile_grid_9**: grid_size=9 → returns 9 tiles (3×3) centered
|
||||
9. **get_tile_grid_25**: grid_size=25 → returns 25 tiles (5×5)
|
||||
10. **expand_search_grid_1_to_4**: Returns 3 new tiles only
|
||||
11. **expand_search_grid_4_to_9**: Returns 5 new tiles only
|
||||
12. **expand_search_grid_9_to_16**: Returns 7 new tiles only
|
||||
13. **expand_search_grid_no_duplicates**: Expanded tiles not in original set
|
||||
|
||||
## Integration Tests
|
||||
1. **h06_delegation_verify**: compute_tile_coords() result matches direct H06.latlon_to_tile()
|
||||
2. **grid_bounds_coverage**: get_tile_grid(9) → all 9 tile bounds form contiguous area
|
||||
3. **expand_completes_grid**: get_tile_grid(4) + expand_search_grid(4,9) == get_tile_grid(9)
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
# Feature: Tile Fetching
|
||||
|
||||
## Description
|
||||
Handles HTTP-based satellite tile retrieval from external provider API with multiple fetching patterns: single tile, grid, progressive expansion, and route corridor prefetching. Integrates with cache for performance optimization and supports parallel fetching for throughput.
|
||||
|
||||
## Component APIs Implemented
|
||||
- `fetch_tile(lat: float, lon: float, zoom: int) -> Optional[np.ndarray]`
|
||||
- `fetch_tile_grid(center_lat: float, center_lon: float, grid_size: int, zoom: int) -> Dict[str, np.ndarray]`
|
||||
- `prefetch_route_corridor(waypoints: List[GPSPoint], corridor_width_m: float, zoom: int) -> bool`
|
||||
- `progressive_fetch(center_lat: float, center_lon: float, grid_sizes: List[int], zoom: int) -> Iterator[Dict[str, np.ndarray]]`
|
||||
|
||||
## External Tools and Services
|
||||
- **Satellite Provider API**: HTTP tile source (`GET /api/satellite/tiles/latlon`)
|
||||
- **httpx** or **requests**: HTTP client with async support
|
||||
- **numpy**: Image array handling
|
||||
|
||||
## Internal Dependencies
|
||||
- **01_feature_tile_cache_management**: cache_tile, get_cached_tile
|
||||
- **02_feature_tile_coordinate_operations**: compute_tile_coords, get_tile_grid
|
||||
|
||||
## Internal Methods
|
||||
- `_fetch_from_api(tile_coords: TileCoords) -> Optional[np.ndarray]`: HTTP GET to satellite provider, handles response parsing
|
||||
- `_fetch_with_retry(tile_coords: TileCoords, max_retries: int = 3) -> Optional[np.ndarray]`: Wraps _fetch_from_api with retry logic
|
||||
- `_fetch_tiles_parallel(tiles: List[TileCoords], max_concurrent: int = 20) -> Dict[str, np.ndarray]`: Parallel fetching with connection pooling
|
||||
- `_compute_corridor_tiles(waypoints: List[GPSPoint], corridor_width_m: float, zoom: int) -> List[TileCoords]`: Calculates tiles covering route corridor polygon
|
||||
- `_generate_tile_id(tile_coords: TileCoords) -> str`: Creates unique tile identifier string
|
||||
|
||||
## Unit Tests
|
||||
1. **fetch_tile_cache_hit**: Tile in cache → returns immediately, no HTTP call
|
||||
2. **fetch_tile_cache_miss**: Not cached → HTTP fetch, cache, return
|
||||
3. **fetch_tile_api_error**: HTTP 500 → returns None
|
||||
4. **fetch_tile_invalid_coords**: Invalid GPS → returns None
|
||||
5. **fetch_tile_retry_success**: First attempt fails, second succeeds → returns tile
|
||||
6. **fetch_tile_retry_exhausted**: All 3 attempts fail → returns None
|
||||
7. **fetch_tile_grid_2x2**: grid_size=4 → returns dict with 4 tiles
|
||||
8. **fetch_tile_grid_3x3**: grid_size=9 → returns dict with 9 tiles
|
||||
9. **fetch_tile_grid_partial_failure**: 2 of 9 tiles fail → returns 7 tiles
|
||||
10. **fetch_tile_grid_all_cached**: All tiles cached → no HTTP calls
|
||||
11. **prefetch_route_corridor_success**: 10 waypoints → prefetches tiles, returns True
|
||||
12. **prefetch_route_corridor_partial_failure**: Some tiles fail → continues, returns True
|
||||
13. **prefetch_route_corridor_complete_failure**: All tiles fail → returns False
|
||||
14. **progressive_fetch_yields_sequence**: [1,4,9] → yields 3 dicts in order
|
||||
15. **progressive_fetch_early_termination**: Break after 4 → doesn't fetch 9,16,25
|
||||
|
||||
## Integration Tests
|
||||
1. **fetch_and_cache_verify**: fetch_tile() → get_cached_tile() returns same data
|
||||
2. **progressive_search_simulation**: progressive_fetch with simulated match on grid 9
|
||||
3. **grid_expansion_no_refetch**: fetch_tile_grid(4) then expand → no duplicate fetches
|
||||
4. **corridor_prefetch_coverage**: prefetch_route_corridor → all corridor tiles cached
|
||||
5. **concurrent_fetch_stress**: Fetch 100 tiles in parallel → all complete within timeout
|
||||
|
||||
Reference in New Issue
Block a user