Last active
March 29, 2016 02:20
-
-
Save sundeepgupta/39d9e74e46aa509041c3 to your computer and use it in GitHub Desktop.
MapView demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ViewController.m | |
// Map Hacks | |
// | |
// Created by Ken Woo on 2016-02-02. | |
// Copyright © 2016 Lighthouse Labs. All rights reserved. | |
// | |
#import "ViewController.h" | |
#import <CoreLocation/CoreLocation.h> | |
#import <MapKit/MapKit.h> | |
@interface ViewController () <CLLocationManagerDelegate, MKMapViewDelegate> | |
@property (assign, nonatomic) BOOL initialLocationSet; | |
@property (strong, nonatomic) CLLocationManager *locationManager; | |
@property (strong, nonatomic) IBOutlet MKMapView *mapView; | |
@end | |
@implementation ViewController | |
- (void)viewDidLoad { | |
[super viewDidLoad]; | |
// Set our view controller to be the mapView's delegate | |
self.mapView.delegate = self; | |
// We are going to use this property to zoom in on the user's initial location only once | |
self.initialLocationSet = NO; | |
// Create an instance of your location manager and be its delegate | |
self.locationManager = [[CLLocationManager alloc] init]; | |
self.locationManager.delegate = self; | |
// Some ways to change how often we get updated or how accurate we need to be | |
//self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; | |
//self.locationManager.distanceFilter = 50; | |
// Request for the user's permission if we have not done so | |
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) { | |
// Make the actual request. This will FAIL if you are missing the NSLocationWhenInUseUsageDescription key from the Info.plist | |
[self.locationManager requestWhenInUseAuthorization]; | |
} | |
// Load some bike stations | |
[self loadBikeStationsJSON]; | |
} | |
- (void)loadBikeStationsJSON { | |
// Load the bikeStations.json from a local file | |
NSString *jsonPath =[[NSBundle mainBundle] pathForResource:@"bikeStations" ofType:@"json"]; | |
NSData *jsonData = [NSData dataWithContentsOfFile:jsonPath]; | |
NSError *error = nil; | |
NSDictionary *stationDict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; | |
if (!error) { | |
NSArray *stations = stationDict[@"stationBeanList"]; | |
// For each station, create an annotation and add it on the map after setting up some properties | |
for (NSDictionary *station in stations) { | |
MKPointAnnotation *marker = [[MKPointAnnotation alloc] init]; | |
marker.coordinate = CLLocationCoordinate2DMake([station[@"latitude"] doubleValue], [station[@"longitude"] doubleValue]); | |
marker.title = station[@"stationName"]; | |
marker.subtitle = station[@"statusValue"]; | |
[self.mapView addAnnotation:marker]; | |
} | |
} | |
} | |
#pragma mark CLLocationManagerDelegate | |
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { | |
NSLog(@"Authorization changed"); | |
// If the user's allowed us to use their location, we can start getting location updates | |
if (status == kCLAuthorizationStatusAuthorizedWhenInUse) { | |
[self.locationManager startUpdatingLocation]; | |
} | |
} | |
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations { | |
// Get the last object from the list of locations we get back | |
CLLocation *userLocation = [locations lastObject]; | |
// Only do the zoom in once | |
if (!self.initialLocationSet) { | |
self.initialLocationSet = YES; | |
// Create a region around the user's location | |
CLLocationCoordinate2D userCoordinate = userLocation.coordinate; | |
MKCoordinateRegion userRegion = MKCoordinateRegionMake(userCoordinate, MKCoordinateSpanMake(0.01, 0.01)); | |
// Tell our map view to zoom in to that region | |
[self.mapView setRegion:userRegion animated:YES]; | |
// We can tell our location manager to stop updating locations | |
// [self.locationManager stopUpdatingLocation]; | |
// Use a CLGeocoder to determine a GPS coordinate from an address string | |
CLGeocoder *geoCoder = [[CLGeocoder alloc] init]; | |
[geoCoder geocodeAddressString:@"46 Spadina, Toronto" completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) { | |
if (!error) { | |
// The Placemark will have information about the location, like the coordinates, postal code, etc. | |
CLPlacemark *placemark = [placemarks lastObject]; | |
NSLog(@"%@", placemark); | |
} | |
}]; | |
// Use a MKLocalSearch to do a map search | |
MKLocalSearchRequest *searchRequest = [[MKLocalSearchRequest alloc] init]; | |
searchRequest.naturalLanguageQuery = @"Smoke's Poutinerie"; | |
MKLocalSearch *localSearch = [[MKLocalSearch alloc] initWithRequest:searchRequest]; | |
[localSearch startWithCompletionHandler:^(MKLocalSearchResponse * _Nullable response, NSError * _Nullable error) { | |
// We get back a bunch of map items, map items have a placemark property with information similar to what we get from CLGeoCoder | |
MKMapItem *mapItem = [response.mapItems lastObject]; | |
CLPlacemark *placemark = mapItem.placemark; | |
NSLog(@"%@", placemark); | |
}]; | |
} | |
NSLog(@"%@", locations); | |
} | |
#pragma mark MKMapViewDelegate | |
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { | |
// Don't customize user's location annotation | |
if (annotation == mapView.userLocation) { | |
return nil; | |
} | |
// Create our own annotations and customize the image | |
MKAnnotationView *pinView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"BikeStation"]; | |
if (!pinView) { | |
pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"BikeStation"]; | |
pinView.image = [UIImage imageNamed:@"bikeStation.png"]; | |
pinView.centerOffset = CGPointMake(0, -pinView.image.size.height/2); | |
pinView.canShowCallout = YES; | |
} | |
return pinView; | |
} | |
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view { | |
} | |
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control { | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment