[ios] revamp settings/debug UI in test app (#6421)

This commit is contained in:
Justin R. Miller
2016-09-21 15:07:44 -07:00
committed by GitHub
parent c0ed193c20
commit 673d8f90f2

View File

@@ -5,6 +5,7 @@
#import "MBXOfflinePacksTableViewController.h"
#import "MBXAnnotationView.h"
#import "MBXUserLocationAnnotationView.h"
#import "MGLFillStyleLayer.h"
#import <Mapbox/Mapbox.h>
@@ -20,6 +21,52 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXViewControllerAnnotationViewReuseIdentifer";
typedef NS_ENUM(NSInteger, MBXSettingsSections) {
MBXSettingsCoreRendering = 0,
MBXSettingsAnnotations,
MBXSettingsRuntimeStyling,
MBXSettingsMiscellaneous,
};
typedef NS_ENUM(NSInteger, MBXSettingsCoreRenderingRows) {
MBXSettingsCoreRenderingResetPosition = 0,
MBXSettingsCoreRenderingTileBoundaries,
MBXSettingsCoreRenderingTileInfo,
MBXSettingsCoreRenderingTimestamps,
MBXSettingsCoreRenderingCollisionBoxes,
MBXSettingsCoreRenderingOverdrawVisualization,
};
typedef NS_ENUM(NSInteger, MBXSettingsAnnotationsRows) {
MBXSettingsAnnotations100Views = 0,
MBXSettingsAnnotations1000Views,
MBXSettingsAnnotations10000Views,
MBXSettingsAnnotations100Sprites,
MBXSettingsAnnotations1000Sprites,
MBXSettingsAnnotations10000Sprites,
MBXSettingsAnnotationsTestShapes,
MBXSettingsAnnotationsCustomCallout,
MBXSettingsAnnotationsRemoveAnnotations,
};
typedef NS_ENUM(NSInteger, MBXSettingsRuntimeStylingRows) {
MBXSettingsRuntimeStylingWater = 0,
MBXSettingsRuntimeStylingRoads,
MBXSettingsRuntimeStylingRaster,
MBXSettingsRuntimeStylingGeoJSON,
MBXSettingsRuntimeStylingSymbols,
MBXSettingsRuntimeStylingBuildings,
MBXSettingsRuntimeStylingFerry,
MBXSettingsRuntimeStylingParks,
};
typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
MBXSettingsMiscellaneousWorldTour = 0,
MBXSettingsMiscellaneousCustomUserDot,
MBXSettingsMiscellaneousPrintLogFile,
MBXSettingsMiscellaneousDeleteLogFile,
};
@interface MBXDroppedPinAnnotation : MGLPointAnnotation
@end
@@ -38,7 +85,9 @@ static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXVie
@implementation MBXSpriteBackedAnnotation
@end
@interface MBXViewController () <UIActionSheetDelegate, MGLMapViewDelegate>
@interface MBXViewController () <UITableViewDelegate,
UITableViewDataSource,
MGLMapViewDelegate>
@property (nonatomic) IBOutlet MGLMapView *mapView;
@property (nonatomic) NSInteger styleIndex;
@@ -52,7 +101,7 @@ static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXVie
BOOL _isTouringWorld;
}
#pragma mark - Setup
#pragma mark - Setup & Teardown
+ (void)initialize
{
@@ -167,153 +216,271 @@ static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXVie
}
}
#pragma mark - Actions
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self saveState:nil];
}
#pragma mark - Debugging Interface
- (IBAction)showSettings:(__unused id)sender
{
MGLMapDebugMaskOptions debugMask = self.mapView.debugMask;
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Map Settings"
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:
@"Reset Position",
((debugMask & MGLMapDebugTileBoundariesMask)
? @"Hide Tile Boundaries"
: @"Show Tile Boundaries"),
((debugMask & MGLMapDebugTileInfoMask)
? @"Hide Tile Info"
: @"Show Tile Info"),
((debugMask & MGLMapDebugTimestampsMask)
? @"Hide Tile Timestamps"
: @"Show Tile Timestamps"),
((debugMask & MGLMapDebugCollisionBoxesMask)
? @"Hide Collision Boxes"
: @"Show Collision Boxes"),
((debugMask & MGLMapDebugOverdrawVisualizationMask)
? @"Hide Overdraw Visualization"
: @"Show Overdraw Visualization"),
@"Add 100 Views",
@"Add 1,000 Views",
@"Add 10,000 Views",
@"Add 100 Sprites",
@"Add 1,000 Sprites",
@"Add 10,000 Sprites",
@"Add Test Shapes",
@"Start World Tour",
@"Add Custom Callout Point",
@"Remove Annotations",
@"Manipulate Style",
((_customUserLocationAnnnotationEnabled)
? @"Disable Custom User Dot"
: @"Enable Custom User Dot"),
nil];
if (self.debugLoggingEnabled)
{
[sheet addButtonWithTitle:@"Print Telemetry Logfile"];
[sheet addButtonWithTitle:@"Delete Telemetry Logfile"];
}
[sheet showFromBarButtonItem:self.navigationItem.leftBarButtonItem animated:YES];
UITableViewController *settingsViewController = [[UITableViewController alloc] initWithStyle:UITableViewStyleGrouped];
settingsViewController.tableView.delegate = self;
settingsViewController.tableView.dataSource = self;
settingsViewController.title = @"Debugging";
settingsViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissSettings:)];
UINavigationController *wrapper = [[UINavigationController alloc] initWithRootViewController:settingsViewController];
wrapper.navigationBar.tintColor = self.navigationController.navigationBar.tintColor;
[self.navigationController presentViewController:wrapper animated:YES completion:nil];
}
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
- (void)dismissSettings:(__unused id)sender
{
if (buttonIndex == actionSheet.firstOtherButtonIndex)
[self dismissViewControllerAnimated:YES completion:nil];
}
- (NSArray <NSString *> *)settingsSectionTitles
{
return @[
@"Core Rendering",
@"Annotations",
@"Runtime Styling",
@"Miscellaneous"
];
}
- (NSArray <NSString *> *)settingsTitlesForSection:(NSInteger)section
{
NSMutableArray *settingsTitles = [NSMutableArray array];
MGLMapDebugMaskOptions debugMask = self.mapView.debugMask;
switch (section)
{
[self.mapView resetPosition];
case MBXSettingsCoreRendering:
[settingsTitles addObjectsFromArray:@[
@"Reset Position",
[NSString stringWithFormat:@"%@ Tile Boundaries",
(debugMask & MGLMapDebugTileBoundariesMask ? @"Hide" :@"Show")],
[NSString stringWithFormat:@"%@ Tile Info",
(debugMask & MGLMapDebugTileInfoMask ? @"Hide" :@"Show")],
[NSString stringWithFormat:@"%@ Tile Timestamps",
(debugMask & MGLMapDebugTimestampsMask ? @"Hide" :@"Show")],
[NSString stringWithFormat:@"%@ Collision Boxes",
(debugMask & MGLMapDebugCollisionBoxesMask ? @"Hide" :@"Show")],
[NSString stringWithFormat:@"%@ Overdraw Visualization",
(debugMask & MGLMapDebugOverdrawVisualizationMask ? @"Hide" :@"Show")],
]];
break;
case MBXSettingsAnnotations:
[settingsTitles addObjectsFromArray:@[
@"Add 100 Views",
@"Add 1,000 Views",
@"Add 10,000 Views",
@"Add 100 Sprites",
@"Add 1,000 Sprites",
@"Add 10,000 Sprites",
@"Add Test Shapes",
@"Add Point With Custom Callout",
@"Remove Annotations",
]];
break;
case MBXSettingsRuntimeStyling:
[settingsTitles addObjectsFromArray:@[
@"Apply Water Functions",
@"Apply Road Line Functions",
@"Create Raster & Apply Function",
@"Create GeoJSON & Apply Fill",
@"Apply Symbol Color",
@"Apply Building Fill Color",
@"Apply Ferry Line Color",
@"Remove Park Layer",
]];
break;
case MBXSettingsMiscellaneous:
[settingsTitles addObjectsFromArray:@[
@"Start World Tour",
[NSString stringWithFormat:@"%@ Custom User Dot", (_customUserLocationAnnnotationEnabled ? @"Disable" : @"Enable")],
]];
if (self.debugLoggingEnabled)
{
[settingsTitles addObjectsFromArray:@[
@"Print Telemetry Logfile",
@"Delete Telemetry Logfile",
]];
};
break;
default:
NSAssert(NO, @"All settings sections should be implemented");
break;
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 1)
return settingsTitles;
}
- (void)performActionForSettingAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.section)
{
self.mapView.debugMask ^= MGLMapDebugTileBoundariesMask;
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 2)
{
self.mapView.debugMask ^= MGLMapDebugTileInfoMask;
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 3)
{
self.mapView.debugMask ^= MGLMapDebugTimestampsMask;
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 4)
{
self.mapView.debugMask ^= MGLMapDebugCollisionBoxesMask;
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 5)
{
self.mapView.debugMask ^= MGLMapDebugOverdrawVisualizationMask;
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 6)
{
[self parseFeaturesAddingCount:100 usingViews:YES];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 7)
{
[self parseFeaturesAddingCount:1000 usingViews:YES];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 8)
{
[self parseFeaturesAddingCount:10000 usingViews:YES];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 9)
{
[self parseFeaturesAddingCount:100 usingViews:NO];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 10)
{
[self parseFeaturesAddingCount:1000 usingViews:NO];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 11)
{
[self parseFeaturesAddingCount:10000 usingViews:NO];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 12)
{
[self addTestShapes];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 13)
{
[self startWorldTour:actionSheet];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 14)
{
[self presentAnnotationWithCustomCallout];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 15)
{
[self.mapView removeAnnotations:self.mapView.annotations];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 16)
{
[self testRuntimeStyling];
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 17)
{
_customUserLocationAnnnotationEnabled = !_customUserLocationAnnnotationEnabled;
self.mapView.showsUserLocation = NO;
self.mapView.userTrackingMode = MGLUserTrackingModeFollow;
}
else if (buttonIndex == actionSheet.numberOfButtons - 2 && self.debugLoggingEnabled)
{
NSString *fileContents = [NSString stringWithContentsOfFile:[self telemetryDebugLogfilePath] encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@", fileContents);
}
else if (buttonIndex == actionSheet.numberOfButtons - 1 && self.debugLoggingEnabled)
{
NSString *filePath = [self telemetryDebugLogfilePath];
if ([[NSFileManager defaultManager] isDeletableFileAtPath:filePath]) {
NSError *error;
BOOL success = [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
if (success) {
NSLog(@"Deleted telemetry log.");
} else {
NSLog(@"Error deleting telemetry log: %@", error.localizedDescription);
case MBXSettingsCoreRendering:
switch (indexPath.row)
{
case MBXSettingsCoreRenderingResetPosition:
[self.mapView resetPosition];
break;
case MBXSettingsCoreRenderingTileBoundaries:
self.mapView.debugMask ^= MGLMapDebugTileBoundariesMask;
break;
case MBXSettingsCoreRenderingTileInfo:
self.mapView.debugMask ^= MGLMapDebugTileInfoMask;
break;
case MBXSettingsCoreRenderingTimestamps:
self.mapView.debugMask ^= MGLMapDebugTimestampsMask;
break;
case MBXSettingsCoreRenderingCollisionBoxes:
self.mapView.debugMask ^= MGLMapDebugCollisionBoxesMask;
break;
case MBXSettingsCoreRenderingOverdrawVisualization:
self.mapView.debugMask ^= MGLMapDebugOverdrawVisualizationMask;
break;
default:
NSAssert(NO, @"All core rendering setting rows should be implemented");
break;
}
}
break;
case MBXSettingsAnnotations:
switch (indexPath.row)
{
case MBXSettingsAnnotations100Views:
[self parseFeaturesAddingCount:100 usingViews:YES];
break;
case MBXSettingsAnnotations1000Views:
[self parseFeaturesAddingCount:1000 usingViews:YES];
break;
case MBXSettingsAnnotations10000Views:
[self parseFeaturesAddingCount:10000 usingViews:YES];
break;
case MBXSettingsAnnotations100Sprites:
[self parseFeaturesAddingCount:100 usingViews:NO];
break;
case MBXSettingsAnnotations1000Sprites:
[self parseFeaturesAddingCount:1000 usingViews:NO];
break;
case MBXSettingsAnnotations10000Sprites:
[self parseFeaturesAddingCount:10000 usingViews:NO];
break;
case MBXSettingsAnnotationsTestShapes:
[self addTestShapes];
break;
case MBXSettingsAnnotationsCustomCallout:
[self addAnnotationWithCustomCallout];
break;
case MBXSettingsAnnotationsRemoveAnnotations:
[self.mapView removeAnnotations:self.mapView.annotations];
break;
default:
NSAssert(NO, @"All annotations setting rows should be implemented");
break;
}
break;
case MBXSettingsRuntimeStyling:
switch (indexPath.row)
{
case MBXSettingsRuntimeStylingWater:
[self styleWaterLayer];
break;
case MBXSettingsRuntimeStylingRoads:
[self styleRoadLayer];
break;
case MBXSettingsRuntimeStylingRaster:
[self styleRasterLayer];
break;
case MBXSettingsRuntimeStylingGeoJSON:
[self styleGeoJSONSource];
break;
case MBXSettingsRuntimeStylingSymbols:
[self styleSymbolLayer];
break;
case MBXSettingsRuntimeStylingBuildings:
[self styleBuildingLayer];
break;
case MBXSettingsRuntimeStylingFerry:
[self styleFerryLayer];
break;
case MBXSettingsRuntimeStylingParks:
[self removeParkLayer];
break;
default:
NSAssert(NO, @"All runtime styling setting rows should be implemented");
break;
}
break;
case MBXSettingsMiscellaneous:
switch (indexPath.row)
{
case MBXSettingsMiscellaneousWorldTour:
[self startWorldTour];
break;
case MBXSettingsMiscellaneousCustomUserDot:
[self toggleCustomUserDot];
break;
case MBXSettingsMiscellaneousPrintLogFile:
[self printTelemetryLogFile];
break;
case MBXSettingsMiscellaneousDeleteLogFile:
[self deleteTelemetryLogFile];
break;
default:
NSAssert(NO, @"All miscellaneous setting rows should be implemented");
break;
}
break;
default:
NSAssert(NO, @"All settings sections should be implemented");
break;
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[self settingsSectionTitles] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[self settingsTitlesForSection:section] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
{
return [[self settingsSectionTitles] objectAtIndex:section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
cell.textLabel.text = [[self settingsTitlesForSection:indexPath.section] objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
[self dismissViewControllerAnimated:YES completion:^
{
[self performActionForSettingAtIndexPath:indexPath];
}];
}
#pragma mark - Debugging Actions
- (void)parseFeaturesAddingCount:(NSUInteger)featuresCount usingViews:(BOOL)useViews
{
[self.mapView removeAnnotations:self.mapView.annotations];
@@ -441,68 +608,18 @@ static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXVie
[self.mapView addAnnotation:outerPolygon];
}
- (void)presentAnnotationWithCustomCallout
- (void)addAnnotationWithCustomCallout
{
[self.mapView removeAnnotations:self.mapView.annotations];
MBXCustomCalloutAnnotation *annotation = [[MBXCustomCalloutAnnotation alloc] init];
annotation.coordinate = CLLocationCoordinate2DMake(48.8533940, 2.3775439);
annotation.title = @"Custom Callout";
[self.mapView addAnnotation:annotation];
[self.mapView showAnnotations:@[annotation] animated:YES];
}
- (void)testRuntimeStyling
{
[self styleWaterLayer];
[self styleRoadLayer];
[self styleRasterLayer];
[self styleGeoJSONSource];
[self styleSymbolLayer];
MGLFillStyleLayer *buildingLayer = (MGLFillStyleLayer *)[self.mapView.style layerWithIdentifier:@"building"];
buildingLayer.fillColor = [UIColor blackColor];
MGLLineStyleLayer *ferryLineLayer = (MGLLineStyleLayer *)[self.mapView.style layerWithIdentifier:@"ferry"];
ferryLineLayer.lineColor = [UIColor redColor];
MGLFillStyleLayer *parkLayer = (MGLFillStyleLayer *)[self.mapView.style layerWithIdentifier:@"park"];
[self.mapView.style removeLayer:parkLayer];
}
- (void)styleSymbolLayer
{
MGLSymbolStyleLayer *stateLayer = (MGLSymbolStyleLayer *)[self.mapView.style layerWithIdentifier:@"state-label-lg"];
stateLayer.textColor = [UIColor redColor];
}
- (void)styleGeoJSONSource
{
NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"amsterdam" ofType:@"geojson"];
NSURL *geoJSONURL = [NSURL fileURLWithPath:filePath];
MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"ams" URL:geoJSONURL];
[self.mapView.style addSource:source];
MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithLayerIdentifier:@"test" source:source];
fillLayer.fillColor = [UIColor purpleColor];
[self.mapView.style addLayer:fillLayer];
}
- (void)styleRasterLayer
{
NSURL *rasterURL = [NSURL URLWithString:@"mapbox://mapbox.satellite"];
MGLRasterSource *rasterSource = [[MGLRasterSource alloc] initWithSourceIdentifier:@"my-raster-source" URL:rasterURL tileSize:512];
[self.mapView.style addSource:rasterSource];
MGLRasterStyleLayer *rasterLayer = [[MGLRasterStyleLayer alloc] initWithLayerIdentifier:@"my-raster-layer" source:rasterSource];
MGLStyleAttributeFunction *opacityFunction = [[MGLStyleAttributeFunction alloc] init];
opacityFunction.stops = @{@20.0f: @1.0f,
@5.0f: @0.0f};
rasterLayer.rasterOpacity = opacityFunction;
[self.mapView.style addLayer:rasterLayer];
}
- (void)styleWaterLayer
{
MGLFillStyleLayer *waterLayer = (MGLFillStyleLayer *)[self.mapView.style layerWithIdentifier:@"water"];
@@ -513,7 +630,7 @@ static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXVie
@12.0f: [UIColor greenColor],
@14.0f: [UIColor blueColor]};
waterLayer.fillColor = waterColorFunction;
MGLStyleAttributeFunction *fillAntialias = [[MGLStyleAttributeFunction alloc] init];
fillAntialias.stops = @{@11: @YES,
@12: @NO,
@@ -528,7 +645,7 @@ static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXVie
MGLLineStyleLayer *roadLayer = (MGLLineStyleLayer *)[self.mapView.style layerWithIdentifier:@"road-primary"];
roadLayer.lineColor = [UIColor blackColor];
MGLStyleAttributeFunction *lineWidthFunction = [[MGLStyleAttributeFunction alloc] init];
MGLStyleAttributeFunction *roadLineColor = [[MGLStyleAttributeFunction alloc] init];
roadLineColor.stops = @{@10: [UIColor purpleColor],
@13: [UIColor yellowColor],
@@ -536,12 +653,142 @@ static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXVie
roadLayer.lineColor = roadLineColor;
roadLayer.lineWidth = lineWidthFunction;
roadLayer.lineGapWidth = lineWidthFunction;
roadLayer.visible = YES;
roadLayer.maximumZoomLevel = 15;
roadLayer.minimumZoomLevel = 13;
}
- (void)styleRasterLayer
{
NSURL *rasterURL = [NSURL URLWithString:@"mapbox://mapbox.satellite"];
MGLRasterSource *rasterSource = [[MGLRasterSource alloc] initWithSourceIdentifier:@"my-raster-source" URL:rasterURL tileSize:512];
[self.mapView.style addSource:rasterSource];
MGLRasterStyleLayer *rasterLayer = [[MGLRasterStyleLayer alloc] initWithLayerIdentifier:@"my-raster-layer" source:rasterSource];
MGLStyleAttributeFunction *opacityFunction = [[MGLStyleAttributeFunction alloc] init];
opacityFunction.stops = @{@20.0f: @1.0f,
@5.0f: @0.0f};
rasterLayer.rasterOpacity = opacityFunction;
[self.mapView.style addLayer:rasterLayer];
}
- (void)styleGeoJSONSource
{
NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"amsterdam" ofType:@"geojson"];
NSURL *geoJSONURL = [NSURL fileURLWithPath:filePath];
MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"ams" URL:geoJSONURL];
[self.mapView.style addSource:source];
MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithLayerIdentifier:@"test" source:source];
fillLayer.fillColor = [UIColor purpleColor];
[self.mapView.style addLayer:fillLayer];
}
- (void)styleSymbolLayer
{
MGLSymbolStyleLayer *stateLayer = (MGLSymbolStyleLayer *)[self.mapView.style layerWithIdentifier:@"state-label-lg"];
stateLayer.textColor = [UIColor redColor];
}
- (void)styleBuildingLayer
{
MGLFillStyleLayer *buildingLayer = (MGLFillStyleLayer *)[self.mapView.style layerWithIdentifier:@"building"];
buildingLayer.fillColor = [UIColor blackColor];
}
- (void)styleFerryLayer
{
MGLLineStyleLayer *ferryLineLayer = (MGLLineStyleLayer *)[self.mapView.style layerWithIdentifier:@"ferry"];
ferryLineLayer.lineColor = [UIColor redColor];
}
- (void)removeParkLayer
{
MGLFillStyleLayer *parkLayer = (MGLFillStyleLayer *)[self.mapView.style layerWithIdentifier:@"park"];
[self.mapView.style removeLayer:parkLayer];
}
- (IBAction)startWorldTour
{
_isTouringWorld = YES;
[self.mapView removeAnnotations:self.mapView.annotations];
NSUInteger numberOfAnnotations = sizeof(WorldTourDestinations) / sizeof(WorldTourDestinations[0]);
NSMutableArray *annotations = [NSMutableArray arrayWithCapacity:numberOfAnnotations];
for (NSUInteger i = 0; i < numberOfAnnotations; i++)
{
MBXDroppedPinAnnotation *annotation = [[MBXDroppedPinAnnotation alloc] init];
annotation.coordinate = WorldTourDestinations[i];
[annotations addObject:annotation];
}
[self.mapView addAnnotations:annotations];
[self continueWorldTourWithRemainingAnnotations:annotations];
}
- (void)continueWorldTourWithRemainingAnnotations:(NS_MUTABLE_ARRAY_OF(MGLPointAnnotation *) *)annotations
{
MGLPointAnnotation *nextAnnotation = annotations.firstObject;
if (!nextAnnotation || !_isTouringWorld)
{
_isTouringWorld = NO;
return;
}
[annotations removeObjectAtIndex:0];
MGLMapCamera *camera = [MGLMapCamera cameraLookingAtCenterCoordinate:nextAnnotation.coordinate
fromDistance:10
pitch:arc4random_uniform(60)
heading:arc4random_uniform(360)];
__weak MBXViewController *weakSelf = self;
[self.mapView flyToCamera:camera completionHandler:^{
MBXViewController *strongSelf = weakSelf;
[strongSelf performSelector:@selector(continueWorldTourWithRemainingAnnotations:)
withObject:annotations
afterDelay:2];
}];
}
- (void)toggleCustomUserDot
{
_customUserLocationAnnnotationEnabled = !_customUserLocationAnnnotationEnabled;
self.mapView.showsUserLocation = NO;
self.mapView.userTrackingMode = MGLUserTrackingModeFollow;
}
- (void)printTelemetryLogFile
{
NSString *fileContents = [NSString stringWithContentsOfFile:[self telemetryDebugLogFilePath] encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@", fileContents);
}
- (void)deleteTelemetryLogFile
{
NSString *filePath = [self telemetryDebugLogFilePath];
if ([[NSFileManager defaultManager] isDeletableFileAtPath:filePath])
{
NSError *error;
BOOL success = [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
if (success) {
NSLog(@"Deleted telemetry log.");
} else {
NSLog(@"Error deleting telemetry log: %@", error.localizedDescription);
}
}
}
- (NSString *)telemetryDebugLogFilePath
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy'-'MM'-'dd"];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:[NSString stringWithFormat:@"telemetry_log-%@.json", [dateFormatter stringFromDate:[NSDate date]]]];
return filePath;
}
#pragma mark - User Actions
- (IBAction)handleLongPress:(UILongPressGestureRecognizer *)longPress
{
if (longPress.state == UIGestureRecognizerStateBegan)
@@ -643,69 +890,7 @@ static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXVie
[sender setAccessibilityValue:nextAccessibilityValue];
}
- (IBAction)startWorldTour:(__unused id)sender
{
_isTouringWorld = YES;
[self.mapView removeAnnotations:self.mapView.annotations];
NSUInteger numberOfAnnotations = sizeof(WorldTourDestinations) / sizeof(WorldTourDestinations[0]);
NSMutableArray *annotations = [NSMutableArray arrayWithCapacity:numberOfAnnotations];
for (NSUInteger i = 0; i < numberOfAnnotations; i++)
{
MBXDroppedPinAnnotation *annotation = [[MBXDroppedPinAnnotation alloc] init];
annotation.coordinate = WorldTourDestinations[i];
[annotations addObject:annotation];
}
[self.mapView addAnnotations:annotations];
[self continueWorldTourWithRemainingAnnotations:annotations];
}
- (void)continueWorldTourWithRemainingAnnotations:(NS_MUTABLE_ARRAY_OF(MGLPointAnnotation *) *)annotations
{
MGLPointAnnotation *nextAnnotation = annotations.firstObject;
if (!nextAnnotation || !_isTouringWorld)
{
_isTouringWorld = NO;
return;
}
[annotations removeObjectAtIndex:0];
MGLMapCamera *camera = [MGLMapCamera cameraLookingAtCenterCoordinate:nextAnnotation.coordinate
fromDistance:10
pitch:arc4random_uniform(60)
heading:arc4random_uniform(360)];
__weak MBXViewController *weakSelf = self;
[self.mapView flyToCamera:camera completionHandler:^{
MBXViewController *strongSelf = weakSelf;
[strongSelf performSelector:@selector(continueWorldTourWithRemainingAnnotations:)
withObject:annotations
afterDelay:2];
}];
}
- (NSString *)telemetryDebugLogfilePath
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy'-'MM'-'dd"];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:[NSString stringWithFormat:@"telemetry_log-%@.json", [dateFormatter stringFromDate:[NSDate date]]]];
return filePath;
}
- (IBAction)unwindToMapViewController:(__unused UIStoryboardSegue *)sender {
}
#pragma mark - Destruction
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self saveState:nil];
}
#pragma mark - MGLMapViewDelegate
#pragma mark - Map Delegate
- (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id<MGLAnnotation>)annotation
{