This commit is contained in:
Peter Liu
2015-04-27 16:26:55 -07:00
57 changed files with 942 additions and 864 deletions

2
.gitmodules vendored
View File

@@ -12,7 +12,7 @@
[submodule "test/ios/KIF"]
path = test/ios/KIF
url = https://github.com/mapbox/KIF.git
url = https://github.com/kif-framework/KIF.git
[submodule "platform/ios/vendor/SMCalloutView"]
path = platform/ios/vendor/SMCalloutView

View File

@@ -57,6 +57,7 @@ env:
- IOS_PROFILE_NAME="ios-in-house"
- secure: "nQqSM8rd7OHtV4MqmNqVnkrVHqxKqQsaWRYk4/nPdhbeVWtTtkk0df711LrF1TUtbEPEewHxYUvTZ/UXmwJNeoKdzTHavI8hnatRkgjyxGERPn1il1Otelht9I+LQQHf+plrpRjVWBrNIW0Zox1B3cqn6d3NglpbXrEQ2EjYGNA="
# end iOS code signing
- KIF_SCREENSHOTS="${TRAVIS_BUILD_DIR}/screenshots"
before_install:
- if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then sudo service mysql stop; fi
@@ -68,6 +69,7 @@ before_install:
- ./scripts/travis_before_install.sh
- if [[ ${TRAVIS_OS_NAME} == "linux" && ${MASON_PLATFORM} != "android" ]]; then export LD_LIBRARY_PATH=`mason prefix mesa 10.4.3`/lib; fi
- if [[ ${TRAVIS_OS_NAME} == "linux" && ${MASON_PLATFORM} != "android" ]]; then glxinfo; fi
- if [[ ${TRAVIS_OS_NAME} == "osx" && ${TEST_OS} == "ios" ]]; then mkdir -p ${KIF_SCREENSHOTS}; fi
install:
- ulimit -c
@@ -88,6 +90,9 @@ script:
after_script:
- ./scripts/ios_travis/remove-key.sh
after_failure:
- if [[ ${TRAVIS_OS_NAME} == "osx" && ${TEST_OS} == "ios" ]]; then ./scripts/ios_travis/upload_screenshots.sh; fi
notifications:
slack:
secure: HHQYr7sF8M1SzoWSqgKVYtwAgGdLLCyTMsQjFhEEQNYO92ZwURE5s03qWTGH5k8+4Yqn26yrXt3NztLC4JIOpcGervN2mSZyq4dZgFTcWEd61igw0qwSenlwvFfbE1ASK/KYCzfyn9MIfHN+ovwLoRxXZkPwinKDvl3DXjBaFNg=

125
Makefile
View File

@@ -4,11 +4,16 @@ PREFIX ?= /usr/local
ANDROID_ABI ?= arm-v7
ifeq ($(shell uname -s), Darwin)
HOST ?= osx
HEADLESS ?= cgl
HOST = osx
HEADLESS = cgl
JOBS ?= $(shell sysctl -n hw.ncpu)
endif
HOST ?= linux
ifeq ($(shell uname -s), Linux)
HOST = linux
JOBS ?= $(shell sysctl -n hw.ncpu)
endif
JOBS ?= 1
all: mbgl
@@ -29,49 +34,45 @@ styles/styles:
SMCalloutView:
git submodule update --init platform/ios/vendor/SMCalloutView
KIF:
git submodule update --init test/ios/KIF
#### Build files ###############################################################
.PRECIOUS: Makefile/project
Makefile/project: config/$(HOST).gypi styles/styles SMCalloutView
deps/run_gyp gyp/project.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make
.PRECIOUS: Xcode/project
Xcode/project: config/$(HOST).gypi styles/styles SMCalloutView
deps/run_gyp gyp/project.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f xcode
#### Library builds ############################################################
.PRECIOUS: Makefile/mbgl
Makefile/mbgl: config/$(HOST).gypi styles/styles SMCalloutView
deps/run_gyp mbgl.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make
mbgl: Makefile/mbgl
mbgl: Makefile/project
$(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) everything
standalone: Makefile/mbgl
standalone: Makefile/project
LINK=`pwd`/gyp/link.py $(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) standalone
install: Makefile/mbgl
install: Makefile/project
LINK=`pwd`/gyp/link.py $(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) install
.PRECIOUS: Xcode/mbgl
Xcode/mbgl: config/$(HOST).gypi styles/styles SMCalloutView
deps/run_gyp mbgl.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f xcode
##### Test builds ##############################################################
.PRECIOUS: Makefile/test
Makefile/test: test/test.gyp config/$(HOST).gypi styles/styles SMCalloutView
deps/run_gyp test/test.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make
.PHONY: test
test: Makefile/test
test: Makefile/project
$(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) test
test-%: test
./scripts/run_tests.sh "build/$(HOST)/$(BUILDTYPE)/test" --gtest_filter=$*
.PRECIOUS: Xcode/test
Xcode/test: test/test.gyp config/osx.gypi styles/styles SMCalloutView
deps/run_gyp test/test.gyp $(CONFIG_osx) $(LIBS_osx) --generator-output=./build/osx -f xcode
.PHONY: lproj lbuild run-xlinux
xtest-proj: Xcode/test
open ./build/osx/test/test.xcodeproj
xtest: Xcode/test
xcodebuild -project ./build/osx/test/test.xcodeproj -configuration $(BUILDTYPE) -target test -jobs $(JOBS)
.PHONY: xtest
xtest: Xcode/project
xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target test -jobs $(JOBS)
xtest-%: xtest
./scripts/run_tests.sh "build/osx/Build/Products/$(BUILDTYPE)/test" --gtest_filter=$*
@@ -79,31 +80,22 @@ xtest-%: xtest
#### Mac OS X application builds ###############################################
.PRECIOUS: Makefile/osx
Makefile/osx: macosx/mapboxgl-app.gyp config/osx.gypi styles/styles
deps/run_gyp macosx/mapboxgl-app.gyp $(CONFIG_osx) $(LIBS_osx) --generator-output=./build/osx -f make
.PHONY: osx run-osx
osx: Makefile/osx
osx: Makefile/project
$(MAKE) -C build/osx BUILDTYPE=$(BUILDTYPE) osxapp
run-osx: osx
"build/osx/$(BUILDTYPE)/Mapbox GL.app/Contents/MacOS/Mapbox GL"
.PRECIOUS: Xcode/osx
Xcode/osx: macosx/mapboxgl-app.gyp config/osx.gypi styles/styles
deps/run_gyp macosx/mapboxgl-app.gyp $(CONFIG_osx) $(LIBS_osx) --generator-output=./build/osx -f xcode
.PHONY: xosx-proj xosx run-xosx
xosx-proj: Xcode/osx
open ./build/osx/macosx/mapboxgl-app.xcodeproj
xosx-proj: Xcode/project
open ./build/osx/gyp/project.xcodeproj
xosx: Xcode/osx
xcodebuild -project ./build/osx/macosx/mapboxgl-app.xcodeproj -configuration $(BUILDTYPE) -target osxapp -jobs $(JOBS)
xosx: Xcode/project
xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target osxapp -jobs $(JOBS)
run-xosx: xosx
"build/osx/Build/Products/$(BUILDTYPE)/Mapbox GL.app/Contents/MacOS/Mapbox GL"
"gyp/build/$(BUILDTYPE)/Mapbox GL.app/Contents/MacOS/Mapbox GL"
# Legacy name
xproj: xosx-proj
@@ -129,40 +121,28 @@ isim: Xcode/ios
ipackage: clean Xcode/ios
./scripts/package_ios.sh
itest: ipackage KIF
./scripts/test_ios.sh
# Legacy name
iproj: ios-proj
#### Linux application builds ##################################################
.PRECIOUS: Makefile/linux
Makefile/linux: linux/mapboxgl-app.gyp config/$(HOST).gypi styles/styles
deps/run_gyp linux/mapboxgl-app.gyp $(CONFIG_$(HOST)) $(LIBS_linux) --generator-output=./build/$(HOST) -f make
.PHONY: linux run-linux
linux: Makefile/linux
linux: Makefile/project
$(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) linuxapp
run-linux: linux
(cd build/$(HOST)/$(BUILDTYPE) && ./mapbox-gl)
.PRECIOUS: Xcode/linux
Xcode/linux: linux/mapboxgl-app.gyp config/osx.gypi styles/styles
deps/run_gyp linux/mapboxgl-app.gyp $(CONFIG_osx) $(LIBS_linux) --generator-output=./build/osx -f xcode
.PHONY: lproj lbuild run-xlinux
xlinux-proj: Xcode/linux
open ./build/osx/linux/mapboxgl-app.xcodeproj
xlinux: Xcode/linux
xcodebuild -project ./build/osx/linux/mapboxgl-app.xcodeproj -configuration $(BUILDTYPE) -target linuxapp
.PHONY: xlinux run-xlinux
xlinux: Xcode/project
xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target linuxapp -jobs $(JOBS)
run-xlinux: xlinux
"build/osx/Build/Products/$(BUILDTYPE)/mapbox-gl"
# Legacy name
lproj: xlinux-proj
"gyp/build/$(BUILDTYPE)/mapbox-gl"
#### Android libaries #########################################################
@@ -194,22 +174,15 @@ android-deploy: $(ANDROID_ABIS)
android-project: android-lib
##### Render builds ############################################################
.PRECIOUS: Makefile/render
Makefile/render: bin/render.gyp config/$(HOST).gypi
deps/run_gyp bin/render.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make
render: Makefile/render
render: Makefile/project
$(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) mbgl-render
.PRECIOUS: Xcode/render
Xcode/render: bin/render.gyp config/osx.gypi styles/styles
deps/run_gyp bin/render.gyp $(CONFIG_osx) $(LIBS_osx) --generator-output=./build/osx -f xcode
.PHONY: xrender-proj
xrender-proj: Xcode/render
open ./build/osx/bin/render.xcodeproj
.PHONY: xrender run-xrender
xrender: Xcode/project
xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target mbgl-render -jobs $(JOBS)
##### Maintenace operations ####################################################

View File

@@ -70,6 +70,8 @@ If you merely want to install the library for iOS and try it out as an Objective
If you want to build from source and/or contribute to development of the project, run `make iproj`, which will create and open an Xcode project which can build the entire library from source as well as an Objective-C test app.
You can also run `make itest` to run the included tests. Requires `brew install xcpretty`.
Target devices: iPhone 4S and above (5, 5c, 5s, 6, 6 Plus) and iPad 2 and above (3, 4, Mini, Air, Mini 2, Air 2).
Target iOS: 7.0 through 8.1

19
gyp/project.gyp Normal file
View File

@@ -0,0 +1,19 @@
{
'conditions': [
['host == "osx"', {
'includes': [
'../macosx/mapboxgl-app.gypi',
'../linux/mapboxgl-app.gypi',
'../test/test.gypi',
'../bin/render.gypi',
]
}],
['host == "linux"', {
'includes': [
'../linux/mapboxgl-app.gypi',
'../test/test.gypi',
'../bin/render.gypi',
]
}],
],
}

View File

@@ -32,6 +32,7 @@ extern NSString *const MGLEventGestureRotateStart;
+ (void) setToken:(NSString *)token;
+ (void) setAppName:(NSString *)appName;
+ (void) setAppVersion:(NSString *)appVersion;
+ (void) setAppBuildNumber:(NSString *)appBuildNumber;
+ (void) pauseMetricsCollection;
+ (void) resumeMetricsCollection;

View File

@@ -74,6 +74,11 @@ inline vec2<T> normal(const S1& a, const S2& b) {
return { dx / c, dy / c };
}
template <typename T>
inline T perp(const T& a) {
return T(-a.y, a.x);
}
template <typename T, typename S1, typename S2>
inline T dist(const S1& a, const S2& b) {
T dx = b.x - a.x;
@@ -93,6 +98,11 @@ inline T mag(const S& a) {
return std::sqrt(a.x * a.x + a.y * a.y);
}
template <typename S>
inline S unit(const S& a) {
return a * (1 / mag(a));
}
template <typename T>
T clamp(T value, T min, T max) {
return value < min ? min : (value > max ? max : value);

View File

@@ -61,7 +61,13 @@ struct vec2 {
template <typename O>
inline typename std::enable_if<!std::is_arithmetic<O>::value, vec2>::type
operator-(const O &o) const {
return {x - o.x, y - o.y};
return vec2<T>(x - o.x, y - o.y);
}
template <typename O>
inline typename std::enable_if<!std::is_arithmetic<O>::value, vec2>::type
operator+(const O &o) const {
return vec2<T>(x + o.x, y + o.y);
}
template <typename M>

View File

@@ -1,7 +1,7 @@
Pod::Spec.new do |m|
m.name = 'MapboxGL'
m.version = '0.2.14'
m.version = '0.2.15'
m.summary = 'Open source vector map solution for iOS with full styling capabilities.'
m.description = 'Open source OpenGL-based vector map solution for iOS with full styling capabilities and Cocoa bindings.'

View File

@@ -21,7 +21,7 @@
<key>CFBundleSignature</key>
<string>MBGL</string>
<key>CFBundleVersion</key>
<string>0.0.2</string>
<string>0.0.3</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSHumanReadableCopyright</key>

View File

@@ -53,7 +53,7 @@
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
'SDKROOT': 'macosx',
'INFOPLIST_FILE': 'Info.plist',
'INFOPLIST_FILE': '../macosx/Info.plist',
'CLANG_ENABLE_OBJC_ARC': 'YES'
},
}

View File

@@ -223,8 +223,10 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
// metrics: initial setup
NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
NSString *appVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
NSString *appBuildNumber = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
if (appName != nil) [MGLMapboxEvents setAppName:appName];
if (appVersion != nil) [MGLMapboxEvents setAppVersion:appVersion];
if (appBuildNumber != nil) [MGLMapboxEvents setAppBuildNumber:appBuildNumber];
// create GL view
//
@@ -242,7 +244,8 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
_glView.contentMode = UIViewContentModeCenter;
[self setBackgroundColor:[UIColor clearColor]];
self.backgroundColor = [UIColor clearColor];
self.clipsToBounds = YES;
// load extensions
//
@@ -293,9 +296,9 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
// setup logo bug
//
_logoBug = [[UIImageView alloc] initWithImage:[MGLMapView resourceImageNamed:@"mapbox.png"]];
UIImage *logo = [[MGLMapView resourceImageNamed:@"mapbox.png"] imageWithAlignmentRectInsets:UIEdgeInsetsMake(1.5, 4, 3.5, 2)];
_logoBug = [[UIImageView alloc] initWithImage:logo];
_logoBug.accessibilityLabel = @"Mapbox logo";
_logoBug.frame = CGRectMake(8, self.bounds.size.height - _logoBug.bounds.size.height - 4, _logoBug.bounds.size.width, _logoBug.bounds.size.height);
_logoBug.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_logoBug];
@@ -304,7 +307,6 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
_attributionButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
_attributionButton.accessibilityLabel = @"Attribution info";
[_attributionButton addTarget:self action:@selector(showAttribution:) forControlEvents:UIControlEventTouchUpInside];
_attributionButton.frame = CGRectMake(self.bounds.size.width - _attributionButton.bounds.size.width - 8, self.bounds.size.height - _attributionButton.bounds.size.height - 8, _attributionButton.bounds.size.width, _attributionButton.bounds.size.height);
_attributionButton.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_attributionButton];
@@ -315,7 +317,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
UIImage *compassImage = [MGLMapView resourceImageNamed:@"Compass.png"];
_compass.frame = CGRectMake(0, 0, compassImage.size.width, compassImage.size.height);
_compass.alpha = 0;
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(self.bounds.size.width - compassImage.size.width - 5, 5, compassImage.size.width, compassImage.size.height)];
UIView *container = [[UIView alloc] initWithFrame:CGRectZero];
[container addSubview:_compass];
container.translatesAutoresizingMaskIntoConstraints = NO;
[container addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleCompassTapGesture:)]];
@@ -491,70 +493,122 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
// views so they don't underlap navigation or tool bars. If we don't have a reference, apply
// constraints against ourself to maintain (albeit less ideal) placement of the subviews.
//
NSString *topGuideFormatString = (self.viewControllerForLayoutGuides ? @"[topLayoutGuide]" : @"|");
NSString *bottomGuideFormatString = (self.viewControllerForLayoutGuides ? @"[bottomLayoutGuide]" : @"|");
id topGuideViewsObject = (self.viewControllerForLayoutGuides ? (id)self.viewControllerForLayoutGuides.topLayoutGuide : (id)@"");
id bottomGuideViewsObject = (self.viewControllerForLayoutGuides ? (id)self.viewControllerForLayoutGuides.bottomLayoutGuide : (id)@"");
UIView *constraintParentView = (self.viewControllerForLayoutGuides.view ? self.viewControllerForLayoutGuides.view : self);
UIView *constraintParentView = (self.viewControllerForLayoutGuides.view ?
self.viewControllerForLayoutGuides.view :
self);
// compass
//
UIView *compassContainer = self.compass.superview;
[constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:%@-topSpacing-[container]", topGuideFormatString]
options:0
metrics:@{ @"topSpacing" : @(5) }
views:@{ @"topLayoutGuide" : topGuideViewsObject,
@"container" : compassContainer }]];
if (self.viewControllerForLayoutGuides)
{
[constraintParentView addConstraint:
[NSLayoutConstraint constraintWithItem:compassContainer
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationGreaterThanOrEqual
toItem:self.viewControllerForLayoutGuides.topLayoutGuide
attribute:NSLayoutAttributeBottom
multiplier:1
constant:5]];
}
[constraintParentView addConstraint:
[NSLayoutConstraint constraintWithItem:compassContainer
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationGreaterThanOrEqual
toItem:self
attribute:NSLayoutAttributeTop
multiplier:1
constant:5]];
[constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[container]-rightSpacing-|"
options:0
metrics:@{ @"rightSpacing" : @(5) }
views:@{ @"container" : compassContainer }]];
[constraintParentView addConstraint:
[NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:compassContainer
attribute:NSLayoutAttributeTrailing
multiplier:1
constant:5]];
[compassContainer addConstraint:[NSLayoutConstraint constraintWithItem:compassContainer
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:self.compass.image.size.width]];
[compassContainer addConstraint:
[NSLayoutConstraint constraintWithItem:compassContainer
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:self.compass.image.size.width]];
[compassContainer addConstraint:[NSLayoutConstraint constraintWithItem:compassContainer
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:self.compass.image.size.height]];
[compassContainer addConstraint:
[NSLayoutConstraint constraintWithItem:compassContainer
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:self.compass.image.size.height]];
// logo bug
//
[constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:[logoBug]-bottomSpacing-%@", bottomGuideFormatString]
options:0
metrics:@{ @"bottomSpacing" : @(4) }
views:@{ @"logoBug" : self.logoBug,
@"bottomLayoutGuide" : bottomGuideViewsObject }]];
if (self.viewControllerForLayoutGuides)
{
[constraintParentView addConstraint:
[NSLayoutConstraint constraintWithItem:self.viewControllerForLayoutGuides.bottomLayoutGuide
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationGreaterThanOrEqual
toItem:self.logoBug
attribute:NSLayoutAttributeBaseline
multiplier:1
constant:8]];
}
[constraintParentView addConstraint:
[NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationGreaterThanOrEqual
toItem:self.logoBug
attribute:NSLayoutAttributeBaseline
multiplier:1
constant:8]];
[constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-leftSpacing-[logoBug]"
options:0
metrics:@{ @"leftSpacing" : @(8) }
views:@{ @"logoBug" : self.logoBug }]];
[constraintParentView addConstraint:
[NSLayoutConstraint constraintWithItem:self.logoBug
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeLeading
multiplier:1
constant:8]];
// attribution button
//
[constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:[attributionButton]-bottomSpacing-%@", bottomGuideFormatString]
options:0
metrics:@{ @"bottomSpacing" : @(8) }
views:@{ @"attributionButton" : self.attributionButton,
@"bottomLayoutGuide" : bottomGuideViewsObject }]];
if (self.viewControllerForLayoutGuides)
{
[constraintParentView addConstraint:
[NSLayoutConstraint constraintWithItem:self.viewControllerForLayoutGuides.bottomLayoutGuide
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationGreaterThanOrEqual
toItem:self.attributionButton
attribute:NSLayoutAttributeBaseline
multiplier:1
constant:8]];
}
[constraintParentView addConstraint:
[NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationGreaterThanOrEqual
toItem:self.attributionButton
attribute:NSLayoutAttributeBaseline
multiplier:1
constant:8]];
[constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[attributionButton]-rightSpacing-|"
options:0
metrics:@{ @"rightSpacing" : @(8) }
views:@{ @"attributionButton" : self.attributionButton }]];
[constraintParentView addConstraint:
[NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:self.attributionButton
attribute:NSLayoutAttributeTrailing
multiplier:1
constant:8]];
[super updateConstraints];
}
@@ -1151,12 +1205,6 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
if (finished)
{
[self notifyMapChange:@(animated ? mbgl::MapChangeRegionDidChangeAnimated : mbgl::MapChangeRegionDidChange)];
[UIView animateWithDuration:MGLAnimationDuration
animations:^
{
self.compass.alpha = 0;
}];
}
}];
}
@@ -2255,6 +2303,17 @@ CLLocationCoordinate2D latLngToCoordinate(mbgl::LatLng latLng)
}
completion:nil];
}
else if (mbglMap->getBearing() == 0 && self.compass.alpha > 0)
{
[UIView animateWithDuration:MGLAnimationDuration
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^
{
self.compass.alpha = 0;
}
completion:nil];
}
}
+ (UIImage *)resourceImageNamed:(NSString *)imageName

View File

@@ -50,7 +50,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
// from within a single thread use underscore syntax.
//
// All captures of `self` from within asynchronous
// dispatches will use a `weakSelf` to avoid cyclical
// dispatches will use a `strongSelf` to avoid cyclical
// strong references.
//
@@ -62,6 +62,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
@property (atomic) NSString *token;
@property (atomic) NSString *appName;
@property (atomic) NSString *appVersion;
@property (atomic) NSString *appBuildNumber;
@property (atomic) NSString *instanceID;
@property (atomic) NSString *advertiserId;
@property (atomic) NSString *vendorId;
@@ -74,6 +75,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
@property (atomic) NSDateFormatter *rfc3339DateFormatter;
@property (atomic) CGFloat scale;
@property (atomic) NSURLSession *session;
@property (atomic) NSData *digicertCert;
@property (atomic) NSData *geoTrustCert;
@@ -111,13 +113,13 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
if (self) {
// Put Settings bundle into memory
NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
if(!settingsBundle) {
NSString *appSettingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
if(!appSettingsBundle) {
NSLog(@"Could not find Settings.bundle");
} else {
// Dynamic Settings.bundle loading based on:
// http://stackoverflow.com/questions/510216/can-you-make-the-settings-in-settings-bundle-default-even-if-you-dont-open-the
NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Root.plist"]];
NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[appSettingsBundle stringByAppendingPathComponent:@"Root.plist"]];
NSArray *preferences = [settings objectForKey:@"PreferenceSpecifiers"];
NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]];
for(NSDictionary *prefSpecification in preferences) {
@@ -140,18 +142,17 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
// Load Local Copy of Server's Public Key
NSString *cerPath = nil;
NSArray *bundles = [NSBundle allFrameworks];
for (int lc = 0; lc < bundles.count; lc++) {
NSBundle *b = [bundles objectAtIndex:lc];
cerPath = [[NSBundle mainBundle] pathForResource:@"api_mapbox_com-geotrust" ofType:@"der"];
if (cerPath != nil) {
break;
}
}
cerPath = [[NSBundle bundleForClass:[MGLMapboxEvents class]] pathForResource:@"api_mapbox_com-geotrust" ofType:@"der"];
if (cerPath != nil) {
_geoTrustCert = [NSData dataWithContentsOfFile:cerPath];
}
cerPath = nil;
cerPath = [[NSBundle bundleForClass:[MGLMapboxEvents class]] pathForResource:@"api_mapbox_com-digicert" ofType:@"der"];
if (cerPath != nil) {
_digicertCert = [NSData dataWithContentsOfFile:cerPath];
}
// Events Control
_eventQueue = [[NSMutableArray alloc] init];
_flushAt = 20;
@@ -254,6 +255,13 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
[MGLMapboxEvents sharedManager].appVersion = appVersion;
}
// Must be called from the main thread.
//
+ (void) setAppBuildNumber:(NSString *)appBuildNumber {
assert([[NSThread currentThread] isMainThread]);
[MGLMapboxEvents sharedManager].appBuildNumber = appBuildNumber;
}
// Must be called from the main thread.
//
+ (void) pauseMetricsCollection {
@@ -292,6 +300,9 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
__weak MGLMapboxEvents *weakSelf = self;
dispatch_async(_serialQueue, ^{
MGLMapboxEvents *strongSelf = weakSelf;
if ( ! strongSelf) return;
// Opt Out Checking When Built
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"mapbox_metrics_enabled_preference"]) {
[_eventQueue removeAllObjects];
@@ -315,35 +326,35 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
// mapbox-events stock attributes
[evt setObject:event forKey:@"event"];
[evt setObject:@(1) forKey:@"version"];
[evt setObject:[weakSelf.rfc3339DateFormatter stringFromDate:[NSDate date]] forKey:@"created"];
[evt setObject:weakSelf.instanceID forKey:@"instance"];
[evt setObject:weakSelf.advertiserId forKey:@"advertiserId"];
[evt setObject:weakSelf.vendorId forKey:@"vendorId"];
[evt setObject:weakSelf.appBundleId forKeyedSubscript:@"appBundleId"];
[evt setObject:[strongSelf.rfc3339DateFormatter stringFromDate:[NSDate date]] forKey:@"created"];
[evt setObject:strongSelf.instanceID forKey:@"instance"];
[evt setObject:strongSelf.advertiserId forKey:@"advertiserId"];
[evt setObject:strongSelf.vendorId forKey:@"vendorId"];
[evt setObject:strongSelf.appBundleId forKeyedSubscript:@"appBundleId"];
// mapbox-events-ios stock attributes
[evt setValue:weakSelf.model forKey:@"model"];
[evt setValue:weakSelf.iOSVersion forKey:@"operatingSystem"];
[evt setValue:[weakSelf getDeviceOrientation] forKey:@"orientation"];
[evt setValue:strongSelf.model forKey:@"model"];
[evt setValue:strongSelf.iOSVersion forKey:@"operatingSystem"];
[evt setValue:[strongSelf getDeviceOrientation] forKey:@"orientation"];
[evt setValue:@((int)(100 * [UIDevice currentDevice].batteryLevel)) forKey:@"batteryLevel"];
[evt setValue:@(weakSelf.scale) forKey:@"resolution"];
[evt setValue:weakSelf.carrier forKey:@"carrier"];
[evt setValue:@(strongSelf.scale) forKey:@"resolution"];
[evt setValue:strongSelf.carrier forKey:@"carrier"];
NSString *cell = [weakSelf getCurrentCellularNetworkConnectionType];
NSString *cell = [strongSelf getCurrentCellularNetworkConnectionType];
if (cell) {
[evt setValue:cell forKey:@"cellularNetworkType"];
} else {
[evt setObject:[NSNull null] forKey:@"cellularNetworkType"];
}
NSString *wifi = [weakSelf getWifiNetworkName];
NSString *wifi = [strongSelf getWifiNetworkName];
if (wifi) {
[evt setValue:wifi forKey:@"wifi"];
} else {
[evt setObject:[NSNull null] forKey:@"wifi"];
}
[evt setValue:@([weakSelf getContentSizeScale]) forKey:@"accessibilityFontScale"];
[evt setValue:@([strongSelf getContentSizeScale]) forKey:@"accessibilityFontScale"];
// Make Immutable Version
NSDictionary *finalEvent = [NSDictionary dictionaryWithDictionary:evt];
@@ -352,12 +363,12 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
[_eventQueue addObject:finalEvent];
// Has Flush Limit Been Reached?
if (_eventQueue.count >= weakSelf.flushAt) {
[weakSelf flush];
if (_eventQueue.count >= strongSelf.flushAt) {
[strongSelf flush];
}
// Reset Timer (Initial Starting of Timer after first event is pushed)
[weakSelf startTimer];
[strongSelf startTimer];
});
}
@@ -375,10 +386,13 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
__weak MGLMapboxEvents *weakSelf = self;
dispatch_async(_serialQueue, ^{
MGLMapboxEvents *strongSelf = weakSelf;
if ( ! strongSelf) return;
__block NSArray *events;
NSUInteger upper = weakSelf.flushAt;
if (weakSelf.flushAt > [_eventQueue count]) {
NSUInteger upper = strongSelf.flushAt;
if (strongSelf.flushAt > [_eventQueue count]) {
if ([_eventQueue count] == 0) {
return;
}
@@ -393,7 +407,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
[_eventQueue removeObjectsInRange:theRange];
// Send Array of Events to Server
[weakSelf postEvents:events];
[strongSelf postEvents:events];
});
}
@@ -456,8 +470,8 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
// Can be called from any thread.
//
- (NSString *) getUserAgent {
if (self.appName != nil && self.appVersion != nil && ([self.userAgent rangeOfString:self.appName].location == NSNotFound)) {
self.userAgent = [NSString stringWithFormat:@"%@/%@ %@", self.appName, self.appVersion, self.userAgent];
if (self.appName != nil && self.appVersion != nil && self.appBuildNumber != nil && ([self.userAgent rangeOfString:self.appName].location == NSNotFound)) {
self.userAgent = [NSString stringWithFormat:@"%@/%@-%@ %@", self.appName, self.appVersion, self.appBuildNumber, self.userAgent];
}
return self.userAgent;
}
@@ -680,6 +694,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
long numKeys = SecTrustGetCertificateCount(serverTrust);
BOOL found = false;
// Try GeoTrust Cert First
for (int lc = 0; lc < numKeys; lc++) {
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, lc);
NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
@@ -694,8 +709,24 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
}
if (!found) {
// The certificate wasn't found in the certificate chain; cancel the connection
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
// Fallback to Digicert Cert
for (int lc = 0; lc < numKeys; lc++) {
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, lc);
NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
// Compare Remote Key With Local Version
if ([remoteCertificateData isEqualToData:_digicertCert]) {
// Found the certificate; continue connecting
completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
found = true;
break;
}
}
if (!found) {
// The certificate wasn't found in GeoTrust nor Digicert. Cancel the connection.
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
}
}
}
else

View File

@@ -30,6 +30,7 @@ const CGFloat MGLTrackingDotRingWidth = 24.0;
self.annotation.mapView = mapView;
_mapView = mapView;
[self setupLayers];
self.accessibilityLabel = @"User location";
}
return self;
}

Binary file not shown.

View File

@@ -13,9 +13,9 @@ else:
if sys.argv[2] == sys.argv[3]:
tag = [0, 0, 0]
else:
ver = re.sub("[^0-9.]", "", sys.argv[2])
ver = re.sub("[^0-9.]", "", sys.argv[2])
tag = map(int, ver.split('.'))
rev = sys.argv[3][0:8]
rev = sys.argv[3][0:8]
def mkdir_p(path):

View File

@@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -e
set -o pipefail
set -u
ls $KIF_SCREENSHOTS/
REPO_NAME=$(basename $TRAVIS_REPO_SLUG)
aws s3 cp $KIF_SCREENSHOTS/ s3://mapbox/$REPO_NAME/ios/tests/$TRAVIS_JOB_NUMBER/ --acl public-read --recursive > /dev/null
echo http://mapbox.s3.amazonaws.com/$REPO_NAME/ios/tests/$TRAVIS_JOB_NUMBER/index.html

View File

@@ -31,11 +31,12 @@ step "Creating build files..."
export MASON_PLATFORM=ios
export BUILDTYPE=${BUILDTYPE:-Release}
export HOST=ios
make Xcode/mbgl
make Xcode/ios
step "Building iOS targets..."
step "Building iOS device targets..."
xcodebuild -sdk iphoneos${IOS_SDK_VERSION} \
ARCHS="arm64 armv7 armv7s" \
ONLY_ACTIVE_ARCH=NO \
-project ./build/ios/mbgl.xcodeproj \
-configuration ${BUILDTYPE} \
-target everything \
@@ -45,6 +46,7 @@ xcodebuild -sdk iphoneos${IOS_SDK_VERSION} \
step "Building iOS Simulator targets..."
xcodebuild -sdk iphonesimulator${IOS_SDK_VERSION} \
ARCHS="x86_64 i386" \
ONLY_ACTIVE_ARCH=NO \
-project ./build/ios/mbgl.xcodeproj \
-configuration ${BUILDTYPE} \
-target everything \

16
scripts/test_ios.sh Executable file
View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -e
set -o pipefail
set -u
xcodebuild \
-project ./test/ios/ios-tests.xcodeproj \
-scheme 'Mapbox GL Tests' \
-sdk iphonesimulator \
-destination 'platform=iOS Simulator,name=iPhone 5s,OS=7.1' \
-destination 'platform=iOS Simulator,name=iPhone 5s,OS=latest' \
-destination 'platform=iOS Simulator,name=iPad 2,OS=7.1' \
-destination 'platform=iOS Simulator,name=iPad 2,OS=latest' \
test \
| xcpretty

View File

@@ -48,15 +48,24 @@ elif [[ ${TRAVIS_OS_NAME} == "osx" && ${MASON_PLATFORM} == "osx" ]]; then
elif [[ ${TRAVIS_OS_NAME} == "osx" && ${MASON_PLATFORM} == "ios" ]]; then
#
# build & package iOS
#
mapbox_time "package_ios"
make ipackage
#
# conditionally deploy iOS build
# conditionally publish or test
#
if [[ -n "$PUBLISH_TAG" ]]; then
#
# build & package iOS
#
mapbox_time "package_ios"
make ipackage
#
# publish iOS build
#
mapbox_time "deploy_ios"
./scripts/publish_ios.sh "$PUBLISH_VERSION"
else
#
# build & test iOS
#
mapbox_time "run_ios_tests"
make itest
fi
fi

View File

@@ -14,8 +14,3 @@ void LineElementsBuffer::add(element_type a, element_type b) {
elements[0] = a;
elements[1] = b;
}
void PointElementsBuffer::add(element_type a) {
uint16_t *data = static_cast<element_type *>(addElement());
data[0] = a;
}

View File

@@ -44,16 +44,6 @@ public:
void add(element_type a, element_type b);
};
class PointElementsBuffer : public Buffer<
2, // bytes per point (1 unsigned short)
GL_ELEMENT_ARRAY_BUFFER
> {
public:
typedef uint16_t element_type;
void add(element_type a);
};
}
#endif

View File

@@ -245,7 +245,7 @@ TileData::State Source::addTile(Map &map, Worker &worker,
}
if (!new_tile.data) {
new_tile.data = cache.get(id.to_uint64());
new_tile.data = cache.get(normalized_id.to_uint64());
}
if (!new_tile.data) {
@@ -418,7 +418,7 @@ void Source::update(Map &map,
if (!obsolete) {
retain_data.insert(tile.data->id);
} else if (type != SourceType::Raster && tile.data->ready()) {
tileCache.add(tile.id.to_uint64(), tile.data);
tileCache.add(tile.id.normalized().to_uint64(), tile.data);
}
return obsolete;
});
@@ -432,7 +432,7 @@ void Source::update(Map &map,
bool obsolete = retain_data.find(tile->id) == retain_data.end();
if (obsolete) {
if (!tileCache.has(tile->id.to_uint64())) {
if (!tileCache.has(tile->id.normalized().to_uint64())) {
tile->cancel();
}
return true;

View File

@@ -20,11 +20,16 @@ void TileCache::setSize(size_t size_) {
void TileCache::add(uint64_t key, std::shared_ptr<TileData> data) {
assert(tiles.find(key) == tiles.end());
// insert new or query existing data
if (tiles.emplace(key, data).second) {
// remove existing data key
orderedKeys.remove(key);
}
tiles.emplace(key, data);
// (re-)insert data key as newest
orderedKeys.push_back(key);
// purge oldest key/data if necessary
if (orderedKeys.size() > size) {
get(orderedKeys.front());
}

View File

@@ -172,8 +172,7 @@ std::unique_ptr<Bucket> TileParser::createFillBucket(const GeometryTileLayer& la
std::unique_ptr<Bucket> TileParser::createLineBucket(const GeometryTileLayer& layer,
const StyleBucket& bucket_desc) {
auto bucket = util::make_unique<LineBucket>(tile.lineVertexBuffer,
tile.triangleElementsBuffer,
tile.pointElementsBuffer);
tile.triangleElementsBuffer);
const float z = tile.id.z;
auto& layout = bucket->layout;

View File

@@ -50,7 +50,6 @@ protected:
TriangleElementsBuffer triangleElementsBuffer;
LineElementsBuffer lineElementsBuffer;
PointElementsBuffer pointElementsBuffer;
// Holds the buckets of this tile.
// They contain the location offsets in the buffers stored above

View File

@@ -8,34 +8,25 @@
#include <mbgl/util/std.hpp>
#include <mbgl/platform/gl.hpp>
#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
#ifndef BUFFER_OFFSET
#define BUFFER_OFFSET(i) ((char*)nullptr + (i))
#endif
#include <cassert>
using namespace mbgl;
LineBucket::LineBucket(LineVertexBuffer &vertexBuffer_,
TriangleElementsBuffer &triangleElementsBuffer_,
PointElementsBuffer &pointElementsBuffer_)
LineBucket::LineBucket(LineVertexBuffer& vertexBuffer_,
TriangleElementsBuffer& triangleElementsBuffer_)
: vertexBuffer(vertexBuffer_),
triangleElementsBuffer(triangleElementsBuffer_),
pointElementsBuffer(pointElementsBuffer_),
vertex_start(vertexBuffer_.index()),
triangle_elements_start(triangleElementsBuffer_.index()),
point_elements_start(pointElementsBuffer_.index()) {
}
triangle_elements_start(triangleElementsBuffer_.index()){};
LineBucket::~LineBucket() {
// Do not remove. header file only contains forward definitions to unique pointers.
}
struct TriangleElement {
TriangleElement(uint16_t a_, uint16_t b_, uint16_t c_) : a(a_), b(b_), c(c_) {}
uint16_t a, b, c;
};
typedef uint16_t PointElement;
void LineBucket::addGeometry(const GeometryCollection& geometryCollection) {
for (auto& line : geometryCollection) {
addGeometry(line);
@@ -43,366 +34,365 @@ void LineBucket::addGeometry(const GeometryCollection& geometryCollection) {
}
void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
// TODO: use roundLimit
// const float roundLimit = geometry.round_limit;
const auto len = [&vertices] {
auto l = vertices.size();
// If the line has duplicate vertices at the end, adjust length to remove them.
while (l > 2 && vertices[l - 1] == vertices[l - 2]) {
l--;
}
return l;
}();
if (vertices.size() < 2) {
if (len < 2) {
// fprintf(stderr, "a line must have at least two vertices\n");
return;
}
Coordinate firstVertex = vertices.front();
Coordinate lastVertex = vertices.back();
bool closed = firstVertex.x == lastVertex.x && firstVertex.y == lastVertex.y;
const float miterLimit = layout.join == JoinType::Bevel ? 1.05f : layout.miter_limit;
if (vertices.size() == 2 && closed) {
const Coordinate firstVertex = vertices.front();
const Coordinate lastVertex = vertices[len - 1];
const bool closed = firstVertex == lastVertex;
if (len == 2 && closed) {
// fprintf(stderr, "a line may not have coincident points\n");
return;
}
CapType beginCap = layout.cap;
CapType endCap = closed ? CapType::Butt : layout.cap;
JoinType currentJoin = JoinType::Miter;
Coordinate currentVertex = Coordinate::null(),
prevVertex = Coordinate::null(),
nextVertex = Coordinate::null();
vec2<double> prevNormal = vec2<double>::null(),
nextNormal = vec2<double>::null();
int32_t e1 = -1, e2 = -1, e3 = -1;
const CapType beginCap = layout.cap;
const CapType endCap = closed ? CapType::Butt : layout.cap;
int8_t flip = 1;
double distance = 0;
bool startOfLine = true;
Coordinate currentVertex = Coordinate::null(), prevVertex = Coordinate::null(),
nextVertex = Coordinate::null();
vec2<double> prevNormal = vec2<double>::null(), nextNormal = vec2<double>::null();
// the last three vertices added
e1 = e2 = e3 = -1;
if (closed) {
currentVertex = vertices[vertices.size() - 2];
nextNormal = util::normal<double>(currentVertex, lastVertex);
currentVertex = vertices[len - 2];
nextNormal = util::perp(util::unit(vec2<double>(firstVertex - currentVertex)));
}
int32_t start_vertex = (int32_t)vertexBuffer.index();
const int32_t startVertex = (int32_t)vertexBuffer.index();
std::vector<TriangleElement> triangleStore;
std::vector<TriangleElement> triangle_store;
std::vector<PointElement> point_store;
for (size_t i = 0; i < vertices.size(); ++i) {
if (nextNormal) prevNormal = { -nextNormal.x, -nextNormal.y };
if (currentVertex) prevVertex = currentVertex;
currentVertex = vertices[i];
currentJoin = layout.join;
if (prevVertex) distance += util::dist<double>(currentVertex, prevVertex);
// Find the next vertex.
if (i + 1 < vertices.size()) {
for (size_t i = 0; i < len; ++i) {
if (closed && i == len - 1) {
// if the line is closed, we treat the last vertex like the first
nextVertex = vertices[i];
} else if (i + 1 < len) {
// just the next vertex
nextVertex = vertices[i + 1];
} else {
// there is no next vertex
nextVertex = Coordinate::null();
}
// If the line is closed, we treat the last vertex like the first vertex.
if (!nextVertex && closed) {
nextVertex = vertices[1];
// if two consecutive vertices exist, skip the current one
if (nextVertex && vertices[i] == nextVertex) {
continue;
}
if (nextVertex) {
// if two consecutive vertices exist, skip one
if (currentVertex.x == nextVertex.x && currentVertex.y == nextVertex.y) continue;
if (nextNormal) {
prevNormal = nextNormal;
}
if (currentVertex) {
prevVertex = currentVertex;
}
currentVertex = vertices[i];
// Calculate how far along the line the currentVertex is
if (prevVertex)
distance += util::dist<double>(currentVertex, prevVertex);
// Calculate the normal towards the next vertex in this line. In case
// there is no next vertex, pretend that the line is continuing straight,
// meaning that we are just reversing the previous normal
if (nextVertex) {
nextNormal = util::normal<double>(currentVertex, nextVertex);
} else {
nextNormal = { -prevNormal.x, -prevNormal.y };
}
// meaning that we are just using the previous normal.
nextNormal = nextVertex ? util::perp(util::unit(vec2<double>(nextVertex - currentVertex)))
: prevNormal;
// If we still don't have a previous normal, this is the beginning of a
// non-closed line, so we're doing a straight "join".
if (!prevNormal) {
prevNormal = { -nextNormal.x, -nextNormal.y };
prevNormal = nextNormal;
}
// Determine the normal of the join extrusion. It is the angle bisector
// of the segments between the previous line and the next line.
vec2<double> joinNormal = {
prevNormal.x + nextNormal.x,
prevNormal.y + nextNormal.y
};
vec2<double> joinNormal = util::unit(prevNormal + nextNormal);
// Cross product yields 0..1 depending on whether they are parallel
// or perpendicular.
double joinAngularity = nextNormal.x * joinNormal.y - nextNormal.y * joinNormal.x;
joinNormal.x /= joinAngularity;
joinNormal.y /= joinAngularity;
double roundness = std::fmax(std::abs(joinNormal.x), std::abs(joinNormal.y));
/* joinNormal prevNormal
* ↖ ↑
* .________. prevVertex
* |
* nextNormal ← | currentVertex
* |
* nextVertex !
*
*/
// Calculate the length of the miter (the ratio of the miter to the width).
// Find the cosine of the angle between the next and join normals
// using dot product. The inverse of that is the miter length.
const float cosHalfAngle = joinNormal.x * nextNormal.x + joinNormal.y * nextNormal.y;
const float miterLength = 1 / cosHalfAngle;
// Switch to miter joins if the angle is very low.
if (currentJoin != JoinType::Miter) {
if (std::fabs(joinAngularity) < 0.5 && roundness < layout.miter_limit) {
// The join if a middle vertex, otherwise the cap
const bool middleVertex = prevVertex && nextVertex;
JoinType currentJoin = layout.join;
const CapType currentCap = nextVertex ? beginCap : endCap;
if (middleVertex) {
if (currentJoin == JoinType::Round && miterLength < layout.round_limit) {
currentJoin = JoinType::Miter;
}
}
// Add offset square begin cap.
if (!prevVertex && beginCap == CapType::Square) {
// Add first vertex
e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
flip * (prevNormal.x + prevNormal.y), flip * (-prevNormal.x + prevNormal.y), // extrude normal
0, 0, distance) - start_vertex; // texture normal
if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
e1 = e2; e2 = e3;
// Add second vertex
e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
flip * (prevNormal.x - prevNormal.y), flip * (prevNormal.x + prevNormal.y), // extrude normal
0, 1, distance) - start_vertex; // texture normal
if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
e1 = e2; e2 = e3;
}
// Add offset square end cap.
else if (!nextVertex && endCap == CapType::Square) {
// Add first vertex
e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
nextNormal.x - flip * nextNormal.y, flip * nextNormal.x + nextNormal.y, // extrude normal
0, 0, distance) - start_vertex; // texture normal
if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
e1 = e2; e2 = e3;
// Add second vertex
e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
nextNormal.x + flip * nextNormal.y, -flip * nextNormal.x + nextNormal.y, // extrude normal
0, 1, distance) - start_vertex; // texture normal
if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
e1 = e2; e2 = e3;
}
else if (currentJoin == JoinType::Miter) {
// MITER JOIN
if (std::fabs(joinAngularity) < 0.01) {
// The two normals are almost parallel.
joinNormal.x = -nextNormal.y;
joinNormal.y = nextNormal.x;
} else if (roundness > layout.miter_limit) {
// If the miter grows too large, flip the direction to make a
// bevel join.
joinNormal.x = (prevNormal.x - nextNormal.x) / joinAngularity;
joinNormal.y = (prevNormal.y - nextNormal.y) / joinAngularity;
if (currentJoin == JoinType::Miter && miterLength > miterLimit) {
currentJoin = JoinType::Bevel;
}
if (roundness > layout.miter_limit) {
flip = -flip;
}
// Add first vertex
e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
flip * joinNormal.x, flip * joinNormal.y, // extrude normal
0, 0, distance) - start_vertex; // texture normal
if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
e1 = e2; e2 = e3;
// Add second vertex
e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
-flip * joinNormal.x, -flip * joinNormal.y, // extrude normal
0, 1, distance) - start_vertex; // texture normal
if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
e1 = e2; e2 = e3;
if ((!prevVertex && beginCap == CapType::Round) ||
(!nextVertex && endCap == CapType::Round)) {
point_store.emplace_back(e1);
}
}
else {
// Close up the previous line
// Add first vertex
e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
flip * prevNormal.y, -flip * prevNormal.x, // extrude normal
0, 0, distance) - start_vertex; // texture normal
if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
e1 = e2; e2 = e3;
// Add second vertex.
e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
-flip * prevNormal.y, flip * prevNormal.x, // extrude normal
0, 1, distance) - start_vertex; // texture normal
if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
e1 = e2; e2 = e3;
prevNormal = { -nextNormal.x, -nextNormal.y };
flip = 1;
// begin/end caps
if ((!prevVertex && beginCap == CapType::Round) ||
(!nextVertex && endCap == CapType::Round)) {
point_store.emplace_back(e1);
}
if (currentJoin == JoinType::Round) {
if (prevVertex && nextVertex && (!closed || i > 0)) {
point_store.emplace_back(e1);
if (currentJoin == JoinType::Bevel) {
// The maximum extrude length is 128 / 63 = 2 times the width of the line
// so if miterLength >= 2 we need to draw a different type of bevel where.
if (miterLength > 2) {
currentJoin = JoinType::FlipBevel;
}
// Reset the previous vertices so that we don't accidentally create
// any triangles.
e1 = -1; e2 = -1; e3 = -1;
// If the miterLength is really small and the line bevel wouldn't be visible,
// just draw a miter join to save a triangle.
if (miterLength < miterLimit) {
currentJoin = JoinType::Miter;
}
}
}
if (middleVertex && currentJoin == JoinType::Miter) {
joinNormal = joinNormal * miterLength;
addCurrentVertex(currentVertex, flip, distance, joinNormal, 0, 0, false, startVertex,
triangleStore);
} else if (middleVertex && currentJoin == JoinType::FlipBevel) {
// miter is too big, flip the direction to make a beveled join
if (miterLength > 100) {
// Almost parallel lines
joinNormal = nextNormal;
} else {
const float bevelLength = miterLength * util::mag(prevNormal + nextNormal) /
util::mag(prevNormal - nextNormal);
joinNormal = util::perp(joinNormal) * bevelLength;
}
// Start the new quad.
// Add first vertex
e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
-flip * nextNormal.y, flip * nextNormal.x, // extrude normal
0, 0, distance) - start_vertex; // texture normal
addCurrentVertex(currentVertex, flip, distance, joinNormal, 0, 0, false, startVertex,
triangleStore);
flip = -flip;
if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
e1 = e2; e2 = e3;
} else if (middleVertex && currentJoin == JoinType::Bevel) {
const float dir = prevNormal.x * nextNormal.y - prevNormal.y * nextNormal.x;
const float offset = -std::sqrt(miterLength * miterLength - 1);
float offsetA;
float offsetB;
// Add second vertex
e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos
flip * nextNormal.y, -flip * nextNormal.x, // extrude normal
0, 1, distance) - start_vertex; // texture normal
if (flip * dir > 0) {
offsetB = 0;
offsetA = offset;
} else {
offsetA = 0;
offsetB = offset;
}
if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3);
e1 = e2; e2 = e3;
// Close previous segement with bevel
if (!startOfLine) {
addCurrentVertex(currentVertex, flip, distance, prevNormal, offsetA, offsetB, false,
startVertex, triangleStore);
}
// Start next segment
if (nextVertex) {
addCurrentVertex(currentVertex, flip, distance, nextNormal, -offsetA, -offsetB,
false, startVertex, triangleStore);
}
} else if (!middleVertex && currentCap == CapType::Butt) {
if (!startOfLine) {
// Close previous segment with a butt
addCurrentVertex(currentVertex, flip, distance, prevNormal, 0, 0, false,
startVertex, triangleStore);
}
// Start next segment with a butt
if (nextVertex) {
addCurrentVertex(currentVertex, flip, distance, nextNormal, 0, 0, false,
startVertex, triangleStore);
}
} else if (!middleVertex && currentCap == CapType::Square) {
if (!startOfLine) {
// Close previous segment with a square cap
addCurrentVertex(currentVertex, flip, distance, prevNormal, 1, 1, false,
startVertex, triangleStore);
// The segment is done. Unset vertices to disconnect segments.
e1 = e2 = -1;
flip = 1;
}
// Start next segment
if (nextVertex) {
addCurrentVertex(currentVertex, flip, distance, nextNormal, -1, -1, false,
startVertex, triangleStore);
}
} else if (middleVertex ? currentJoin == JoinType::Round : currentCap == CapType::Round) {
if (!startOfLine) {
// Close previous segment with a butt
addCurrentVertex(currentVertex, flip, distance, prevNormal, 0, 0, false,
startVertex, triangleStore);
// Add round cap or linejoin at end of segment
addCurrentVertex(currentVertex, flip, distance, prevNormal, 1, 1, true, startVertex,
triangleStore);
// The segment is done. Unset vertices to disconnect segments.
e1 = e2 = -1;
flip = 1;
} else if (beginCap == CapType::Round) {
// Add round cap before first segment
addCurrentVertex(currentVertex, flip, distance, nextNormal, -1, -1, true,
startVertex, triangleStore);
}
// Start next segment with a butt
if (nextVertex) {
addCurrentVertex(currentVertex, flip, distance, nextNormal, 0, 0, false,
startVertex, triangleStore);
}
}
startOfLine = false;
}
size_t end_vertex = vertexBuffer.index();
size_t vertex_count = end_vertex - start_vertex;
const size_t endVertex = vertexBuffer.index();
const size_t vertexCount = endVertex - startVertex;
// Store the triangle/line groups.
{
if (!triangleGroups.size() || (triangleGroups.back()->vertex_length + vertex_count > 65535)) {
if (!triangleGroups.size() ||
(triangleGroups.back()->vertex_length + vertexCount > 65535)) {
// Move to a new group because the old one can't hold the geometry.
triangleGroups.emplace_back(util::make_unique<triangle_group_type>());
triangleGroups.emplace_back(util::make_unique<TriangleGroup>());
}
assert(triangleGroups.back());
triangle_group_type& group = *triangleGroups.back();
for (const auto& triangle : triangle_store) {
triangleElementsBuffer.add(
group.vertex_length + triangle.a,
group.vertex_length + triangle.b,
group.vertex_length + triangle.c
);
auto& group = *triangleGroups.back();
for (const auto& triangle : triangleStore) {
triangleElementsBuffer.add(group.vertex_length + triangle.a,
group.vertex_length + triangle.b,
group.vertex_length + triangle.c);
}
group.vertex_length += vertex_count;
group.elements_length += triangle_store.size();
}
// Store the line join/cap groups.
{
if (!pointGroups.size() || (pointGroups.back()->vertex_length + vertex_count > 65535)) {
// Move to a new group because the old one can't hold the geometry.
pointGroups.emplace_back(util::make_unique<point_group_type>());
}
assert(pointGroups.back());
point_group_type& group = *pointGroups.back();
for (const auto point : point_store) {
pointElementsBuffer.add(group.vertex_length + point);
}
group.vertex_length += vertex_count;
group.elements_length += point_store.size();
group.vertex_length += vertexCount;
group.elements_length += triangleStore.size();
}
}
void LineBucket::render(Painter &painter, const StyleLayer &layer_desc, const TileID &id,
const mat4 &matrix) {
void LineBucket::addCurrentVertex(const Coordinate& currentVertex,
float flip,
double distance,
const vec2<double>& normal,
float endLeft,
float endRight,
bool round,
int32_t startVertex,
std::vector<TriangleElement>& triangleStore) {
int8_t tx = round ? 1 : 0;
vec2<double> extrude = normal * flip;
if (endLeft)
extrude = extrude - (util::perp(normal) * endLeft);
e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, extrude.x, extrude.y, tx, 0,
distance) -
startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
}
e1 = e2;
e2 = e3;
extrude = normal * (-flip);
if (endRight)
extrude = extrude - (util::perp(normal) * endRight);
e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, extrude.x, extrude.y, tx, 1,
distance) -
startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
}
e1 = e2;
e2 = e3;
}
void LineBucket::render(Painter& painter,
const StyleLayer& layer_desc,
const TileID& id,
const mat4& matrix) {
painter.renderLine(*this, layer_desc, id, matrix);
}
bool LineBucket::hasData() const {
return !triangleGroups.empty() || !pointGroups.empty();
}
bool LineBucket::hasPoints() const {
if (!pointGroups.empty()) {
for (const auto& group : pointGroups) {
assert(group);
if (group->elements_length) {
return true;
}
}
}
return false;
return !triangleGroups.empty();
}
void LineBucket::drawLines(LineShader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
char *elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize);
char* vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
char* elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize);
for (auto& group : triangleGroups) {
assert(group);
if (!group->elements_length) {
continue;
}
group->array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * triangleElementsBuffer.itemSize;
}
}
void LineBucket::drawLineSDF(LineSDFShader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
char *elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize);
char* vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
char* elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize);
for (auto& group : triangleGroups) {
assert(group);
if (!group->elements_length) {
continue;
}
group->array[2].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * triangleElementsBuffer.itemSize;
}
}
void LineBucket::drawLinePatterns(LinepatternShader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
char *elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize);
char* vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
char* elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize);
for (auto& group : triangleGroups) {
assert(group);
if (!group->elements_length) {
continue;
}
group->array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index));
MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * triangleElementsBuffer.itemSize;
}
}
void LineBucket::drawPoints(LinejoinShader& shader) {
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
char *elements_index = BUFFER_OFFSET(point_elements_start * pointElementsBuffer.itemSize);
for (auto& group : pointGroups) {
assert(group);
if (!group->elements_length) {
continue;
}
group->array[0].bind(shader, vertexBuffer, pointElementsBuffer, vertex_index);
MBGL_CHECK_ERROR(glDrawElements(GL_POINTS, group->elements_length, GL_UNSIGNED_SHORT, elements_index));
vertex_index += group->vertex_length * vertexBuffer.itemSize;
elements_index += group->elements_length * pointElementsBuffer.itemSize;
}
}

View File

@@ -18,18 +18,14 @@ class Style;
class LineVertexBuffer;
class TriangleElementsBuffer;
class LineShader;
class LinejoinShader;
class LineSDFShader;
class LinepatternShader;
class LineBucket : public Bucket {
typedef ElementGroup<3> triangle_group_type;
typedef ElementGroup<1> point_group_type;
using TriangleGroup = ElementGroup<3>;
public:
LineBucket(LineVertexBuffer &vertexBuffer,
TriangleElementsBuffer &triangleElementsBuffer,
PointElementsBuffer &pointElementsBuffer);
LineBucket(LineVertexBuffer &vertexBuffer, TriangleElementsBuffer &triangleElementsBuffer);
~LineBucket() override;
void render(Painter &painter, const StyleLayer &layer_desc, const TileID &id,
@@ -39,12 +35,18 @@ public:
void addGeometry(const GeometryCollection&);
void addGeometry(const std::vector<Coordinate>& line);
bool hasPoints() const;
void drawLines(LineShader& shader);
void drawLineSDF(LineSDFShader& shader);
void drawLinePatterns(LinepatternShader& shader);
void drawPoints(LinejoinShader& shader);
private:
struct TriangleElement {
TriangleElement(uint16_t a_, uint16_t b_, uint16_t c_) : a(a_), b(b_), c(c_) {}
uint16_t a, b, c;
};
void addCurrentVertex(const Coordinate& currentVertex, float flip, double distance,
const vec2<double>& normal, float endLeft, float endRight, bool round,
int32_t startVertex, std::vector<LineBucket::TriangleElement>& triangleStore);
public:
StyleLayoutLine layout;
@@ -52,14 +54,15 @@ public:
private:
LineVertexBuffer& vertexBuffer;
TriangleElementsBuffer& triangleElementsBuffer;
PointElementsBuffer& pointElementsBuffer;
const size_t vertex_start;
const size_t triangle_elements_start;
const size_t point_elements_start;
std::vector<std::unique_ptr<triangle_group_type>> triangleGroups;
std::vector<std::unique_ptr<point_group_type>> pointGroups;
int32_t e1;
int32_t e2;
int32_t e3;
std::vector<std::unique_ptr<TriangleGroup>> triangleGroups;
};
}

View File

