API de Geolocalización de HTML5
La API de Geolocalización es una de las características más útiles introducidas en HTML5, permitiendo a los sitios web y aplicaciones web determinar la ubicación geográfica del usuario. Esta funcionalidad abre un abanico de posibilidades para crear experiencias personalizadas basadas en la ubicación, como mostrar contenido local relevante, calcular rutas o proporcionar servicios específicos según la zona geográfica.
La API de Geolocalización está integrada directamente en el navegador y se accede a través del objeto navigator
del DOM. Esta API funciona tanto en dispositivos móviles como en ordenadores de escritorio, aunque la precisión puede variar dependiendo del dispositivo y el método utilizado para determinar la ubicación.
Funcionamiento básico
El navegador puede determinar la ubicación del usuario a través de diferentes métodos de localización:
- GPS (en dispositivos móviles principalmente)
- Redes WiFi cercanas
- Dirección IP
- Triangulación de torres de telefonía móvil
- Bluetooth
La precisión de la ubicación dependerá del método utilizado, siendo el GPS el más preciso pero también el que más batería consume en dispositivos móviles.
Acceso a la API
Para utilizar la API de Geolocalización, primero debemos comprobar si el navegador la soporta:
if ("geolocation" in navigator) {
// El navegador soporta geolocalización
} else {
// El navegador no soporta geolocalización
}
Este código verifica si el objeto geolocation
existe dentro del objeto navigator
, lo que indica que el navegador soporta esta funcionalidad.
Obtener la ubicación actual
El método principal para obtener la ubicación del usuario es getCurrentPosition()
. Este método acepta tres parámetros:
- Una función de éxito (obligatoria)
- Una función de error (opcional)
- Un objeto de opciones (opcional)
Veamos un ejemplo básico:
navigator.geolocation.getCurrentPosition(
// Función de éxito
function(position) {
// Accedemos a las coordenadas
const latitude = position.coords.latitude;
const longitude = position.coords.longitude;
console.log(`Latitud: ${latitude}, Longitud: ${longitude}`);
},
// Función de error
function(error) {
console.error("Error al obtener la ubicación:", error.message);
}
);
El objeto Position
Cuando la geolocalización tiene éxito, la función de callback recibe un objeto Position
que contiene información detallada sobre la ubicación del usuario. Las propiedades más importantes son:
coords.latitude
: La latitud en grados decimalescoords.longitude
: La longitud en grados decimalescoords.accuracy
: La precisión de las coordenadas en metros
Además, dependiendo del dispositivo y el navegador, puede incluir:
coords.altitude
: La altitud en metros (puede ser null)coords.altitudeAccuracy
: La precisión de la altitud en metros (puede ser null)coords.heading
: La dirección en grados respecto al norte (puede ser null)coords.speed
: La velocidad en metros por segundo (puede ser null)timestamp
: La hora en la que se obtuvo la posición
Manejo de errores
La función de error recibe un objeto PositionError
con información sobre el problema ocurrido:
error.code
: Un código numérico que identifica el tipo de errorerror.message
: Un mensaje que describe el error
Los códigos de error posibles son:
1
(PERMISSION_DENIED): El usuario denegó el permiso2
(POSITION_UNAVAILABLE): No se pudo determinar la posición3
(TIMEOUT): Se agotó el tiempo de espera
function handleError(error) {
switch(error.code) {
case error.PERMISSION_DENIED:
console.error("El usuario denegó el permiso para la geolocalización");
break;
case error.POSITION_UNAVAILABLE:
console.error("La información de ubicación no está disponible");
break;
case error.TIMEOUT:
console.error("Se agotó el tiempo para obtener la ubicación");
break;
default:
console.error("Error desconocido de geolocalización");
}
}
Opciones de configuración
El tercer parámetro de getCurrentPosition()
es un objeto de opciones que permite configurar el comportamiento de la geolocalización:
const options = {
enableHighAccuracy: true, // Intenta obtener la mejor precisión posible
timeout: 5000, // Tiempo máximo (en ms) para obtener la ubicación
maximumAge: 0 // No usar ubicaciones en caché
};
navigator.geolocation.getCurrentPosition(
handleSuccess,
handleError,
options
);
enableHighAccuracy
: Cuando estrue
, intenta proporcionar una posición más precisa (puede ser más lento y consumir más batería)timeout
: El tiempo máximo (en milisegundos) que el dispositivo puede tomar para devolver una posiciónmaximumAge
: El tiempo máximo (en milisegundos) de una posición en caché que se puede aceptar
Ejemplo práctico: Mostrar la ubicación en un mapa
Un caso de uso común es mostrar la ubicación del usuario en un mapa. Aquí hay un ejemplo sencillo utilizando un iframe con Google Maps:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mi Ubicación</title>
<style>
#map {
width: 100%;
height: 400px;
border: none;
}
#status {
margin-bottom: 10px;
font-family: Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Mi Ubicación Actual</h1>
<div id="status">Buscando tu ubicación...</div>
<iframe id="map" src="about:blank"></iframe>
<script>
const statusElement = document.getElementById('status');
const mapElement = document.getElementById('map');
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition(
function(position) {
const latitude = position.coords.latitude;
const longitude = position.coords.longitude;
// Actualizar el estado
statusElement.textContent = `Ubicación encontrada: ${latitude.toFixed(4)}, ${longitude.toFixed(4)}`;
// Actualizar el mapa
const mapUrl = `https://maps.google.com/maps?q=${latitude},${longitude}&z=15&output=embed`;
mapElement.src = mapUrl;
},
function(error) {
statusElement.textContent = `Error: ${error.message}`;
},
{
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 0
}
);
} else {
statusElement.textContent = "Tu navegador no soporta geolocalización";
}
</script>
</body>
</html>
Este ejemplo muestra cómo:
- Verificar si el navegador soporta geolocalización
- Solicitar la ubicación del usuario
- Mostrar las coordenadas en la página
- Cargar un mapa centrado en la ubicación del usuario
Consideraciones de rendimiento
Al utilizar la API de Geolocalización, es importante tener en cuenta algunas consideraciones de rendimiento:
- La opción
enableHighAccuracy
puede aumentar significativamente el consumo de batería en dispositivos móviles - Establecer un valor adecuado para
timeout
evita que la aplicación se quede esperando indefinidamente - Utilizar un valor razonable para
maximumAge
puede evitar solicitudes innecesarias si la ubicación no cambia con frecuencia
Compatibilidad con navegadores
La API de Geolocalización tiene un amplio soporte en navegadores modernos, incluyendo:
- Chrome
- Firefox
- Safari
- Edge
- Opera
- La mayoría de navegadores móviles
Sin embargo, siempre es recomendable verificar la disponibilidad antes de intentar utilizarla, como se muestra en los ejemplos anteriores.
¿Te está gustando esta lección?
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
Solicitud de permisos y consideraciones de privacidad
La geolocalización es una funcionalidad que implica acceder a información personal sensible del usuario, por lo que los navegadores implementan un sistema de permisos estricto para proteger la privacidad. Entender cómo funciona este sistema es fundamental para crear experiencias de usuario respetuosas y transparentes.
Modelo de permisos en navegadores
Cuando una página web intenta acceder a la ubicación del usuario por primera vez, el navegador muestra automáticamente un diálogo de solicitud de permiso. Este comportamiento es consistente en todos los navegadores modernos y no puede ser personalizado por los desarrolladores.
El diálogo de permiso generalmente presenta tres opciones al usuario:
- Permitir: Concede acceso a los datos de ubicación
- Bloquear: Deniega el acceso a los datos de ubicación
- Ignorar: Cierra el diálogo sin tomar una decisión (equivale a denegar temporalmente)
Es importante destacar que este permiso:
- Debe ser otorgado explícitamente por el usuario
- Se solicita por dominio (no por página individual)
- Puede ser revocado por el usuario en cualquier momento
- Puede tener diferentes estados: concedido, denegado o no decidido
Buenas prácticas para solicitar permisos
Para aumentar las probabilidades de que los usuarios concedan permiso para acceder a su ubicación, es recomendable seguir estas buenas prácticas:
- Explicar el propósito antes de solicitar la ubicación:
<div id="location-explanation">
<p>Para mostrarle tiendas cercanas, necesitamos acceder a su ubicación.</p>
<button id="request-location">Mostrar tiendas cercanas</button>
</div>
<script>
document.getElementById('request-location').addEventListener('click', function() {
// Solicitar ubicación solo después de que el usuario haga clic
navigator.geolocation.getCurrentPosition(showNearbyStores, handleError);
});
</script>
-
Solicitar el permiso como respuesta a una acción del usuario (como un clic en un botón) en lugar de hacerlo automáticamente al cargar la página.
-
Proporcionar una alternativa para los usuarios que no deseen compartir su ubicación:
<div id="location-options">
<button id="use-location">Usar mi ubicación actual</button>
<p>o</p>
<input type="text" id="postal-code" placeholder="Introduce tu código postal">
<button id="use-postal">Buscar con código postal</button>
</div>
- Mostrar feedback visual durante el proceso de solicitud de permisos:
function requestLocation() {
const statusElement = document.getElementById('status');
statusElement.textContent = "Solicitando acceso a tu ubicación...";
navigator.geolocation.getCurrentPosition(
function(position) {
statusElement.textContent = "¡Gracias! Usando tu ubicación para personalizar el contenido.";
// Procesar la ubicación...
},
function(error) {
if (error.code === error.PERMISSION_DENIED) {
statusElement.textContent = "Has denegado el acceso a tu ubicación. Puedes cambiar esta configuración en tu navegador.";
}
}
);
}
Estados de permiso y manejo de errores
Los navegadores no proporcionan una forma directa de consultar el estado actual del permiso de geolocalización antes de solicitarlo. La única manera de saber si el usuario ha concedido o denegado el permiso es intentar acceder a la ubicación y manejar los posibles errores.
El código de error PERMISSION_DENIED
(valor 1) indica que el usuario ha denegado el permiso:
function handleLocationError(error) {
const messageElement = document.getElementById('error-message');
switch(error.code) {
case error.PERMISSION_DENIED:
messageElement.textContent = "No podemos acceder a tu ubicación porque has denegado el permiso.";
// Mostrar alternativa (entrada manual de ubicación)
document.getElementById('manual-location').style.display = 'block';
break;
// Otros casos de error...
}
}
Persistencia de permisos
Los permisos de geolocalización son persistentes entre sesiones de navegación. Esto significa que:
- Si un usuario concede permiso, el navegador recordará esta decisión
- Si un usuario deniega el permiso, futuras solicitudes serán rechazadas automáticamente sin mostrar el diálogo
Los usuarios pueden gestionar estos permisos a través de la configuración del navegador:
- Chrome: Configuración > Privacidad y seguridad > Configuración de sitios > Ubicación
- Firefox: Preferencias > Privacidad y seguridad > Permisos > Ubicación
- Safari: Preferencias > Sitios web > Ubicación
Consideraciones de privacidad
Al implementar la geolocalización, es fundamental tener en cuenta estas consideraciones de privacidad:
- Transparencia: Informar claramente al usuario sobre:
- Qué datos de ubicación se recopilarán
- Cómo se utilizarán estos datos
- Si se compartirán con terceros
- Cuánto tiempo se almacenarán
- Minimización de datos: Recopilar solo los datos de ubicación necesarios con la precisión requerida:
// Si solo necesitas una ubicación aproximada, no solicites alta precisión
const options = {
enableHighAccuracy: false, // No necesitamos GPS de alta precisión
maximumAge: 600000 // Aceptar ubicaciones de hasta 10 minutos de antigüedad
};
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options);
- Seguridad: Siempre utilizar HTTPS para proteger los datos de ubicación durante la transmisión:
<!-- El navegador bloqueará las solicitudes de geolocalización en páginas no seguras -->
<meta http-equiv="Content-Security-Policy" content="geolocation 'self'">
- Cumplimiento normativo: Asegurarse de cumplir con las regulaciones de privacidad aplicables como GDPR en Europa o CCPA en California:
<div id="privacy-notice">
<p>Utilizamos tu ubicación solo para mostrarte contenido relevante y no la compartimos con terceros.</p>
<p>Puedes revocar este permiso en cualquier momento desde la configuración de tu navegador.</p>
<a href="/privacy-policy">Ver política de privacidad completa</a>
</div>
Consideraciones para sitios web en producción
Para sitios web en producción, es importante tener en cuenta:
-
HTTPS es obligatorio: Los navegadores modernos requieren conexiones seguras (HTTPS) para utilizar la API de Geolocalización.
-
Política de permisos en segundo plano: Algunos navegadores restringen el acceso a la geolocalización cuando la página no está activa o está en segundo plano.
-
Comportamiento en dispositivos móviles vs. escritorio: La precisión y los métodos de obtención de la ubicación varían significativamente entre dispositivos.
-
Pruebas en diferentes navegadores: El comportamiento de los diálogos de permiso y la gestión de errores puede variar entre navegadores.
Ejemplo completo con manejo de permisos
A continuación se muestra un ejemplo que implementa buenas prácticas para la solicitud de permisos:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ejemplo de Geolocalización con Permisos</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
.hidden {
display: none;
}
#status {
padding: 10px;
margin: 10px 0;
border-radius: 4px;
}
.info {
background-color: #e3f2fd;
}
.success {
background-color: #e8f5e9;
}
.error {
background-color: #ffebee;
}
</style>
</head>
<body>
<h1>Buscador de restaurantes cercanos</h1>
<div id="explanation">
<p>Para encontrar restaurantes cerca de ti, necesitamos acceder a tu ubicación actual.</p>
<p>Solo utilizaremos esta información para mostrarte resultados relevantes y no la almacenaremos.</p>
</div>
<div id="permission-request">
<button id="find-restaurants">Buscar restaurantes cercanos</button>
</div>
<div id="status" class="info hidden"></div>
<div id="manual-location" class="hidden">
<p>También puedes buscar introduciendo tu ubicación manualmente:</p>
<input type="text" id="location-input" placeholder="Introduce tu ciudad o código postal">
<button id="search-manual">Buscar</button>
</div>
<div id="results" class="hidden">
<!-- Aquí se mostrarían los resultados -->
</div>
<script>
// Referencias a elementos del DOM
const findButton = document.getElementById('find-restaurants');
const statusElement = document.getElementById('status');
const manualLocationDiv = document.getElementById('manual-location');
const resultsDiv = document.getElementById('results');
// Función para mostrar mensajes de estado
function updateStatus(message, type) {
statusElement.textContent = message;
statusElement.className = type;
statusElement.classList.remove('hidden');
}
// Manejador para el botón de búsqueda
findButton.addEventListener('click', function() {
// Verificar soporte de geolocalización
if (!("geolocation" in navigator)) {
updateStatus("Tu navegador no soporta geolocalización.", "error");
manualLocationDiv.classList.remove('hidden');
return;
}
// Mostrar estado de espera
updateStatus("Solicitando acceso a tu ubicación...", "info");
// Solicitar la ubicación
navigator.geolocation.getCurrentPosition(
// Éxito
function(position) {
updateStatus("¡Ubicación obtenida! Buscando restaurantes cercanos...", "success");
// Aquí procesaríamos las coordenadas para buscar restaurantes
const latitude = position.coords.latitude;
const longitude = position.coords.longitude;
// Simulación de búsqueda (en una aplicación real, aquí haríamos una petición a un servidor)
setTimeout(function() {
resultsDiv.innerHTML = `
<h2>Restaurantes cerca de ti</h2>
<p>Coordenadas: ${latitude.toFixed(4)}, ${longitude.toFixed(4)}</p>
<ul>
<li>Restaurante El Buen Sabor (0.5 km)</li>
<li>Pizzería Napolitana (0.8 km)</li>
<li>Sushi Express (1.2 km)</li>
</ul>
`;
resultsDiv.classList.remove('hidden');
}, 1500);
},
// Error
function(error) {
switch(error.code) {
case error.PERMISSION_DENIED:
updateStatus("Has denegado el permiso para acceder a tu ubicación.", "error");
break;
case error.POSITION_UNAVAILABLE:
updateStatus("No se pudo determinar tu ubicación actual.", "error");
break;
case error.TIMEOUT:
updateStatus("Se agotó el tiempo de espera al intentar determinar tu ubicación.", "error");
break;
default:
updateStatus("Ocurrió un error desconocido al intentar acceder a tu ubicación.", "error");
}
// Mostrar alternativa manual
manualLocationDiv.classList.remove('hidden');
},
// Opciones
{
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 0
}
);
});
// Manejador para la búsqueda manual
document.getElementById('search-manual').addEventListener('click', function() {
const location = document.getElementById('location-input').value.trim();
if (location) {
updateStatus(`Buscando restaurantes en "${location}"...`, "info");
// Aquí iría el código para buscar por ubicación manual
} else {
updateStatus("Por favor, introduce una ubicación válida.", "error");
}
});
</script>
</body>
</html>
Este ejemplo muestra cómo:
- Explicar al usuario por qué se necesita su ubicación antes de solicitarla
- Solicitar la ubicación solo después de una acción explícita del usuario (clic en botón)
- Proporcionar feedback durante todo el proceso
- Ofrecer una alternativa (búsqueda manual) si el usuario deniega el permiso
- Manejar adecuadamente los diferentes tipos de errores
Métodos getCurrentPosition y watchPosition
La API de Geolocalización de HTML5 proporciona dos métodos principales para obtener la ubicación del usuario: getCurrentPosition()
y watchPosition()
. Aunque ambos métodos permiten acceder a los datos de ubicación, tienen propósitos y comportamientos diferentes que es importante comprender para implementarlos correctamente.
Método getCurrentPosition()
El método getCurrentPosition()
es la forma más básica y directa de obtener la ubicación actual del usuario. Como su nombre indica, este método realiza una única solicitud para determinar la posición en un momento específico.
La sintaxis básica es:
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options);
Donde:
successCallback
: Función que se ejecuta cuando se obtiene la ubicación con éxitoerrorCallback
: Función que se ejecuta si ocurre algún error (opcional)options
: Objeto con opciones de configuración (opcional)
Un ejemplo práctico de implementación:
const locationButton = document.getElementById('get-location');
locationButton.addEventListener('click', function() {
const statusElement = document.getElementById('status');
statusElement.textContent = "Obteniendo tu ubicación...";
navigator.geolocation.getCurrentPosition(
// Función de éxito
function(position) {
const lat = position.coords.latitude;
const lng = position.coords.longitude;
statusElement.textContent = `Ubicación: ${lat.toFixed(4)}, ${lng.toFixed(4)}`;
// Aquí podrías hacer algo con las coordenadas
showMap(lat, lng);
},
// Función de error
function(error) {
statusElement.textContent = `Error: ${error.message}`;
},
// Opciones
{
enableHighAccuracy: true, // Intenta obtener la mejor precisión posible
timeout: 5000, // Tiempo máximo (en ms) para obtener la ubicación
maximumAge: 0 // No usar ubicaciones en caché
}
);
});
function showMap(lat, lng) {
// Código para mostrar un mapa centrado en las coordenadas
}
Este método es ideal para situaciones donde solo necesitas la ubicación una vez, como:
- Mostrar la ubicación actual en un mapa
- Personalizar contenido basado en la ubicación del usuario
- Completar automáticamente un formulario con la dirección actual
Método watchPosition()
A diferencia de getCurrentPosition()
, el método watchPosition()
está diseñado para monitorear continuamente la ubicación del usuario y notificar cuando esta cambia. Esto es especialmente útil para aplicaciones que necesitan seguir el movimiento del usuario en tiempo real.
La sintaxis es similar a getCurrentPosition()
:
const watchId = navigator.geolocation.watchPosition(successCallback, errorCallback, options);
La diferencia clave es que watchPosition()
devuelve un identificador único (watchId
) que puede utilizarse posteriormente para detener el seguimiento.
Veamos un ejemplo de implementación:
<button id="start-tracking">Iniciar seguimiento</button>
<button id="stop-tracking" disabled>Detener seguimiento</button>
<div id="tracking-status">Haz clic en "Iniciar seguimiento" para comenzar</div>
<div id="position-history"></div>
<script>
let watchId = null;
const startButton = document.getElementById('start-tracking');
const stopButton = document.getElementById('stop-tracking');
const statusElement = document.getElementById('tracking-status');
const historyElement = document.getElementById('position-history');
startButton.addEventListener('click', function() {
// Verificar soporte
if (!("geolocation" in navigator)) {
statusElement.textContent = "Tu navegador no soporta geolocalización";
return;
}
statusElement.textContent = "Iniciando seguimiento de ubicación...";
// Iniciar el seguimiento
watchId = navigator.geolocation.watchPosition(
// Función de éxito
function(position) {
const lat = position.coords.latitude;
const lng = position.coords.longitude;
const accuracy = position.coords.accuracy;
const timestamp = new Date(position.timestamp).toLocaleTimeString();
statusElement.textContent = `Ubicación actual: ${lat.toFixed(4)}, ${lng.toFixed(4)} (±${accuracy.toFixed(0)}m)`;
// Agregar la nueva posición al historial
const positionEntry = document.createElement('div');
positionEntry.textContent = `[${timestamp}] Lat: ${lat.toFixed(4)}, Lng: ${lng.toFixed(4)}`;
historyElement.prepend(positionEntry);
},
// Función de error
function(error) {
statusElement.textContent = `Error: ${error.message}`;
stopTracking();
},
// Opciones
{
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 0
}
);
// Actualizar estado de los botones
startButton.disabled = true;
stopButton.disabled = false;
});
stopButton.addEventListener('click', stopTracking);
function stopTracking() {
if (watchId !== null) {
navigator.geolocation.clearWatch(watchId);
watchId = null;
statusElement.textContent = "Seguimiento detenido";
startButton.disabled = false;
stopButton.disabled = true;
}
}
</script>
Este ejemplo muestra cómo:
- Iniciar el seguimiento de la ubicación
- Mostrar actualizaciones en tiempo real
- Mantener un historial de posiciones
- Detener el seguimiento cuando sea necesario
Método clearWatch()
Para detener el seguimiento iniciado con watchPosition()
, se utiliza el método clearWatch()
pasando el identificador obtenido previamente:
navigator.geolocation.clearWatch(watchId);
Este método es esencial para conservar la batería del dispositivo y evitar un consumo innecesario de recursos cuando ya no se necesita el seguimiento de ubicación.
Diferencias clave entre getCurrentPosition() y watchPosition()
| Característica | getCurrentPosition() | watchPosition() | |----------------|----------------------|-----------------| | Frecuencia | Una sola vez | Continuo (múltiples actualizaciones) | | Uso de recursos | Bajo (una sola solicitud) | Alto (monitoreo constante) | | Valor de retorno | Ninguno | Identificador numérico (watchId) | | Casos de uso | Ubicación puntual | Seguimiento en tiempo real | | Detención | No necesaria | Requiere llamar a clearWatch() |
Opciones avanzadas
Ambos métodos aceptan un objeto de opciones que permite configurar el comportamiento de la geolocalización:
const options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
-
enableHighAccuracy: Cuando es
true
, el dispositivo intentará proporcionar la posición más precisa posible, lo que puede implicar activar el GPS en dispositivos móviles. Esto mejora la precisión pero aumenta el consumo de batería y puede tardar más tiempo. -
timeout: Define el tiempo máximo (en milisegundos) que el dispositivo puede tomar para devolver una posición. Si se supera este tiempo, se ejecutará la función de error con un código
TIMEOUT
. -
maximumAge: Especifica el tiempo máximo (en milisegundos) que puede tener una posición en caché para ser considerada válida. Un valor de
0
significa que el dispositivo debe obtener una nueva posición, mientras queInfinity
permitiría usar cualquier posición previamente almacenada.
Ejemplo práctico: Seguimiento de ruta
Un caso de uso común para watchPosition()
es el seguimiento de rutas, como en aplicaciones de fitness o navegación:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Seguimiento de Ruta</title>
<style>
#map {
height: 300px;
width: 100%;
margin-top: 20px;
border: 1px solid #ccc;
}
.controls {
margin: 15px 0;
}
.stats {
display: flex;
justify-content: space-between;
margin-top: 10px;
}
.stat-box {
background-color: #f0f0f0;
padding: 10px;
border-radius: 4px;
flex: 1;
margin: 0 5px;
text-align: center;
}
</style>
</head>
<body>
<h1>Mi Ruta</h1>
<div class="controls">
<button id="start-route">Iniciar ruta</button>
<button id="stop-route" disabled>Finalizar ruta</button>
</div>
<div class="stats">
<div class="stat-box">
<div>Distancia</div>
<div id="distance">0.00 km</div>
</div>
<div class="stat-box">
<div>Tiempo</div>
<div id="time">00:00</div>
</div>
<div class="stat-box">
<div>Velocidad</div>
<div id="speed">0.0 km/h</div>
</div>
</div>
<div id="map">Mapa de la ruta</div>
<script>
// Variables para el seguimiento
let watchId = null;
let routePoints = [];
let startTime = null;
let timerInterval = null;
// Referencias a elementos del DOM
const startButton = document.getElementById('start-route');
const stopButton = document.getElementById('stop-route');
const distanceElement = document.getElementById('distance');
const timeElement = document.getElementById('time');
const speedElement = document.getElementById('speed');
// Iniciar el seguimiento de ruta
startButton.addEventListener('click', function() {
if (!("geolocation" in navigator)) {
alert("Tu navegador no soporta geolocalización");
return;
}
// Reiniciar datos
routePoints = [];
startTime = new Date();
// Iniciar temporizador
timerInterval = setInterval(updateTimer, 1000);
// Iniciar seguimiento
watchId = navigator.geolocation.watchPosition(
// Éxito
function(position) {
const newPoint = {
lat: position.coords.latitude,
lng: position.coords.longitude,
timestamp: position.timestamp
};
// Agregar punto a la ruta
routePoints.push(newPoint);
// Actualizar estadísticas
updateStats();
// Aquí se actualizaría el mapa con la nueva posición
// updateMap(routePoints);
},
// Error
function(error) {
alert(`Error: ${error.message}`);
},
// Opciones
{
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 0
}
);
// Actualizar estado de botones
startButton.disabled = true;
stopButton.disabled = false;
});
// Detener el seguimiento
stopButton.addEventListener('click', function() {
if (watchId !== null) {
// Detener seguimiento
navigator.geolocation.clearWatch(watchId);
watchId = null;
// Detener temporizador
clearInterval(timerInterval);
// Actualizar estado de botones
startButton.disabled = false;
stopButton.disabled = true;
// Aquí podrías guardar la ruta o mostrar un resumen
console.log("Ruta finalizada:", routePoints);
}
});
// Actualizar el temporizador
function updateTimer() {
if (startTime) {
const elapsedTime = Math.floor((new Date() - startTime) / 1000);
const minutes = Math.floor(elapsedTime / 60).toString().padStart(2, '0');
const seconds = (elapsedTime % 60).toString().padStart(2, '0');
timeElement.textContent = `${minutes}:${seconds}`;
}
}
// Calcular y actualizar estadísticas
function updateStats() {
if (routePoints.length > 1) {
// Calcular distancia total
let totalDistance = 0;
for (let i = 1; i < routePoints.length; i++) {
totalDistance += calculateDistance(
routePoints[i-1].lat, routePoints[i-1].lng,
routePoints[i].lat, routePoints[i].lng
);
}
// Mostrar distancia en km
distanceElement.textContent = `${totalDistance.toFixed(2)} km`;
// Calcular velocidad promedio
const elapsedHours = (new Date() - startTime) / 3600000; // ms a horas
const avgSpeed = totalDistance / elapsedHours;
speedElement.textContent = `${avgSpeed.toFixed(1)} km/h`;
}
}
// Función para calcular distancia entre dos puntos (fórmula de Haversine)
function calculateDistance(lat1, lon1, lat2, lon2) {
const R = 6371; // Radio de la Tierra en km
const dLat = (lat2 - lat1) * Math.PI / 180;
const dLon = (lon2 - lon1) * Math.PI / 180;
const a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon/2) * Math.sin(dLon/2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c; // Distancia en km
}
// Aquí iría la función para actualizar el mapa
// function updateMap(points) { ... }
</script>
</body>
</html>
Este ejemplo muestra cómo:
- Iniciar y detener el seguimiento de una ruta
- Recopilar puntos de ubicación a lo largo del tiempo
- Calcular estadísticas como distancia recorrida y velocidad promedio
Consideraciones de rendimiento
Al utilizar estos métodos, es importante tener en cuenta algunas consideraciones de rendimiento:
-
Consumo de batería:
watchPosition()
conenableHighAccuracy: true
puede agotar rápidamente la batería de dispositivos móviles. Utiliza esta configuración solo cuando sea necesario. -
Frecuencia de actualizaciones: La frecuencia con la que
watchPosition()
proporciona actualizaciones varía según el dispositivo y el navegador. No hay una forma estándar de especificar un intervalo exacto. -
Filtrado de actualizaciones: Para aplicaciones que no necesitan cada actualización, considera implementar un filtro:
let lastPosition = null;
const MIN_DISTANCE = 10; // metros
watchId = navigator.geolocation.watchPosition(function(position) {
// Si es la primera posición o si nos hemos movido lo suficiente
if (!lastPosition || calculateDistance(
lastPosition.coords.latitude, lastPosition.coords.longitude,
position.coords.latitude, position.coords.longitude
) * 1000 > MIN_DISTANCE) {
// Actualizar la última posición
lastPosition = position;
// Procesar la nueva posición
updatePositionDisplay(position);
}
});
Compatibilidad con navegadores
Ambos métodos tienen un amplio soporte en navegadores modernos, pero es importante recordar que:
- En dispositivos móviles, la precisión y disponibilidad dependen del hardware (GPS, WiFi, etc.)
- En algunos navegadores, la geolocalización solo funciona en contextos seguros (HTTPS)
- El comportamiento puede variar ligeramente entre navegadores y sistemas operativos
Resumen de buenas prácticas
- Usa
getCurrentPosition()
para obtener la ubicación una sola vez - Usa
watchPosition()
para seguimiento continuo, pero no olvides llamar aclearWatch()
cuando termines - Configura
timeout
para evitar esperas indefinidas - Usa
enableHighAccuracy
con moderación para conservar batería - Proporciona siempre una función de manejo de errores
- Considera la privacidad del usuario y solicita la ubicación solo cuando sea necesario
Aprendizajes de esta lección
- Comprender qué es la API de Geolocalización de HTML5 y cómo acceder a ella desde el navegador.
- Aprender a obtener la ubicación actual del usuario mediante getCurrentPosition() y manejar posibles errores.
- Diferenciar entre los métodos getCurrentPosition() y watchPosition() y sus casos de uso.
- Implementar buenas prácticas para solicitar permisos de geolocalización respetando la privacidad del usuario.
- Configurar opciones avanzadas para optimizar precisión, rendimiento y consumo de batería en aplicaciones reales.
Completa HTML y certifícate
Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs