Archivo de la etiqueta: leaflet

Mostrar un mapa offline en Ionic con Leaflet

En el siguiente enlace tienes el 铆ndice para acceder al resto de entradas de este tutorial:

 

隆隆Atenci贸n!! este tutorial se basa en ionic 3 y est谩 desactualizado por lo que es posible que los ejemplos no funcionen en la 煤ltima versi贸n de ionic, haz click aqu铆 para acceder a un tutorial mas actual de Ionic.

Hola a todos:

En posts anteriores vimos como mostrar un mapa de Google maps en ionic, sin embargo 驴que pasa si queremos mostrar informaci贸n en un mapa sin conexi贸n?, google maps no nos podr谩 mostrar el mapa.

En lugar de utlizar Google maps en esta ocasi贸n vamos a utilizar Leaflet para mostrar un mapa.

Leaflet聽 es una biblioteca javascript de c贸digo abierto que nos permite crear mapas.

Lanzado por primera vez en 2011,聽es compatible con la mayor铆a de las plataformas m贸viles y de escritorio, y es compatible con聽HTML5聽y聽CSS3聽.

Es una de las bibliotecas de mapas de JavaScript m谩s populares y es utilizada por los sitios web como聽FourSquare聽,聽Pinterest聽y聽Flickr聽.

Para poder mostrar un mapa offline es necesario tener alojados loc谩lmente los titles que forman el mapa, si quieres mostrar un mapa de todo el mundo offline a d铆a de hoy podemos afirmar聽 que es inviable ya que eso supondr铆a much铆simos gigas de informaci贸n, sin embargo si que puede ser viable mostrar un mapa offline de una ciudad.

Si por ejemplo est谩s desarrollando una aplicaci贸n de turismo de una ciudad concreta donde vas a mostrar en un mapa聽 los monumentos que merece la pena visitar en dicha ciudad, o cualquier otra informaci贸n geolocalizada en un mapa, puede ser interesante el poder mostrar un mapa sin necesidad de tener conexi贸n a Internet en ese preciso momento.

Vamos a ver como podemos solucionar esto en ionic 3, y como siempre la mejor manera de verlo es con un ejemplo.

Lo primero que vamos ha hacer es crear un nuevo proyecto en ionic que vamos a llamar mapaoffline:

ionic start mapaoffline blank

Una vez creado el en proyecto entramos en la carpeta con:

cd mapaoffline

Ahora vamos a descargar Leaflet, para ello descargamos la 煤ltima versi贸n desde聽 la secci贸n de descargas de su p谩gina oficial en el siguiente enlace:

http://leafletjs.com/download.html

Se habr谩 descargado un archivo .zip, antes de nada debemos descomprimirlo para extraer su contenido:

 

Ahora vamos a crear una carpeta llamada leaflet en src/assets y dentro vamos a copiar la carpeta images y el archivo leaflet.css.

Una vez hecho esto vamos a cargar el archivo leaflet.css en index.html:

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="UTF-8">
  <title>Ionic App</title>
  <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <meta name="format-detection" content="telephone=no">
  <meta name="msapplication-tap-highlight" content="no">

  <link rel="icon" type="image/x-icon" href="assets/icon/favicon.ico">
  <link rel="manifest" href="manifest.json">
  <meta name="theme-color" content="#4e8ef7">

  <!-- add to homescreen for ios -->
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">

  <!-- cordova.js required for cordova apps -->
  <script src="cordova.js"></script>

  <!-- un-comment this code to enable service worker
聽聽
聽聽聽聽if ('serviceWorker' in navigator) {
聽聽聽聽聽聽navigator.serviceWorker.register('service-worker.js')
聽聽聽聽聽聽聽聽.then(() => console.log('service worker installed'))
聽聽聽聽聽聽聽聽.catch(err => console.error('Error', err));
聽聽聽聽}
聽聽-->

  <link href="build/main.css" rel="stylesheet">
  <link href="assets/leaflet/leaflet.css" rel="stylesheet">


