DEV Community 👩‍💻👨‍💻

Thian Lopez Zambrano for Ecudevs

Posted on • Updated on

Integrando Ionic Framework 4 con Google maps

Este es mi primer post en Dev.to, y es un complemento al curso de Ionic Framework que dicto en Ecudevs.

En esta ocasión vamos a integrar nuestra aplicación hecha en Ionic Framework con el api de Google Maps. Debido a que este post va como refuerzo al curso vamos a trabajar con el código fuente resultante de la pequeña aplicación que desarrollamos en el transcurso del mismo, por lo que puedes clonar el siguiente repositorio:

GitHub logo ecudevs / ionic-5

Clase 5 Ionic Framework Ecudevs

Código fuente de la clase 5 de Ionic Framerk en

Ecudevs

Una vez clonado el repositorio ejecuta: npm install y luego ionic serve --lab






Esta es una pequeña app que realiza el mantenimiento de una colección de una base de datos de MongoDB.

Una vez clonado nuestro repositorio y haber instalado todas las dependencias nos ponemos manos a la obra.

1. Obtén un api key de Google

Lo primero que debes hacer es obtener un Api Key de Google Maps y esto lo hacemos desde el Cloud Console de Google, accede con tu cuenta de Google y crea un nuevo proyecto.

Google Console

Después de haber creado tu proyecto accede a la biblioteca de APIs en el menú lateral.

Acesso a la biblioteca de APIs

Aquí busca y selecciona la opción Maps SDK for Android y habilita esta API.

Luego, en el apartado de credenciales, damos clic en "Crear credenciales" y seleccionamos la opción API key.

Crear una credencial

Automáticamente este proceso nos genera un key el cual por el momento lo vamos a guardar en un lugar seguro para luego utilizarlo, por lo que finalmente vamos a cerrar el cuadro de dialogo que se desplegó.

API key generado

2. Integración con Ionic Native

Ionic Native es una herramienta que sirve para agregar funcionalidad nativa a nuestra aplicación de Ionic a través de Cordova.

En este caso, nosotros, para los mapas de google vamos a usar un plugin llamado ionic-native-google-maps, el cual lo podemos instalar a través de npm e Ionic CLI con los siguientes comandos:

npm install @ionic-native/core@beta @ionic-native/google-maps@beta


ionic cordova plugin add https://github.com/mapsplugin/cordova-plugin-googlemaps#multiple_maps
Enter fullscreen mode Exit fullscreen mode

Una vez instaladas las dependencias para nuestro mapa de Google, tenemos que ir a nuestro archivo config.xml y justo después del último nodo de preferencias pegamos lo siguiente reemplazando el valor de el API KEY que obtuvimos en el primer paso:

<preference name="GOOGLE_MAPS_ANDROID_API_KEY" value="NUESTRO_API_KEY" />
Enter fullscreen mode Exit fullscreen mode

Y nuestro código debería quedar algo así:

config.xml

Con nuestras configuraciones listas, vamos a lo que verdaderamente nos concierne, a nuestro código.

3. A programar nuestro mapa

Nuestro proyecto extiende del template de tipo Tabs que nos ofrece Ionic CLI al momento de generarlo, y toda la programación hasta este momento se centra en solo un tab que es el tab1, nuestro mapa de Google lo vamos a programar en el tab2.

Lo primero que debemos hacer es darle forma a nuestra vista por lo que nos vamos a centrar en los archivos html y scss de nuestro componente tab2, y dentro de la etiqueta <ion-content> vamos a ubicar lo siguiente.

  <div id="map_canvas"></div>
  <ion-fab vertical="bottom" horizontal="end" slot="fixed">
    <ion-fab-button color="danger" (click)="localizar()">
      <ion-icon name="pin"></ion-icon>
    </ion-fab-button>
  </ion-fab>
Enter fullscreen mode Exit fullscreen mode

Nuestro código debería quedar algo parecido a esto:
tab2.page.html

El primer div que agregamos a nuestra vista se refiere al espacio donde nuestro mapa será renderizado. A este div debemos configurar ciertos estilos para en este caso estos estilos que vamos agregar harán que nuestro mapa ocupe la totalidad de la pantalla, entonces para eso vamos a el archivo scss de este componente y agregamos lo siguiente:

#map_canvas {
  width: 100%;
  height: 100%;
}
Enter fullscreen mode Exit fullscreen mode

No olvides configurar estos estilos, ya que, si no, el mapa no se va a mostrar en la pantalla.

Regresando a nuestra vista, el siguiente elemento que agregamos después del div que contiene al mapa, es un simple ion-fab que ejecutará el método localizar() del componente, esta función hará que se muestre nuestra ubicación en el mapa.

Es el turno de trabajar en el controlador de esta vista, vamos al archivo tab2.page.ts en donde deberemos agregar el siguiente código:

import { Component, OnInit } from "@angular/core";

import {
  GoogleMaps,
  GoogleMap,
  GoogleMapsEvent,
  Marker,
  GoogleMapsAnimation,
  MyLocation
} from "@ionic-native/google-maps";

import { Platform, LoadingController, ToastController } from "@ionic/angular";

@Component({
  selector: "app-tab2",
  templateUrl: "tab2.page.html",
  styleUrls: ["tab2.page.scss"]
})
export class Tab2Page implements OnInit {
  map: GoogleMap;
  loading: any;

  constructor(
    public loadingCtrl: LoadingController,
    public toastCtrl: ToastController,
    private platform: Platform
  ) {}

  async ngOnInit() {
    // Debido ngOnInit() inicia antes del evento
    // deviceready, debemos detectar cuando este evento se
    // ejecute para en ese momento cargar nuestro mapa sin problema alguno
    await this.platform.ready();
    await this.loadMap();
  }

  loadMap() {
    // Esta función inicializa la propiedad de clase
    // map
    // que va a contener el control de nuestro mapa de google

    // Para crear nuestro mapa debemos enviar como parametros
    // el id del div en donde se va a renderizar el mapa (paso anterior)
    // y las opciones que configuran nuestro mapa
    this.map = GoogleMaps.create("map_canvas", {
      camera: {
        target: {
          lat: -2.1537488,
          lng: -79.8883037
        },
        zoom: 18,
        tilt: 30
      }
    });
  }

  async localizar() {
    // Limpiamos todos los elementos de nuestro mapa
    this.map.clear();

    // Creamos un componente de Ionic para mostrar un mensaje
    // mientras obtenemos esperamos que termine el proceso de
    // obtener la ubicación
    this.loading = await this.loadingCtrl.create({
      message: "Espera por favor..."
    });

    // Presentamos el componente creado en el paso anterior
    await this.loading.present();

    // Ejecutamos el método getMyLocation de nuestra propiedad de clase
    // map
    // para obtener nuestra ubicación actual
    this.map
      .getMyLocation()
      .then((location: MyLocation) => {
        // Una vez obtenida la ubicación cerramos el mensaje de diálogo
        this.loading.dismiss();

        // Movemos la camara a nuestra ubicación con una pequeña animación
        this.map.animateCamera({
          target: location.latLng,
          zoom: 17,
          tilt: 30
        });

        // Agregamos un nuevo marcador
        let marker: Marker = this.map.addMarkerSync({
          title: "Estoy aquí!",
          snippet: "This plugin is awesome!",
          position: location.latLng,
          animation: GoogleMapsAnimation.BOUNCE
        });

        // Mostramos un InfoWindow
        marker.showInfoWindow();

        // Podemos configurar un evento que se ejecute cuando
        // se haya dado clic
        marker.on(GoogleMapsEvent.MARKER_CLICK).subscribe(() => {
          this.showToast("clicked!");
        });
      })
      .catch(error => {
        // En caso de que haya un problema en obtener la
        // ubicación
        this.loading.dismiss();
        this.showToast(error.error_message);
      });
  }

  // Función que muestra un Toast en la parte inferior
  // de la pantalla
  async showToast(mensaje) {
    let toast = await this.toastCtrl.create({
      message: mensaje,
      duration: 2000,
      position: "bottom"
    });

    toast.present();
  }
}
Enter fullscreen mode Exit fullscreen mode

Propiedad map

