VAADIN

Google Maps Add-on: Cómo obtener y rastrear la ubicación actual

18 julio, 2024

Google Maps Add-on es un componente creado a partir de Google Maps Web Component. Este add-on permite mostrar un mapa personalizado e incorporar distintos elementos como marcadores, polígonos, controles personalizados y más. Puedes explorar todas las características que ofrece el add-on visitando nuestro demo online. Por ahora, nos enfocaremos en cómo obtener y rastrear la ubicación actual del usuario.

Antes de continuar, es importante destacar que la API de nuestro componente es de código abierto y está disponible de forma gratuita para que cualquiera la use, pero recuerda que necesitas tener tu propia Clave de API para utilizar los servicios de Google Maps. Para obtener orientación sobre cómo crear una Clave de API, puedes consultar la documentación de Google Maps.

Ir a la Ubicación Actual

Simplemente llamando al método goToCurrentLocation() se puede obtener la ubicación geográfica actual del usuario y hacer que el mapa coloque su centro en esa ubicación.

Sin embargo, la ubicación geográfica solo se mostrará si el usuario otorga permiso para compartir su ubicación. El navegador solicitará al usuario que permita el acceso a la ubicación cuando se llame a esta función.

Cómo funciona

La magia detrás de esta funcionalidad reside en la API de Geolocalización HTML5 del navegador. Cuando el usuario activa la solicitud de geolocalización mediante la invocación de goToCurrentLocation(), en segundo plano se llama al método navigator.geolocation.getCurrentPosition(). Este recupera la ubicación geográfica del dispositivo y envía la respuesta al servidor, permitiendo que la API del add-on utilice la información.

Cuando el servidor recibe una respuesta exitosa, obtiene los valores de latitud y longitud que representan la ubicación actual del usuario y establece estos valores como el centro del mapa. Además, dispara un evento CurrentLocationEvent. Puedes agregar un listener para este evento para realizar diferentes acciones que se ejecuten al establecerse la ubicación. Por ejemplo, agregar marcadores o mostrar alguna notificación.

Para encontrar la ubicación exacta, puedes invocar al método getCenter(), que devuelve el centro actual del mapa en términos de latitud y longitud.

Para manejar los errores que puedan ocurrir al intentar recuperar la ubicación del usuario, la API del componente proporciona un listerner del evento GeolocationErrorEvent. Este permite controlar el comportamiento si ocurre un error, como por ejemplo, mostrando una notificación al usuario.

Ejemplo: Obtener la Ubicación Actual

Aquí tienes un ejemplo detallado de cómo obtener la ubicación actual en tu aplicación Vaadin:

1. Inicializa el mapa: instancia el componente Google Maps y agrégalo a la vista.

GoogleMap gmaps = new GoogleMap("YOUR_API_KEY", null, null);
gmaps.setMapType(MapType.ROADMAP);
gmaps.setSizeFull();
add(gmaps);

2. Crea un Botón para ir a la Ubicación Actual: al hacer click, activará la llamada al método goToCurrentLocation() y, si tiene éxito, centrará el mapa en la ubicación actual del usuario.

 Button currentLocationButton = new Button("Go to current location",
        VaadinIcon.CROSSHAIRS.create(), e -> gmaps.goToCurrentLocation());

3. Agrega un Marcador en la Ubicación Actual: con la ayuda del listener del CurrentLocationEvent, agrega un marcador para indicar la ubicación actual en el mapa.

 gmaps.addCurrentLocationEventListener(e -> gmaps
        .addMarker(new GoogleMapMarker("You are here!", gmaps.getCenter(), false, Markers.GREEN)));

4. Maneja los Errores de Geolocalización: agrega un listener para el evento GeolocationErrorEvent para poder mostrar una notificación al usuario, indicando si el navegador no soporta la geolocalización o si hubo otro problema al recuperar la ubicación (por ejemplo, si el usuario niega el permiso).

gmaps.addGeolocationErrorEventListener(e -> 
    Notification.show(e.isBrowserHasGeolocationSupport()
        ? "The geolocation service failed to retrieve your location."
        : "Your browser doesn't support geolocation.")
);

5. Usa Controles Personalizados (Custom Controls): la interacción del usuario se puede mejorar agregando botones u otros controles directamente en el mapa y así lograr una experiencia de usuario más integrada. Por ejemplo, en lugar de colocar el botón para activar la actualización de la ubicación actual en la vista, puedes agregarlo al mapa. Con este código, el botón se colocará en la parte superior central del mapa. La posición se determina mediante el valor ControlPosition. Puedes consultar más información sobre las posiciones de control (ControlPosition) admitidas aquí.

CustomControl geolocationControl = new CustomControl(currentLocationButton, ControlPosition.TOP_CENTER);
gmaps.setCustomControls(geolocationControl);

Finalmente, el ejemplo completo se verá así:

import com.flowingcode.vaadin.addons.googlemaps.ControlPosition;
import com.flowingcode.vaadin.addons.googlemaps.CustomControl;
import com.flowingcode.vaadin.addons.googlemaps.GoogleMap;
import com.flowingcode.vaadin.addons.googlemaps.GoogleMap.MapType;
import com.flowingcode.vaadin.addons.googlemaps.GoogleMapMarker;
import com.flowingcode.vaadin.addons.googlemaps.Markers;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;

@Route("currentlocation")
public class GoToCurrentLocationView extends VerticalLayout {

    public GoToCurrentLocationView() {   
        GoogleMap gmaps = new GoogleMap("YOUR_API_KEY", null, null);  
        gmaps.setMapType(MapType.ROADMAP);
        gmaps.setSizeFull();
        add(gmaps);
       
        Button currentLocationButton = new Button("Go to current location",
        VaadinIcon.CROSSHAIRS.create(), e -> gmaps.goToCurrentLocation()); 

        gmaps.addCurrentLocationEventListener(e -> gmaps
        .addMarker(new GoogleMapMarker("You are here!", gmaps.getCenter(), false, Markers.GREEN)));

        gmaps.addGeolocationErrorEventListener(e -> 
            Notification.show(e.isBrowserHasGeolocationSupport()
                ? "The geolocation service failed to retrieve your location."
                : "Your browser doesn't support geolocation.")
        );
        
        CustomControl geolocationControl = new CustomControl(currentLocationButton, ControlPosition.TOP_CENTER);
        gmaps.setCustomControls(geolocationControl);
    }
}

Ten en cuenta que si queremos que el botón de control personalizado “Go to Current Location” se vea similar a los otros controles del mapa, necesitamos implementar algunas reglas de CSS. Aquí puedes encontrar los estilos aplicados en este caso.

Puedes probar el ejemplo completo en nuestro demo online.

Rastrear la Ubicación Actual

Además de obtener la ubicación actual, el Google Maps Add-on permite rastrear la ubicación actual del usuario. Esto se puede lograr con dos métodos simples: trackLocation() para comenzar el rastreo y stopTrackLocation() para detenerlo.

Cómo funciona

Similar a la obtención de la ubicación actual, el rastreo se basa en la API de Geolocalización HTML5 del navegador. Cuando el usuario inicia el rastreo de ubicación llamando al método de la API trackLocation(), en segundo plano se llama al método navigator.geolocation.watchPosition(). Este método rastrea continuamente la ubicación geográfica del dispositivo y envía las actualizaciones al servidor, permitiendo que la API del add-on las maneje. Al invocarse por primera vez, devuelve el ID de rastreo de la sesión de rastreo que está comenzando. El componente guarda este valor internamente.

Cuando el usuario solicita detener el rastreo a través del método de la API stopTrackLocation(), navigator.geolocation.clearWatch(id) maneja la llamada usando el ID de rastreo de la sesión de rastreo actual para finalizarla.

La API también proporciona un evento LocationTrackingActivatedEvent que se dispara cuando se activa el rastreo de ubicación. Puedes agregar un listener para este evento para realizar acciones al activar el rastreo, como puede ser notificar al usuario que el rastreo ha comenzado.

Es importante notar que solo se puede iniciar una sesión de rastreo a la vez. Si se intenta iniciar una segunda sesión mientras la primera ya está en curso, se lanzará una IllegalStateException.

Como se mencionó antes, obtener la ubicación geográfica solo será posible si el usuario otorga permiso para compartir su ubicación.

Ejemplo: Rastrear la Ubicación Actual

Ahora presentamos un ejemplo que muestra cómo se puede implementar el rastreo de ubicación en una aplicación Vaadin:

1. Inicializa el mapa: instancia el componente Google Maps y agrégalo a la vista.

GoogleMap gmaps = new GoogleMap("YOUR_API_KEY", null, null);
gmaps.setMapType(MapType.ROADMAP);
gmaps.setSizeFull();
gmaps.setZoom(15); 
add(gmaps);

2. Crea Botones para Iniciar y Detener el Rastreo de Ubicación: crea un botón que, al hacer click, llame al método trackLocation() para comenzar el rastreo. Luego, crea un segundo botón que llame al método stopTrackLocation() para detener el rastreo. Agrega los botones a la vista (estos botones también se puedrían agregar como controles personalizados si lo deseas).

Button startLocationTrackingButton = new Button("Start tracking my location");
Button stopLocationTrackingButton = new Button("Stop tracking my location");
startLocationTrackingButton.addClickListener(e -> {
  gmaps.trackLocation();
  stopLocationTrackingButton.setEnabled(true);
});
startLocationTrackingButton.setDisableOnClick(true);
stopLocationTrackingButton.addClickListener(e -> {
  gmaps.stopTrackLocation();
  startLocationTrackingButton.setEnabled(true);
});
stopLocationTrackingButton.setEnabled(false);
stopLocationTrackingButton.setDisableOnClick(true);
add(new HorizontalLayout(startLocationTrackingButton, stopLocationTrackingButton));

