Files
MapLibreParticleLab/ios/app/MBXViewController.mm
2015-03-02 23:17:26 -08:00

267 lines
8.7 KiB
Plaintext

#import "MBXViewController.h"
#import <mbgl/ios/MGLMapView.h>
#import <mbgl/platform/darwin/settings_nsuserdefaults.hpp>
#import <CoreLocation/CoreLocation.h>
static UIColor *const kTintColor = [UIColor colorWithRed:0.120 green:0.550 blue:0.670 alpha:1.000];
static NSDictionary *const kStyles = @{
@"bright-v7": @"Bright",
@"basic-v7": @"Basic",
@"outdoors-v7": @"Outdoors",
@"satellite-v7": @"Satellite"
};
@interface MBXViewController () <UIActionSheetDelegate, CLLocationManagerDelegate>
@property (nonatomic) MGLMapView *mapView;
@property (nonatomic) CLLocationManager *locationManager;
@end
@implementation MBXViewController
mbgl::Settings_NSUserDefaults *settings = nullptr;
#pragma mark - Setup
- (id)init
{
self = [super init];
if (self)
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveState:) name:UIApplicationDidEnterBackgroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(restoreState:) name:UIApplicationWillEnterForegroundNotification object:nil];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"];
if (accessToken) {
// Store to preferences so that we can launch the app later on without having to specify
// token.
[[NSUserDefaults standardUserDefaults] setObject:accessToken forKey:@"access_token"];
} else {
// Try to retrieve from preferences, maybe we've stored them there previously and can reuse
// the token.
accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"access_token"];
}
if ( ! accessToken) NSLog(@"No access token set. Mapbox vector tiles won't work.");
self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds accessToken:accessToken];
self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:self.mapView];
self.mapView.viewControllerForLayoutGuides = self;
self.view.tintColor = kTintColor;
self.navigationController.navigationBar.tintColor = kTintColor;
self.mapView.tintColor = kTintColor;
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"settings.png"]
style:UIBarButtonItemStylePlain
target:self
action:@selector(showSettings)];
UIButton *titleButton = [UIButton buttonWithType:UIButtonTypeCustom];
[titleButton setFrame:CGRectMake(0, 0, 120, 40)];
[titleButton setTitle:[[kStyles allValues] firstObject] forState:UIControlStateNormal];
[titleButton setTitleColor:kTintColor forState:UIControlStateNormal];
[titleButton addTarget:self action:@selector(cycleStyles) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.titleView = titleButton;
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"locateUser.png"]
style:UIBarButtonItemStylePlain
target:self
action:@selector(locateUser)];
settings = new mbgl::Settings_NSUserDefaults();
[self restoreState:nil];
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
- (void)saveState:(NSNotification *)notification
{
if (self.mapView && settings)
{
settings->longitude = self.mapView.centerCoordinate.longitude;
settings->latitude = self.mapView.centerCoordinate.latitude;
settings->zoom = self.mapView.zoomLevel;
settings->bearing = self.mapView.direction;
settings->debug = self.mapView.isDebugActive;
settings->save();
}
}
- (void)restoreState:(NSNotification *)notification
{
if (self.mapView && settings) {
settings->load();
[self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(settings->latitude, settings->longitude) zoomLevel:settings->zoom animated:NO];
self.mapView.direction = settings->bearing;
[self.mapView setDebugActive:settings->debug];
}
}
#pragma clang diagnostic pop
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
#pragma mark - Actions
- (void)showSettings
{
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Map Settings"
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:@"Reset North", @"Reset Position", @"Toggle Debug", nil];
[sheet showFromBarButtonItem:self.navigationItem.leftBarButtonItem animated:YES];
}
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == actionSheet.firstOtherButtonIndex)
{
[self.mapView resetNorth];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 1)
{
[self.mapView resetPosition];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 2)
{
[self.mapView toggleDebug];
}
}
- (void)cycleStyles
{
UIButton *titleButton = (UIButton *)self.navigationItem.titleView;
NSString *styleName = [titleButton titleForState:UIControlStateNormal];
if ( ! styleName)
{
styleName = [[kStyles allKeys] firstObject];
}
else
{
NSUInteger index = [[kStyles allValues] indexOfObject:styleName] + 1;
if (index == [[kStyles allKeys] count]) index = 0;
styleName = [[kStyles allKeys] objectAtIndex:index];
}
[self.mapView useBundledStyleNamed:styleName];
[titleButton setTitle:kStyles[styleName] forState:UIControlStateNormal];
}
- (void)locateUser
{
if ( ! self.locationManager)
{
self.locationManager = [CLLocationManager new];
self.locationManager.delegate = self;
}
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied)
{
[[[UIAlertView alloc] initWithTitle:@"Authorization Denied"
message:@"Please enable location services for this app in Privacy settings."
delegate:nil
cancelButtonTitle:nil otherButtonTitles:@"OK", nil] show];
}
else
{
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
if ([CLLocationManager instancesRespondToSelector:@selector(requestWhenInUseAuthorization)])
{
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse)
{
[self.locationManager startUpdatingLocation];
}
else
{
[_locationManager requestWhenInUseAuthorization];
}
}
else
{
[self.locationManager startUpdatingLocation];
}
#else
[self.locationManager startUpdatingLocation];
#endif
}
}
#pragma mark - Destruction
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
if (settings)
{
[self saveState:nil];
delete settings;
settings = nullptr;
}
}
#pragma mark - Location
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch (status)
{
case kCLAuthorizationStatusAuthorizedAlways:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
case kCLAuthorizationStatusAuthorizedWhenInUse:
#endif
{
[manager startUpdatingLocation];
break;
}
default:
{
}
}
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *latestLocation = locations.lastObject;
if ([latestLocation distanceFromLocation:[[CLLocation alloc] initWithLatitude:self.mapView.centerCoordinate.latitude longitude:self.mapView.centerCoordinate.longitude]] > 100)
{
[self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(latestLocation.coordinate.latitude, latestLocation.coordinate.longitude) zoomLevel:17 animated:YES];
}
[self.locationManager stopUpdatingLocation];
}
#pragma clang diagnostic pop
@end