Nuestra clase posee una propiedad map la cual contendrá toda la información y métodos de nuestro mapa de Google como tal, entonces lo primero que debemos hacer es crear una nueva instancia de mapa apenas iniciado nuestro componente, para hacer tal cosa implementamos la interfaz OnInit y al mismo tiempo el método ngOnInit() y es exactamente aquí donde debe ir toda la lógica que crea mi mapa, esta lógica va a ser invocada desde un método llamado loadMap(). Pero bien, antes de la llamada a esta función debemos asegurarnos de que la plataforma que está ejecutando nuestro código está lista y poder invocar funcionalidad nativa, para de esta manera no tener problemas al cargar nuestro mapa, esto lo hacemos mediante un service propio de Ionic llamado Platform, service que posee un método ready() que me va a devolver una promesa cuando nuestra plataforma esté lista.

loadMap()

Este método realiza la creación de nuestro mapa como tal a través del método create de la clase GoogleMaps. El método create recibe como primer parámetro el Id del div donde va a renderizar nuestro mapa y como segundo parámetro un objeto que debe implementar la interfaz GoogleMapOptions, en este caso pasamos a través de este objeto una propiedad camera en donde a su vez configuramos parámetros acerca de donde queremos que se ubique nuestro mapa, es decir la longitud y latitud, también configuramos el zoom y el ángulo de la vista (tilt).

localizar()

En este método vamos a hacer que nuestro mapa obtenga nuestra ubicación actual y mostraremos un pequeño marcador al cual configuraremos un evento que se va a ejecutar cuando demos clic en el mismo.

Primero dejamos limpio nuestro mapa de todos los elementos gráficos que este pudiera tener con el método this.map.clear(), luego mostramos un pequeño diálogo para que nuestro usuario no desespere mientras obtenemos la ubicación.

 this.map.clear();

 this.loading = await this.loadingCtrl.create({
  message: "Espera por favor..."
 });

await this.loading.present();
Enter fullscreen mode Exit fullscreen mode

Luego ejecutamos el método getMyLocation() de nuestro objeto map el cual me va a devolver una promesa cuando se haya obtenido la ubicación.

this.map.getMyLocation()
 .then((location: MyLocation) => {
        ...
  })
 .catch(error => {
        ...
 });
Enter fullscreen mode Exit fullscreen mode

Una vez que obtuvimos la información de nuestra ubicación vamos a movernos en el mapa a través de this.map.animateCamera, método al que debemos enviar información muy parecida a la que le enviamos por default a nuestro mapa, con la diferencia de que la longitud y latitud va a ser la que hemos obtenido.

this.map.animateCamera({
 target: location.latLng,
 zoom: 17,
 tilt: 30
});
Enter fullscreen mode Exit fullscreen mode

Con nuestra vista situada en la ubicación obtenida vamos a dibujar un nuevo marcador, configurando un título, un pequeño texto de descripción, la posición y una pequeña animación GoogleMapsAnimation.BOUNCE la cual hará que al dibjuarse el marcador dispare una animación de rebote.

let marker: Marker = this.map.addMarkerSync({
 title: "Estoy aquí!",
 snippet: "This plugin is awesome!",
 position: location.latLng,
 animation: GoogleMapsAnimation.BOUNCE
});
Enter fullscreen mode Exit fullscreen mode

Y por último configuramos el evento clic en nuestro marcador haciendo que se muestre un toast cuando este se dispare.

marker.on(GoogleMapsEvent.MARKER_CLICK).subscribe(() => { 
 this.showToast("clicked!"); 
});
Enter fullscreen mode Exit fullscreen mode

Resultado final

Conclusión

El uso de los mapas de Google es una práctica muy común hoy en día, la importancia de referenciar ubicaciones, lugares se vuelve parte de nuestro día a día, y es por esta razón que en nuestro programa abarcamos este tema, espero que haya sido de bastante ayuda y no olvides tu like y comentarios, que nos ayudan mucho para mejorar.

Top comments (2)

Collapse
 
zimarron72 profile image
zimarron72

De antemano gracias por el aporte. Pero me ocurre que al final no visualizo el mapa y la función getmylocation() no se resuelve quedando fijo el aviso de "espere un momento". Con anterioridad uso otro procedimiento que no utiliza el plugin github.com/mapsplugin/cordova-plug..., a diferencia de su procedimiento, en este obtenia errores durante el compilado relacionado con la inexistencia de la libreria android para googlemap. Alguna recomendación adicional.

Gracias de antemano

Collapse
 
angelalexqc profile image
Ángel Quiroz

Me sirvió mucho crack, gracias.

DEV has this feature:

Settings

Go to your customization settings to nudge your home feed to show content more relevant to your developer experience level. 🛠