summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--ios/MBXViewController.mm354
m---------ios/MVKMapKit0
-rw-r--r--ios/llmr-app.gyp2
4 files changed, 37 insertions, 322 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000000..37a988d2ba
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "ios/MVKMapKit"]
+ path = ios/MVKMapKit
+ url = git@github.com:mapbox/MVKMapKit.git
diff --git a/ios/MBXViewController.mm b/ios/MBXViewController.mm
index 9c4b5d2fe8..6cad26762b 100644
--- a/ios/MBXViewController.mm
+++ b/ios/MBXViewController.mm
@@ -1,24 +1,14 @@
#import "MBXViewController.h"
+#import "MVKMapView.h"
+
#import "../common/settings_nsuserdefaults.hpp"
-#import "../common/foundation_request.h"
-#import <OpenGLES/EAGL.h>
-#import <QuartzCore/QuartzCore.h>
-#import <GLKit/GLKit.h>
#import <CoreLocation/CoreLocation.h>
-#include <llmr/llmr.hpp>
-#include <llmr/platform/platform.hpp>
-#include <llmr/map/tile.hpp>
-
-@interface MBXViewController () <UIGestureRecognizerDelegate, CLLocationManagerDelegate>
+@interface MBXViewController () <CLLocationManagerDelegate>
-@property (nonatomic) EAGLContext *context;
-@property (nonatomic) CGPoint center;
-@property (nonatomic) CGFloat scale;
-@property (nonatomic) CGFloat angle;
-@property (nonatomic) CGFloat quickZoomStart;
+@property (nonatomic) MVKMapView *mapView;
@property (nonatomic) BOOL debug;
@property (nonatomic) UIView *palette;
@property (nonatomic) CLLocationManager *locationManager;
@@ -27,12 +17,7 @@
@implementation MBXViewController
-class View;
-
-llmr::Map *map = nullptr;
-View *viewObj = nullptr;
llmr::Settings_NSUserDefaults *settings = nullptr;
-MBXViewController *viewController = nullptr;
#pragma mark - Setup
@@ -49,110 +34,52 @@ MBXViewController *viewController = nullptr;
return self;
}
-- (void)loadView
-{
- [super loadView];
-
- self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
-
- if (!self.context)
- {
- NSLog(@"Failed to create OpenGL ES context");
- }
-
- GLKView *view = [[GLKView alloc] initWithFrame:[[UIScreen mainScreen] bounds] context:self.context];
- view.enableSetNeedsDisplay = NO;
- view.drawableStencilFormat = GLKViewDrawableStencilFormat8;
- view.drawableDepthFormat = GLKViewDrawableDepthFormat16;
- [view bindDrawable];
-
- self.view = view;
-}
-
- (void)viewDidLoad
{
[super viewDidLoad];
- [self setupMap];
- [self setupInteraction];
+ self.mapView = [[MVKMapView alloc] initWithFrame:self.view.bounds];
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ [self.view addSubview:self.mapView];
+
+ settings = new llmr::Settings_NSUserDefaults();
+ [self restoreState];
+
[self setupDebugUI];
self.locationManager = [CLLocationManager new];
self.locationManager.delegate = self;
-
- map->start();
-}
-
-- (void)setupMap
-{
- viewObj = new View(self);
- map = new llmr::Map(*viewObj);
-
- // Load settings
- settings = new llmr::Settings_NSUserDefaults();
- [self restoreState];
}
- (void)saveState
{
- if (map && settings)
+ if (self.mapView && settings)
{
- map->getLonLatZoom(settings->longitude, settings->latitude, settings->zoom);
- settings->angle = map->getAngle();
- settings->debug = map->getDebug();
+ settings->longitude = self.mapView.centerCoordinate.longitude;
+ settings->latitude = self.mapView.centerCoordinate.latitude;
+ settings->zoom = self.mapView.zoomLevel;
+ settings->angle = self.mapView.direction;
+ settings->debug = self.mapView.isDebugActive;
settings->save();
}
}
- (void)restoreState
{
- if (map && settings) {
+ if (self.mapView && settings) {
settings->load();
- map->setLonLatZoom(settings->longitude, settings->latitude, settings->zoom);
- map->setAngle(settings->angle);
- map->setDebug(settings->debug);
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(settings->latitude, settings->longitude) zoomLevel:settings->zoom animated:NO];
+ self.mapView.direction = settings->angle;
+ [self.mapView setDebugActive:settings->debug];
}
}
-- (void)setupInteraction
+- (void)setupDebugUI
{
- UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)];
- pan.delegate = self;
- [self.view addGestureRecognizer:pan];
-
- UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinchGesture:)];
- pinch.delegate = self;
- [self.view addGestureRecognizer:pinch];
-
- UIRotationGestureRecognizer *rotate = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleRotateGesture:)];
- rotate.delegate = self;
- [self.view addGestureRecognizer:rotate];
-
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTapGesture:)];
singleTap.numberOfTapsRequired = 1;
- [self.view addGestureRecognizer:singleTap];
-
- UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTapGesture:)];
- doubleTap.numberOfTapsRequired = 2;
- [self.view addGestureRecognizer:doubleTap];
-
- [singleTap requireGestureRecognizerToFail:doubleTap];
+ [self.mapView addGestureRecognizer:singleTap];
- UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerTapGesture:)];
- twoFingerTap.numberOfTouchesRequired = 2;
- [self.view addGestureRecognizer:twoFingerTap];
-
- if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
- {
- UILongPressGestureRecognizer *quickZoom = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleQuickZoomGesture:)];
- quickZoom.numberOfTapsRequired = 1;
- quickZoom.minimumPressDuration = 0.25;
- [self.view addGestureRecognizer:quickZoom];
- }
-}
-
-- (void)setupDebugUI
-{
NSArray *selectorNames = @[ @"unrotate", @"resetPosition", @"toggleDebug", @"toggleRaster", @"locateUser" ];
CGFloat buttonSize = 40;
CGFloat bufferSize = 20;
@@ -182,32 +109,19 @@ MBXViewController *viewController = nullptr;
- (NSUInteger)supportedInterfaceOrientations
{
- // We support everything; it's up to the embedding application to limit the orientations.
return UIInterfaceOrientationMaskAll;
}
-#pragma mark - Rendering delegates
+#pragma mark - Debugging UI
-- (void)swap
+- (void)handleSingleTapGesture:(UITapGestureRecognizer *)singleTap
{
- if (map->needsSwap())
+ if (singleTap.state == UIGestureRecognizerStateEnded)
{
- [(GLKView *)self.view display];
- map->swapped();
+ [self togglePalette];
}
}
-- (void)viewWillLayoutSubviews
-{
- [super viewWillLayoutSubviews];
-
- GLKView *view = (GLKView *)self.view;
- CGRect rect = [view bounds];
- map->resize(rect.size.width, rect.size.height, view.contentScaleFactor, view.drawableWidth, view.drawableHeight);
-}
-
-#pragma mark - Debugging UI
-
- (void)togglePalette
{
if (self.palette.alpha < 1)
@@ -232,24 +146,24 @@ MBXViewController *viewController = nullptr;
- (void)unrotate
{
- map->resetNorth();
+ [self.mapView resetNorth];
}
- (void)resetPosition
{
- map->resetPosition();
+ [self.mapView resetPosition];
}
- (void)toggleDebug
{
- map->toggleDebug();
+ [self.mapView toggleDebug];
self.debug = ! self.debug;
}
- (void)toggleRaster
{
- map->toggleRaster();
+ [self.mapView toggleRaster];
}
- (void)locateUser
@@ -269,197 +183,10 @@ MBXViewController *viewController = nullptr;
if (settings)
{
- // Save settings
[self saveState];
delete settings;
settings = nullptr;
}
-
- if (map)
- {
- delete map;
- map = nullptr;
- }
-
- if (viewObj)
- {
- delete viewObj;
- viewObj = nullptr;
- }
-
- if ([[EAGLContext currentContext] isEqual:self.context])
- {
- [EAGLContext setCurrentContext:nil];
- }
-}
-
-#pragma mark - UI gestures
-
-- (void)cancelPreviousActions
-{
- map->cancelTransitions();
-
- [self.locationManager stopUpdatingLocation];
-}
-
-- (void)handlePanGesture:(UIPanGestureRecognizer *)pan
-{
- [self cancelPreviousActions];
-
- if (pan.state == UIGestureRecognizerStateBegan)
- {
- self.center = CGPointMake(0, 0);
- }
- else if (pan.state == UIGestureRecognizerStateChanged)
- {
- CGPoint delta = CGPointMake([pan translationInView:pan.view].x - self.center.x,
- [pan translationInView:pan.view].y - self.center.y);
-
- map->moveBy(delta.x, delta.y);
-
- self.center = CGPointMake(self.center.x + delta.x, self.center.y + delta.y);
- }
- else if (pan.state == UIGestureRecognizerStateEnded)
- {
- if ([pan velocityInView:pan.view].x < 50 && [pan velocityInView:pan.view].y < 50)
- {
- return;
- }
-
- CGPoint finalCenter = CGPointMake(self.center.x + (0.1 * [pan velocityInView:pan.view].x),
- self.center.y + (0.1 * [pan velocityInView:pan.view].y));
-
- CGFloat duration = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad ? 0.3 : 0.5);
-
- map->moveBy(finalCenter.x - self.center.x, finalCenter.y - self.center.y, duration);
- }
-}
-
-- (void)handlePinchGesture:(UIPinchGestureRecognizer *)pinch
-{
- [self cancelPreviousActions];
-
- if (pinch.state == UIGestureRecognizerStateBegan)
- {
- map->startScaling();
-
- self.scale = map->getScale();
- }
- else if (pinch.state == UIGestureRecognizerStateChanged)
- {
- CGFloat tolerance = 2.5;
- CGFloat adjustment = 0;
-
- if (pinch.scale > 1)
- {
- adjustment = (pinch.scale / tolerance) - (1 / tolerance);
- }
- else
- {
- adjustment = (-1 / pinch.scale) / tolerance + (1 / tolerance);
- }
-
- CGFloat newZoom = log2f(self.scale) + adjustment;
-
- map->scaleBy(powf(2, newZoom) / map->getScale(), [pinch locationInView:pinch.view].x, [pinch locationInView:pinch.view].y);
- }
- else if (pinch.state == UIGestureRecognizerStateEnded)
- {
- map->stopScaling();
-
- if (fabsf(pinch.velocity) < 20)
- {
- return;
- }
-
- CGFloat finalZoom = log2f(map->getScale()) + (0.01 * pinch.velocity);
-
- double scale = map->getScale();
- double new_scale = powf(2, finalZoom);
-
- CGFloat duration = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad ? 0.3 : 0.5);
-
- map->scaleBy(new_scale / scale, [pinch locationInView:pinch.view].x, [pinch locationInView:pinch.view].y, duration);
- }
- else if (pinch.state == UIGestureRecognizerStateCancelled)
- {
- map->stopScaling();
- }
-}
-
-- (void)handleRotateGesture:(UIRotationGestureRecognizer *)rotate
-{
- [self cancelPreviousActions];
-
- if (rotate.state == UIGestureRecognizerStateBegan)
- {
- map->startRotating();
-
- self.angle = map->getAngle();
- }
- else if (rotate.state == UIGestureRecognizerStateChanged)
- {
- map->setAngle(self.angle + rotate.rotation, [rotate locationInView:rotate.view].x, [rotate locationInView:rotate.view].y);
- }
- else if (rotate.state == UIGestureRecognizerStateEnded || rotate.state == UIGestureRecognizerStateCancelled)
- {
- map->stopRotating();
- }
-}
-
-- (void)handleSingleTapGesture:(UITapGestureRecognizer *)singleTap
-{
- if (singleTap.state == UIGestureRecognizerStateEnded)
- {
- [self togglePalette];
- }
-}
-
-- (void)handleDoubleTapGesture:(UITapGestureRecognizer *)doubleTap
-{
- [self cancelPreviousActions];
-
- if (doubleTap.state == UIGestureRecognizerStateEnded)
- {
- map->scaleBy(2, [doubleTap locationInView:doubleTap.view].x, [doubleTap locationInView:doubleTap.view].y, 0.3);
- }
-}
-
-- (void)handleTwoFingerTapGesture:(UITapGestureRecognizer *)twoFingerTap
-{
- [self cancelPreviousActions];
-
- if (twoFingerTap.state == UIGestureRecognizerStateEnded)
- {
- map->scaleBy(0.5, [twoFingerTap locationInView:twoFingerTap.view].x, [twoFingerTap locationInView:twoFingerTap.view].y, 0.3);
- }
-}
-
-- (void)handleQuickZoomGesture:(UILongPressGestureRecognizer *)quickZoom
-{
- [self cancelPreviousActions];
-
- if (quickZoom.state == UIGestureRecognizerStateBegan)
- {
- self.scale = map->getScale();
-
- self.quickZoomStart = [quickZoom locationInView:quickZoom.view].y;
- }
- else if (quickZoom.state == UIGestureRecognizerStateChanged)
- {
- CGFloat distance = self.quickZoomStart - [quickZoom locationInView:quickZoom.view].y;
-
- CGFloat newZoom = log2f(self.scale) + (distance / 100);
-
- map->scaleBy(powf(2, newZoom) / map->getScale(), self.view.bounds.size.width / 2, self.view.bounds.size.height / 2);
- }
-}
-
-- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
-{
- NSArray *validSimultaneousGestures = @[ [UIPanGestureRecognizer class], [UIPinchGestureRecognizer class], [UIRotationGestureRecognizer class] ];
-
- return ([validSimultaneousGestures containsObject:[gestureRecognizer class]] && [validSimultaneousGestures containsObject:[otherGestureRecognizer class]]);
}
#pragma mark - User location
@@ -468,24 +195,7 @@ MBXViewController *viewController = nullptr;
{
CLLocation *latestLocation = locations.lastObject;
- map->setLonLatZoom(latestLocation.coordinate.longitude, latestLocation.coordinate.latitude, 17, 0.3);
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(latestLocation.coordinate.latitude, latestLocation.coordinate.longitude) zoomLevel:17 animated:YES];
}
-class View : public llmr::View {
-public:
- View(MBXViewController *controller) : controller(controller) {}
- virtual ~View() {}
-
- void make_active() {
- [EAGLContext setCurrentContext:controller.context];
- }
-
- void swap() {
- [controller performSelectorOnMainThread:@selector(swap) withObject:nil waitUntilDone:NO];
- }
-
-private:
- MBXViewController *controller = nullptr;
-};
-
@end
diff --git a/ios/MVKMapKit b/ios/MVKMapKit
new file mode 160000
+Subproject 9c536c3b12636292ef70bbbc9800858a9d19a1e
diff --git a/ios/llmr-app.gyp b/ios/llmr-app.gyp
index c0b40c1cc8..6bd463ab71 100644
--- a/ios/llmr-app.gyp
+++ b/ios/llmr-app.gyp
@@ -14,6 +14,8 @@
"./MBXAppDelegate.m",
"./MBXViewController.h",
"./MBXViewController.mm",
+ "./MVKMapKit/MVKMapKit/MVKMapView.h",
+ "./MVKMapKit/MVKMapKit/MVKMapView.mm",
"../common/settings_nsuserdefaults.hpp",
"../common/settings_nsuserdefaults.mm",
"../common/foundation_request.h",