</head>
<body>

  <!-- Ionic's root component and where the app will load -->
  <ion-app></ion-app>

  <!-- The polyfills js is generated during the build process -->
  <script src="build/polyfills.js"></script>

  <!-- The vendor js is generated during the build process
聽聽聽聽聽聽聽It contains all of the dependencies in node_modules -->
  <script src="build/vendor.js"></script>


  <!-- The main bundle js is generated during the build process -->
  <script src="build/main.js"></script>

</body>
</html>

Ahora vamos a instalar leaflet desde consola con los siguiente comandos:

npm install leaflet --save
npm install @types/leaflet --save

Ahora que ya tenemos instalado leaflet necesitamos descargar los tiles del mapa que vamos a mostrar, para ello vamos a echar mano de una herramienta llamada Mobile Atlas Creator (MOBAC), para descargarla accedemos al siguiente enlace:聽http://mobac.sourceforge.net/聽y bajamos en la p谩gina hasta encontrar Download y pulsamos en latest stable version聽para descargar la aplicaci贸n.

Una vez descargada tenemos que descomprimir el archivo zip y dentro encontraremos el archivo ejecutable.

Al ejecutar Mobile Atlas Creator nos pide introducir un nombre para el atlas (en este caso le llamamos simplemente mapa) y el formato, tenemos que seleccionar Osmdroid ZIP.

 

Pulsamos Aceptar y nos mostrar谩 un mapa, podemos mover zoom para ver mejor la zona que queremos seleccionar. Si hacemos doble click en un punto el mapa har谩 zoom y se centrar谩 en ese punto, por ello para localizar la zona que queremos mostrar es mejor partir de un zoom que nos permita ver donde estamos e ir haciendo doble click hasta obtener la localizaci贸n y zoom que nos interesa.

En el panel de la izquierda en la secci贸n map source tenemos los mapas de los que podemos obtener los tiles, muchos son solo de una zona en concreto, yo para este ejemplo voy a utilizar OpenStreetMap4UMaps.eu聽que nos ofrece un mapa de todo el mundo.

Debajo del panel Map Source tenemos聽 el panel Zoom Levels, aqui debemos seleccionar los niveles de zoom que queremos que tenga el mapa, cabe mencionar que cuantos m谩s niveles de zoom mas tiles necesitaremos y por ende mas espacio ocupar谩n las im谩genes.

Marcamos por ejemplo 11,12,13,14, y 15.

Ahora tenemos que seleccionar la porci贸n del mapa que queremos descargar:

En la parte de arriba del mapa tenemos una barra de zoom que podemos mover para ver mejor la parte del mapa que queremos seleccionar. Con el rat贸n sobre el mapa seleccionamos un 谩rea.

Yo por ejemplo he seleccionado la zona de Bilbao, de est谩 manera podr茅 mostrar un mapa de Bilbao sin conexi贸n.

Ahora debajo del panel Zoom Levels tenemos el panel Atlas content, aqu铆 vamos a pulsar en el bot贸n聽Add Selection聽lo que nos crear谩 un Layer聽 que si lo desplegamos vemos que contiene dentro los niveles de zoom que hemos seleccionado.

Bien, una vez que hemos seleccionado el 谩rea que queremos descargar tenemos que seleccionar Create Atlas聽y聽acto seguido comenzar谩 a generar el atlas:

El atlas que se ha generado ser谩 un archico .zip con el nombre que le hemos dado al atlas en este caso mapa seguido de la fecha y hora en la que ha sido generado y lo encontrar谩s en la carpeta atlases聽dentro de la carpeta聽 donde tengas Mobile Atlas Creator.

Bien, ahora vamos descomprimir el archivo zip que nos ha generado, al descomprimir vemos que dentro de la carpeta que nos ha creado hay otra carpeta llamada 4uMaps, vamos a cambiarle el nombre a la carpeta por simplemente聽mapa聽y a copiar esta carpeta dentro de la carpeta assets de nuestro proyecto:

 

