/** * Geolocation Service * Migrated from Angular geolocation.service.ts */ const geolocationService = { /** * Get current GPS coordinates */ async getCurrentPosition() { return new Promise((resolve, reject) => { if (!navigator.geolocation) { reject(new Error('Geolocation no está soportada por este navegador')); return; } navigator.geolocation.getCurrentPosition( (position) => { resolve({ latitude: position.coords.latitude, longitude: position.coords.longitude, accuracy: position.coords.accuracy, timestamp: new Date(position.timestamp) }); }, (error) => { let errorMessage = 'Error obteniendo ubicación'; switch (error.code) { case error.PERMISSION_DENIED: errorMessage = 'Permiso de ubicación denegado'; break; case error.POSITION_UNAVAILABLE: errorMessage = 'Ubicación no disponible'; break; case error.TIMEOUT: errorMessage = 'Tiempo de espera agotado'; break; } reject(new Error(errorMessage)); }, { enableHighAccuracy: true, timeout: 60000, // 60 seconds for full hardware satellite lock maximumAge: 0 // Force fresh location every time } ); }); }, /** * Watch position for continuous tracking */ watchPosition(onSuccess, onError) { if (!navigator.geolocation) { onError(new Error('Geolocation no está soportada')); return null; } return navigator.geolocation.watchPosition( (position) => { onSuccess({ latitude: position.coords.latitude, longitude: position.coords.longitude, accuracy: position.coords.accuracy, timestamp: new Date(position.timestamp) }); }, (error) => { onError(error); }, { enableHighAccuracy: true, timeout: 60000, maximumAge: 0 } ); }, /** * Clear position watch */ clearWatch(watchId) { if (watchId && navigator.geolocation) { navigator.geolocation.clearWatch(watchId); } }, /** * Get address name from coordinates using OpenStreetMap Nominatim */ async getAddress(latitude, longitude) { try { if (!navigator.onLine) return null; const response = await fetch( `https://nominatim.openstreetmap.org/reverse?format=json&lat=${latitude}&lon=${longitude}&zoom=18&addressdetails=1` ); if (!response.ok) throw new Error('Error al consultar el servicio de direcciones'); const data = await response.json(); // Try to get a meaningful name const address = data.address; if (!address) return data.display_name || null; // Enhanced Marine-aware priority: search for natural features first const place = address.natural || address.water || address.beach || address.island || address.islet || address.sea || address.suburb || address.neighbourhood || address.village || address.town || address.city || address.county || address.state; return place ? `${place}, RD` : data.display_name; } catch (error) { console.warn('Geocoding error:', error); return null; } } };