Está en la página 1de 8

EN ES

Publicado por: Eric Cobos Sanchez | GPS Tracking | Ionic3

28
C o m o t ra z a r r u t a G PS c o n I o n i c 3

ABR

Aquí veremos como trazar correctamente la ruta que un usuario realiza con nuestra app

de Ionic3, como por ejemplo hacen Runtastic o Wikiloc. Nos centraremos en crear un

servicio que ofrezca a nuestra aplicación la ruta más exacta que hace el usuario, esto

significa tener en cuenta que el GPS puede fallar, devolvernos puntos falsos, ir en

Utilizamos cookieszigzag,
para asegurar
etc. Loque
quedamos
vamoslaamejor
hacerexperiencia al usuario
es aprender entodas
a filtrar nuestro sitio
las web. Si continúa
posiciones que nos

utilizando este
facilita el GPSsitio
paraasumiremos que está
intentar hacer unde acuerdo. del
seguimiento Estoy de acuerdo
usuario lo más preciso posible.

Lo primero que haremos será preparar una aplicación de Ionic3 nueva:

$ ionic start gpstracker blank

Ya tenemos la estructura de nuestra app creada, ahora lo que haremos será añadir los

plugins de Google Maps y de Geolocalización:

$ ionic plugin add cordova-plugin-geolocation


$ npm install --save @ionic-native/geolocation
$ ionic plugin add cordova-plugin-googlemaps --variable API_KEY_FOR_ANDROID="YOU
$ npm install --save @ionic-native/google-maps

Para los que usáis el plugin de Google Maps por primera vez, os recomendaría que

leyerais el manual de instalación del mismo, ya que para obtener las claves de API hay

que realizar varios pasos, aquí os dejo el

enlace: h ps://github.com/mapsplugin/cordova-plugin-googlemaps-

doc/blob/master/v1.4.0/Installation/windows/cli/README.md

También necesitaremos una librería llamada simplify-js, que será la encargada de ir

simplificando nuestra ruta mediante una combinación de los algoritmos Douglas

Peucker y de Distancia Radial.

$ npm install --save simplify-js

Una vez tenemos los plugins listos, vamos a ponernos manos a la obra.

Primero de todo crearemos una carpeta models y dentro un archivo que vamos a llamar

CustomGeoposition.ts, en donde tendremos nuestro propio modelo implementando

Geoposition, al que le añadiremos dos variables, x e y, las cuales necesitarán la librería

simplify-js para reconocer los puntos.

impo {Geoposition} from "@ionic-native/geolocation";

