From 6c3804069260c5e8cca5a027d9b31c38f1c7ec49 Mon Sep 17 00:00:00 2001 From: "zmiles@gwu.edu" Date: Wed, 11 Dec 2019 10:25:54 -0500 Subject: [PATCH] Add change worldview boundaries example --- Examples.xcodeproj/project.pbxproj | 10 ++ Examples/Examples.h | 1 + Examples/Examples.m | 2 + .../ObjectiveC/ChangeWorldviewBoundaries.m | 95 +++++++++++++++++++ .../Headers/ChangeWorldviewBoundaries.h | 14 +++ .../ChangeWorldviewBoundariesExample.swift | 76 +++++++++++++++ 6 files changed, 198 insertions(+) create mode 100644 Examples/ObjectiveC/ChangeWorldviewBoundaries.m create mode 100644 Examples/ObjectiveC/Headers/ChangeWorldviewBoundaries.h create mode 100644 Examples/Swift/ChangeWorldviewBoundariesExample.swift diff --git a/Examples.xcodeproj/project.pbxproj b/Examples.xcodeproj/project.pbxproj index 87fee561..c1f7c439 100644 --- a/Examples.xcodeproj/project.pbxproj +++ b/Examples.xcodeproj/project.pbxproj @@ -80,6 +80,8 @@ 3EC92DB71E78C431001D0503 /* metro-line.geojson in Resources */ = {isa = PBXBuildFile; fileRef = 3EC92DB61E78C431001D0503 /* metro-line.geojson */; }; 3ED403411E006B5200230C95 /* CameraFlyToExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ED403401E006B5200230C95 /* CameraFlyToExample.swift */; }; 3ED403481E006BE800230C95 /* CameraFlyToExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 3ED403471E006BE800230C95 /* CameraFlyToExample.m */; }; + 583C02ED23A0B305005393D8 /* ChangeWorldviewBoundariesExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583C02EC23A0B305005393D8 /* ChangeWorldviewBoundariesExample.swift */; }; + 583C02EF23A0B3E5005393D8 /* ChangeWorldviewBoundaries.m in Sources */ = {isa = PBXBuildFile; fileRef = 583C02EE23A0B3E5005393D8 /* ChangeWorldviewBoundaries.m */; }; 60E0DCA0CEED683C3A4F18F2 /* Pods_Examples.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EC12D8F1A97963D68BFA871 /* Pods_Examples.framework */; }; 646B62971DEF6DAF000AA523 /* ShowHideLayerExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 646B62961DEF6DAF000AA523 /* ShowHideLayerExample.swift */; }; 646B629C1DEF6DF1000AA523 /* ShowHideLayerExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 646B629B1DEF6DF1000AA523 /* ShowHideLayerExample.m */; }; @@ -269,6 +271,9 @@ 3ED403461E006BE800230C95 /* CameraFlyToExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CameraFlyToExample.h; sourceTree = ""; }; 3ED403471E006BE800230C95 /* CameraFlyToExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CameraFlyToExample.m; sourceTree = ""; }; 532FB53EE0142E4DAC3FB49B /* Pods-Shared-Examples.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Shared-Examples.release.xcconfig"; path = "Pods/Target Support Files/Pods-Shared-Examples/Pods-Shared-Examples.release.xcconfig"; sourceTree = ""; }; + 583C02EC23A0B305005393D8 /* ChangeWorldviewBoundariesExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeWorldviewBoundariesExample.swift; sourceTree = ""; }; + 583C02EE23A0B3E5005393D8 /* ChangeWorldviewBoundaries.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ChangeWorldviewBoundaries.m; sourceTree = ""; }; + 583C02F023A0B6E0005393D8 /* ChangeWorldviewBoundaries.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ChangeWorldviewBoundaries.h; sourceTree = ""; }; 589ABF8859560819F8B431C7 /* Pods-ExamplesTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExamplesTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ExamplesTests/Pods-ExamplesTests.debug.xcconfig"; sourceTree = ""; }; 646B62961DEF6DAF000AA523 /* ShowHideLayerExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShowHideLayerExample.swift; sourceTree = ""; }; 646B629B1DEF6DF1000AA523 /* ShowHideLayerExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShowHideLayerExample.m; sourceTree = ""; }; @@ -451,6 +456,7 @@ 05536CB4200F9EEB00657097 /* SwitchStylesExample.swift */, 64CF970F1DF224E400C3C27B /* ThirdPartyVectorStyleExample.swift */, 1F070160225556FA0045E061 /* MissingIconsExample.swift */, + 583C02EC23A0B305005393D8 /* ChangeWorldviewBoundariesExample.swift */, ); name = "Map styles"; sourceTree = ""; @@ -545,6 +551,7 @@ 9691AAA21C5AAD8F006A58C6 /* StudioStyleExample.m */, 05536CB1200F9B0900657097 /* SwitchStylesExample.m */, 05FA53951FE2F9FE001F3D7D /* ThirdPartyVectorStyleExample.m */, + 583C02EE23A0B3E5005393D8 /* ChangeWorldviewBoundaries.m */, ); name = "Map styles"; sourceTree = ""; @@ -810,6 +817,7 @@ 3E18060E1EAA800A004DB131 /* UserLocationAnnotationExample.h */, 969E7FDB1D25C31700663F84 /* UserTrackingModesExample.h */, 64BBDAFB1DF24DD700BB705D /* WebAPIDataExample.h */, + 583C02F023A0B6E0005393D8 /* ChangeWorldviewBoundaries.h */, ); path = Headers; sourceTree = ""; @@ -1354,6 +1362,7 @@ 3ED403481E006BE800230C95 /* CameraFlyToExample.m in Sources */, 3EBCD71D1DC28240001E342F /* StudioClassicStyleExample.swift in Sources */, 646B62B01DEF7161000AA523 /* AnimatedLineExample.swift in Sources */, + 583C02ED23A0B305005393D8 /* ChangeWorldviewBoundariesExample.swift in Sources */, 3E52ACD31EE8D8AF0056242C /* LiveDataExample.m in Sources */, 3EA5AA041FAD2EC7007073C0 /* StaticSnapshotExample.swift in Sources */, 05FA53A91FE2FB46001F3D7D /* CustomCalloutView.m in Sources */, @@ -1394,6 +1403,7 @@ A42F4A5122EF9ACD005097F3 /* CacheManagementExample.swift in Sources */, 05FA53A11FE2FA1E001F3D7D /* PolygonPatternExample.m in Sources */, 0774A77423394B750038264E /* ShapeAnnotationsExample.m in Sources */, + 583C02EF23A0B3E5005393D8 /* ChangeWorldviewBoundaries.m in Sources */, 3E3FB66E1F0588B3004512C6 /* BuildingLightExample.m in Sources */, 968247271C5C1DC700494AB8 /* CameraAnimationExample.m in Sources */, CA39B2BF209B881300D37037 /* BuildingLightExample+UITesting.m in Sources */, diff --git a/Examples/Examples.h b/Examples/Examples.h index fdad2058..4ea50362 100644 --- a/Examples/Examples.h +++ b/Examples/Examples.h @@ -23,6 +23,7 @@ extern NSString *const MBXExampleBlockingGesturesDelegate; extern NSString *const MBXExampleBuildingLight; extern NSString *const MBXExampleCameraAnimation; extern NSString *const MBXExampleCameraFlyTo; +extern NSString *const MBXExampleChangeWorldviewBoundaries; extern NSString *const MBXExampleClustering; extern NSString *const MBXExampleClusteringWithImages; extern NSString *const MBXExampleCustomCalloutView; diff --git a/Examples/Examples.m b/Examples/Examples.m index c25de13d..e2124e7d 100644 --- a/Examples/Examples.m +++ b/Examples/Examples.m @@ -28,6 +28,8 @@ + (NSArray *)groups { @{@"className": MBXExampleThirdPartyVectorStyle, @"title": @"Use third-party vector tiles"}, @{@"className": MBXExampleSwitchStyles, @"title": @"Switch between map styles"}, @{@"className": MBXExampleCameraFlyTo, @"title": @"Camera fly to"}, + @{@"className": MBXExampleChangeWorldviewBoundaries, @"title": @"Adjust administrative boundaries"}, + ] }, @{ diff --git a/Examples/ObjectiveC/ChangeWorldviewBoundaries.m b/Examples/ObjectiveC/ChangeWorldviewBoundaries.m new file mode 100644 index 00000000..6987a59c --- /dev/null +++ b/Examples/ObjectiveC/ChangeWorldviewBoundaries.m @@ -0,0 +1,95 @@ +#import "ChangeWorldviewBoundaries.h" + +@import Mapbox; + +NSString *const MBXExampleChangeWorldviewBoundaries = @"ChangeWorldviewBoundariesExample"; + +@interface ChangeWorldviewBoundariesExample () + +@property (nonatomic) MGLMapView *mapView; +@property MGLLineStyleLayer *layer; + + +@end + +@implementation ChangeWorldviewBoundariesExample + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.mapView = [[MGLMapView alloc] initWithFrame: CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)]; + self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + + // Set the map's initial style, center coordinate, and zoom level + self.mapView.styleURL = [MGLStyle lightStyleURL]; + [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(25.251, 95.69) + zoomLevel:3 + animated:NO]; + [self.view addSubview:self.mapView]; + + // Create a UISegmentedControl to toggle between map styles + UISegmentedControl *styleToggle =[[UISegmentedControl alloc] initWithItems:@[@" US ", @" CN ", @" IN ", @" All "]]; + styleToggle.translatesAutoresizingMaskIntoConstraints = NO; + styleToggle.tintColor = [UIColor colorWithRed:0.976f green:0.843f blue:0.831f alpha:1]; + styleToggle.backgroundColor = [UIColor colorWithRed:0.721f green:0.804f blue:0.831f alpha:1]; + styleToggle.layer.cornerRadius = 4; + styleToggle.clipsToBounds = YES; + [self.view insertSubview:styleToggle aboveSubview:self.mapView]; + [styleToggle addTarget:self action:@selector(changeStyle:) forControlEvents:UIControlEventValueChanged]; + + // Configure autolayout constraints for the UISegmentedControl to align + // at the bottom of the map view and above the Mapbox logo and attribution + NSMutableArray *constraints = [NSMutableArray array]; + + [constraints addObject:[NSLayoutConstraint constraintWithItem:styleToggle attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.mapView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:1.0]]; + [constraints addObject:[NSLayoutConstraint constraintWithItem:styleToggle attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.mapView.logoView attribute:NSLayoutAttributeTop multiplier:1 constant:-20]]; + + [self.view addConstraints:constraints]; +} + + // Change the map style based on the selected index of the UISegmentedControl + - (void)changeStyle:(UISegmentedControl *)sender { + + MGLStyle *style = self.mapView.style; + + MGLVectorTileSource *source = [[MGLVectorTileSource alloc] initWithIdentifier:@"admin-bounds" configurationURL: [NSURL URLWithString:@"mapbox://mapbox.mapbox-streets-v8"]]; + + if ([_layer.identifier isEqual: @"admin"]) { + printf("source already exists"); + [style removeLayer:_layer]; + + } else { + _layer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"admin" source:source]; + [style addSource:source]; + } + _layer.sourceLayerIdentifier = @"admin"; + _layer.lineColor = [NSExpression expressionForConstantValue: UIColor.lightGrayColor]; + + switch(sender.selectedSegmentIndex){ + case 0: + printf("US"); + _layer.predicate = [ NSPredicate predicateWithFormat: @"CAST(worldview, 'NSString') == 'US'"]; + [style addLayer:_layer]; + break; + case 1: + printf("CN"); + _layer.predicate = [ NSPredicate predicateWithFormat: @"CAST(worldview, 'NSString') == 'CN'"]; + [style addLayer:_layer]; + break; + case 2: + printf("IN"); + _layer.predicate = [ NSPredicate predicateWithFormat: @"CAST(worldview, 'NSString') == 'IN'"]; + [style addLayer:_layer]; + break; + case 3: + printf("All"); + _layer.predicate = [ NSPredicate predicateWithFormat: @"CAST(worldview, 'NSString') == 'all'"]; + [style addLayer:_layer]; + break; + default: + [style addLayer:_layer]; + break; + } + } + +@end diff --git a/Examples/ObjectiveC/Headers/ChangeWorldviewBoundaries.h b/Examples/ObjectiveC/Headers/ChangeWorldviewBoundaries.h new file mode 100644 index 00000000..6c07686b --- /dev/null +++ b/Examples/ObjectiveC/Headers/ChangeWorldviewBoundaries.h @@ -0,0 +1,14 @@ +// +// ChangeWorldviewBoundaries.h +// Examples +// +// Created by ZiZi Miles on 12/11/19. +// Copyright © 2019 Mapbox. All rights reserved. +// + +#import + +@interface ChangeWorldviewBoundariesExample : UIViewController + +@end + diff --git a/Examples/Swift/ChangeWorldviewBoundariesExample.swift b/Examples/Swift/ChangeWorldviewBoundariesExample.swift new file mode 100644 index 00000000..12c8d6d0 --- /dev/null +++ b/Examples/Swift/ChangeWorldviewBoundariesExample.swift @@ -0,0 +1,76 @@ +import UIKit +import Mapbox + +@objc(ChangeWorldviewBoundariesExample_Swift) + +class ChangeWorldviewBoundariesExample: UIViewController, MGLMapViewDelegate { + + let mapView = MGLMapView() + let source = MGLVectorTileSource(identifier: "admin-bounds", configurationURL: NSURL(string: "mapbox://mapbox.mapbox-streets-v8")! as URL) + var adminLayers = [String]() + var layer: MGLLineStyleLayer? + override func viewDidLoad() { + super.viewDidLoad() + + mapView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height) + mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + + // Set the map's initial style, center coordinate, and zoom level + mapView.styleURL = MGLStyle.lightStyleURL + mapView.setCenter(CLLocationCoordinate2D(latitude: 25.251, longitude: 95.69), zoomLevel: 3, animated: false) + + view.addSubview(mapView) + + // Create a UISegmentedControl to toggle between map styles + let styleToggle = UISegmentedControl(items: [" US ", " CN ", " IN "," All "]) + styleToggle.translatesAutoresizingMaskIntoConstraints = false + styleToggle.tintColor = UIColor(red: 0.976, green: 0.843, blue: 0.831, alpha: 1) + styleToggle.backgroundColor = UIColor(red: 184/255, green: 205/255, blue: 212/255, alpha: 1) + styleToggle.layer.cornerRadius = 4 + styleToggle.clipsToBounds = true +// styleToggle.selectedSegmentIndex = 0 + view.insertSubview(styleToggle, aboveSubview: mapView) + styleToggle.addTarget(self, action: #selector(changeStyle(sender:)), for: .valueChanged) + + // Configure autolayout constraints for the UISegmentedControl to align + // at the bottom of the map view and above the Mapbox logo and attribution + NSLayoutConstraint.activate([NSLayoutConstraint(item: styleToggle, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: mapView, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1.0, constant: 0.0)]) + NSLayoutConstraint.activate([NSLayoutConstraint(item: styleToggle, attribute: .bottom, relatedBy: .equal, toItem: mapView.logoView, attribute: .top, multiplier: 1, constant: -20)]) + + } + + // Change the map style based on the selected index of the UISegmentedControl + @objc func changeStyle(sender: UISegmentedControl) { + + guard let style = self.mapView.style else {return} + + if layer?.identifier == "admin" { + print("source already exists") + style.removeLayer(layer!) + } else { + layer = MGLLineStyleLayer(identifier: "admin", source: source) + style.addSource(source) + } + layer?.sourceLayerIdentifier = "admin" + layer?.lineColor = NSExpression(forConstantValue: UIColor.lightGray) + + switch sender.selectedSegmentIndex { + case 0: + + layer?.predicate = NSPredicate(format: "CAST(worldview, 'NSString') == 'US'") + style.addLayer(layer!) + case 1: + layer?.predicate = NSPredicate(format: "CAST(worldview, 'NSString') == 'CN'") + style.addLayer(layer!) + case 2: + layer?.predicate = NSPredicate(format: "CAST(worldview, 'NSString') == 'IN'") + style.addLayer(layer!) + case 3: + layer?.predicate = NSPredicate(format: "CAST(worldview, 'NSString') == 'all'") + style.addLayer(layer!) + default: + style.addLayer(layer!) + + } + } +}