Una vez que tenemos Los tiles copiados en la carpeta assets de nuestro proyecto ya podemos mostrarlos en el mapa.

Vamos a editar home.html聽e igual que hac铆amos cuando creamos un mapa con google maps vamos a crear un div con id=”map” donde se renderizar谩 el mapa:

<ion-header>
<ion-navbar>
  <ion-title>
    Ionic Blank
  </ion-title>
</ion-navbar>
</ion-header>

<ion-content padding>
<div id="map"></div>
</ion-content>

Ahora le vamos a definir el tama帽o para que ocupe toda la pantalla por lo tanto editamos home.scss y a帽adimos lo siguiente:

page-home {
聽聽聽聽#map{
聽聽聽聽聽聽聽聽width:100%;
聽聽聽聽聽聽聽聽height: 100%;
    }
}

Ahora en home.ts vamos a ver como se crea un mapa con leaflet:

Lo primero que debemos hacer es importar leaflet:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import * as L from 'leaflet';

Ahora vamos a crear una variable de clase llamada map donde guardaremos la instancia del mapa que vamos a crear:

...

export class HomePage {

  map : any;

  constructor(public navCtrl: NavController) {

  }

...

Ahora cuando se haya cargado la p谩gina en el m茅todo onViewDidLoad vamos a crear el mapa de la siguiente manera:

ionViewDidLoad() {

   this.map = L.map('map').
     setView([ 43.2603479, -2.9334110],
     12);

   L.tileLayer('assets/mapa/{z}/{x}/{y}.png', {    maxZoom: 15  }).addTo(this.map);

   L.marker([ 43.2603479,-2.9334110],{draggable: true}).addTo(this.map);

 }

Para crear un mapa con Leaflet utilizamos L.map(‘map’), ‘map’ es el id del div que hemos creado en la vista home.html y que es donde se va a renderizar el mapa.

Despu茅s con el metodo .setView le indicamos las coordenadas donde se tiene que posicionar el mapa, en este caso son las del centro de Bilbao.

Con L.tileLayer()聽a帽adimos al mapa una capa de tiles que va a contener los tiles del mapa que hemos descargado, como primer par谩metro le pasamos la ruta donde se encuentran los tiles que puede ser una url si estamos utilizando un mapa online o la ruta donde se encuentrar alojados los archivos para mostrar el mapa offline como es el caso.

Si nos fijamos en la ruta vemos que es ‘assets/mapa/{z}/{x}/{y}.png’,聽聽聽z, x e y hacen referencia respectivamente al nivel de Zoom, tiles en el eje X y tiles en el eje Y.

Obtendr谩n el valor correspondiente autom谩ticamente en funci贸n de la posici贸n del mapa y al tener la carpeta de los tiles ordenada por estos par谩metros no te tienes que preocupar.

Despues con聽L.marker聽 creamos un marcador en en las coordenadas indicadas y le decimos que sea聽 arratrable (draggable) y con .addTo(this.map) lo a帽adimos a nuestro mapa.

El c贸digo completo de home.ts quedar铆a as铆:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import * as L from 'leaflet';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  map;

  constructor(public navCtrl: NavController) {

  }

  ionViewDidLoad() {

    this.map = L.map('map').
      setView([ 43.2603479, -2.9334110],
      12);

    L.tileLayer('assets/mapa/{z}/{x}/{y}.jpg', {    maxZoom: 15  }).addTo(this.map);

    L.marker([ 43.2603479,-2.9334110],{draggable: true}).addTo(this.map);

  }

}

Ahora si ejecutamos nuestra app aunque no tengamos conexi贸n a internet podemos mostrar un mapa:

 

Eso es todo por hoy, como siempre espero que os sea de utilidad.

 

Si necesitas desarrollar una aplicaci贸n m贸vil no dudes en solicitarme un presupuesto sin compromiso: