• Save
Core Location and Map Kit: Bringing Your Own Maps [Voices That Matter: iPhone 2010]
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Core Location and Map Kit: Bringing Your Own Maps [Voices That Matter: iPhone 2010]

on

  • 11,683 views

The iPhone SDK provides a nearly-complete toolkit for navigation and travel applications. Its Core Location framework uses a variety of technologies to pinpoint your location, direction, and ...

The iPhone SDK provides a nearly-complete toolkit for navigation and travel applications. Its Core Location framework uses a variety of technologies to pinpoint your location, direction, and orientation, while Map Kit easily serves up map images to show where you are. But there's a missing piece: what's nearby and how to get to it. This middle step, which Apple refers to as "bringing your own maps", is what your app needs in order to provide local search and turn-by-turn directions. In this presentation, we'll look at how iPhone apps can use third-party mapping APIs like MapQuest, Google Maps, NAVTEQ, and Bing, and how to connect between Core Location, geodata, and Map Kit.

Statistics

Views

Total Views
11,683
Views on SlideShare
10,190
Embed Views
1,493

Actions

Likes
12
Downloads
0
Comments
1

7 Embeds 1,493

http://iphonegeeksworld.wordpress.com 1381
http://www.slideshare.net 102
http://maciejmatyjas.com 3
http://matyjas.posterous.com 2
url_unknown 2
http://translate.googleusercontent.com 2
http://74.6.117.48 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Core Location and Map Kit: Bringing Your Own Maps [Voices That Matter: iPhone 2010] Presentation Transcript

  • 1. Core Location & Map Kit: Bringing Your Own Maps Chris Adamson @invalidname Voices That Matter: iPhone Developer Conference 2010
  • 2. What You’ll Learn Today Getting current location information from Core Location Getting a map UI from Map Kit Getting route and other geo-data from third-party providers
  • 3. Where Am I?
  • 4. Location technologies in iPhone Wi-fi Can look up location via Skyhook Cellular network Can triangulate location from cell towers GPS
  • 5. Beyond location Course: which direction are you going? Speed: how fast are you moving? Heading: which direction are you facing? Altitude: how high up are you?
  • 6. Core Location Abstracts away the specific location technologies No direct access to any specific location technology (GPS, etc.) Lets you focus on your use of location data
  • 7. Basic Core Location use Add Core Location framework to your project #import <CoreLocation/ CoreLocation.h>
  • 8. Core Location framework Three classes CLHeading, CLLocation, CLLocationManager One Protocol CLLocationManagerDelegate
  • 9. Building a simple CL demo
  • 10. The CL Basics Create a CLLocationManager Set its delegate Set desired accuracy and filter Call startUpdatingLocation and/or startUpdatingHeading Handle delegate callbacks
  • 11. Creating a CLLocationManager locationManager = [[CLLocationManager alloc] init]; locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; locationManager.distanceFilter = 10;
  • 12. CLLocationManagerDelegate locationManager:didUpdateToLocation: fromLocation: locationManager:didUpdateHeading: locationManager:didFailWithError: locationManagerShouldDisplayHeading Calibration:
  • 13. Location updates CLLocation object contains: coordinate — struct with latitude and longitude course, speed, altitude properties accuracy properties timestamp!
  • 14. Delegate implementation - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { ! latLabel.text = [NSString stringWithFormat:@"%0.3f", newLocation.coordinate.latitude]; ! lngLabel.text = [NSString stringWithFormat:@"%0.3f", newLocation.coordinate.longitude]; ! altitudeLabel.text = [NSString stringWithFormat:@"%0.3f", newLocation.altitude]; ! courseLabel.text = (newLocation.course >= 0.0) ? ! ! [NSString stringWithFormat:@"%0.3f", newLocation.course] : ! ! @"N/A"; ! speedLabel.text = (newLocation.speed >= 0.0) ? ! ! [NSString stringWithFormat:@"%0.3f", newLocation.speed]: ! ! @"N/A"; ! timestampLabel.text = [timestampFormatter stringFromDate:newLocation.timestamp]; }
  • 15. Using coordinates Latitude and Longitude are CLLocationDegrees (doubles) -90° ≤ Latitude ≤ 90° -180° ≤ Longitude ≤ 180° 1° latitude ≅ 69 miles 1° longitude varies from 69 mi. to 0
  • 16. You might get an error! kCLErrorLocationUnknown - can be ignored. CL is still trying. kCLErrorDenied - user declined location services to your app. Handle with grace.
  • 17. Handling delegate errors - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { ! if ([error code] == kCLErrorDenied) { ! ! userDeclinedLocationPrivilegesHUD.hidden = NO; ! } }
  • 18. Demo: Simple Core Location
  • 19. Other CL points of interest -[CLLocation getDistanceFrom:] CLHeading properties: magneticHeading trueHeading
  • 20. Looking at Maps
  • 21. Map Kit Framework to provide map images to UIKit applications #import <MapKit/MapKit.h>
  • 22. Map Kit Basic Use Create an MKMapView and assign a delegate Add MKAnnotations to the map Set region or span of map Delegate handles events from map
  • 23. Building a Map Kit Demo
  • 24. About the demo Converted CSV list of Apple Store coordinates and addresses (circa 2007) to .plist http://www.poi-factory.com/node/1700 Given starting location, gets distance to each store and sorts the POI array On tap, add nearest POI as annotation
  • 25. MKMapView Add to your UI in IB or in code Requires a network connection to fetch map image tiles from Google Binds you to Google Maps terms of service
  • 26. MKAnnotation Protocol to represent a point of interest Added to MKMapViews Properties: coordinate, title, subtitle MKPlacemark offers a concrete implementation
  • 27. Implementing MKAnnotation @interface MyMapAnnotation : NSObject <MKAnnotation> { ! CLLocationCoordinate2D coordinate; ! NSString *title; ! MKPinAnnotationColor color; } @property (nonatomic, readonly) CLLocationCoordinate2D coordinate; @property (nonatomic) MKPinAnnotationColor color; -(id) initWithCoordinate:(CLLocationCoordinate2D)coordinateP title:(NSString*) titleP color: (MKPinAnnotationColor) colorP; @end
  • 28. MKAnnotationView Visual representation of an MKAnnotation on an MKMapView Concrete implementation: MKPinAnnotationView MKMapView dequeues and reuses MKAnnotationViews (similar to UITableView / UITableViewCell)
  • 29. Adding annotations to map -(IBAction) plusButtonTapped: (id) sender { ! // todo: bounds check ! NSDictionary *poiDict = [poiArray objectAtIndex:nextPoiIndex++]; ! CLLocationCoordinate2D poiCoordinate; ! poiCoordinate.latitude = [[poiDict valueForKey:@"latitude"] doubleValue]; ! poiCoordinate.longitude = [[poiDict valueForKey:@"longitude"] doubleValue]; ! MyMapAnnotation *poiAnnotation = [[MyMapAnnotation alloc] ! ! ! ! ! ! ! ! ! initWithCoordinate:poiCoordinate ! ! ! ! ! ! ! ! ! title:[poiDict valueForKey:@"name"] ! ! ! ! ! ! ! ! ! color:MKPinAnnotationColorRed! ]; ! [mapView addAnnotation:poiAnnotation]; ! [self adjustMapZoom]; }
  • 30. Zooming MKMapView, pt. 1 -(void) adjustMapZoom { ! if ([mapView.annotations count] == 1) { ! ! // if only one point, zoom smartly around it ! ! [mapView setRegion:MKCoordinateRegionMakeWithDistance ! ! ! ! ! ! ! ([[mapView.annotations objectAtIndex:0] coordinate], ! ! ! ! ! ! ! 2000, // 2 km lat span ! ! ! ! ! ! ! 2000) // 2 km lng span ! ! ! ! animated: YES]; }
  • 31. Zooming MKMapView, pt. 2 ! else { ! ! // find a region encompassing all annotations ! ! CLLocationDegrees maxLatitude = -180; ! ! CLLocationDegrees minLatitude = 180; ! ! CLLocationDegrees maxLongitude = -180; ! ! CLLocationDegrees minLongitude = 180; ! ! ! ! for (id<MKAnnotation> annotation in [mapView annotations]) { ! ! ! if ([annotation coordinate].latitude > maxLatitude) { ! ! ! ! maxLatitude = [annotation coordinate].latitude; ! ! ! } ! ! ! if ([annotation coordinate].latitude < minLatitude) { ! ! ! ! minLatitude = [annotation coordinate].latitude; ! ! ! } ! ! ! if ([annotation coordinate].longitude > maxLongitude) { ! ! ! ! maxLongitude = [annotation coordinate].longitude; ! ! ! } ! ! ! if ([annotation coordinate].longitude < minLongitude) { ! ! ! ! minLongitude = [annotation coordinate].longitude; ! ! ! } ! ! } ! ! ! ! CLLocation *maxPoint = [[[CLLocation alloc] initWithLatitude:maxLatitude ! ! ! ! ! ! longitude:maxLongitude] autorelease]; ! ! CLLocation *minPoint = [[[CLLocation alloc] initWithLatitude:minLatitude ! ! ! ! ! ! longitude:minLongitude] autorelease]; ! ! CLLocationDistance distance = [maxPoint getDistanceFrom:minPoint]; ! ! MKCoordinateRegion region; ! ! region.center.latitude = (maxPoint.coordinate.latitude + minPoint.coordinate.latitude) / 2.0; ! ! region.center.longitude = (maxPoint.coordinate.longitude + minPoint.coordinate.longitude) / 2.0; ! ! region.span.latitudeDelta = (distance / METERS_PER_DEGREE_LATITUDE) * 1.10; ! ! region.span.longitudeDelta = 0.0; ! ! MKCoordinateRegion adjustedRegion = [mapView regionThatFits:region]; ! ! [mapView setRegion:adjustedRegion animated:YES]; ! }
  • 32. MKMapViewDelegate Called when region changes (scaling, scrolling), and as map images load Provides event when a “callout accessory view” is tapped (e.g., disclosure button) Requests views for newly-added annotations
  • 33. Providing views for annotations - (MKAnnotationView *)mapView:(MKMapView *)mapViewP viewForAnnotation:(id <MKAnnotation>)annotation { ! MKPinAnnotationView *pinView = (MKPinAnnotationView*) [mapViewP dequeueReusableAnnotationViewWithIdentifier:@"pin"]; ! if (pinView) { ! ! pinView.annotation = annotation; ! } else { ! ! pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pin"] autorelease]; ! } ! ! pinView.animatesDrop = YES; ! pinView.canShowCallout = YES; ! if ([annotation isKindOfClass:[MyMapAnnotation class]]) { ! ! MyMapAnnotation *myAnnotation = (MyMapAnnotation*) annotation; ! ! pinView.pinColor = myAnnotation.color; ! } ! return pinView; }
  • 34. Demo: Apple Store Finder
  • 35. Also: Reverse Geocoding Geocoding: finding coordinates for an address. Map Kit doesn’t do this. Reverse geocoding: finding address for given coordinates MKReverseGeocoder and MKReverseGeocoderDelegate You must display a map to use this API
  • 36. The Treachery of Images
  • 37. This is not a city
  • 38. This is not a body of water
  • 39. This is not a street
  • 40. Demo: Why Apple Store Finder is Broken
  • 41. Map Kit Doesn’t Provide Maps Map Kit provides map images Nothing in Map Kit has any awareness of geography, transportation, political borders, cultural or regional distinctions, etc. All it does is push pixels to your screen
  • 42. Bringing Your Own Maps Google Maps terms prohibit Apple from providing map data in Map Kit You have to provide it yourself Typically via a third-party
  • 43. Third-Party Map Providers Google MapQuest NAVTEQ Bing Others
  • 44. What Map Providers Offer POI search — businesses, geographic features, roads, etc. Directions and traffic info Geocoding and reverse geocoding Map images
  • 45. Map data access On-board database Network access
  • 46. Section 3.3.1 Considerations
  • 47. Section 3.3.1 Considerations
  • 48. Section 3.3.1 Considerations
  • 49. Section 3.3.1 Considerations
  • 50. Section 3.3.1 Considerations
  • 51. Calling Map Providers Safest approach may be to use a network API, using Cocoa’s URL Loading Service or CFNetwork APIs e.g., MapQuest web services NAVTEQ Smart APIs for Mobile - iPhone-only API
  • 52. Fixing Apple Store Demo
  • 53. Fix Strategy Sort POIs by linear distance, then use a map provider to get driving distances for the first few and re-sort Sort later POIs as more are consumed from array
  • 54. Using MapQuest API Sign up at developer.mapquest.com Get an API key Provide this key with each request Compose webservice request URL Parse XML result
  • 55. Send web service request #define MQ_DIRECTIONS_REQUEST_FORMAT @"http://www.mapquestapi.com/directions/v1/route?key=%@&from=%f,%f&to=%@, %@&outFormat=xml" -(void) addDrivingDistanceToPoiDict: (NSMutableDictionary*) poiDict { ! NSString *poiLat = [poiDict valueForKey: @"latitude"]; ! NSString *poiLng = [poiDict valueForKey: @"longitude"]; ! NSString *mqURLS = [NSString stringWithFormat:MQ_DIRECTIONS_REQUEST_FORMAT, ! ! ! ! ! ! MQ_APP_KEY, ! ! ! ! ! ! homeCoordinate.latitude, homeCoordinate.longitude, ! ! ! ! ! ! poiLat, poiLng]; ! NSURL *mqURL = [NSURL URLWithString:mqURLS]; ! NSURLRequest *mqURLRequest = [NSURLRequest requestWithURL:mqURL]; ! NSURLResponse *mqURLResponse = nil; ! NSError *mqURLError = nil; ! NSData *routeData = [NSURLConnection sendSynchronousRequest:mqURLRequest ! ! ! ! ! ! ! ! ! ! returningResponse:&mqURLResponse ! ! ! ! ! ! ! ! ! ! error:&mqURLError]; ! MQDirectionsParser *parser = [[MQDirectionsParser alloc] initWithXML:routeData];
  • 56. Get web service result <?xml version="1.0" encoding="UTF-8"?> <response> <info> <statusCode>0</statusCode> <messages/> <copyright> <imageUrl>http://tile21.mqcdn.com/res/mqlogo.gif</imageUrl> <imageAltText>© 2010 MapQuest, Inc.</imageAltText> <text>© 2010 MapQuest, Inc.</text> </copyright> </info> <route> <sessionId>4bd0285d-01bc-0000-02b7-3827-001e4f148321</sessionId> <options> <shapeFormat>raw</shapeFormat> <generalize>-1.0</generalize> <maxLinkId>0</maxLinkId> <narrativeType>text</narrativeType> <stateBoundaryDisplay>true</stateBoundaryDisplay> <countryBoundaryDisplay>true</countryBoundaryDisplay> <sideOfStreetDisplay>true</sideOfStreetDisplay> <destinationManeuverDisplay>true</destinationManeuverDisplay> <avoidTimedConditions>false</avoidTimedConditions> <timeType>0</timeType> <routeType>FASTEST</routeType> <locale>en_US</locale> <unit>M</unit> <tryAvoidLinkIds/> <mustAvoidLinkIds/> <manmaps>true</manmaps> </options> <boundingBox> <ul> <lat>47.663799</lat> <lng>-122.348854</lng> </ul> <lr> <lat>47.60448</lat>
  • 57. Create an XML parser -(id) initWithXML: (NSData*) xml { ! if (self = [super init]) { ! ! routeDict = [[NSMutableDictionary alloc] init]; ! ! routeDistance = -1; ! ! ! ! NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xml]; ! ! [parser setDelegate:self]; ! ! [parser parse]; ! } ! return self; }
  • 58. Notice interesting tags - (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName ! ! ! ! ! ! ! ! namespaceURI:(NSString *)namespaceURI ! ! ! ! ! ! ! ! qualifiedName:(NSString *)qualifiedName ! ! ! ! ! ! ! ! attributes:(NSDictionary *)attributeDict { ! // only care about "distance" and "narrative" tags ! if ([elementName isEqualToString:@"distance"] | ! ! [elementName isEqualToString:@"narrative"]) { ! ! currentCharacters = [[NSMutableString alloc] init]; ! } ! if ([elementName isEqualToString:@"legs"]) { ! ! narrativeArray = [[NSMutableArray alloc] init]; ! } } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { ! [currentCharacters appendString:string]; }
  • 59. Retrieve values from tags - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName ! ! ! ! ! ! ! ! ! namespaceURI:(NSString *)namespaceURI ! ! ! ! ! ! ! ! ! qualifiedName:(NSString *)qName { ! if ([elementName isEqualToString:@"distance"]) { ! ! // if this is first distance, not part of a leg, then it's the whole trip ! ! if (routeDistance == -1) { ! ! ! routeDistance = [currentCharacters doubleValue]; ! ! } ! } ! if ([elementName isEqualToString:@"narrative"]) { ! ! [narrativeArray addObject:currentCharacters]; ! } ! ! [currentCharacters release]; ! currentCharacters = nil; }
  • 60. Demo: Fixed Apple Store Finder
  • 61. The Catch
  • 62. TNSAAFL! All third-party mapping providers have terms of service You should actually read them Because you’ll probably violate them without knowing it
  • 63. Interesting MapQuest TOS 01. (d) Traffic information shall not be (i) used for Real-Time Navigation; (ii) used in conjunction with in-car or stand alone portable navigation devices; or (iii) used for the primary purpose of Your page or application. For the purposes of this Agreement, “Real-Time Navigation” shall mean using a sensor to determine location and providing contemporaneous turn-by-turn directions as the user moves through the route. RESTRICTIONS. Except as expressly authorized by MapQuest, You shall not: ▪ derive results from the Service based on sensor-derived location data or information or input in the form of coordinate data, provided that a coordinate location or location derived by a single sensor, including without limitation a sensor incorporated into, connected to or in communication with any mobile device or system, may be used solely as an origin or destination in deriving a map or direction; ▪ […] ▪ use the Service with products, systems or applications capable of navigation, positioning, tracking or routing of a movable asset; http://developer.mapquest.com/web/info/terms-of- use-free
  • 64. Interesting Google Maps TOS Your Maps API Implementation must be generally accessible to users without charge. You may require users to log in to your Maps API Implementation if you do not require users to pay a fee. Unless you have entered into a separate written agreement with Google or obtained Google's written permission, your Maps API Implementation must not: (a) require a fee-based subscription or other fee-based restricted access; or (b) operate only behind a firewall or only on an internal network (except during the development and testing phase). http://code.google.com/apis/maps/terms.html
  • 65. Interesting Bing Maps TOS If you would like to develop or host an Application that is designed to access and use the service for commercial, non-commercial or government use, provided that such use is not educational or non-profit as defined under Section 2(i), and your Application and content will be available publically without restriction (for example, login or password must not be required) you may do so without entering into a MWS/BM agreement or licensing the service through Microsoft Volume Licensing by complying with the following terms: In addition to all of the restrictions on educational and non-profit use, including the limitations on Traffic Data, set forth in Section 2(i) above, the following restriction also applies: • You may not exceed more than 125,000 sessions or 500,000 transactions, both as defined in the SDKs, in any twelve month period http://www.microsoft.com/maps/product/terms.html
  • 66. More Bing Maps TOS Restrictions on your use: We do have some restrictions on your use of the service. You may not: • copy, store, archive, or create a database of the content, except that geocodes may be stored locally only for use with your Applications; • exceed 50,000 geocoding transactions or requests in any 24 hour period; • download more than 250 points of interest at any one time; • use the service for business asset tracking, fleet management, or dispatch; • present or alert an end user to individual maneuvers of a route in any way that is synchronized with the end-user’s sensor-based position along the route, (e.g. “real-time” navigation); • […] • integrate the Bing Maps Platform or any of its content with any other mapping platform; http://www.microsoft.com/maps/product/terms.html
  • 67. Mapping terms of service Most free terms prohibit: Use in commercial apps Use with a GPS-determined location Use with competitors’ maps or data You can get around some of these with commercial licensing
  • 68. Other hazards Handle bad data gracefully Expect mis-formed or missing tags and values Expect some data to be out of date (e.g., closed businesses) Handle network latency gracefully
  • 69. Summary
  • 70. iPhone Mapping Core Location is great Map Kit is great Using them together is great But…
  • 71. More Mapping Really understanding the relationship between multiple points of interest requires real map data Look to third parties for this You will probably need a commercial license
  • 72. Further Reading http://code.google.com/apis/maps/ http://www.microsoft.com/maps/ developers/ http://developer.mapquest.com/ http://www.nn4d.com
  • 73. Q&A
  • 74. Thanks! http://www.subfurther.com/blog @invalidname invalidname [at] gmail [dot] com