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:
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.
Después de haber creado tu proyecto accede a la biblioteca de APIs en el menú lateral.
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.
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ó.
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
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" />
Y nuestro código debería quedar algo así:
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>
Nuestro código debería quedar algo parecido a esto:
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%;
}
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();
}
}
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();
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 => {
...
});
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
});
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
});
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!");
});
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)
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
Me sirvió mucho crack, gracias.