Geolocalización con HTML

Intermedio
HTML
HTML
Actualizado: 01/05/2025

¡Desbloquea el curso completo!

IA
Ejercicios
Certificado
Entrar

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:

  1. Una función de éxito (obligatoria)
  2. Una función de error (opcional)
  3. 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 decimales
  • coords.longitude: La longitud en grados decimales
  • coords.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 error
  • error.message: Un mensaje que describe el error

Los códigos de error posibles son:

  • 1 (PERMISSION_DENIED): El usuario denegó el permiso
  • 2 (POSITION_UNAVAILABLE): No se pudo determinar la posición
  • 3 (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 es true, 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ón
  • maximumAge: 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:

  1. Verificar si el navegador soporta geolocalización
  2. Solicitar la ubicación del usuario
  3. Mostrar las coordenadas en la página
  4. 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.

Progreso guardado
Asistente IA
Ejercicios
Iniciar sesión gratis

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.

Diálogo de permiso de geolocalización

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:

  1. 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>
  1. 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.

  2. 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>
  1. 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:

  1. 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
  1. 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);
  1. 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'">
  1. 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:

  1. HTTPS es obligatorio: Los navegadores modernos requieren conexiones seguras (HTTPS) para utilizar la API de Geolocalización.

  2. 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.

  3. 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.

  4. 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:

  1. Explicar al usuario por qué se necesita su ubicación antes de solicitarla
  2. Solicitar la ubicación solo después de una acción explícita del usuario (clic en botón)
  3. Proporcionar feedback durante todo el proceso
  4. Ofrecer una alternativa (búsqueda manual) si el usuario deniega el permiso
  5. 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 éxito
  • errorCallback: 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:

  1. Iniciar el seguimiento de la ubicación
  2. Mostrar actualizaciones en tiempo real
  3. Mantener un historial de posiciones
  4. 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 que Infinity 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:

  1. Iniciar y detener el seguimiento de una ruta
  2. Recopilar puntos de ubicación a lo largo del tiempo
  3. 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() con enableHighAccuracy: 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 a clearWatch() 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

⭐⭐⭐⭐⭐
4.9/5 valoración