Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de...

19
Mapas en iOS Índice 1 La vista de mapa........................................................................................................... 2 2 Configuraciones del MapView..................................................................................... 3 2.1 Posición actual......................................................................................................... 3 2.2 Tipo de mapa............................................................................................................4 2.3 Zoom en región........................................................................................................ 4 2.4 Modo de seguimiento............................................................................................... 5 3 Anotaciones.................................................................................................................. 6 3.1 Crear anotaciones..................................................................................................... 6 3.2 Mostrar anotaciones................................................................................................. 7 3.3 Personalizar anotaciones.......................................................................................... 8 3.4 Personalización avanzada........................................................................................ 9 4 Capas.......................................................................................................................... 11 4.1 Definiendo un MKOverlay.................................................................................... 12 5 Usando el Geocoder................................................................................................... 14 5.1 Geocodificación común......................................................................................... 15 5.2 Geocodificación inversa.........................................................................................16 6 Navegación paso a paso............................................................................................. 16 Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Transcript of Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de...

Page 1: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

Mapas en iOS

Índice

1 La vista de mapa...........................................................................................................2

2 Configuraciones del MapView.....................................................................................3

2.1 Posición actual......................................................................................................... 3

2.2 Tipo de mapa............................................................................................................4

2.3 Zoom en región........................................................................................................ 4

2.4 Modo de seguimiento...............................................................................................5

3 Anotaciones.................................................................................................................. 6

3.1 Crear anotaciones.....................................................................................................6

3.2 Mostrar anotaciones................................................................................................. 7

3.3 Personalizar anotaciones..........................................................................................8

3.4 Personalización avanzada........................................................................................ 9

4 Capas.......................................................................................................................... 11

4.1 Definiendo un MKOverlay.................................................................................... 12

5 Usando el Geocoder................................................................................................... 14

5.1 Geocodificación común......................................................................................... 15

5.2 Geocodificación inversa.........................................................................................16

6 Navegación paso a paso............................................................................................. 16

Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 2: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

En muchas ocasiones deberemos incorporar un mapa a nuestra aplicación móvil paramostrar la posición de algún sitio, para situarnos en el o simplemente para interactuar conel de una forma u otra. Los mapas de iOS son muy sencillos de usar e implementar.Desde iOS 6, Apple pone a disposición de los desarrolladores su propio sistema demapas, realizados en su totalidad con imágenes en formato vectorial y con toda lainformación recogida de la base de datos de Tom Tom. Existen otras opciones, como usarmapas de Google o de OpenStreetMaps, lo cual complica en parte la incorporación deestos en una aplicación. En esta sesión estudiaremos como podemos incorporar elcomponente de mapa y añadir marcadores con información en el.

Mapas en iOS 6

1. La vista de mapa

El SDK de iOS incluye un framework completo para la implementación de mapas ennuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistasque nos permiten realizar varias tareas sobre los mapas. Uno de los componentes másimportantes de este framework es el MKMapView. El MKMapView es el mapa en sí, será labase sobre la que se dibujarán los marcadores y las capas que deseemos. Si no hacemosningún tipo de modificación, el componente MKMapView contendrá simplemente un mapacomo el que podemos encontrar en la aplicación de Mapas nativa de iOS. Añadir estecomponente a nuestra aplicación es muy sencillo:

Primero deberemos de importar el framework MapKit a nuestro proyecto. Esto loharemos entrando en la configuración del proyecto, dentro de la pestaña "Build Phases",en el apartado "Link Binary With Libraries" pulsamos sobre el botón con el símbolo "+".Ahí deberemos de buscar "mapkit". Seleccionamos el framework MapKit.framework ypulsamos sobre el botón "Add".

Mapas en iOS

2Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 3: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

Pantalla importar framework

Una vez que hemos añadido el framework de MapKit deberemos abrir la vista en dondequeramos añadir el mapa y arrastrar desde la librería de objetos el componente "MapView".

Componente Map View

Ahora tenemos que indicar a la controladora que vamos usar el framework de MKMapKit,para ello debemos de definir el import al principio del código del fichero .h.

#import <MapKit/MapKit.h>

