// GigLez - Upload Functionality
let selectedFiles = [];
let autoDetectedGPS = null; // Store GPS detected from filenames
// Initialize upload functionality
document.addEventListener('DOMContentLoaded', () => {
setupDropZone();
setupFileInput();
});
// GPS Extraction from Filenames
// Matches patterns like: 34.0478N_118.2349W_1650_test_raw.sub
class GPSFilenameExtractor {
constructor() {
// Pattern 1: Decimal degrees with N/S/E/W (most common)
this.PATTERN_NSEW = /(\d+\.?\d*)([NS])_(\d+\.?\d*)([EW])/i;
// Pattern 2: lat/lon prefix format
this.PATTERN_LATLON = /lat(-?\d+\.?\d+)lon(-?\d+\.?\d+)/i;
// Pattern 3: Signed decimal degrees
this.PATTERN_SIGNED = /(-?\d+\.?\d+)_(-?\d+\.?\d+)/;
}
extract(filename) {
// Try each pattern
let coords = this.tryNSEW(filename) ||
this.tryLatLon(filename) ||
this.trySigned(filename);
return coords;
}
tryNSEW(filename) {
const match = filename.match(this.PATTERN_NSEW);
if (!match) return null;
let lat = parseFloat(match[1]);
let lon = parseFloat(match[3]);
const latDir = match[2].toUpperCase();
const lonDir = match[4].toUpperCase();
// Apply direction (N=positive, S=negative, E=positive, W=negative)
if (latDir === 'S') lat = -lat;
if (lonDir === 'W') lon = -lon;
if (!this.validateCoordinates(lat, lon)) return null;
return {
latitude: lat,
longitude: lon,
source: 'filename_nsew'
};
}
tryLatLon(filename) {
const match = filename.match(this.PATTERN_LATLON);
if (!match) return null;
const lat = parseFloat(match[1]);
const lon = parseFloat(match[2]);
if (!this.validateCoordinates(lat, lon)) return null;
return {
latitude: lat,
longitude: lon,
source: 'filename_latlon'
};
}
trySigned(filename) {
const match = filename.match(this.PATTERN_SIGNED);
if (!match) return null;
const lat = parseFloat(match[1]);
const lon = parseFloat(match[2]);
if (!this.validateCoordinates(lat, lon)) return null;
return {
latitude: lat,
longitude: lon,
source: 'filename_signed'
};
}
validateCoordinates(lat, lon) {
return lat >= -90 && lat <= 90 && lon >= -180 && lon <= 180;
}
}
const gpsExtractor = new GPSFilenameExtractor();
function setupDropZone() {
const dropZone = document.getElementById('drop-zone');
dropZone.addEventListener('click', () => {
document.getElementById('file-input').click();
});
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.classList.add('drag-over');
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('drag-over');
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('drag-over');
const files = Array.from(e.dataTransfer.files).filter(f => f.name.endsWith('.sub'));
addFiles(files);
});
}
function setupFileInput() {
const fileInput = document.getElementById('file-input');
fileInput.addEventListener('change', (e) => {
const files = Array.from(e.target.files);
addFiles(files);
});
}
function addFiles(files) {
if (files.length === 0) {
alert('Please select .sub files');
return;
}
// Add new files
selectedFiles.push(...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;
// Auto-populate GPS fields
document.getElementById('default-lat').value = coords.latitude.toFixed(6);
document.getElementById('default-lon').value = coords.longitude.toFixed(6);
// Show notification
showGPSDetectionNotification(file.name, coords);
break;
}
}
}
// Show file list
document.getElementById('file-list').style.display = 'block';
// Render file list
renderFileList();
}
function showGPSDetectionNotification(filename, coords) {
const notification = document.createElement('div');
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #10b981;
color: white;
padding: 1rem 1.5rem;
border-radius: 0.5rem;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
z-index: 10000;
max-width: 400px;
animation: slideIn 0.3s ease-out;
`;
notification.innerHTML = `
📍 GPS Auto-Detected!
From: ${filename}
Coordinates: ${coords.latitude.toFixed(6)}, ${coords.longitude.toFixed(6)}
`;
document.body.appendChild(notification);
// Add animation
const style = document.createElement('style');
style.textContent = `
@keyframes slideIn {
from { transform: translateX(400px); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
`;
document.head.appendChild(style);
// Remove after 5 seconds
setTimeout(() => {
notification.style.animation = 'slideIn 0.3s ease-out reverse';
setTimeout(() => notification.remove(), 300);
}, 5000);
}
function renderFileList() {
const container = document.getElementById('files-container');
container.innerHTML = selectedFiles.map((file, index) => {
const coords = gpsExtractor.extract(file.name);
const hasGPS = coords !== null;
return `
Successfully uploaded: ${successCount} files
${errorCount > 0 ? `Failed: ${errorCount} files
` : ''}