expo class CustomGeoposition implements Geoposition {

public coords: Coordinates;

Utilizamos cookies para asegurar que damos la mejor experiencia al usuario en nuestro sitio web. Si continúa
public timestamp: number;
utilizando este sitio asumiremos que está de acuerdo. Estoy de acuerdo
public x;
public y; 

constructor (geoposition: Geoposition){

this.coords = geoposition.coords;

this.timestamp = geoposition.timestamp;

this.x = geoposition.coords.latitude;

this.y = geoposition.coords.longitude;

Una vez tenemos nuestro modelo auxiliar implementado, crearemos una carpeta

services y dentro introducimos nuestro servicio de tracking, TrackingService.ts

impo {Injectable} from "@angular/core";

impo * as simplify from "simplify-js";

impo {CustomGeoposition} from "../models/CustomGeoposition";

impo {BehaviorSubject} from "rxjs/BehaviorSubject";

impo {Observable} from "rxjs/Observable";

impo {Geoposition} from "@ionic-native/geolocation";

impo { Geolocation } from '@ionic-native/geolocation';

@Injectable()

expo class TrackingService {

// Here we set the min accuracy that we want to keep

minAccuracy: number = 25;

// This will determine how frequently we simplify and emit positions

positionPile: number = 3;

// We use positionArray to temporary store positions in order to simplify them later

positionArray: CustomGeoposition[] = [];

// We store the last position emi ed here in order to avoid jumps that could be produced

previousPosition: CustomGeoposition = null;

// We define the Subject and the observable that will emit the position values to the sub

private _actualPosition: BehaviorSubject<Geoposition> = new BehaviorSubject<Geopo

public actualPosition: Observable<Geoposition> = this._actualPosition.asObservable();

constructor(private geolocation: Geolocation) { }

Utilizamos cookies para asegurar que damos la mejor experiencia al usuario en nuestro sitio web. Si continúa
// This method should be called in order the service sta s emi ing positions

utilizando este Tsitio


public sta asumiremos
racking(): void { que está de acuerdo. Estoy de acuerdo
// We subscribe to the geolocation services 
this.geolocation.watchPosition({enableHighAccuracy: true}).subscribe(

actualPosition => {

// Check if the position is valid

if(actualPosition.coords !== undefined){

// Validate the position, if speed is 0 it means that user is stopped, so we don't need

if (actualPosition.coords.speed > 0 && actualPosition.coords.accuracy < this.minAc

//If the position is valid we push to our positions array

this.positionArray.push(new CustomGeoposition(actualPosition));

// Once we've reached the maximum stack of positions we process them

if (this.positionArray.length > this.positionPile) {

// Adding at first position the last position processed, to force simplification to sta

if(this.previousPosition==null){

this.previousPosition = this.positionArray[0];

this.positionArray.unshi (this.previousPosition);

// Simplifying line

let filteredPoints = simplify(this.positionArray, 15, true);

// Rese ing the array

this.positionArray = [];

filteredPoints.unshi (this.previousPosition);

// We call a method that will emit the simplified positions

this.parseFilteredPoints(filteredPoints);

);

// This method gets the array of simplified positions and emits them to the subscribers

parseFilteredPoints(filteredPoints: CustomGeoposition[]){

filteredPoints.forEach(point => {

this._actualPosition.next( point );

this.previousPosition = point;

});

Nuestro servicio se encarga de suscribirse al servicio de posicionamiento, va


Utilizamos cookies para asegurar que damos la mejor experiencia al usuario en nuestro sitio web. Si continúa
recogiendo las posiciones que este emite, tratándolas y filtrándolas, y las va
utilizando este sitio asumiremos que está de acuerdo. Estoy de acuerdo
almacenando en una pila. 

Cuando la pila llega a su límite, se simplifican los puntos almacenados en la misma y se

emite la simplificación para todo lo que esté suscrito al Observable actualPosition.

Ahora, lo que tenemos que hacer es crear un componente que consuma nuestro

servicio y que pinte en Google Maps la ruta que el usuario va trazando.

Lo haremos directamente sobre el Home page.

impo {Component, OnInit} from '@angular/core';

impo { NavController } from 'ionic-angular';

impo {GoogleMap, GoogleMapsEvent, LatLng} from "@ionic-native/google-maps";

impo {Geoposition} from "@ionic-native/geolocation";

impo {TrackingService} from "../../services/TrackingService";

declare var plugin: any;

@Component({

selector: 'page-home',

templateUrl: 'home.html'

})

expo class HomePage implements OnInit {

map: GoogleMap;

previousPosition: Geoposition;

constructor(public navCtrl: NavController, private trackingService: TrackingService) {

ngOnInit(){

this.setMap();

this.loadMap();

this.trackingService.sta Tracking();

this.trackingService.actualPosition.subscribe(position => {

if(position!=null){

this.drawRoute(position);

Utilizamos cookies para


}) asegurar que damos la mejor experiencia al usuario en nuestro sitio web. Si continúa
utilizando
}
este sitio asumiremos que está de acuerdo. Estoy de acuerdo

setMap(){

let controls: any = {compass: true, myLocationBu on: false, indoorPicker: false, zoom: t

this.map = new GoogleMap('map', {

'backgroundColor': 'white',

'controls': {

'compass': controls.compass,

'myLocationBu on': controls.myLocationBu on,

'indoorPicker': controls.indoorPicker,

'zoom': controls.zoom,

'mapTypeControl': controls.mapTypeControl,

'streetViewControl': controls.streetViewControl

},

'gestures': {

'scroll': true,

'tilt': true,

'rotate': true,

'zoom': true

});

loadMap(){

this.map.on(GoogleMapsEvent.MAP_READY).subscribe(

(map) => {

map.clear();

map.o ();

map.setMapTypeId(plugin.google.maps.MapTypeId.HYBRID);

map.setMyLocationEnabled(true);

},(error)=>{

console.error("Error:", error);

);

drawRoute(pos:Geoposition):void{

if(this.previousPosition==null){

this.previousPosition = pos;

}
Utilizamos cookies para asegurar que damos la mejor experiencia al usuario en nuestro sitio web. Si continúa
this.map.addPolyline(
utilizando este sitio asumiremos que está de acuerdo. Estoy de acuerdo
{ 
points: [new LatLng(this.previousPosition.coords.latitude, this.previousPosition.coord

visible: true,

color:'#FF0000',

width:4

}).then(

(res)=>{

this.previousPosition = pos;

).catch(

(err)=>{

console.log("err: "+JSON.stringify(err));

);

¡Ya lo tenemos casi todo listo! Solamente faltaría añadir los providers necesarios al

app.module, esto sería así:

providers: [

StatusBar,

SplashScreen,

{provide: ErrorHandler, useClass: IonicErrorHandler},

TrackingService,

Geolocation

¡Ahora si, ya podemos probar nuestra app! Espero que os haya gustado y lo encontréis

de utilidad. Podéis encontrar todo el código en mi

repositorio h ps://github.com/psykologist90/gpstracker

Utilizamos cookies para asegurar que damos la mejor experiencia al usuario en nuestro sitio web. Si continúa
utilizando este sitio asumiremos que está de acuerdo. Estoy de acuerdo

RIL, 2017
th Hacking vs. Digital Marketing

Utilizamos cookies para asegurar que damos la mejor experiencia al usuario en nuestro sitio web. Si continúa
utilizando este sitio asumiremos que está de acuerdo. Estoy de acuerdo

También podría gustarte