Por último nos falta indicar que la controladora va a implementar el protocolo del mapaMKMapViewDelegate, esto lo hacemos en la definición de la interfaz, añadiendo elprotocolo MKMapViewDelegate tal y como se muestra a continuación:

@interface ViewController : UIViewController <MKMapViewDelegate>

Una vez hecho esto, si arrancamos la aplicación veremos que nos aparecerá el mapa ennuestra vista. ¡Es así de fácil!

2. Configuraciones del MapView

El componente MKMapView se puede configurar según una serie de parámetros. En esteapartado veremos como adaptarlo según los requerimientos de nuestra aplicación.

2.1. Posición actual

Uno de los requerimientos más solicitados a la hora de mostrar un mapa en nuestras

Mapas en iOS

3Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 4: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

aplicaciones es indicar en el la posición actual en donde nos encontramos. Esto es muysencillo gracias al MapView de UIKit.

Para activar esta propiedad deberemos de abrir la vista con el componente Map View en elInterface Builder. Seleccionamos el componente Map View y marcamos la opción "ShowUser Location" que se encuentra entre las primeras opciones de la pestaña "AttributesInspector". Con tan sólo marcar esta casilla ya se mostrará la posición actual en el mapa.

Si deseamos cambiar esta propiedad por código deberemos de modificar el valor delatributo showsUserLocation a nuestro gusto (YES o NO).

Solicitud de permisosAl arrancar la aplicación por primera vez al usuario le aparecerá un Alert pidiendo permiso paraque la esta pueda usar la ubicación actual. Si el usuario selecciona "No permitir", entonces no semostrará la posición actual en el mapa.

Nuestra posición en el mapa corresponderá al punto azul que aparece. Si pulsamos sobreél aparecerá un pequeño globo con el texto "Current position". En los siguientes apartadosveremos como personalizar este tipo de mensajes.

2.2. Tipo de mapa

Como ya sabemos, algunos sistemas de mapas (Google, Apple, Nokia...) ofrecen distintosmodos de visualización como clásico, satélite, etc. En este apartado veremos comocambiar el modo de visualización de los mapas de Apple usando el componente Map

View.

Al igual que en el apartado anterior, esto podemos hacerlo mediante las opciones delInterface Builder o por código. Si usamos el Interfaz Builder deberemos de seleccionar elcomponente Map View y después, dentro de la pestaña "Attributes Inspector", seleccionaren el primer desplegable ("Type") el tipo de mapa que queremos que se muestre pordefecto al arrancar la aplicación. Podremos elegir entre Map, Satellite o Hybrid.

La propiedad correspondiente del componente MKMapView para indicar el tipo de mapa ausar es mapType:

// Mostramos el tipo de mapa híbrido (satelite y plano)self.mapView.mapType = MKMapTypeHybrid;

La propiedad mapType recibe un tipo enumerado: MKMapTypeStandard,MKMapTypeSatellite o MKMapTypeHybrid.

2.3. Zoom en región

El propio componente MKMapView nos permite hacer zoom o centrar el mapa de una

Mapas en iOS

4Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 5: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

forma muy sencilla por código. Para implementar esta funcionalidad deberemos de usar elmétodo setRegion: que recibirá como parámetro un tipo struct llamadoMKCoordinateRegion.

El MKCoordinateRegion podemos inicializarlo de varias formas. Una de las mássencillas es indicando las coordenadas del centro de la región y la distancia en metrosdesde esas coordenadas. Esto lo haremos de la siguiente forma:

// Coordenadas de ejemploCLLocationCoordinate2D coordenadas =

CLLocationCoordinate2DMake(38.362404,-0.411748);

// Creamos una region a partir de las coordenadas y una distancia de1000 mentros

MKCoordinateRegion region =MKCoordinateRegionMakeWithDistance(coordenadas, 1000, 1000);

// Indicamos al mapa que queremos centrar la vista en esa region[self.mapView setRegion:region];

En este ejemplo vamos a centrar el mapa según unas coordenadas de ejemplo y con unradio de distancia de 1000 metros (1 km). Es así de sencillo.

Pruebas en el simuladorPuede que el simulador de XCode actúe de forma "extraña" cuando estamos usando funciones delocalización tales como GPS, brújula, etc. Esto es porque el simulador no incorpora ningún chipde posicionamiento. Es recomendable probar este tipo de aplicaciones en dispositivos reales.

2.4. Modo de seguimiento

Esta funcionalidad fue introducida a con el SDK de iOS 5 y es muy interesante.Configurando un modo de seguimiento podremos obtener en tiempo real la localizacióndel usuario a medida que este se vaya desplazando. El modo de seguimiento o Usertracking mode está activado por defecto. Podemos desactivarlo modificando el parámetrouserTrackingMode del componente MKMapView. En el código siguiente podemos ver unejemplo de implementación:

// La controladora debe de implementar el protocolo MKMapViewDelegate// para recibir las actualizaciones de localización@interface ViewController : UIViewController <MKMapViewDelegate>

En el método viewDidLoad activamos el modo de seguimiento:

// Indicamos al Map View que active el modo de seguimiento básico[self.mapView setUserTrackingMode:MKUserTrackingModeFollow];

Método del protocolo MKMapViewDelegate que captura las actualizaciones delocalización del usuario:

Mapas en iOS

5Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 6: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

// Implementamos el método didUpdateUserLocation del protocoloMKMapViewDelegate-(void) mapView:(MKMapView *)mapView

didUpdateUserLocation:(MKUserLocation *)userLocation{

NSLog(@"Nueva localización: %@", [userLocation.locationdescription]);}

Mediante el código anterior capturamos en todo momento la posición del usuario. Cadavez que los servicios de localización del dispositivo detectan movimiento, se ejecutará elmétodo didUpdateUserLocation.

Framework Core LocationPara poder usar los métodos de localización necesitaremos importar a nuestro proyecto elframework CoreLocation.framework. Si no lo importamos nos aparecerá un error decompilación.

3. Anotaciones

En bastantes ocasiones tendremos que mostrar marcadores en el mapa con el fin deindicar ciertos puntos de interés que queremos destacar en nuestra aplicación, esto loharemos mediante las anotaciones. Las anotaciones mantendrán su tamañoindependientemente del zoom que hagamos sobre el mapa. Para implementar este tipo deanotaciones deberemos de hacer uso de la clase MKAnnotationView.

En este apartado estudiaremos cómo crear anotaciones, cómo integrarlas en nuestro mapay por último, cómo personalizarlas.

3.1. Crear anotaciones

Para crear una o varias anotaciones en un MapView deberemos de definir una clase de tipoNSObject que implmente MKAnnotation. La versión más básica de esta clase puede sercomo sigue:

// Fichero .h#import <Foundation/Foundation.h>#import <MapKit/MapKit.h>

@interface CustomAnnotation : NSObject <MKAnnotation>

@property (nonatomic) CLLocationCoordinate2D coordinate;@property (nonatomic, retain) NSString *title;@property (nonatomic, retain) NSString *subtitle;

- (id)initWithCoordinate:(CLLocationCoordinate2D) c;- (id)initWithCoordinate:(CLLocationCoordinate2D)cwithName:(NSString*)namewithAddress:(NSString*)address;

Mapas en iOS

6Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 7: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

@end

// Fichero .m@implementation CustomAnnotation

- (id)initWithCoordinate:(CLLocationCoordinate2D) c {self.coordinate = c;self.title = @"Titulo";self.subtitle = @"Subtitulo";return self;

}

-(id)initWithCoordinate:(CLLocationCoordinate2D)c withName:(NSString*)namewithAddress:(NSString*)address {

self = [super init];if (self) {

self.coordinate = c;self.title = name;self.subtitle = address;

}return self;

}

@end

Mediante el código anterior definimos una clase que hemos llamado CustomAnnotation.Es importante tener en cuenta que una anotación debe de tener al menos unascoordenadas (CLLocationCoordinate2D), un título y un subtítulo. En nuestro ejemplo,además de las coordenadas hemos añadido un título y un subtítulo a la anotación.También hemos definido dos constructores.

Con esto tenemos nuestra clase CustomAnnotation lista para ser usada en nuestrocódigo.

3.2. Mostrar anotaciones

Una vez que hemos definido la clase para nuestras anotaciones, deberemos usarla paracrear una anotación en unas coordenadas y añadirla al mapa. Esto lo programamos de lasiguiente forma:

CustomAnnotation *customAnnotation = [[CustomAnnotation alloc]initWithCoordinate:coordenadas];

[self.mapView addAnnotation:customAnnotation];

En el código anterior creamos un objeto de tipo CustomAnnotation, lo inicializamos conunas coordenadas (CLLocationCoordinate2D) y lo añadimos al MapView.

Si arrancamos la aplicación veremos que aparece una anotación con forma de "pin" decolor rojo en el mapa. En el siguiente apartado aprenderemos como personalizar estaanotación añadiendo una imagen en lugar del pin, por ejemplo.

Mapas en iOS

7Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 8: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

Mapa con pin

3.3. Personalizar anotaciones

Hasta aquí hemos aprendido como crear anotaciones y mostrarlas en un componenteMapView. En este apartado continuaremos con las anotaciones y veremos comopersonalizarlas un poco más. Al final del bloque sabremos como mostrar una imagen enlugar del pin que se muestra por defecto.

El protocolo MKMapViewDelegate contiene una serie de métodos que permiten trabajar enprofundidad con el componente MKMapView. Entre esos métodos hay varios que nosfacilitan la personalización de las anotaciones que se muestran en el. Vamos a ver comopodemos implementar dichos métodos.

El método más importante que nos permite personalizar las anotaciones esmapView:viewForAnnotation. A continuación podemos ver un ejemplo sencillo deimplementación de este método en el que asignamos una imagen a la anotación:

#pragma mark - MapView Methods- (MKAnnotationView *)mapView:(MKMapView *)mapViewviewForAnnotation:(id <MKAnnotation>)annotation{

static NSString *annotationViewReuseIdentifier =@"annotationViewReuseIdentifier";

MKAnnotationView *annotationView = (MKAnnotationView *)[mapViewdequeueReusableAnnotationViewWithIdentifier:annotationViewReuseIdentifier];

if (annotationView == nil){

annotationView = [[MKAnnotationView alloc]initWithAnnotation:annotation

reuseIdentifier:annotationViewReuseIdentifier];}

annotationView.image = [UIImage imageNamed:@"mi_imagen.png"];

Mapas en iOS

8Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 9: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

annotationView.annotation = annotation;

return annotationView;}

El método anterior recibe como parámetros el MapView y la anotación en sí. En estemétodo deberemos de devolver un objeto de tipo MKAnnotationView que será una vistacomún (UIView). Aquí es donde podemos personalizar como deseemos la anotación. Enel ejemplo anterior asignamos una imagen a la anotación.

Mapa con anotación personalizada

Podemos eliminar las anotaciones de un mapa haciendo uso del método [self.mapView

removeAnnotations:arrayAnotaciones]. También podemos acceder a todas lasanotaciones de un mapa a través de la propiedad annotations del MapView.

Iconos para mapas gratisDesde esta web podemos descargarnos miles de iconos para usarlos como anotaciones ennuestras aplicaciones: http://mapicons.nicolasmollet.com/.

3.4. Personalización avanzada

Si deseamos personalizar la vista que aparece al pulsar sobre la anotación deberemos demodificar el método mapView:viewForAnnotation:. Un ejemplo de personalizaciónpodemos verlo en el código siguiente.

- (MKAnnotationView *)mapView:(MKMapView *)mapViewviewForAnnotation:(id <MKAnnotation>)annotation{

static NSString *annotationViewReuseIdentifier =@"annotationViewReuseIdentifier";

MKAnnotationView *annotationView = (MKAnnotationView *)[mapViewdequeueReusableAnnotationViewWithIdentifier:annotationViewReuseIdentifier];

Mapas en iOS

9Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 10: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

if (annotationView == nil){

annotationView = [[MKAnnotationView alloc]initWithAnnotation:annotation

reuseIdentifier:annotationViewReuseIdentifier];}

annotationView.image = [UIImage imageNamed:@"mi_imagen.png"];annotationView.annotation = annotation;[annotationView setCanShowCallout:YES];

// ButtonUIButton *button = [UIButton

buttonWithType:UIButtonTypeDetailDisclosure];button.frame = CGRectMake(0, 0, 23, 23);annotationView.rightCalloutAccessoryView = button;

// Image and two labelsUIView *leftCAV = [[UIView alloc]

initWithFrame:CGRectMake(0,0,23,23)];

UILabel *labelCallout = [[UILabel alloc]initWithFrame:CGRectMake(0,0,100,23)];

labelCallout.text = @"texto label";[leftCAV addSubview:labelCallout];

annotationView.leftCalloutAccessoryView = leftCAV;

return annotationView;}

Anotación con botón

Si queremos hacer una personalización más compleja, como por ejemplo añadir nuevasvistas, modificar el tamaño de la anotación, añadir más textos o imagenes, etc...deberemos de implementar otro sistema, como por ejemplo crear una vista en una capasuperior al mapa y ahí mostrar los detalles de la anotación cuando la pulsemos y ocultarlacuando pulsemos fuera.

Es muy frecuente que necesitemos detectar la anotación que pulsa el usuario, para

Mapas en iOS

10Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 11: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

capturar esto debemos usar dos métodos del protocolo de MKMapViewDelegate. Estosmétodos son:

-(void) mapView:(MKMapView *)mapViewdidSelectAnnotationView:(MKAnnotationView *)view{

NSLog(@"Anotación seleccionada");}

-(void) mapView:(MKMapView *)mapViewdidDeselectAnnotationView:(MKAnnotationView *)view{

NSLog(@"Anotación deseleccionada");}

4. Capas

Utilizamos las capas (overlays) para dibujar rutas o imagenes en un punto dado del mapa.A diferencia de como ocurre con las anotaciones, el tamaño de las capas sí se adaptan alnivel de zoom que tenga el mapa. A continuación podemos ver dos ejemplos de uso de lascapas:

Ejemplo aplicación con capas

Mapas en iOS

11Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 12: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

Ejemplo aplicación con capas

A modo de ejemplo en este apartado vamos a aprender como mostrar una imagen de labiblioteca de la UA en su posición real dentro de un mapa.

4.1. Definiendo un MKOverlay

Lo primero que debemos hacer es crear una clase que implemente el protocoloMKOverlay. En esta clase se definirán varias propiedades de la capa como lascoordenadas y el tamaño. El código de la clase puede ser como el que se muestra acontinuación:

// Fichero MapOverlay.h#import <Foundation/Foundation.h>#import <MapKit/MapKit.h>#import <CoreLocation/CoreLocation.h>

@interface MapOverlay : NSObject <MKOverlay> {

}

- (MKMapRect)boundingMapRect;

@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

@end

// Fichero MapOverlay.m#import "MapOverlay.h"

@implementation MapOverlay

-(CLLocationCoordinate2D)coordinate {//Coordenadas centralesreturn CLLocationCoordinate2DMake(38.3833, -0.5120);

}

- (MKMapRect)boundingMapRect{

// Coordenadas de cada esquina

Mapas en iOS

12Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 13: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

MKMapPointsuperiorIzquierda=MKMapPointForCoordinate(CLLocationCoordinate2DMake(38.3833,-0.5128));

MKMapPoint superiorDerecha =MKMapPointForCoordinate(CLLocationCoordinate2DMake(38.3837,-0.5116));

MKMapPoint abajoIzquierda =MKMapPointForCoordinate(CLLocationCoordinate2DMake(38.3829,-0.5118));

// Rectangulo en donde se posiciona la imagen en el mapaMKMapRect bounds = MKMapRectMake(superiorIzquierda.x,

superiorIzquierda.y,fabs(superiorIzquierda.x -

superiorDerecha.x),fabs(superiorIzquierda.y -

abajoIzquierda.y));

return bounds;}

@end

4.1.1. Definiendo un MKOverlayView

Una vez que hemos definido las propiedades de la capa mediante un MKOverlay quedaimplementar la clase encargada de renderizar la imagen que queremos mostrar. Esta claseheredará de MKOverlayView y podemos implementarla como muestro a continuación:

// Fichero MapOverlayView.h#import <UIKit/UIKit.h>#import <MapKit/MapKit.h>

@interface MapOverlayView : MKOverlayView {

}

@end

// Fichero MapOverlayView.m#import "MapOverlayView.h"#import "MapOverlay.h"

@implementation MapOverlayView

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScaleinContext:(CGContextRef)ctx{

// Cargamos la imagenUIImage *image = [UIImage imageNamed:@"img_biblioteca.png"];CGImageRef imageReference = image.CGImage;

MKMapRect theMapRect = [self.overlay boundingMapRect];CGRect theRect = [self rectForMapRect:theMapRect];

// Volteamos y movemos la imagen a su posición originalCGContextScaleCTM(ctx, 1.0, -1.0);CGContextTranslateCTM(ctx, 0.0, -theRect.size.height);

//Dibujamos la imagen en el contextoCGContextDrawImage(ctx, theRect, imageReference);

Mapas en iOS

13Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 14: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

}

@end

En el código anterior hemos definido la vista de la capa. Ahora sólo queda añadirla anuestro mapa. Esto lo tendremos que hacer en la controladora principal, donde seimplementan los métodos del protocolo MKMapViewDelegate:

// Dentro del método viewDidLoad de la clase

MapOverlay * mapOverlay = [[MapOverlay alloc] init];[self.mapView addOverlay:mapOverlay];

- (MKOverlayView *)mapView:(MKMapView *)mapViewviewForOverlay:(id <MKOverlay>)overlay {

MapOverlay *mapOverlay = (MapOverlay *)overlay;MapOverlayView *mapOverlayView = [[MapOverlayView alloc]

initWithOverlay:mapOverlay];

return mapOverlayView;}

Mediante el método mapView:viewForOverlay mostramos el overlay que hemosimplementado anteriormente. El componente MapView se encargará de mostrarlo en elmapa en la posición que hemos indicado y con el tamaño adecuado.

Ahora si arrancamos la aplicación y desplazamos el mapa hasta la Universidad deAlicante veremos que en la posición de la biblioteca aparece la capa que hemosimplementado.

Overlay de la Biblioteca UA

5. Usando el Geocoder

Mapas en iOS

14Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 15: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

Dentro de todas las funcionalidades que podemos encontrar en el framework CoreLocation está una muy interesante: Geocodificación (Geocoder). Mediante lageocodificación podemos obtener una dirección postal a partir de unas coordenadas yviceversa.

Si no dispusieramos de esta funcionalidad tendríamos que hacer uso de un servicio webexterno, por ejemplo de Google. Gracias al framework de Core Location implementaresta funcionalidad en nuestras aplicaciones iOS es muy sencillo. En este apartadoestudiaremos como incorporar funciones de geocodificación en una aplicación iOSusando la clase CLGeocoder.

5.1. Geocodificación común

Este tipo de geocodificación consiste en obtener una serie de posiciones o coordenadas apartir de una dirección postal. Imaginemos que tenemos una aplicación en la que elusuario introduce una dirección postal completa (calle, número, ciudad y país) y laaplicación mostrará en un mapa el/los punto/s (latitud y longitud) que corresponden a esadirección. Esto lo implementaremos haciendo uso de la geocodificación común.

Para implementar esta funcionalidad en nuestro código deberemos primero asegurarnosde importar el framework CoreLocation.framework. Una vez hecho esto ya podemosusar la clase CLGeocoder entre otras.

Un ejemplo sencillo de uso de la clase CLGeocoder para implementar la geocodificacióncomún puede ser el siguiente:

NSString *address = @"Avda. General Marvá, 20, Alicante";

CLGeocoder *geocoder = [[CLGeocoder alloc] init];[geocoder geocodeAddressString:addresscompletionHandler:^(NSArray *placemarks, NSError *error) {

if ([placemarks count] > 0) {CLPlacemark *placemark = [placemarks objectAtIndex:0];

NSLog(@"Lugar encontrado: %@", [placemark description]);}

}];

En el código anterior crearmos un objeto de la clase CLGeocoder que será en responsablede realizar la geocodificación. Después usamos el método geocodeAddressString: paraobtener mediante un bloque el array de posiciones (placemarks>). Este array deposiciones estará formado por objetos de la clase CLPlacemark. Esta clase contiene todoslos datos sobre una posición en concreto: dirección postal completa, ciudad, país,coordenadas latitud y longitud, etc.

// Salida de consolaLugar encontrado: Avenida del General Marvá 20, 03005 Alicante,

Mapas en iOS

15Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 16: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

Alicante, Spain @<+38.34788286,-0.49242750> +/- 100.00m,region (identifier <+38.34788286,-0.49242750> radius 282.58)<+38.34788286,-0.49242750> radius 282.58m

5.2. Geocodificación inversa

La geocodificación inversa o reverse geocoding consiste en obtener una o variasdirecciones a partir de unas coordenadas (latitud y longitud). Es lo opuesto a lageocodifación común que hemos analizado en el apartado anterior.

Al igual que hemos podido ver anteriormente, implementar este tipo de codificación esmuy sencillo gracias al framework Core Location y la clase CLGeocoder. Un ejemplo decódigo de implementación podemos verlo a continuación:

CLLocationCoordinate2D coordinates = CLLocationCoordinate2DMake(38.362404,-0.411748);

CLLocation *location = [[CLLocation alloc]initWithLatitude:coordinates.latitudelongitude:coordinates.longitude];

CLGeocoder *geocoder = [[CLGeocoder alloc] init];[geocoder reverseGeocodeLocation:location

completionHandler:^(NSArray *placemarks, NSError *error){

if(!error){for(CLPlacemark *placemark in placemarks){

NSLog(@"%@",[placemark description]);}

}}];

Como podemos ver en el código anterior, para implementar la geocodificación inversahacemos uso del método reverseGeocodeLocation: de la clase CLGeocoder. Al igualque en el apartado anterior, el método ejecuta un bloque al recibir los puntos(placemarks).

6. Navegación paso a paso

Una de las nuevas funcionalidades del SDK de iOS 6 y que se incorporó junto a losnuevos mapas de Apple es la navegación paso a paso. Mediante esta opción podremosañadir a nuestra aplicación de una forma muy sencilla un sistema de navegación GPS,similar al que usa cualquier navegador GPS del mercado.

Mapas en iOS

16Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 17: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

Navegación paso a paso

En resumen, podremos acceder en cualquier momento dentro de la ejecución de nuestraaplicación al sistema de navegación GPS de los mapas de Apple. Implementar estafuncionalidad en nuestra aplicación es muy sencillo gracias a la clase MKMapItem delframework MapKit.framework de iOS 6.

Sólo disponible a partir de iOS 6Esta funcionalidad únicamente está disponible a partir de iOS 6, por lo que si desarrollamos unaaplicación compatible con sistemas iOS anteriores tendremos que adaptar nuestro código para nose produzca un error de ejecución.

Para implementar la navegación paso a paso deberemos de definir un array de objetos detipo MKMapItem y después ejecutar el método openMapsWithItems:launchOptions de laclase MKMapItem tal y como se puede ver en el fragmento de código siguiente:

MKMapItem *mapItem1 = [[MKMapItem alloc] initWithPlacemark:placemark];

// Array de puntosNSArray *mapItems = @[mapItem1];

// OpcionesNSDictionary *options = @{

// navegacion paso a pasoMKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving,

// tipo de mapaMKLaunchOptionsMapTypeKey:[NSNumber

numberWithInteger:MKMapTypeSatellite],// mostrar traficoMKLaunchOptionsShowsTrafficKey:@YES

};

// Lanzamos la aplicación de mapas

Mapas en iOS

17Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 18: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

[MKMapItem openMapsWithItems:mapItemslaunchOptions:options];

Si ejecutamos el código anterior nos aparecerá la aplicación de Mapas de Apple con lanavegación paso a paso activada con el punto que hemos indicado como destino.

Mapas en iOS

18Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.

Page 19: Mapas en iOS · 2013-01-31 · nuestras aplicaciones: MapKit. Este framework incluye una serie de controladoras y vistas que nos permiten realizar varias tareas sobre los mapas. Uno

Mapas en iOS

19Copyright © 2012-13 Dept. Ciencia de la Computación e IA All rights reserved.