04bd80b25b
Major milestone: GPS coordinates now auto-extract from filenames and uploads appear on map with full end-to-end workflow functional! ✨ GPS Auto-Extraction Features: - JavaScript GPS extractor class matching Python patterns - Supports 3 filename formats: * N/S/E/W: 34.0478N_118.2349W_filename.sub * lat/lon prefix: lat34.0478lon-118.2348_filename.sub * Signed decimal: -34.0478_118.2348_filename.sub - Auto-populates latitude/longitude form fields on file drop - Green notification toast shows detected coordinates - File list shows GPS badge for files with coordinates 🗺️ Web Interface Improvements: - Upload endpoint now stores captures in-memory - Query endpoint returns uploaded captures for map display - Stats endpoint shows real-time upload counts - Map displays uploaded captures as markers - Color-coded by frequency band 📁 Updated Files: - static/js/upload.js: GPS extraction + auto-population - src/api/main_simple.py: In-memory storage + endpoints - src/parser/gps_extractor.py: Backend GPS extraction (Python) - scripts/test_gps_extraction.py: Python test suite - test_gps_extraction.html: Browser test suite 📊 T-Embed Files Updated: - 34.0478N_118.2348W_1637_raw_8.sub: 315 MHz Princeton - 34.0478N_118.2349W_1351_raw_10.sub: 433.92 MHz Princeton - 34.0478N_118.2349W_1650_test_raw.sub: 433.92 MHz RAW - All now have proper Flipper SubGhz headers ✅ Tested Features: - GPS extraction from filename: 34.0478N_118.2349W → 34.0478, -118.2349 - Auto-population of GPS fields in upload form - File upload with GPS validation - Capture appears on map after upload - Statistics update in real-time - Frequency distribution calculated correctly 🎯 End-to-End Flow Working: 1. User drops .sub file with GPS in filename 2. GPS auto-detected and form fields populate 3. User clicks Upload 4. Server parses RF data + GPS coordinates 5. Capture stored in memory 6. Map refreshes and displays new marker 7. Stats update with new counts 🚀 Demo: http://localhost:8000 Upload 34.0478N_118.2349W_1351_raw_10.sub and watch it appear on map! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
227 lines
6.3 KiB
Markdown
227 lines
6.3 KiB
Markdown
# GPS Auto-Extraction from Filenames
|
|
|
|
## Feature Overview
|
|
|
|
The web interface now automatically detects and extracts GPS coordinates from filenames, eliminating the need for manual coordinate entry when filenames contain location data.
|
|
|
|
## Supported Filename Patterns
|
|
|
|
### 1. N/S/E/W Format (Primary)
|
|
**Pattern**: `LAT[NS]_LON[EW]`
|
|
|
|
**Examples**:
|
|
- `34.0478N_118.2348W_1637_raw_8.sub` → 34.0478, -118.2348
|
|
- `34.0478N_118.2349W_1351_raw_10.sub` → 34.0478, -118.2349
|
|
- `40.7128N_74.0060W_capture.sub` → 40.7128, -74.0060
|
|
|
|
**Notes**:
|
|
- Most common format from T-Embed RF captures
|
|
- N = positive latitude, S = negative latitude
|
|
- E = positive longitude, W = negative longitude
|
|
|
|
### 2. lat/lon Prefix Format
|
|
**Pattern**: `latLATlonLON`
|
|
|
|
**Examples**:
|
|
- `lat34.0478lon-118.2348_test.sub` → 34.0478, -118.2348
|
|
- `lat40.7128lon-74.0060_capture.sub` → 40.7128, -74.0060
|
|
|
|
**Notes**:
|
|
- Allows signed decimal notation
|
|
- Case-insensitive (LAT/LON also works)
|
|
|
|
### 3. Signed Decimal Format
|
|
**Pattern**: `LAT_LON` (with optional negative signs)
|
|
|
|
**Examples**:
|
|
- `-34.0478_118.2348_capture.sub` → -34.0478, 118.2348
|
|
- `40.7128_-74.0060_test.sub` → 40.7128, -74.0060
|
|
|
|
**Notes**:
|
|
- Simple signed decimal degrees
|
|
- Less common but supported
|
|
|
|
## How It Works
|
|
|
|
### 1. File Upload Detection
|
|
When user selects/drops .sub files:
|
|
```javascript
|
|
1. Files are added to upload queue
|
|
2. First file with GPS coordinates is automatically detected
|
|
3. GPS fields are auto-populated
|
|
4. User sees notification toast
|
|
```
|
|
|
|
### 2. UI Indicators
|
|
- **GPS Detection Notification**: Green toast shows which file provided coordinates
|
|
- **File List Badge**: Files with GPS show 📍 GPS badge
|
|
- **Coordinate Display**: Extracted coordinates appear next to filename
|
|
|
|
### 3. Validation
|
|
- Latitude range: -90 to 90
|
|
- Longitude range: -180 to 180
|
|
- Invalid coordinates are rejected
|
|
- Malformed patterns are skipped
|
|
|
|
## User Experience
|
|
|
|
### Upload Flow with GPS in Filename
|
|
|
|
1. **Drop/Select File**: User uploads `34.0478N_118.2348W_capture.sub`
|
|
2. **Auto-Detection**: System extracts GPS (34.0478, -118.2348)
|
|
3. **Notification**: Green toast appears:
|
|
```
|
|
📍 GPS Auto-Detected!
|
|
From: 34.0478N_118.2348W_capture.sub
|
|
Coordinates: 34.047800, -118.234800
|
|
```
|
|
4. **Form Population**: Latitude and longitude fields auto-fill
|
|
5. **Upload**: User clicks "Upload Files" (no manual GPS entry needed)
|
|
|
|
### Upload Flow WITHOUT GPS in Filename
|
|
|
|
1. **Drop/Select File**: User uploads `raw_7.sub`
|
|
2. **No Detection**: No GPS found in filename
|
|
3. **Manual Entry**: User must manually enter GPS or use "Use Current Location"
|
|
4. **Validation**: System checks for valid coordinates before upload
|
|
|
|
## Implementation Details
|
|
|
|
### JavaScript GPS Extractor Class
|
|
Location: `static/js/upload.js`
|
|
|
|
```javascript
|
|
class GPSFilenameExtractor {
|
|
extract(filename) {
|
|
// Try each pattern in order
|
|
return this.tryNSEW(filename) ||
|
|
this.tryLatLon(filename) ||
|
|
this.trySigned(filename);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Pattern Matching
|
|
- **PATTERN_NSEW**: `/(\d+\.?\d*)([NS])_(\d+\.?\d*)([EW])/i`
|
|
- **PATTERN_LATLON**: `/lat(-?\d+\.?\d+)lon(-?\d+\.?\d+)/i`
|
|
- **PATTERN_SIGNED**: `/(-?\d+\.?\d+)_(-?\d+\.?\d+)/`
|
|
|
|
### Auto-Population Logic
|
|
```javascript
|
|
function addFiles(files) {
|
|
// Try to extract GPS from first file with coordinates
|
|
if (!autoDetectedGPS) {
|
|
for (const file of files) {
|
|
const coords = gpsExtractor.extract(file.name);
|
|
if (coords) {
|
|
autoDetectedGPS = coords;
|
|
document.getElementById('default-lat').value = coords.latitude.toFixed(6);
|
|
document.getElementById('default-lon').value = coords.longitude.toFixed(6);
|
|
showGPSDetectionNotification(file.name, coords);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Testing
|
|
|
|
### Test Suite
|
|
Location: `test_gps_extraction.html`
|
|
|
|
Open in browser to verify all patterns:
|
|
```bash
|
|
firefox test_gps_extraction.html
|
|
# or
|
|
chromium test_gps_extraction.html
|
|
```
|
|
|
|
### Test Coverage
|
|
- ✅ N/S/E/W format (3 test cases)
|
|
- ✅ lat/lon prefix format
|
|
- ✅ Signed decimal format
|
|
- ✅ Negative detection (files without GPS)
|
|
|
|
### Python Compatibility
|
|
The JavaScript implementation matches the Python `GPSFilenameExtractor` class:
|
|
- Same pattern support
|
|
- Same validation rules
|
|
- Same coordinate transformation logic
|
|
|
|
## T-Embed RF Compatibility
|
|
|
|
### Tested Files
|
|
From `signatures/t-embed-rf/`:
|
|
- ✅ `34.0478N_118.2348W_1637_raw_8.sub` → Auto-detected
|
|
- ✅ `34.0478N_118.2349W_1351_raw_10.sub` → Auto-detected
|
|
- ✅ `34.0478N_118.2349W_1650_test_raw.sub` → Auto-detected
|
|
- ⏭️ `raw_4.sub` → Manual entry required
|
|
- ⏭️ `raw_5.sub` → Manual entry required
|
|
|
|
**Success Rate**: 37.5% (3 of 8 files) auto-detected
|
|
|
|
## Error Messages
|
|
|
|
### GPS Required
|
|
If no GPS provided (manual or filename):
|
|
```
|
|
Please provide GPS coordinates (manually or via filename like: 34.0478N_118.2349W_filename.sub)
|
|
```
|
|
|
|
### GPS Detected but Not Populated
|
|
If GPS exists in filename but form is empty:
|
|
```
|
|
GPS detected in filename but not populated. Please refresh and try again.
|
|
```
|
|
|
|
### Out of Range
|
|
If coordinates exceed valid ranges:
|
|
```
|
|
GPS coordinates out of range
|
|
```
|
|
|
|
## Benefits
|
|
|
|
1. **Faster Uploads**: No manual GPS entry for T-Embed captures
|
|
2. **Fewer Errors**: Eliminates coordinate typos
|
|
3. **Better UX**: Clear feedback when GPS is detected
|
|
4. **Flexible**: Still allows manual entry for files without GPS
|
|
5. **Compatible**: Matches Python backend extraction logic
|
|
|
|
## Future Enhancements
|
|
|
|
### Additional Patterns
|
|
- DMS format: `34d02m52sN_118d14m05sW`
|
|
- Compact format: `N34.0478W118.2348`
|
|
- Plus codes: `8762+MXP_capture.sub`
|
|
|
|
### Multi-File GPS
|
|
Currently uses first file's GPS for all uploads. Future enhancement:
|
|
- Per-file GPS extraction
|
|
- Mixed batch uploads (some with GPS, some without)
|
|
- GPS override UI per file
|
|
|
|
### Companion JSON
|
|
Check for `.json` files alongside `.sub` files:
|
|
```json
|
|
{
|
|
"capture.sub": {
|
|
"latitude": 34.0478,
|
|
"longitude": -118.2348,
|
|
"accuracy": 5.0
|
|
}
|
|
}
|
|
```
|
|
|
|
## Related Files
|
|
|
|
- `static/js/upload.js` - Frontend GPS extraction
|
|
- `src/parser/gps_extractor.py` - Backend GPS extraction
|
|
- `scripts/test_gps_extraction.py` - Python test suite
|
|
- `test_gps_extraction.html` - JavaScript test suite
|
|
|
|
## Summary
|
|
|
|
GPS auto-extraction is **LIVE** and working with the format `34.0478N_118.2349W_filename.sub`. Users can now simply drag and drop T-Embed captures without manually entering coordinates!
|