@@ -62,7 +62,6 @@ void Painter::setup() {
assert(plainShader);
assert(outlineShader);
assert(lineShader);
assert(linejoinShader);
assert(linepatternShader);
assert(patternShader);
assert(rasterShader);
@@ -96,7 +95,6 @@ void Painter::setupShaders() {
if (!plainShader) plainShader = util::make_unique<PlainShader>();
if (!outlineShader) outlineShader = util::make_unique<OutlineShader>();
if (!lineShader) lineShader = util::make_unique<LineShader>();
if (!linejoinShader) linejoinShader = util::make_unique<LinejoinShader>();
if (!linesdfShader) linesdfShader = util::make_unique<LineSDFShader>();
if (!linepatternShader) linepatternShader = util::make_unique<LinepatternShader>();
if (!patternShader) patternShader = util::make_unique<PatternShader>();
@@ -112,7 +110,6 @@ void Painter::deleteShaders() {
plainShader = nullptr;
outlineShader = nullptr;
lineShader = nullptr;
linejoinShader = nullptr;
linepatternShader = nullptr;
patternShader = nullptr;
iconShader = nullptr;

View File

@@ -13,7 +13,6 @@
#include <mbgl/shader/outline_shader.hpp>
#include <mbgl/shader/pattern_shader.hpp>
#include <mbgl/shader/line_shader.hpp>
#include <mbgl/shader/linejoin_shader.hpp>
#include <mbgl/shader/linesdf_shader.hpp>
#include <mbgl/shader/linepattern_shader.hpp>
#include <mbgl/shader/icon_shader.hpp>
@@ -199,7 +198,6 @@ public:
std::unique_ptr<PlainShader> plainShader;
std::unique_ptr<OutlineShader> outlineShader;
std::unique_ptr<LineShader> lineShader;
std::unique_ptr<LinejoinShader> linejoinShader;
std::unique_ptr<LineSDFShader> linesdfShader;
std::unique_ptr<LinepatternShader> linepatternShader;
std::unique_ptr<PatternShader> patternShader;

View File

@@ -51,29 +51,6 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const
depthRange(strata, 1.0f);
// We're only drawing end caps + round line joins if the line is > 2px. Otherwise, they aren't visible anyway.
if (bucket.hasPoints() && outset > 1.0f) {
useProgram(linejoinShader->program);
linejoinShader->u_matrix = vtxMatrix;
linejoinShader->u_color = color;
linejoinShader->u_world = {{
state.getFramebufferWidth() * 0.5f,
state.getFramebufferHeight() * 0.5f
}};
linejoinShader->u_linewidth = {{
((outset - 0.25f) * state.getPixelRatio()),
((inset - 0.25f) * state.getPixelRatio())
}};
float pointSize = std::ceil(state.getPixelRatio() * outset * 2.0);
#if defined(GL_ES_VERSION_2_0)
linejoinShader->u_size = pointSize;
#else
MBGL_CHECK_ERROR(glPointSize(pointSize));
#endif
bucket.drawPoints(*linejoinShader);
}
if (properties.dash_array.from.size()) {
useProgram(linesdfShader->program);

View File

@@ -35,7 +35,7 @@ void Painter::renderSDF(SymbolBucket &bucket,
}
// If layerStyle.size > bucket.info.fontSize then labels may collide
float fontSize = std::fmin(styleProperties.size, bucketProperties.max_size);
float fontSize = styleProperties.size;
float fontScale = fontSize / sdfFontSize;
matrix::scale(exMatrix, exMatrix, fontScale, fontScale, 1.0f);

View File

@@ -183,7 +183,8 @@ void SymbolBucket::addFeatures(const GeometryTileLayer& layer,
if (feature.label.length()) {
shaping = fontStack->getShaping(
/* string */ feature.label,
/* maxWidth: ems */ layout.text.max_width * 24,
/* maxWidth: ems */ layout.placement != PlacementType::Line ?
layout.text.max_width * 24 : 0,
/* lineHeight: ems */ layout.text.line_height * 24,
/* horizontalAlign */ horizontalAlign,
/* verticalAlign */ verticalAlign,

View File

@@ -1,14 +0,0 @@
uniform vec4 u_color;
uniform vec2 u_linewidth;
varying vec2 v_pos;
void main() {
float dist = length(v_pos - gl_FragCoord.xy);
// Calculate the antialiasing fade factor. This is either when fading in
// the line in case of an offset line (v_linewidth.t) or when fading out
// (v_linewidth.s)
float alpha = clamp(min(dist - (u_linewidth.t - 1.0), u_linewidth.s - dist), 0.0, 1.0);
gl_FragColor = u_color * alpha;
}

View File

@@ -1,13 +0,0 @@
attribute vec2 a_pos;
uniform mat4 u_matrix;
uniform vec2 u_world;
uniform float u_size;
varying vec2 v_pos;
void main() {
gl_Position = u_matrix * vec4(floor(a_pos / 2.0), 0.0, 1.0);
v_pos = (gl_Position.xy + 1.0) * u_world;
gl_PointSize = u_size;
}

View File

@@ -1,22 +0,0 @@
#include <mbgl/shader/linejoin_shader.hpp>
#include <mbgl/shader/shaders.hpp>
#include <mbgl/platform/gl.hpp>
#include <cstdio>
using namespace mbgl;
LinejoinShader::LinejoinShader()
: Shader(
"linejoin",
shaders[LINEJOIN_SHADER].vertex,
shaders[LINEJOIN_SHADER].fragment
) {
a_pos = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_pos"));
}
void LinejoinShader::bind(char *offset) {
MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
// Note: We're referring to the vertices in a line array, which are 8 bytes long!
MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset));
}

View File

@@ -1,27 +0,0 @@
#ifndef MBGL_SHADER_SHADER_LINEJOIN
#define MBGL_SHADER_SHADER_LINEJOIN
#include <mbgl/shader/shader.hpp>
#include <mbgl/shader/uniform.hpp>
namespace mbgl {
class LinejoinShader : public Shader {
public:
LinejoinShader();
void bind(char *offset);
UniformMatrix<4> u_matrix = {"u_matrix", *this};
Uniform<std::array<float, 4>> u_color = {"u_color", *this};
Uniform<std::array<float, 2>> u_world = {"u_world", *this};
Uniform<std::array<float, 2>> u_linewidth = {"u_linewidth", *this};
Uniform<float> u_size = {"u_size", *this};
private:
int32_t a_pos = -1;
};
}
#endif

View File

@@ -22,7 +22,6 @@ const std::map<PropertyKey, PropertyValue> PropertyFallbackValue::properties = {
{ PropertyKey::LineBlur, defaultStyleProperties<LineProperties>().blur },
{ PropertyKey::IconOpacity, defaultStyleProperties<SymbolProperties>().icon.opacity },
{ PropertyKey::IconRotate, defaultStyleProperties<SymbolProperties>().icon.rotate },
{ PropertyKey::IconSize, defaultStyleProperties<SymbolProperties>().icon.size },
{ PropertyKey::IconColor, defaultStyleProperties<SymbolProperties>().icon.color },
{ PropertyKey::IconHaloColor, defaultStyleProperties<SymbolProperties>().icon.halo_color },

View File

@@ -194,7 +194,6 @@ void StyleLayer::applyStyleProperties<SymbolProperties>(const float z, const Tim
properties.set<SymbolProperties>();
SymbolProperties &symbol = properties.get<SymbolProperties>();
applyTransitionedStyleProperty(PropertyKey::IconOpacity, symbol.icon.opacity, z, now, zoomHistory);
applyTransitionedStyleProperty(PropertyKey::IconRotate, symbol.icon.rotate, z, now, zoomHistory);
applyTransitionedStyleProperty(PropertyKey::IconSize, symbol.icon.size, z, now, zoomHistory);
applyTransitionedStyleProperty(PropertyKey::IconColor, symbol.icon.color, z, now, zoomHistory);
applyTransitionedStyleProperty(PropertyKey::IconHaloColor, symbol.icon.halo_color, z, now, zoomHistory);

View File

@@ -811,7 +811,6 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) {
parseOptionalProperty<Function<float>>("icon-opacity", Key::IconOpacity, klass, value);
parseOptionalProperty<PropertyTransition>("icon-opacity-transition", Key::IconOpacity, klass, value);
parseOptionalProperty<Function<float>>("icon-rotate", Key::IconRotate, klass, value);
parseOptionalProperty<Function<float>>("icon-size", Key::IconSize, klass, value);
parseOptionalProperty<PropertyTransition>("icon-size-transition", Key::IconSize, klass, value);
parseOptionalProperty<Function<Color>>("icon-color", Key::IconColor, klass, value);

View File

@@ -51,7 +51,6 @@ struct SymbolProperties {
struct {
float opacity = 1.0f;
float rotate = 0.0f;
float size = 1.0f;
Color color = {{ 0, 0, 0, 1 }};
Color halo_color = {{ 0, 0, 0, 0 }};

View File

@@ -91,13 +91,15 @@ MBGL_DEFINE_ENUM_CLASS(CapTypeClass, CapType, {
enum class JoinType : uint8_t {
Miter,
Bevel,
Round
Round,
FlipBevel
};
MBGL_DEFINE_ENUM_CLASS(JoinTypeClass, JoinType, {
{ JoinType::Miter, "miter" },
{ JoinType::Bevel, "bevel" },
{ JoinType::Round, "round" },
{ JoinType::FlipBevel, "flipbevel" },
});
// -------------------------------------------------------------------------------------------------

View File

@@ -1,11 +1,12 @@
#import <UIKit/UIKit.h>
#import <KIF/KIF.h>
@class MGLMapView;
@class MGLTViewController, MGLMapView;
@interface KIFTestActor (MapboxGL)
@property (nonatomic, readonly) UIWindow *window;
@property (nonatomic, readonly) UIViewController *viewController;
@property (nonatomic, readonly) MGLTViewController *viewController;
@property (nonatomic, readonly) MGLMapView *mapView;
@property (nonatomic, readonly) UIView *compass;

View File

@@ -1,7 +1,8 @@
#import "KIFTestActor+MapboxGL.h"
#import "MapboxGL.h"
#import <KIF/UIApplication-KIFAdditions.h>
#import <KIF/UIAccessibilityElement-KIFAdditions.h>
#import "MGLMapView.h"
@implementation KIFTestActor (MapboxGL)
@@ -9,8 +10,8 @@
return [[UIApplication sharedApplication] statusBarWindow];
}
- (UIViewController *)viewController {
return (UIViewController *)[[tester.mapView nextResponder] nextResponder];
- (MGLTViewController *)viewController {
return (MGLTViewController *)[[tester.mapView nextResponder] nextResponder];
}
- (MGLMapView *)mapView {

View File

@@ -2,6 +2,6 @@
@interface MGLTAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic) UIWindow *window;
@end

View File

@@ -2,4 +2,7 @@
@interface MGLTViewController : UIViewController
- (void)insetMapView;
- (void)resetMapView;
@end

View File

@@ -1,18 +1,31 @@
#import "MGLTViewController.h"
#import "MGLMapView.h"
#import "MapboxGL.h"
@implementation MGLTViewController
{
MGLMapView *_mapView;
}
- (void)viewDidLoad
{
[super viewDidLoad];
MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds
_mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds
accessToken:@"pk.eyJ1IjoianVzdGluIiwiYSI6Ik9RX3RRQzAifQ.dmOg_BAp1ywuDZMM7YsXRg"];
mapView.viewControllerForLayoutGuides = self;
mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_mapView.viewControllerForLayoutGuides = self;
_mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:mapView];
[self.view addSubview:_mapView];
}
- (void)insetMapView
{
_mapView.frame = CGRectInset(_mapView.frame, 50, 50);
}
- (void)resetMapView
{
_mapView.frame = self.view.bounds;
}
@end

View File

@@ -1,5 +0,0 @@
#import <KIF/KIF.h>
@interface MapViewTests : KIFTestCase
@end

View File

@@ -1,9 +1,12 @@
#import "MapViewTests.h"
#import <KIF/KIF.h>
#import <KIF/KIFTestStepValidation.h>
#import "KIFTestActor+MapboxGL.h"
#import "MGLMapView.h"
@interface MapViewTests () <MGLMapViewDelegate>
#import "KIFTestActor+MapboxGL.h"
#import "MapboxGL.h"
#import "MGLTViewController.h"
@interface MapViewTests : KIFTestCase <MGLMapViewDelegate>
@end
@@ -11,120 +14,133 @@
- (void)beforeEach {
[system simulateDeviceRotationToOrientation:UIDeviceOrientationPortrait];
tester.mapView.viewControllerForLayoutGuides = tester.viewController;
[tester.viewController resetMapView];
tester.mapView.centerCoordinate = CLLocationCoordinate2DMake(38.913175, -77.032458);
tester.mapView.zoomLevel = 14;
tester.mapView.direction = 0;
tester.mapView.zoomEnabled = YES;
tester.mapView.scrollEnabled = YES;
tester.mapView.rotateEnabled = YES;
tester.viewController.navigationController.navigationBarHidden = YES;
tester.viewController.navigationController.toolbarHidden = YES;
tester.mapView.delegate = self;
}
- (void)testDirectionSet {
tester.mapView.direction = 270;
__KIFAssertEqual(tester.mapView.direction,
270,
@"setting direction should take effect");
XCTAssertEqual(tester.mapView.direction,
270,
@"setting direction should take effect");
[tester waitForTimeInterval:1];
__KIFAssertEqual(tester.compass.alpha,
1,
@"compass should be visible when map is rotated");
__KIFAssertEqualObjects([NSValue valueWithCGAffineTransform:tester.compass.transform],
[NSValue valueWithCGAffineTransform:CGAffineTransformMakeRotation(M_PI * 1.5)],
@"compass rotation should indicate map rotation");
XCTAssertEqual(tester.compass.alpha,
1,
@"compass should be visible when map is rotated");
XCTAssertEqualObjects([NSValue valueWithCGAffineTransform:tester.compass.transform],
[NSValue valueWithCGAffineTransform:CGAffineTransformMakeRotation(M_PI * 1.5)],
@"compass rotation should indicate map rotation");
}
- (void)testCompassTap {
tester.mapView.direction = 180;
__KIFAssertEqual(tester.mapView.direction,
180,
@"setting direction should take effect");
[tester waitForTimeInterval:1];
XCTAssertEqual(tester.mapView.direction,
180,
@"setting direction should take effect");
[tester.compass tap];
[tester waitForTimeInterval:1];
__KIFAssertEqual(tester.mapView.direction,
0,
@"tapping compass should reset map direction");
__KIFAssertEqual(tester.compass.alpha,
0,
@"compass should not be visible when map is unrotated");
__KIFAssertEqualObjects([NSValue valueWithCGAffineTransform:tester.compass.transform],
[NSValue valueWithCGAffineTransform:CGAffineTransformIdentity],
@"compass rotation should indicate map rotation");
XCTAssertEqual(tester.mapView.direction,
0,
@"tapping compass should reset map direction");
XCTAssertEqual(tester.compass.alpha,
0,
@"compass should not be visible when map is unrotated");
XCTAssertEqualObjects([NSValue valueWithCGAffineTransform:tester.compass.transform],
[NSValue valueWithCGAffineTransform:CGAffineTransformIdentity],
@"compass rotation should indicate map rotation");
}
- (void)testDirectionReset {
tester.mapView.direction = 100;
__KIFAssertEqual(tester.mapView.direction,
100,
@"setting direction should take effect");
tester.mapView.direction = 90;
XCTAssertEqual(tester.mapView.direction,
90,
@"setting direction should take effect");
[tester.mapView resetNorth];
[tester waitForTimeInterval:1];
__KIFAssertEqual(tester.mapView.direction,
0,
@"resetting north should reset map direction");
__KIFAssertEqual(tester.compass.alpha,
0,
@"compass should not be visible when map is unrotated");
__KIFAssertEqualObjects([NSValue valueWithCGAffineTransform:tester.compass.transform],
[NSValue valueWithCGAffineTransform:CGAffineTransformIdentity],
@"compass rotation should indicate map rotation");
XCTAssertEqual(tester.mapView.direction,
0,
@"resetting north should reset map direction");
XCTAssertEqual(tester.compass.alpha,
0,
@"compass should not be visible when map is unrotated");
XCTAssertEqualObjects([NSValue valueWithCGAffineTransform:tester.compass.transform],
[NSValue valueWithCGAffineTransform:CGAffineTransformIdentity],
@"compass rotation should indicate map rotation");
}
- (void)testZoom {
double zoom = tester.mapView.zoomLevel;
[tester.mapView zoomAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2,
[tester.mapView zoomAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2,
tester.mapView.bounds.size.height / 2)
distance:50
steps:10];
XCTAssertTrue(tester.mapView.zoomLevel > zoom,
@"zoom gesture should increase zoom level");
XCTAssertGreaterThan(tester.mapView.zoomLevel,
zoom,
@"zoom gesture should increase zoom level");
zoom = tester.mapView.zoomLevel;
[tester.mapView pinchAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2,
[tester.mapView pinchAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2,
tester.mapView.bounds.size.height / 2)
distance:50
steps:10];
XCTAssertTrue(tester.mapView.zoomLevel < zoom,
@"pinch gesture should decrease zoom level");
XCTAssertLessThan(tester.mapView.zoomLevel,
zoom,
@"pinch gesture should decrease zoom level");
}
- (void)testZoomDisabled {
tester.mapView.zoomEnabled = NO;
double zoom = tester.mapView.zoomLevel;
[tester.mapView zoomAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2,
[tester.mapView zoomAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2,
tester.mapView.bounds.size.height / 2)
distance:50
steps:10];
__KIFAssertEqual(tester.mapView.zoomLevel,
zoom,
@"disabling zoom gesture should disallow zooming");
XCTAssertEqual(tester.mapView.zoomLevel,
zoom,
@"disabling zoom gesture should disallow zooming");
[tester.mapView pinchAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2,
tester.mapView.bounds.size.height / 2)
[tester.mapView pinchAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2,
tester.mapView.bounds.size.height / 2)
distance:50
steps:10];
__KIFAssertEqual(tester.mapView.zoomLevel,
zoom,
@"disabling zoom gesture should disallow pinching");
XCTAssertEqual(tester.mapView.zoomLevel,
zoom,
@"disabling zoom gesture should disallow pinching");
}
- (void)testPan {
@@ -132,10 +148,13 @@
[tester.mapView dragFromPoint:CGPointMake(10, 10) toPoint:CGPointMake(300, 300) steps:10];
XCTAssertTrue(tester.mapView.centerCoordinate.latitude > centerCoordinate.latitude,
@"panning map down should increase center latitude");
XCTAssertTrue(tester.mapView.centerCoordinate.longitude < centerCoordinate.longitude,
@"panning map right should decrease center longitude");
XCTAssertGreaterThan(tester.mapView.centerCoordinate.latitude,
centerCoordinate.latitude,
@"panning map down should increase center latitude");
XCTAssertLessThan(tester.mapView.centerCoordinate.longitude,
centerCoordinate.longitude,
@"panning map right should decrease center longitude");
}
- (void)testPanDisabled {
@@ -144,42 +163,82 @@
[tester.mapView dragFromPoint:CGPointMake(10, 10) toPoint:CGPointMake(300, 300) steps:10];
__KIFAssertEqual(centerCoordinate.latitude,
tester.mapView.centerCoordinate.latitude,
@"disabling pan gesture should disallow vertical panning");
__KIFAssertEqual(centerCoordinate.longitude,
tester.mapView.centerCoordinate.longitude,
@"disabling pan gesture should disallow horizontal panning");
XCTAssertEqualWithAccuracy(centerCoordinate.latitude,
tester.mapView.centerCoordinate.latitude,
0.005,
@"disabling pan gesture should disallow vertical panning");
XCTAssertEqualWithAccuracy(centerCoordinate.longitude,
tester.mapView.centerCoordinate.longitude,
0.005,
@"disabling pan gesture should disallow horizontal panning");
}
- (void)testRotate {
CLLocationDirection startAngle = tester.mapView.direction;
XCTAssertNotEqual(startAngle,
45,
@"start angle must not be destination angle");
[tester.mapView twoFingerRotateAtPoint:tester.mapView.center angle:45];
XCTAssertGreaterThanOrEqual(fabs(tester.mapView.direction - startAngle),
20,
@"rotating map should change angle");
}
- (void)testRotateDisabled {
tester.mapView.rotateEnabled = NO;
CLLocationDirection startAngle = tester.mapView.direction;
XCTAssertNotEqual(startAngle,
45,
@"start angle must not be destination angle");
[tester.mapView twoFingerRotateAtPoint:tester.mapView.center angle:45];
XCTAssertEqualWithAccuracy(tester.mapView.direction,
startAngle,
0.005,
@"disabling rotation show disallow rotation gestures");
}
- (void)testCenterSet {
CLLocationCoordinate2D newCenterCoordinate = CLLocationCoordinate2DMake(45.23237263, -122.23287129);
XCTAssertNotEqual(tester.mapView.centerCoordinate.latitude,
newCenterCoordinate.latitude,
@"initial setup should have differing center latitude");
XCTAssertNotEqual(tester.mapView.centerCoordinate.longitude,
newCenterCoordinate.longitude,
@"initial setup should have differing center longitude");
[tester.mapView setCenterCoordinate:newCenterCoordinate];
tester.mapView.centerCoordinate = newCenterCoordinate;
XCTAssertTrue(tester.mapView.centerCoordinate.latitude == newCenterCoordinate.latitude,
@"setting center should change latitude");
XCTAssertTrue(tester.mapView.centerCoordinate.longitude == newCenterCoordinate.longitude,
@"setting center should change longitude");
XCTAssertEqual(tester.mapView.centerCoordinate.latitude,
newCenterCoordinate.latitude,
@"setting center should change latitude");
XCTAssertEqual(tester.mapView.centerCoordinate.longitude,
newCenterCoordinate.longitude,
@"setting center should change longitude");
}
- (void)testZoomSet {
double newZoom = 11.65;
XCTAssertNotEqual(tester.mapView.zoomLevel,
newZoom,
@"initial setup should have differing zoom");
tester.mapView.zoomLevel = newZoom;
__KIFAssertEqual(tester.mapView.zoomLevel,
newZoom,
@"setting zoom should take effect");
XCTAssertEqualWithAccuracy(tester.mapView.zoomLevel,
newZoom,
0.01,
@"setting zoom should take effect");
}
- (void)testTopLayoutGuide {
@@ -233,19 +292,41 @@
logoBugFrame = [logoBug.superview convertRect:logoBug.frame toView:nil];
toolbarFrame = [tester.window convertRect:toolbar.frame toView:nil];
XCTAssertFalse(CGRectIntersectsRect(logoBugFrame, toolbarFrame),
@"rotated device should not have logo buy under toolbar");
@"rotated device should not have logo bug under toolbar");
attributionButtonFrame = [attributionButton.superview convertRect:attributionButton.frame toView:nil];
XCTAssertFalse(CGRectIntersectsRect(attributionButtonFrame, toolbarFrame),
@"rotated device should not have attribution button under toolbar");
}
- (void)testInsetMapView {
[tester.viewController insetMapView];
[tester waitForAnimationsToFinish];
UIView *logoBug = (UIView *)[tester waitForViewWithAccessibilityLabel:@"Mapbox logo"];
UIView *attributionButton = (UIView *)[tester waitForViewWithAccessibilityLabel:@"Attribution info"];
CGRect mapViewFrame = [tester.mapView.superview convertRect:tester.mapView.frame toView:nil];
CGRect logoBugFrame = [logoBug.superview convertRect:logoBug.frame toView:nil];
XCTAssertTrue(CGRectIntersectsRect(logoBugFrame, mapViewFrame),
@"logo bug should lie inside shrunken map view");
CGRect attributionButtonFrame = [attributionButton.superview convertRect:attributionButton.frame toView:nil];
XCTAssertTrue(CGRectIntersectsRect(attributionButtonFrame, mapViewFrame),
@"attribution button should lie inside shrunken map view");
CGRect compassFrame = [tester.compass.superview convertRect:tester.compass.frame toView:nil];
XCTAssertTrue(CGRectIntersectsRect(compassFrame, mapViewFrame),
@"compass should lie inside shrunken map view");
}
- (void)testDelegateRegionWillChange {
__block NSUInteger unanimatedCount = 0;
__block NSUInteger animatedCount = 0;
__block NSUInteger unanimatedCount;
__block NSUInteger animatedCount;
[[NSNotificationCenter defaultCenter] addObserverForName:@"regionWillChangeAnimated"
object:tester.mapView
queue:[NSOperationQueue mainQueue]
queue:nil
usingBlock:^(NSNotification *note) {
if ([note.userInfo[@"animated"] boolValue]) {
animatedCount++;
@@ -254,35 +335,40 @@
}
}];
[tester waitForTimeInterval:1];
unanimatedCount = 0;
animatedCount = 0;
NSNotification *notification = [system waitForNotificationName:@"regionWillChangeAnimated"
object:tester.mapView
whileExecutingBlock:^{
tester.mapView.centerCoordinate = CLLocationCoordinate2DMake(0, 0);
}];
[tester waitForTimeInterval:1];
XCTAssertNotNil(notification,
@"regionWillChange delegate should produce a notification");
__KIFAssertEqual([notification.userInfo[@"animated"] boolValue],
NO,
@"regionWillChange delegate should not indicate animated change");
__KIFAssertEqual(unanimatedCount,
1,
@"regionWillChange delegate should indicate one unanimated change");
XCTAssertEqual([notification.userInfo[@"animated"] boolValue],
NO,
@"regionWillChange delegate should not indicate animated change");
XCTAssertEqual(unanimatedCount,
1,
@"regionWillChange delegate should indicate one unanimated change");
notification = [system waitForNotificationName:@"regionWillChangeAnimated"
object:tester.mapView
whileExecutingBlock:^{
[tester.mapView setCenterCoordinate:CLLocationCoordinate2DMake(45, 100) animated:YES];
}];
[tester waitForTimeInterval:1];
XCTAssertNotNil(notification,
@"regionWillChange delegate should produce a notification");
__KIFAssertEqual([notification.userInfo[@"animated"] boolValue],
YES,
@"regionWillChange delegate should indicate an animated change");
__KIFAssertEqual(animatedCount,
1,
@"regionWillChange delegate should indicate one animated change");
XCTAssertEqual([notification.userInfo[@"animated"] boolValue],
YES,
@"regionWillChange delegate should indicate an animated change");
XCTAssertEqual(animatedCount,
1,
@"regionWillChange delegate should indicate one animated change");
[[NSNotificationCenter defaultCenter] removeObserver:self
name:@"regionWillChangeAnimated"
@@ -296,11 +382,11 @@
}
- (void)testDelegateRegionDidChange {
__block NSUInteger unanimatedCount = 0;
__block NSUInteger animatedCount = 0;
__block NSUInteger unanimatedCount;
__block NSUInteger animatedCount;
[[NSNotificationCenter defaultCenter] addObserverForName:@"regionDidChangeAnimated"
object:tester.mapView
queue:[NSOperationQueue mainQueue]
queue:nil
usingBlock:^(NSNotification *note) {
if ([note.userInfo[@"animated"] boolValue]) {
animatedCount++;
@@ -309,35 +395,40 @@
}
}];
[tester waitForTimeInterval:1];
unanimatedCount = 0;
animatedCount = 0;
NSNotification *notification = [system waitForNotificationName:@"regionDidChangeAnimated"
object:tester.mapView
whileExecutingBlock:^{
tester.mapView.centerCoordinate = CLLocationCoordinate2DMake(0, 0);
}];
[tester waitForTimeInterval:1];
XCTAssertNotNil(notification,
@"regionDidChange delegate should produce a notification");
__KIFAssertEqual([notification.userInfo[@"animated"] boolValue],
NO,
@"regionDidChange delegate should not indicate animated change");
__KIFAssertEqual(unanimatedCount,
1,
@"regionDidChange delegate should indicate one unanimated change");
XCTAssertEqual([notification.userInfo[@"animated"] boolValue],
NO,
@"regionDidChange delegate should not indicate animated change");
XCTAssertEqual(unanimatedCount,
1,
@"regionDidChange delegate should indicate one unanimated change");
notification = [system waitForNotificationName:@"regionDidChangeAnimated"
object:tester.mapView
whileExecutingBlock:^{
[tester.mapView setCenterCoordinate:CLLocationCoordinate2DMake(45, 100) animated:YES];
}];
[tester waitForTimeInterval:1];
XCTAssertNotNil(notification,
@"regionDidChange delegate should produce a notification");
__KIFAssertEqual([notification.userInfo[@"animated"] boolValue],
YES,
@"regionDidChange delegate should indicate animated change");
__KIFAssertEqual(animatedCount,
1,
@"regionDidChange delegate should indicate one animated change");
XCTAssertEqual([notification.userInfo[@"animated"] boolValue],
YES,
@"regionDidChange delegate should indicate animated change");
XCTAssertEqual(animatedCount,
1,
@"regionDidChange delegate should indicate one animated change");
[[NSNotificationCenter defaultCenter] removeObserver:self
name:@"regionDidChangeAnimated"

View File

@@ -1,9 +0,0 @@
This is a harness app for integration testing of Mapbox GL Cocoa. It uses the static library build of Mapbox GL Cocoa in order to be entirely self-contained and not need the `mapbox-gl-native` upstream C++ project.
To run tests, either open the enclosed `ios-tests.xcodeproj` and run the tests or use `xcodebuild test` at the command line from this directory. For example:
```bash
xcodebuild -scheme 'Mapbox GL Tests' \
-destination 'platform=iOS Simulator,name=iPad,OS=7.1' \
test
```

View File

@@ -7,27 +7,24 @@
objects = {
/* Begin PBXBuildFile section */
DD043327196DB9BC00E6F39D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD043326196DB9BC00E6F39D /* Foundation.framework */; };
DD043329196DB9BC00E6F39D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD043328196DB9BC00E6F39D /* CoreGraphics.framework */; };
DD04332B196DB9BC00E6F39D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD04332A196DB9BC00E6F39D /* UIKit.framework */; };
DD043363196DBBD500E6F39D /* MGLTAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DD04335F196DBBD500E6F39D /* MGLTAppDelegate.m */; };
DD043364196DBBD500E6F39D /* MGLTViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DD043360196DBBD500E6F39D /* MGLTViewController.m */; };
DD043366196DBBE000E6F39D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DD043365196DBBE000E6F39D /* main.m */; };
DD1A9EA8199BEA0D007BC651 /* libc++.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DD1A9EA7199BEA0D007BC651 /* libc++.dylib */; };
DD61240819CCF06E006845B1 /* libMapboxGL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD61240619CCF06E006845B1 /* libMapboxGL.a */; };
DD61240919CCF06E006845B1 /* MapboxGL.bundle in Resources */ = {isa = PBXBuildFile; fileRef = DD61240719CCF06E006845B1 /* MapboxGL.bundle */; };
DD8A790D196DC0A900FAD883 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DD8A790C196DC0A900FAD883 /* libz.dylib */; };
DD8A790F196DC0AD00FAD883 /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD8A790E196DC0AD00FAD883 /* GLKit.framework */; };
DD8A7911196DC0BB00FAD883 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD8A7910196DC0BB00FAD883 /* CoreLocation.framework */; };
DD96917919F1C08400729E7D /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DD96917819F1C08400729E7D /* libsqlite3.dylib */; };
DD96918119F1C09200729E7D /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD96918019F1C09200729E7D /* SystemConfiguration.framework */; };
DDBD0154196DC3D70033959E /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDBD0153196DC3D70033959E /* XCTest.framework */; };
DDBD0155196DC3D70033959E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD043326196DB9BC00E6F39D /* Foundation.framework */; };
DDBD0156196DC3D70033959E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD04332A196DB9BC00E6F39D /* UIKit.framework */; };
DD0580E81ACB628200B112C9 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD0580E71ACB628200B112C9 /* IOKit.framework */; };
DD0581041ACB661200B112C9 /* Headers in Resources */ = {isa = PBXBuildFile; fileRef = DD0581031ACB661200B112C9 /* Headers */; };
DD0581061ACB661C00B112C9 /* MapboxGL.bundle in Resources */ = {isa = PBXBuildFile; fileRef = DD0581051ACB661C00B112C9 /* MapboxGL.bundle */; };
DD0581081ACB663200B112C9 /* libMapboxGL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD0581071ACB663200B112C9 /* libMapboxGL.a */; };
DD41CE091ACB5DBC00FA7979 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE081ACB5DBC00FA7979 /* CoreTelephony.framework */; };
DD41CE0B1ACB5DC400FA7979 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE0A1ACB5DC400FA7979 /* SystemConfiguration.framework */; };
DD41CE0D1ACB5DCB00FA7979 /* libc++.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE0C1ACB5DCB00FA7979 /* libc++.dylib */; };
DD41CE0F1ACB5DD000FA7979 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE0E1ACB5DD000FA7979 /* libsqlite3.dylib */; };
DD41CE111ACB5DD500FA7979 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE101ACB5DD500FA7979 /* libz.dylib */; };
DD41CE131ACB5DDA00FA7979 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE121ACB5DDA00FA7979 /* MobileCoreServices.framework */; };
DD41CE151ACB5DE000FA7979 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE141ACB5DE000FA7979 /* ImageIO.framework */; };
DD41CE171ACB5DE700FA7979 /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE161ACB5DE700FA7979 /* GLKit.framework */; };
DDBD016C196DC4740033959E /* MapViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DDBD0168196DC4740033959E /* MapViewTests.m */; };
DDBD016D196DC4740033959E /* KIFTestActor+MapboxGL.m in Sources */ = {isa = PBXBuildFile; fileRef = DDBD016A196DC4740033959E /* KIFTestActor+MapboxGL.m */; };
DDBD016E196DC4A10033959E /* libKIF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DDBD0144196DC3AE0033959E /* libKIF.a */; };
DDBD016F196DC4A90033959E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD043328196DB9BC00E6F39D /* CoreGraphics.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -77,35 +74,30 @@
/* Begin PBXFileReference section */
DD043323196DB9BC00E6F39D /* Mapbox GL Tests.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Mapbox GL Tests.app"; sourceTree = BUILT_PRODUCTS_DIR; };
DD043326196DB9BC00E6F39D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
DD043328196DB9BC00E6F39D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
DD04332A196DB9BC00E6F39D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
DD04335F196DBBD500E6F39D /* MGLTAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLTAppDelegate.m; sourceTree = SOURCE_ROOT; };
DD043360196DBBD500E6F39D /* MGLTViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLTViewController.m; sourceTree = SOURCE_ROOT; };
DD043361196DBBD500E6F39D /* MGLTViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLTViewController.h; sourceTree = SOURCE_ROOT; };
DD043362196DBBD500E6F39D /* MGLTAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLTAppDelegate.h; sourceTree = SOURCE_ROOT; };
DD043365196DBBE000E6F39D /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; };
DD043367196DBCC200E6F39D /* App-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "App-Info.plist"; sourceTree = SOURCE_ROOT; };
DD1A9EA7199BEA0D007BC651 /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "usr/lib/libc++.dylib"; sourceTree = SDKROOT; };
DD61240019CCF06E006845B1 /* MGLMapView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGLMapView.h; path = ../dist/static/Headers/MGLMapView.h; sourceTree = SOURCE_ROOT; };
DD61240119CCF06E006845B1 /* MGLStyleFunctionValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGLStyleFunctionValue.h; path = ../dist/static/Headers/MGLStyleFunctionValue.h; sourceTree = SOURCE_ROOT; };
DD61240219CCF06E006845B1 /* MGLTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGLTypes.h; path = ../dist/static/Headers/MGLTypes.h; sourceTree = SOURCE_ROOT; };
DD61240319CCF06E006845B1 /* NSArray+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSArray+MGLAdditions.h"; path = "../dist/static/Headers/NSArray+MGLAdditions.h"; sourceTree = SOURCE_ROOT; };
DD61240419CCF06E006845B1 /* NSDictionary+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+MGLAdditions.h"; path = "../dist/static/Headers/NSDictionary+MGLAdditions.h"; sourceTree = SOURCE_ROOT; };
DD61240519CCF06E006845B1 /* UIColor+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIColor+MGLAdditions.h"; path = "../dist/static/Headers/UIColor+MGLAdditions.h"; sourceTree = SOURCE_ROOT; };
DD61240619CCF06E006845B1 /* libMapboxGL.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libMapboxGL.a; path = ../dist/static/libMapboxGL.a; sourceTree = SOURCE_ROOT; };
DD61240719CCF06E006845B1 /* MapboxGL.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = MapboxGL.bundle; path = ../dist/static/MapboxGL.bundle; sourceTree = SOURCE_ROOT; };
DD8A790C196DC0A900FAD883 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
DD8A790E196DC0AD00FAD883 /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; };
DD8A7910196DC0BB00FAD883 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
DD96917819F1C08400729E7D /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; };
DD96918019F1C09200729E7D /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
DD0580E71ACB628200B112C9 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/IOKit.framework; sourceTree = DEVELOPER_DIR; };
DD0580EF1ACB62BE00B112C9 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
DD0581031ACB661200B112C9 /* Headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Headers; path = ../../build/ios/pkg/static/Headers; sourceTree = SOURCE_ROOT; };
DD0581051ACB661C00B112C9 /* MapboxGL.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = MapboxGL.bundle; path = ../../build/ios/pkg/static/MapboxGL.bundle; sourceTree = SOURCE_ROOT; };
DD0581071ACB663200B112C9 /* libMapboxGL.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libMapboxGL.a; path = ../../build/ios/pkg/static/libMapboxGL.a; sourceTree = SOURCE_ROOT; };
DD41CE061ACB5DB300FA7979 /* libMapboxGL.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libMapboxGL.a; path = ../../build/ios/pkg/static/libMapboxGL.a; sourceTree = "<group>"; };
DD41CE081ACB5DBC00FA7979 /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; };
DD41CE0A1ACB5DC400FA7979 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
DD41CE0C1ACB5DCB00FA7979 /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "usr/lib/libc++.dylib"; sourceTree = SDKROOT; };
DD41CE0E1ACB5DD000FA7979 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; };
DD41CE101ACB5DD500FA7979 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
DD41CE121ACB5DDA00FA7979 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
DD41CE141ACB5DE000FA7979 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; };
DD41CE161ACB5DE700FA7979 /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; };
DDBD013A196DC3AE0033959E /* KIF.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = KIF.xcodeproj; path = KIF/KIF.xcodeproj; sourceTree = SOURCE_ROOT; };
DDBD0152196DC3D70033959E /* Test Bundle.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Test Bundle.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
DDBD0153196DC3D70033959E /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
DDBD0165196DC4560033959E /* Bundle-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Bundle-Info.plist"; sourceTree = SOURCE_ROOT; };
DDBD0168196DC4740033959E /* MapViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MapViewTests.m; sourceTree = SOURCE_ROOT; };
DDBD0169196DC4740033959E /* MapViewTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapViewTests.h; sourceTree = SOURCE_ROOT; };
DDBD016A196DC4740033959E /* KIFTestActor+MapboxGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "KIFTestActor+MapboxGL.m"; sourceTree = SOURCE_ROOT; };
DDBD016B196DC4740033959E /* KIFTestActor+MapboxGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KIFTestActor+MapboxGL.h"; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
@@ -115,16 +107,15 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DD043329196DB9BC00E6F39D /* CoreGraphics.framework in Frameworks */,
DD8A7911196DC0BB00FAD883 /* CoreLocation.framework in Frameworks */,
DD043327196DB9BC00E6F39D /* Foundation.framework in Frameworks */,
DD8A790F196DC0AD00FAD883 /* GLKit.framework in Frameworks */,
DD96918119F1C09200729E7D /* SystemConfiguration.framework in Frameworks */,
DD04332B196DB9BC00E6F39D /* UIKit.framework in Frameworks */,
DD61240819CCF06E006845B1 /* libMapboxGL.a in Frameworks */,
DD1A9EA8199BEA0D007BC651 /* libc++.dylib in Frameworks */,
DD96917919F1C08400729E7D /* libsqlite3.dylib in Frameworks */,
DD8A790D196DC0A900FAD883 /* libz.dylib in Frameworks */,
DD41CE091ACB5DBC00FA7979 /* CoreTelephony.framework in Frameworks */,
DD41CE171ACB5DE700FA7979 /* GLKit.framework in Frameworks */,
DD41CE151ACB5DE000FA7979 /* ImageIO.framework in Frameworks */,
DD41CE131ACB5DDA00FA7979 /* MobileCoreServices.framework in Frameworks */,
DD41CE0B1ACB5DC400FA7979 /* SystemConfiguration.framework in Frameworks */,
DD0581081ACB663200B112C9 /* libMapboxGL.a in Frameworks */,
DD41CE0D1ACB5DCB00FA7979 /* libc++.dylib in Frameworks */,
DD41CE0F1ACB5DD000FA7979 /* libsqlite3.dylib in Frameworks */,
DD41CE111ACB5DD500FA7979 /* libz.dylib in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -132,10 +123,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DDBD016F196DC4A90033959E /* CoreGraphics.framework in Frameworks */,
DDBD0155196DC3D70033959E /* Foundation.framework in Frameworks */,
DDBD0156196DC3D70033959E /* UIKit.framework in Frameworks */,
DDBD0154196DC3D70033959E /* XCTest.framework in Frameworks */,
DD0580E81ACB628200B112C9 /* IOKit.framework in Frameworks */,
DDBD016E196DC4A10033959E /* libKIF.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -165,16 +153,17 @@
DD043325196DB9BC00E6F39D /* Frameworks */ = {
isa = PBXGroup;
children = (
DD96918019F1C09200729E7D /* SystemConfiguration.framework */,
DD96917819F1C08400729E7D /* libsqlite3.dylib */,
DD043328196DB9BC00E6F39D /* CoreGraphics.framework */,
DD8A7910196DC0BB00FAD883 /* CoreLocation.framework */,
DD043326196DB9BC00E6F39D /* Foundation.framework */,
DD8A790E196DC0AD00FAD883 /* GLKit.framework */,
DD04332A196DB9BC00E6F39D /* UIKit.framework */,
DDBD0153196DC3D70033959E /* XCTest.framework */,
DD1A9EA7199BEA0D007BC651 /* libc++.dylib */,
DD8A790C196DC0A900FAD883 /* libz.dylib */,
DD0580EF1ACB62BE00B112C9 /* CoreGraphics.framework */,
DD41CE081ACB5DBC00FA7979 /* CoreTelephony.framework */,
DD41CE161ACB5DE700FA7979 /* GLKit.framework */,
DD0580E71ACB628200B112C9 /* IOKit.framework */,
DD41CE141ACB5DE000FA7979 /* ImageIO.framework */,
DD41CE121ACB5DDA00FA7979 /* MobileCoreServices.framework */,
DD41CE0A1ACB5DC400FA7979 /* SystemConfiguration.framework */,
DD41CE061ACB5DB300FA7979 /* libMapboxGL.a */,
DD41CE0C1ACB5DCB00FA7979 /* libc++.dylib */,
DD41CE0E1ACB5DD000FA7979 /* libsqlite3.dylib */,
DD41CE101ACB5DD500FA7979 /* libz.dylib */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -186,7 +175,7 @@
DD04335F196DBBD500E6F39D /* MGLTAppDelegate.m */,
DD043361196DBBD500E6F39D /* MGLTViewController.h */,
DD043360196DBBD500E6F39D /* MGLTViewController.m */,
DD8A77AD196DBFDA00FAD883 /* GL Library */,
DDAE739B1ACB557500E1A793 /* GL Library */,
DD04332D196DB9BC00E6F39D /* Supporting Files */,
);
name = App;
@@ -202,26 +191,12 @@
name = "Supporting Files";
sourceTree = "<group>";
};
DD6123FF19CCF06E006845B1 /* Headers */ = {
DDAE739B1ACB557500E1A793 /* GL Library */ = {
isa = PBXGroup;
children = (
DD61240019CCF06E006845B1 /* MGLMapView.h */,
DD61240119CCF06E006845B1 /* MGLStyleFunctionValue.h */,
DD61240219CCF06E006845B1 /* MGLTypes.h */,
DD61240319CCF06E006845B1 /* NSArray+MGLAdditions.h */,
DD61240419CCF06E006845B1 /* NSDictionary+MGLAdditions.h */,
DD61240519CCF06E006845B1 /* UIColor+MGLAdditions.h */,
);
name = Headers;
path = ../../dist/static/Headers;
sourceTree = SOURCE_ROOT;
};
DD8A77AD196DBFDA00FAD883 /* GL Library */ = {
isa = PBXGroup;
children = (
DD6123FF19CCF06E006845B1 /* Headers */,
DD61240619CCF06E006845B1 /* libMapboxGL.a */,
DD61240719CCF06E006845B1 /* MapboxGL.bundle */,
DD0581031ACB661200B112C9 /* Headers */,
DD0581071ACB663200B112C9 /* libMapboxGL.a */,
DD0581051ACB661C00B112C9 /* MapboxGL.bundle */,
);
name = "GL Library";
sourceTree = "<group>";
@@ -231,7 +206,6 @@
children = (
DDBD016B196DC4740033959E /* KIFTestActor+MapboxGL.h */,
DDBD016A196DC4740033959E /* KIFTestActor+MapboxGL.m */,
DDBD0169196DC4740033959E /* MapViewTests.h */,
DDBD0168196DC4740033959E /* MapViewTests.m */,
DDBD0167196DC46B0033959E /* Supporting Files */,
DDBD014D196DC3B00033959E /* KIF */,
@@ -313,7 +287,7 @@
isa = PBXProject;
attributes = {
CLASSPREFIX = MGLT;
LastUpgradeCheck = 0510;
LastUpgradeCheck = 0620;
ORGANIZATIONNAME = Mapbox;
TargetAttributes = {
DDBD0151196DC3D70033959E = {
@@ -389,7 +363,8 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DD61240919CCF06E006845B1 /* MapboxGL.bundle in Resources */,
DD0581041ACB661200B112C9 /* Headers in Resources */,
DD0581061ACB661C00B112C9 /* MapboxGL.bundle in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -407,9 +382,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DD043364196DBBD500E6F39D /* MGLTViewController.m in Sources */,
DD043366196DBBE000E6F39D /* main.m in Sources */,
DD043363196DBBD500E6F39D /* MGLTAppDelegate.m in Sources */,
DD043364196DBBD500E6F39D /* MGLTViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -508,26 +483,20 @@
DD043359196DB9BC00E6F39D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
armv7,
armv7s,
arm64,
i386,
x86_64,
);
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
../dist/static/Headers,
"../../build/ios/pkg/static/**",
);
INFOPLIST_FILE = "$(SRCROOT)/App-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
../dist/static,
../../build/ios/pkg/static,
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
WRAPPER_EXTENSION = app;
@@ -537,26 +506,20 @@
DD04335A196DB9BC00E6F39D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
armv7,
armv7s,
arm64,
i386,
x86_64,
);
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
../dist/static/Headers,
"../../build/ios/pkg/static/**",
);
INFOPLIST_FILE = "$(SRCROOT)/App-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
../dist/static,
../../build/ios/pkg/static,
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
WRAPPER_EXTENSION = app;
@@ -571,6 +534,7 @@
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
"$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks",
);
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
@@ -580,7 +544,7 @@
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
../dist/static/Headers,
"../../build/ios/pkg/static/**",
);
INFOPLIST_FILE = "Bundle-Info.plist";
OTHER_LDFLAGS = (
@@ -603,12 +567,13 @@
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
"$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks",
);
GCC_PREPROCESSOR_DEFINITIONS = "KIF_XCTEST=1";
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
../dist/static/Headers,
"../../build/ios/pkg/static/**",
);
INFOPLIST_FILE = "Bundle-Info.plist";
OTHER_LDFLAGS = (

View File

@@ -14,26 +14,22 @@
<string>https://github.com/mapbox/KIF.git</string>
<key>7E68CB584078A487C0535CC191D3B7551EEE2095</key>
<string>github.com:mapbox/mapbox-gl-native.git</string>
<key>FC967DACF69B3B67E6F2E9FBE56B64B73B118AFF</key>
<string>github.com:mapbox/mapbox-gl-cocoa.git</string>
</dict>
<key>IDESourceControlProjectPath</key>
<string>test/ios-tests.xcodeproj</string>
<string>test/ios/ios-tests.xcodeproj</string>
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
<dict>
<key>10265E242415D473A6A613214DB7AC3EE3D43F93</key>
<string>../../..test/KIF/</string>
<string>../../../..test/ios/KIF</string>
<key>7E68CB584078A487C0535CC191D3B7551EEE2095</key>
<string>../../../../..</string>
<key>FC967DACF69B3B67E6F2E9FBE56B64B73B118AFF</key>
<string>../../..</string>
<string>../../../..</string>
</dict>
<key>IDESourceControlProjectURL</key>
<string>github.com:mapbox/mapbox-gl-cocoa.git</string>
<string>github.com:mapbox/mapbox-gl-native.git</string>
<key>IDESourceControlProjectVersion</key>
<integer>111</integer>
<key>IDESourceControlProjectWCCIdentifier</key>
<string>FC967DACF69B3B67E6F2E9FBE56B64B73B118AFF</string>
<string>7E68CB584078A487C0535CC191D3B7551EEE2095</string>
<key>IDESourceControlProjectWCConfigurations</key>
<array>
<dict>
@@ -42,7 +38,7 @@
<key>IDESourceControlWCCIdentifierKey</key>
<string>7E68CB584078A487C0535CC191D3B7551EEE2095</string>
<key>IDESourceControlWCCName</key>
<string>..</string>
<string>gl-native</string>
</dict>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
@@ -52,14 +48,6 @@
<key>IDESourceControlWCCName</key>
<string>KIF</string>
</dict>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>FC967DACF69B3B67E6F2E9FBE56B64B73B118AFF</string>
<key>IDESourceControlWCCName</key>
<string>mapbox-gl-cocoa</string>
</dict>
</array>
</dict>
</plist>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0510"
LastUpgradeVersion = "0620"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -51,6 +51,11 @@
BlueprintName = "Test Bundle"
ReferencedContainer = "container:ios-tests.xcodeproj">
</BuildableReference>
<SkippedTests>
<Test
Identifier = "MapViewTests/testDelegateRegionWillChange">
</Test>
</SkippedTests>
</TestableReference>
</Testables>
<MacroExpansion>
@@ -72,7 +77,8 @@
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD043322196DB9BC00E6F39D"
@@ -90,7 +96,8 @@
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD043322196DB9BC00E6F39D"

View File

@@ -9,7 +9,7 @@
'actions': [
{
'action_name': 'Symlink Fixture Directory',
'inputs': ['<!@(pwd)'],
'inputs': ['<!@(pwd)/../test'],
'outputs': ['<(PRODUCT_DIR)/TEST_DATA'], # symlinks the test dir into TEST_DATA
'action': ['ln', '-s', '-f', '-n', '<@(_inputs)', '<@(_outputs)' ],
}