39 lines
1.3 KiB
JavaScript
39 lines
1.3 KiB
JavaScript
export function haversineKm(lat1, lon1, lat2, lon2) {
|
|
const R = 6371;
|
|
const dLat = ((lat2 - lat1) * Math.PI) / 180;
|
|
const dLon = ((lon2 - lon1) * Math.PI) / 180;
|
|
const a =
|
|
Math.sin(dLat / 2) ** 2 +
|
|
Math.cos((lat1 * Math.PI) / 180) *
|
|
Math.cos((lat2 * Math.PI) / 180) *
|
|
Math.sin(dLon / 2) ** 2;
|
|
return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
}
|
|
|
|
export function getUserPosition() {
|
|
return new Promise((resolve, reject) => {
|
|
if (!navigator.geolocation) {
|
|
reject(new Error('Geolocalización no compatible con este navegador'));
|
|
return;
|
|
}
|
|
if (typeof window !== 'undefined' && window.isSecureContext === false) {
|
|
reject(new Error('La geolocalización requiere HTTPS (o localhost)'));
|
|
return;
|
|
}
|
|
navigator.geolocation.getCurrentPosition(
|
|
pos => resolve({ lat: pos.coords.latitude, lon: pos.coords.longitude }),
|
|
err => {
|
|
console.error('[geo] getCurrentPosition failed — code:', err && err.code, 'message:', err && err.message);
|
|
reject(err);
|
|
},
|
|
{ timeout: 15000, maximumAge: 60000, enableHighAccuracy: false }
|
|
);
|
|
});
|
|
}
|
|
|
|
export function formatDistance(km) {
|
|
if (km < 1) return `${Math.round(km * 1000)} m`;
|
|
if (km < 10) return `${km.toFixed(1)} km`;
|
|
return `${Math.round(km)} km`;
|
|
}
|