3. Crea un Marcador para Rastrear la Ubicación: este marcador nos ayudará a señalar la ubicación del usuario en el mapa.

GoogleMapMarker locationMarker = new GoogleMapMarker();
locationMarker.setCaption("You're here");
locationMarker.setDraggable(false);
gmaps.addMarker(locationMarker);

4. Agrega un Listener para Saber Cuándo se Activa el Rastreo de Ubicación (Opcional):

gmaps.addLocationTrackingActivatedEventListener(ev -> {
  Notification
      .show("Location tracking was activated with track id: " + gmaps.getTrackLocationId());
  });

5. Agrega un Listener para Actualizar la Posición del Marcador: el listener del evento CurrentLocationEvent, que presentamos en el ejemplo anterior, nos ayudará a actualizar la posición del marcador a la ubicación actual del usuario cada vez que esta cambie.

gmaps.addCurrentLocationEventListener(e -> {
   locationMarker.setPosition(e.getSource().getCenter());
});

6. Maneja Errores de Geolocalización: como en el ejemplo anterior, podríamos usar el listener para el evento GeolocationErrorEvent para mostrar una notificación al usuario si surge algún problema al intentar recuperar la ubicación.

gmaps.addGeolocationErrorEventListener(e -> Notification.show(e.isBrowserHasGeolocationSupport()
   ? "The geolocation service failed on retrieving your location."
   : "Your browser doesn't support geolocation."));

Finalmente, el ejemplo completo se verá así:

import com.flowingcode.vaadin.addons.googlemaps.GoogleMap;
import com.flowingcode.vaadin.addons.googlemaps.GoogleMap.MapType;
import com.flowingcode.vaadin.addons.googlemaps.GoogleMapMarker;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;

@Route(value = "tracklocation")
public class TrackLocationView extends VerticalLayout {
    
    private Integer trackLocationId = null;

    public TrackLocationView() {
      GoogleMap gmaps = new GoogleMap("YOUR_API_KEY", null, null);
      gmaps.setMapType(MapType.ROADMAP);
      gmaps.setSizeFull();
      gmaps.setZoom(15);
      add(gmaps);
  
      Button startLocationTrackingButton = new Button("Start tracking my location");
      Button stopLocationTrackingButton = new Button("Stop tracking my location");
      startLocationTrackingButton.addClickListener(e -> {
        gmaps.trackLocation();
        stopLocationTrackingButton.setEnabled(true);
      });
      startLocationTrackingButton.setDisableOnClick(true);
      stopLocationTrackingButton.addClickListener(e -> {
        gmaps.stopTrackLocation();
        startLocationTrackingButton.setEnabled(true);
      });
      stopLocationTrackingButton.setEnabled(false);
      stopLocationTrackingButton.setDisableOnClick(true);
      add(new HorizontalLayout(startLocationTrackingButton, stopLocationTrackingButton));
  
      GoogleMapMarker locationMarker = new GoogleMapMarker();
      locationMarker.setCaption("You're here");
      locationMarker.setDraggable(false);
      gmaps.addMarker(locationMarker);
  
      gmaps.addLocationTrackingActivatedEventListener(ev -> {
        Notification
          .show("Location tracking was activated with track id: " + gmaps.getTrackLocationId());
      });
  
      gmaps.addCurrentLocationEventListener(e -> {
        locationMarker.setPosition(e.getSource().getCenter());
      });
  
      gmaps.addGeolocationErrorEventListener(e -> Notification.show(e.isBrowserHasGeolocationSupport()
          ? "The geolocation service failed on retrieving your location."
          : "Your browser doesn't support geolocation."));
    }
  }

Puedes ver esta implementación en acción en nuestro demo online.

Conclusión

Como acabamos de ver, integrar Google Maps Add-on en aplicaciones Vaadin es realmente sencillo y nos permite obtener capacidades de geolocalización con un esfuerzo mínimo.

Puedes encontrar más información sobre las versiones existentes del componente y las versiones de Vaadin compatibles en el Directorio de Vaadin. Actualmente, el add-on está disponible para las versiones de Vaadin 14, 23 y 24.

Si crees que estas funcionalidades podrían mejorarse, o encuentras algun problema con el resto de las funcionalidades del componente, no dudes en contactarnos y reportarlo en el repositorio de GitHub.

Por último, te invitamos a visitar nuestra sección de código abierto para aprender más sobre todos nuestros add-ons para Vaadin.

Gracias por leernos ¡and keep the code flowing!

Paola De Bartolo
By Paola De Bartolo

Ingeniera en Sistemas. Java Developer. Entusiasta de Vaadin desde el momento en que escuché "puedes implementar todo el UI con Java". Parte del #FlowingCodeTeam desde 2017.

¡Únete a la conversación!
Profile Picture

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.