summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2016-11-03 13:16:27 -0700
committerMinh Nguyễn <mxn@1ec5.org>2016-11-03 13:16:27 -0700
commit4f40fceb728258e486ffd0b813ddef3e4e2c3cd2 (patch)
tree8fa5fe2e12ffb36290e15c7163cf06c97b4f66e2
parentb8a2fd390cd4b3172e85d18c1718edb41c039036 (diff)
parent7c68d7773d208993c9ebb76ac42a440e1a27c29a (diff)
downloadqtlocation-mapboxgl-4f40fceb728258e486ffd0b813ddef3e4e2c3cd2.tar.gz
Merge branch 'release-ios-v3.4.0' into 1ec5-release-ios-v3.4.0-beta.2-master
-rw-r--r--platform/darwin/scripts/generate-style-code.js3
-rw-r--r--platform/darwin/src/MGLFeature.h25
-rw-r--r--platform/darwin/src/MGLFeature.mm8
-rw-r--r--platform/darwin/src/MGLFeature_Private.h3
-rw-r--r--platform/darwin/src/MGLGeoJSONSource.h33
-rw-r--r--platform/darwin/src/MGLGeoJSONSource.mm134
-rw-r--r--platform/darwin/src/MGLGeoJSONSource_Private.h1
-rw-r--r--platform/darwin/src/MGLMultiPoint.h21
-rw-r--r--platform/darwin/src/MGLMultiPoint.mm28
-rw-r--r--platform/darwin/src/MGLOfflineStorage.h27
-rw-r--r--platform/darwin/src/MGLOfflineStorage.mm28
-rw-r--r--platform/darwin/src/MGLPointCollection.h51
-rw-r--r--platform/darwin/src/MGLPointCollection.mm112
-rw-r--r--platform/darwin/src/MGLPointCollection_Private.h11
-rw-r--r--platform/darwin/src/MGLPolygon.h2
-rw-r--r--platform/darwin/src/MGLPolyline.h2
-rw-r--r--platform/darwin/src/MGLRasterSource.mm23
-rw-r--r--platform/darwin/src/MGLSource.mm17
-rw-r--r--platform/darwin/src/MGLSource_Private.h23
-rw-r--r--platform/darwin/src/MGLStyle.mm12
-rw-r--r--platform/darwin/src/MGLStyleValue.h4
-rw-r--r--platform/darwin/src/MGLSymbolStyleLayer.h2
-rw-r--r--platform/darwin/src/MGLTypes.h8
-rw-r--r--platform/darwin/src/MGLVectorSource.mm22
-rw-r--r--platform/darwin/test/MGLFeatureTests.mm37
-rw-r--r--platform/darwin/test/MGLGeoJSONSourceTests.mm (renamed from platform/ios/test/MGLGeoJSONSourceTests.mm)111
-rw-r--r--platform/darwin/test/MGLOfflineStorageTests.m4
-rw-r--r--platform/darwin/test/MGLStyleLayerTests.m1
-rw-r--r--platform/darwin/test/MGLStyleValueTests.swift36
-rw-r--r--platform/darwin/test/MGLTileSetTests.mm (renamed from platform/ios/test/MGLTileSetTests.mm)0
-rw-r--r--platform/darwin/test/test-Bridging-Header.h3
-rw-r--r--platform/ios/CHANGELOG.md16
-rw-r--r--platform/ios/Mapbox-iOS-SDK-symbols.podspec2
-rw-r--r--platform/ios/Mapbox-iOS-SDK.podspec2
-rw-r--r--platform/ios/app/Info.plist13
-rw-r--r--platform/ios/app/MBXOfflinePacksTableViewController.m4
-rw-r--r--platform/ios/app/MBXViewController.m350
-rw-r--r--platform/ios/app/Main.storyboard62
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj36
-rw-r--r--platform/ios/jazzy.yml3
-rwxr-xr-xplatform/ios/scripts/deploy-packages.sh8
-rw-r--r--platform/ios/src/MGLMapView.h30
-rw-r--r--platform/ios/src/MGLMapView.mm152
-rw-r--r--platform/ios/src/Mapbox.h1
-rw-r--r--platform/ios/test/test-Bridging-Header.h3
-rw-r--r--platform/macos/CHANGELOG.md10
-rw-r--r--platform/macos/jazzy.yml7
-rw-r--r--platform/macos/macos.xcodeproj/project.pbxproj72
-rw-r--r--platform/macos/src/MGLMapView.h21
-rw-r--r--platform/macos/src/MGLMapView.mm44
-rw-r--r--platform/macos/src/Mapbox.h1
-rw-r--r--platform/macos/src/NSColor+MGLAdditions.mm2
52 files changed, 1258 insertions, 373 deletions
diff --git a/platform/darwin/scripts/generate-style-code.js b/platform/darwin/scripts/generate-style-code.js
index 4bcfe54d32..62ab3b6b98 100644
--- a/platform/darwin/scripts/generate-style-code.js
+++ b/platform/darwin/scripts/generate-style-code.js
@@ -152,6 +152,9 @@ global.describeValue = function (value, property, layerType) {
case 'number':
return 'an `NSNumber` object containing the float `' + value + '`';
case 'string':
+ if (value === '') {
+ return 'the empty string';
+ }
return 'the string `' + value + '`';
case 'enum':
let displayValue;
diff --git a/platform/darwin/src/MGLFeature.h b/platform/darwin/src/MGLFeature.h
index 239a338f67..384c5a073e 100644
--- a/platform/darwin/src/MGLFeature.h
+++ b/platform/darwin/src/MGLFeature.h
@@ -3,6 +3,7 @@
#import "MGLPolyline.h"
#import "MGLPolygon.h"
#import "MGLPointAnnotation.h"
+#import "MGLPointCollection.h"
#import "MGLShapeCollection.h"
NS_ASSUME_NONNULL_BEGIN
@@ -18,8 +19,8 @@ NS_ASSUME_NONNULL_BEGIN
using `-[MGLMapView visibleFeaturesAtPoint:]` and related methods. Each feature
object associates a shape with an identifier and attributes as specified by the
source. Like ordinary `MGLAnnotation` objects, some kinds of `MGLFeature`
- objects can also be added to a map view using `-[MGLMapView addAnnotations:]`
- and related methods.
+ objects can also be added to a map view using an `MGLGeoJSONSource` or
+ `-[MGLMapView addAnnotations:]` and related methods.
*/
@protocol MGLFeature <MGLAnnotation>
@@ -48,9 +49,13 @@ NS_ASSUME_NONNULL_BEGIN
For details about the identifiers used in most Mapbox-provided styles, consult
the
<a href="https://www.mapbox.com/vector-tiles/mapbox-streets/">Mapbox Streets</a>
- layer reference.
+ layer reference. Note that while it is possible to change this value on feature
+ instances obtained from `-[MGLMapView visibleFeaturesAtPoint:]` and related
+ methods, there will be no effect on the map. Setting this value can be useful
+ when the feature instance is used to initialize an `MGLGeoJSONSource` and that
+ source is added to the map and styled.
*/
-@property (nonatomic, copy, nullable, readonly) id identifier;
+@property (nonatomic, copy, nullable) id identifier;
/**
A dictionary of attributes for this feature specified by the
@@ -79,9 +84,13 @@ NS_ASSUME_NONNULL_BEGIN
<a href="https://www.mapbox.com/vector-tiles/mapbox-streets/">Mapbox Streets</a>
and
<a href="https://www.mapbox.com/vector-tiles/mapbox-terrain/">Mapbox Terrain</a>
- layer references.
+ layer references. Note that while it is possible to change this value on feature
+ instances obtained from `-[MGLMapView visibleFeaturesAtPoint:]` and related
+ methods, there will be no effect on the map. Setting this value can be useful
+ when the feature instance is used to initialize an `MGLGeoJSONSource` and that
+ source is added to the map and styled.
*/
-@property (nonatomic, copy, readonly) NS_DICTIONARY_OF(NSString *, id) *attributes;
+@property (nonatomic, copy) NS_DICTIONARY_OF(NSString *, id) *attributes;
/**
Returns the feature attribute for the given attribute name.
@@ -126,10 +135,10 @@ NS_ASSUME_NONNULL_BEGIN
@end
/**
- The `MGLMultiPointFeature` class represents a multipoint in a
+ The `MGLPointCollectionFeature` class represents a multipoint in a
<a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile source</a>.
*/
-@interface MGLMultiPointFeature : MGLMultiPoint <MGLFeature>
+@interface MGLPointCollectionFeature : MGLPointCollection <MGLFeature>
@end
/**
diff --git a/platform/darwin/src/MGLFeature.mm b/platform/darwin/src/MGLFeature.mm
index 84dcc4f0bb..5483433710 100644
--- a/platform/darwin/src/MGLFeature.mm
+++ b/platform/darwin/src/MGLFeature.mm
@@ -6,7 +6,7 @@
#import "MGLValueEvaluator.h"
#import "MGLShape_Private.h"
-#import "MGLMultiPoint_Private.h"
+#import "MGLPointCollection_Private.h"
#import "MGLPolyline+MGLAdditions.h"
#import "MGLPolygon+MGLAdditions.h"
#import "NSDictionary+MGLAdditions.h"
@@ -82,10 +82,10 @@
@end
-@interface MGLMultiPointFeature () <MGLFeaturePrivate>
+@interface MGLPointCollectionFeature () <MGLFeaturePrivate>
@end
-@implementation MGLMultiPointFeature
+@implementation MGLPointCollectionFeature
@synthesize identifier;
@synthesize attributes;
@@ -202,7 +202,7 @@ public:
MGLShape <MGLFeaturePrivate> * operator()(const mbgl::MultiPoint<T> &geometry) const {
std::vector<CLLocationCoordinate2D> coordinates = toLocationCoordinates2D(geometry);
- return [[MGLMultiPointFeature alloc] initWithCoordinates:&coordinates[0] count:coordinates.size()];
+ return [[MGLPointCollectionFeature alloc] initWithCoordinates:&coordinates[0] count:coordinates.size()];
}
MGLShape <MGLFeaturePrivate> * operator()(const mbgl::MultiLineString<T> &geometry) const {
diff --git a/platform/darwin/src/MGLFeature_Private.h b/platform/darwin/src/MGLFeature_Private.h
index 5fb82bde5b..e6858c7c11 100644
--- a/platform/darwin/src/MGLFeature_Private.h
+++ b/platform/darwin/src/MGLFeature_Private.h
@@ -26,9 +26,6 @@ NS_DICTIONARY_OF(NSString *, id) *NSDictionaryFeatureForGeometry(NSDictionary *g
@protocol MGLFeaturePrivate <MGLFeature>
-@property (nonatomic, copy, nullable, readwrite) id identifier;
-@property (nonatomic, copy, readwrite) NS_DICTIONARY_OF(NSString *, id) *attributes;
-
- (mbgl::Feature)mbglFeature;
@end
diff --git a/platform/darwin/src/MGLGeoJSONSource.h b/platform/darwin/src/MGLGeoJSONSource.h
index 9eeb1e1188..30232c6211 100644
--- a/platform/darwin/src/MGLGeoJSONSource.h
+++ b/platform/darwin/src/MGLGeoJSONSource.h
@@ -7,33 +7,38 @@ NS_ASSUME_NONNULL_BEGIN
@protocol MGLFeature;
/**
+ Options for `MGLGeoJSONSource` objects.
+ */
+typedef NSString *MGLGeoJSONSourceOption NS_STRING_ENUM;
+
+/**
An `NSNumber` object containing a Boolean enabling or disabling clustering.
If the `features` property contains point features, setting this option to
`YES` clusters the points by radius into groups. The default value is `NO`.
*/
-extern NSString * const MGLGeoJSONClusterOption;
+extern const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionClustered;
/**
An `NSNumber` object containing an integer; specifies the radius of each
cluster if clustering is enabled. A value of 512 produces a radius equal to
the width of a tile. The default value is 50.
*/
-extern NSString * const MGLGeoJSONClusterRadiusOption;
+extern const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionClusterRadius;
/**
An `NSNumber` object containing an integer; specifies the maximum zoom level at
which to cluster points if clustering is enabled. Defaults to one zoom level
- less than the value of `MGLGeoJSONMaximumZoomLevelOption` so that, at the
+ less than the value of `MGLGeoJSONSourceOptionMaximumZoomLevel` so that, at the
maximum zoom level, the features are not clustered.
*/
-extern NSString * const MGLGeoJSONClusterMaximumZoomLevelOption;
+extern const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionMaximumZoomLevelForClustering;
/**
An `NSNumber` object containing an integer; specifies the maximum zoom level at
which to create vector tiles. A greater value produces greater detail at high
zoom levels. The default value is 18.
*/
-extern NSString * const MGLGeoJSONMaximumZoomLevelOption;
+extern const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionMaximumZoomLevel;
/**
An `NSNumber` object containing an integer; specifies the size of the tile
@@ -41,14 +46,14 @@ extern NSString * const MGLGeoJSONMaximumZoomLevelOption;
buffer as wide as the tile itself. Larger values produce fewer rendering
artifacts near tile edges and slower performance. The default value is 128.
*/
-extern NSString * const MGLGeoJSONBufferOption;
+extern const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionBuffer;
/**
An `NSNumber` object containing a double; specifies the Douglas-Peucker
simplification tolerance. A greater value produces simpler geometries and
improves performance. The default value is 0.375.
*/
-extern NSString * const MGLGeoJSONToleranceOption;
+extern const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionSimplificationTolerance;
/**
A GeoJSON source.
@@ -71,7 +76,7 @@ extern NSString * const MGLGeoJSONToleranceOption;
@param options An `NSDictionary` of options for this source.
@return An initialized GeoJSON source.
*/
-- (instancetype)initWithIdentifier:(NSString *)identifier geoJSONData:(NSData *)data options:(nullable NS_DICTIONARY_OF(NSString *, id) *)options NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithIdentifier:(NSString *)identifier geoJSONData:(NSData *)data options:(nullable NS_DICTIONARY_OF(MGLGeoJSONSourceOption, id) *)options NS_DESIGNATED_INITIALIZER;
/**
Returns a GeoJSON source with an identifier, URL, and dictionary of options for
@@ -85,7 +90,7 @@ extern NSString * const MGLGeoJSONToleranceOption;
@param options An `NSDictionary` of options for this source.
@return An initialized GeoJSON source.
*/
-- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url options:(nullable NS_DICTIONARY_OF(NSString *, id) *)options NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url options:(nullable NS_DICTIONARY_OF(MGLGeoJSONSourceOption, id) *)options NS_DESIGNATED_INITIALIZER;
/**
Returns a GeoJSON source with an identifier, features dictionary, and dictionary
@@ -98,7 +103,7 @@ extern NSString * const MGLGeoJSONToleranceOption;
@param options An `NSDictionary` of options for this source.
@return An initialized GeoJSON source.
*/
-- (instancetype)initWithIdentifier:(NSString *)identifier features:(NSArray<id<MGLFeature>> *)features options:(nullable NS_DICTIONARY_OF(NSString *,id) *)options NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithIdentifier:(NSString *)identifier features:(NSArray<id<MGLFeature>> *)features options:(nullable NS_DICTIONARY_OF(MGLGeoJSONSourceOption, id) *)options NS_DESIGNATED_INITIALIZER;
#pragma mark Accessing a Source’s Content
@@ -109,13 +114,13 @@ extern NSString * const MGLGeoJSONToleranceOption;
is set to `nil`. This property is unavailable until the receiver is passed into
`-[MGLStyle addSource]`.
*/
-@property (nonatomic, readonly, nullable) NS_ARRAY_OF(id <MGLFeature>) *features;
+@property (nonatomic, nullable) NS_ARRAY_OF(id <MGLFeature>) *features;
/**
A GeoJSON representation of the contents of the source.
Use the `features` property instead to get an object representation of the
- contents. Alternatively, use NSJSONSerialization with the value of this
+ contents. Alternatively, use `NSJSONSerialization` with the value of this
property to transform it into Foundation types.
If the receiver was initialized using `-initWithIdentifier:URL:options` or
@@ -123,7 +128,7 @@ extern NSString * const MGLGeoJSONToleranceOption;
This property is unavailable until the receiver is passed
into `-[MGLStyle addSource]`.
*/
-@property (nonatomic, readonly, nullable, copy) NSData *geoJSONData;
+@property (nonatomic, nullable, copy) NSData *geoJSONData;
/**
The URL to the GeoJSON document that specifies the contents of the source.
@@ -131,7 +136,7 @@ extern NSString * const MGLGeoJSONToleranceOption;
If the receiver was initialized using `-initWithIdentifier:geoJSONData:options`, this
property is set to `nil`.
*/
-@property (nonatomic, readonly, nullable) NSURL *URL;
+@property (nonatomic, nullable) NSURL *URL;
@end
diff --git a/platform/darwin/src/MGLGeoJSONSource.mm b/platform/darwin/src/MGLGeoJSONSource.mm
index 27f2eb8bda..0dbe1030c6 100644
--- a/platform/darwin/src/MGLGeoJSONSource.mm
+++ b/platform/darwin/src/MGLGeoJSONSource.mm
@@ -1,5 +1,6 @@
-#import "MGLGeoJSONSource.h"
+#import "MGLGeoJSONSource_Private.h"
+#import "MGLMapView_Private.h"
#import "MGLSource_Private.h"
#import "MGLFeature_Private.h"
@@ -7,20 +8,24 @@
#include <mbgl/style/sources/geojson_source.hpp>
-NSString * const MGLGeoJSONClusterOption = @"MGLGeoJSONCluster";
-NSString * const MGLGeoJSONClusterRadiusOption = @"MGLGeoJSONClusterRadius";
-NSString * const MGLGeoJSONClusterMaximumZoomLevelOption = @"MGLGeoJSONClusterMaximumZoomLevel";
-NSString * const MGLGeoJSONMaximumZoomLevelOption = @"MGLGeoJSONMaximumZoomLevel";
-NSString * const MGLGeoJSONBufferOption = @"MGLGeoJSONBuffer";
-NSString * const MGLGeoJSONToleranceOption = @"MGLGeoJSONOptionsClusterTolerance";
+const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionClustered = @"MGLGeoJSONSourceOptionClustered";
+const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionClusterRadius = @"MGLGeoJSONSourceOptionClusterRadius";
+const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionMaximumZoomLevelForClustering = @"MGLGeoJSONSourceOptionMaximumZoomLevelForClustering";
+const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionMaximumZoomLevel = @"MGLGeoJSONSourceOptionMaximumZoomLevel";
+const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionBuffer = @"MGLGeoJSONSourceOptionBuffer";
+const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionSimplificationTolerance = @"MGLGeoJSONSourceOptionSimplificationTolerance";
@interface MGLGeoJSONSource ()
@property (nonatomic, readwrite) NSDictionary *options;
+@property (nonatomic) mbgl::style::GeoJSONSource *rawSource;
@end
@implementation MGLGeoJSONSource
+{
+ std::unique_ptr<mbgl::style::GeoJSONSource> _pendingSource;
+}
- (instancetype)initWithIdentifier:(NSString *)identifier geoJSONData:(NSData *)data options:(NS_DICTIONARY_OF(NSString *, id) *)options
{
@@ -28,6 +33,7 @@ NSString * const MGLGeoJSONToleranceOption = @"MGLGeoJSONOptionsClusterTolerance
{
_geoJSONData = data;
_options = options;
+ [self commonInit];
}
return self;
}
@@ -38,6 +44,7 @@ NSString * const MGLGeoJSONToleranceOption = @"MGLGeoJSONOptionsClusterTolerance
{
_URL = url;
_options = options;
+ [self commonInit];
}
return self;
}
@@ -46,47 +53,75 @@ NSString * const MGLGeoJSONToleranceOption = @"MGLGeoJSONOptionsClusterTolerance
if (self = [super initWithIdentifier:identifier]) {
_features = features;
_options = options;
+ [self commonInit];
}
return self;
}
+- (void)addToMapView:(MGLMapView *)mapView
+{
+ mapView.mbglMap->addSource(std::move(_pendingSource));
+}
+
+- (void)commonInit
+{
+ auto source = std::make_unique<mbgl::style::GeoJSONSource>(self.identifier.UTF8String, self.geoJSONOptions);
+
+ if (self.URL) {
+ NSURL *url = self.URL.mgl_URLByStandardizingScheme;
+ source->setURL(url.absoluteString.UTF8String);
+ _features = nil;
+ } else if (self.geoJSONData) {
+ NSString *string = [[NSString alloc] initWithData:self.geoJSONData encoding:NSUTF8StringEncoding];
+ const auto geojson = mapbox::geojson::parse(string.UTF8String).get<mapbox::geojson::feature_collection>();
+ source->setGeoJSON(geojson);
+ _features = MGLFeaturesFromMBGLFeatures(geojson);
+ } else {
+ mbgl::FeatureCollection featureCollection;
+ featureCollection.reserve(self.features.count);
+ for (id <MGLFeaturePrivate> feature in self.features) {
+ featureCollection.push_back([feature mbglFeature]);
+ }
+ const auto geojson = mbgl::GeoJSON{featureCollection};
+ source->setGeoJSON(geojson);
+ _features = MGLFeaturesFromMBGLFeatures(featureCollection);
+ }
+
+ _pendingSource = std::move(source);
+ self.rawSource = _pendingSource.get();
+}
+
- (mbgl::style::GeoJSONOptions)geoJSONOptions
{
auto mbglOptions = mbgl::style::GeoJSONOptions();
- if (self.options[MGLGeoJSONMaximumZoomLevelOption]) {
- id value = self.options[MGLGeoJSONMaximumZoomLevelOption];
+ if (id value = self.options[MGLGeoJSONSourceOptionMaximumZoomLevel]) {
[self validateValue:value];
mbglOptions.maxzoom = [value integerValue];
}
- if (self.options[MGLGeoJSONBufferOption]) {
- id value = self.options[MGLGeoJSONBufferOption];
+ if (id value = self.options[MGLGeoJSONSourceOptionBuffer]) {
[self validateValue:value];
mbglOptions.buffer = [value integerValue];
}
- if (self.options[MGLGeoJSONToleranceOption]) {
- id value = self.options[MGLGeoJSONToleranceOption];
+ if (id value = self.options[MGLGeoJSONSourceOptionSimplificationTolerance]) {
[self validateValue:value];
mbglOptions.tolerance = [value doubleValue];
}
- if (self.options[MGLGeoJSONClusterRadiusOption]) {
- id value = self.options[MGLGeoJSONClusterRadiusOption];
+ if (id value = self.options[MGLGeoJSONSourceOptionClusterRadius]) {
[self validateValue:value];
mbglOptions.clusterRadius = [value integerValue];
}
- if (self.options[MGLGeoJSONClusterMaximumZoomLevelOption]) {
- id value = self.options[MGLGeoJSONClusterMaximumZoomLevelOption];
+ if (id value = self.options[MGLGeoJSONSourceOptionMaximumZoomLevelForClustering]) {
[self validateValue:value];
mbglOptions.clusterMaxZoom = [value integerValue];
}
- if (self.options[MGLGeoJSONClusterOption]) {
- id value = self.options[MGLGeoJSONClusterOption];
+ if (id value = self.options[MGLGeoJSONSourceOptionClustered]) {
[self validateValue:value];
mbglOptions.cluster = [value boolValue];
}
@@ -102,30 +137,51 @@ NSString * const MGLGeoJSONToleranceOption = @"MGLGeoJSONOptionsClusterTolerance
}
}
-- (std::unique_ptr<mbgl::style::Source>)mbglSource
+- (void)setGeoJSONData:(NSData *)geoJSONData
{
- auto source = std::make_unique<mbgl::style::GeoJSONSource>(self.identifier.UTF8String, self.geoJSONOptions);
+ _geoJSONData = geoJSONData;
- if (self.URL) {
- NSURL *url = self.URL.mgl_URLByStandardizingScheme;
- source->setURL(url.absoluteString.UTF8String);
- } else if (self.geoJSONData) {
- NSString *string = [[NSString alloc] initWithData:self.geoJSONData encoding:NSUTF8StringEncoding];
- const auto geojson = mapbox::geojson::parse(string.UTF8String).get<mapbox::geojson::feature_collection>();
- source->setGeoJSON(geojson);
- _features = MGLFeaturesFromMBGLFeatures(geojson);
- } else {
- mbgl::FeatureCollection featureCollection;
- featureCollection.reserve(self.features.count);
- for (id <MGLFeaturePrivate> feature in self.features) {
- featureCollection.push_back([feature mbglFeature]);
- }
- const auto geojson = mbgl::GeoJSON{featureCollection};
- source->setGeoJSON(geojson);
- _features = MGLFeaturesFromMBGLFeatures(featureCollection);
+ if (self.rawSource == NULL)
+ {
+ [self commonInit];
+ }
+
+ NSString *string = [[NSString alloc] initWithData:_geoJSONData encoding:NSUTF8StringEncoding];
+ const auto geojson = mapbox::geojson::parse(string.UTF8String).get<mapbox::geojson::feature_collection>();
+ self.rawSource->setGeoJSON(geojson);
+
+ _features = MGLFeaturesFromMBGLFeatures(geojson);
+}
+
+- (void)setURL:(NSURL *)URL
+{
+ _URL = URL;
+
+ if (self.rawSource == NULL)
+ {
+ [self commonInit];
+ }
+
+ NSURL *url = self.URL.mgl_URLByStandardizingScheme;
+ self.rawSource->setURL(url.absoluteString.UTF8String);
+}
+
+- (void)setFeatures:(NSArray *)features
+{
+ if (self.rawSource == NULL)
+ {
+ [self commonInit];
+ }
+
+ mbgl::FeatureCollection featureCollection;
+ featureCollection.reserve(features.count);
+ for (id <MGLFeaturePrivate> feature in features) {
+ featureCollection.push_back([feature mbglFeature]);
}
+ const auto geojson = mbgl::GeoJSON{featureCollection};
+ self.rawSource->setGeoJSON(geojson);
- return std::move(source);
+ _features = MGLFeaturesFromMBGLFeatures(featureCollection);
}
@end
diff --git a/platform/darwin/src/MGLGeoJSONSource_Private.h b/platform/darwin/src/MGLGeoJSONSource_Private.h
index 3aeb07ad25..de5bb10fac 100644
--- a/platform/darwin/src/MGLGeoJSONSource_Private.h
+++ b/platform/darwin/src/MGLGeoJSONSource_Private.h
@@ -1,3 +1,4 @@
+#import "MGLGeoJSONSource.h"
#import "MGLGeoJSONSource_Private.h"
#include <mbgl/style/sources/geojson_source.hpp>
diff --git a/platform/darwin/src/MGLMultiPoint.h b/platform/darwin/src/MGLMultiPoint.h
index b936205ab2..69c7295842 100644
--- a/platform/darwin/src/MGLMultiPoint.h
+++ b/platform/darwin/src/MGLMultiPoint.h
@@ -6,25 +6,16 @@
NS_ASSUME_NONNULL_BEGIN
/**
- The `MGLMultiPoint` class is used to define shapes composed of multiple points.
- This class is also the superclass of `MGLPolyline` and `MGLPolygon`. The
- methods and properties of this class can be used to access information about
- the specific points associated with a line or polygon.
+ The `MGLMultiPoint` class is an abstract superclass used to define shapes
+ composed of multiple points. You should not create instances of this class
+ directly. Instead, you should create instances of the `MGLPolyline` or
+ `MGLPolygon` classes. However, you can use the method and properties of this
+ class to access information about the specific points associated with the line
+ or polygon.
*/
@interface MGLMultiPoint : MGLShape
/**
- Creates and returns an `MGLMultiPoint` object from the specified set of
- coordinates.
-
- @param coords The array of coordinates defining the shape. The data in this
- array is copied to the new object.
- @param count The number of items in the `coords` array.
- @return A new multipoint object.
- */
-+ (instancetype)multiPointWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count NS_SWIFT_NAME(multiPoint(coordinates:count:));
-
-/**
The array of coordinates associated with the shape.
This C array is a pointer to a structure inside the multipoint object,
diff --git a/platform/darwin/src/MGLMultiPoint.mm b/platform/darwin/src/MGLMultiPoint.mm
index 0090c5e35f..17a61ed081 100644
--- a/platform/darwin/src/MGLMultiPoint.mm
+++ b/platform/darwin/src/MGLMultiPoint.mm
@@ -18,11 +18,6 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor)
MGLCoordinateBounds _bounds;
}
-+ (instancetype)multiPointWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
-{
- return [[self alloc] initWithCoordinates:coords count:count];
-}
-
- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
{
self = [super init];
@@ -146,29 +141,6 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor)
return mbgl::SymbolAnnotation({mbgl::Point<double>()});
}
-- (mbgl::Feature)featureObject
-{
- mbgl::MultiPoint<double> multiPoint;
- multiPoint.reserve(self.pointCount);
- for (NSInteger i = 0; i< self.pointCount; i++)
- {
- multiPoint.push_back(mbgl::Point<double>(self.coordinates[i].longitude, self.coordinates[i].latitude));
- }
- return mbgl::Feature {multiPoint};
-}
-
-- (NSDictionary *)geoJSONDictionary
-{
- NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:self.pointCount];
- for (NSUInteger index = 0; index < self.pointCount; index++) {
- CLLocationCoordinate2D coordinate = self.coordinates[index];
- [coordinates addObject:@[@(coordinate.longitude), @(coordinate.latitude)]];
- }
-
- return @{@"type": @"MultiPoint",
- @"coordinates": coordinates};
-}
-
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p; count = %lu; bounds = %@>",
diff --git a/platform/darwin/src/MGLOfflineStorage.h b/platform/darwin/src/MGLOfflineStorage.h
index 211135f84f..b3fb7a2d54 100644
--- a/platform/darwin/src/MGLOfflineStorage.h
+++ b/platform/darwin/src/MGLOfflineStorage.h
@@ -24,7 +24,7 @@ NS_ASSUME_NONNULL_BEGIN
alternatively observe KVO change notifications to the pack’s `progress` key
path.
*/
-extern NSString * const MGLOfflinePackProgressChangedNotification;
+extern const NSNotificationName MGLOfflinePackProgressChangedNotification;
/**
Posted by the shared `MGLOfflineStorage` object whenever an `MGLOfflinePack`
@@ -37,7 +37,7 @@ extern NSString * const MGLOfflinePackProgressChangedNotification;
`userInfo` dictionary contains the error object in the
`MGLOfflinePackErrorUserInfoKey` key.
*/
-extern NSString * const MGLOfflinePackErrorNotification;
+extern const NSNotificationName MGLOfflinePackErrorNotification;
/**
Posted by the shared `MGLOfflineStorage` object when the maximum number of
@@ -52,7 +52,12 @@ extern NSString * const MGLOfflinePackErrorNotification;
calling the `-[MGLOfflineStorage removePack:withCompletionHandler:]` method.
Contact your Mapbox sales representative to have the limit raised.
*/
-extern NSString * const MGLOfflinePackMaximumMapboxTilesReachedNotification;
+extern const NSNotificationName MGLOfflinePackMaximumMapboxTilesReachedNotification;
+
+/**
+ A key in the `userInfo` property of a notification posted by `MGLOfflinePack`.
+ */
+typedef NSString *MGLOfflinePackUserInfoKey NS_EXTENSIBLE_STRING_ENUM;
/**
The key for an `NSNumber` object that indicates an offline pack’s current
@@ -60,7 +65,9 @@ extern NSString * const MGLOfflinePackMaximumMapboxTilesReachedNotification;
`MGLOfflinePackProgressChangedNotification` notification. Call `-integerValue`
on the object to receive the `MGLOfflinePackState`-typed state.
*/
-extern NSString * const MGLOfflinePackStateUserInfoKey;
+extern const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyState;
+
+extern NSString * const MGLOfflinePackStateUserInfoKey __attribute__((deprecated("Use MGLOfflinePackUserInfoKeyState")));
/**
The key for an `NSValue` object that indicates an offline pack’s current
@@ -69,7 +76,9 @@ extern NSString * const MGLOfflinePackStateUserInfoKey;
`-MGLOfflinePackProgressValue` on the object to receive the
`MGLOfflinePackProgress`-typed progress.
*/
-extern NSString * const MGLOfflinePackProgressUserInfoKey;
+extern const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyProgress;
+
+extern NSString * const MGLOfflinePackProgressUserInfoKey __attribute__((deprecated("Use MGLOfflinePackUserInfoKeyProgress")));
/**
The key for an `NSError` object that is encountered in the course of
@@ -77,7 +86,9 @@ extern NSString * const MGLOfflinePackProgressUserInfoKey;
an `MGLOfflinePackErrorNotification` notification. The error’s domain is
`MGLErrorDomain`. See `MGLErrorCode` for possible error codes.
*/
-extern NSString * const MGLOfflinePackErrorUserInfoKey;
+extern const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyError;
+
+extern NSString * const MGLOfflinePackErrorUserInfoKey __attribute__((deprecated("Use MGLOfflinePackUserInfoKeyError")));
/**
The key for an `NSNumber` object that indicates the maximum number of
@@ -87,7 +98,9 @@ extern NSString * const MGLOfflinePackErrorUserInfoKey;
`-unsignedLongLongValue` on the object to receive the `uint64_t`-typed tile
limit.
*/
-extern NSString * const MGLOfflinePackMaximumCountUserInfoKey;
+extern const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyMaximumCount;
+
+extern NSString * const MGLOfflinePackMaximumCountUserInfoKey __attribute__((deprecated("Use MGLOfflinePackUserInfoKeyMaximumCount")));
/**
A block to be called once an offline pack has been completely created and
diff --git a/platform/darwin/src/MGLOfflineStorage.mm b/platform/darwin/src/MGLOfflineStorage.mm
index 5f284b76a1..10acc58b25 100644
--- a/platform/darwin/src/MGLOfflineStorage.mm
+++ b/platform/darwin/src/MGLOfflineStorage.mm
@@ -13,14 +13,18 @@
static NSString * const MGLOfflineStorageFileName = @"cache.db";
static NSString * const MGLOfflineStorageFileName3_2_0_beta_1 = @"offline.db";
-NSString * const MGLOfflinePackProgressChangedNotification = @"MGLOfflinePackProgressChanged";
-NSString * const MGLOfflinePackErrorNotification = @"MGLOfflinePackError";
-NSString * const MGLOfflinePackMaximumMapboxTilesReachedNotification = @"MGLOfflinePackMaximumMapboxTilesReached";
-
-NSString * const MGLOfflinePackStateUserInfoKey = @"State";
-NSString * const MGLOfflinePackProgressUserInfoKey = @"Progress";
-NSString * const MGLOfflinePackErrorUserInfoKey = @"Error";
-NSString * const MGLOfflinePackMaximumCountUserInfoKey = @"MaximumCount";
+const NSNotificationName MGLOfflinePackProgressChangedNotification = @"MGLOfflinePackProgressChanged";
+const NSNotificationName MGLOfflinePackErrorNotification = @"MGLOfflinePackError";
+const NSNotificationName MGLOfflinePackMaximumMapboxTilesReachedNotification = @"MGLOfflinePackMaximumMapboxTilesReached";
+
+const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyState = @"State";
+NSString * const MGLOfflinePackStateUserInfoKey = MGLOfflinePackUserInfoKeyState;
+const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyProgress = @"Progress";
+NSString * const MGLOfflinePackProgressUserInfoKey = MGLOfflinePackUserInfoKeyProgress;
+const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyError = @"Error";
+NSString * const MGLOfflinePackErrorUserInfoKey = MGLOfflinePackUserInfoKeyError;
+const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyMaximumCount = @"MaximumCount";
+NSString * const MGLOfflinePackMaximumCountUserInfoKey = MGLOfflinePackUserInfoKeyMaximumCount;
@interface MGLOfflineStorage () <MGLOfflinePackDelegate>
@@ -317,20 +321,20 @@ NSString * const MGLOfflinePackMaximumCountUserInfoKey = @"MaximumCount";
- (void)offlinePack:(MGLOfflinePack *)pack progressDidChange:(__unused MGLOfflinePackProgress)progress {
[[NSNotificationCenter defaultCenter] postNotificationName:MGLOfflinePackProgressChangedNotification object:pack userInfo:@{
- MGLOfflinePackStateUserInfoKey: @(pack.state),
- MGLOfflinePackProgressUserInfoKey: [NSValue valueWithMGLOfflinePackProgress:progress],
+ MGLOfflinePackUserInfoKeyState: @(pack.state),
+ MGLOfflinePackUserInfoKeyProgress: [NSValue valueWithMGLOfflinePackProgress:progress],
}];
}
- (void)offlinePack:(MGLOfflinePack *)pack didReceiveError:(NSError *)error {
[[NSNotificationCenter defaultCenter] postNotificationName:MGLOfflinePackErrorNotification object:pack userInfo:@{
- MGLOfflinePackErrorUserInfoKey: error,
+ MGLOfflinePackUserInfoKeyError: error,
}];
}
- (void)offlinePack:(MGLOfflinePack *)pack didReceiveMaximumAllowedMapboxTiles:(uint64_t)maximumCount {
[[NSNotificationCenter defaultCenter] postNotificationName:MGLOfflinePackMaximumMapboxTilesReachedNotification object:pack userInfo:@{
- MGLOfflinePackMaximumCountUserInfoKey: @(maximumCount),
+ MGLOfflinePackUserInfoKeyMaximumCount: @(maximumCount),
}];
}
diff --git a/platform/darwin/src/MGLPointCollection.h b/platform/darwin/src/MGLPointCollection.h
new file mode 100644
index 0000000000..db497d0a52
--- /dev/null
+++ b/platform/darwin/src/MGLPointCollection.h
@@ -0,0 +1,51 @@
+#import <Foundation/Foundation.h>
+#import <CoreLocation/CoreLocation.h>
+
+#import "MGLOverlay.h"
+#import "MGLShape.h"
+
+/**
+ The `MGLPointCollection` class is used to define an array of disconnected
+ coordinates. The points in the collection may be related but are not
+ connected visually in any way.
+
+ @note `MGLPointCollection` objects cannot be added to a map view using
+ `-[MGLMapView addAnnotations:]` and related methods. However, when used in a
+ `MGLPointCollectionFeature` to initialize a `MGLGeoJSONSource` that is added
+ to the map view's style, the point collection represents as a group of distinct
+ annotations.
+ */
+@interface MGLPointCollection : MGLShape <MGLOverlay>
+
+/**
+ Creates and returns a `MGLPointCollection` object from the specified set of
+ coordinates.
+
+ @param coords The array of coordinates defining the shape. The data in this
+ array is copied to the new object.
+ @param count The number of items in the `coords` array.
+ @return A new point collection object.
+ */
++ (instancetype)pointCollectionWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
+
+/** The array of coordinates associated with the shape. */
+@property (nonatomic, readonly) CLLocationCoordinate2D *coordinates NS_RETURNS_INNER_POINTER;
+
+/** The number of coordinates associated with the shape. */
+@property (nonatomic, readonly) NSUInteger pointCount;
+
+/**
+ Retrieves one or more coordinates associated with the shape.
+
+ @param coords On input, you must provide a C array of structures large enough
+ to hold the desired number of coordinates. On output, this structure
+ contains the requested coordinate data.
+ @param range The range of points you want. The `location` field indicates the
+ first point you are requesting, with `0` being the first point, `1` being
+ the second point, and so on. The `length` field indicates the number of
+ points you want. The array in _`coords`_ must be large enough to accommodate
+ the number of requested coordinates.
+ */
+- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range;
+
+@end
diff --git a/platform/darwin/src/MGLPointCollection.mm b/platform/darwin/src/MGLPointCollection.mm
new file mode 100644
index 0000000000..5871915b5d
--- /dev/null
+++ b/platform/darwin/src/MGLPointCollection.mm
@@ -0,0 +1,112 @@
+#import "MGLPointCollection_Private.h"
+#import "MGLGeometry_Private.h"
+
+#import <mbgl/util/geometry.hpp>
+#import <mbgl/util/feature.hpp>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation MGLPointCollection
+{
+ size_t _count;
+ MGLCoordinateBounds _bounds;
+}
+
++ (instancetype)pointCollectionWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
+{
+ return [[self alloc] initWithCoordinates:coords count:count];
+}
+
+- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
+{
+ self = [super init];
+ if (self)
+ {
+ _count = count;
+ _coordinates = (CLLocationCoordinate2D *)malloc(_count * sizeof(CLLocationCoordinate2D));
+
+ mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty();
+
+ for (NSUInteger i = 0; i < count; i++)
+ {
+ _coordinates[i] = coords[i];
+ bounds.extend(mbgl::LatLng(coords[i].latitude, coords[i].longitude));
+ }
+
+ _bounds = MGLCoordinateBoundsFromLatLngBounds(bounds);
+ }
+ return self;
+}
+
+- (NSUInteger)pointCount
+{
+ return _count;
+}
+
+- (CLLocationCoordinate2D)coordinate
+{
+ assert(_count > 0);
+
+ return CLLocationCoordinate2DMake(_coordinates[0].latitude, _coordinates[0].longitude);
+}
+
+- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range
+{
+ if (range.location + range.length > _count)
+ {
+ [NSException raise:NSRangeException
+ format:@"Invalid coordinate range %@ extends beyond current coordinate count of %zu",
+ NSStringFromRange(range), _count];
+ }
+
+ NSUInteger index = 0;
+
+ for (NSUInteger i = range.location; i < range.location + range.length; i++)
+ {
+ coords[index] = _coordinates[i];
+ index++;
+ }
+}
+
+- (MGLCoordinateBounds)overlayBounds
+{
+ return _bounds;
+}
+
+- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds
+{
+ return MGLLatLngBoundsFromCoordinateBounds(_bounds).intersects(MGLLatLngBoundsFromCoordinateBounds(overlayBounds));
+}
+
+- (mbgl::Feature)featureObject
+{
+ mbgl::MultiPoint<double> multiPoint;
+ multiPoint.reserve(self.pointCount);
+ for (NSInteger i = 0; i< self.pointCount; i++)
+ {
+ multiPoint.push_back(mbgl::Point<double>(self.coordinates[i].longitude, self.coordinates[i].latitude));
+ }
+ return mbgl::Feature {multiPoint};
+}
+
+- (NSDictionary *)geoJSONDictionary
+{
+ NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:self.pointCount];
+ for (NSUInteger index = 0; index < self.pointCount; index++) {
+ CLLocationCoordinate2D coordinate = self.coordinates[index];
+ [coordinates addObject:@[@(coordinate.longitude), @(coordinate.latitude)]];
+ }
+
+ return @{@"type": @"MultiPoint",
+ @"coordinates": coordinates};
+}
+
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"<%@: %p; count = %lu>",
+ NSStringFromClass([self class]), (void *)self, (unsigned long)_count];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLPointCollection_Private.h b/platform/darwin/src/MGLPointCollection_Private.h
new file mode 100644
index 0000000000..039c1f18be
--- /dev/null
+++ b/platform/darwin/src/MGLPointCollection_Private.h
@@ -0,0 +1,11 @@
+#import "MGLPointCollection.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface MGLPointCollection (Private)
+
+- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLPolygon.h b/platform/darwin/src/MGLPolygon.h
index 6d53356ba4..3d5b36abb6 100644
--- a/platform/darwin/src/MGLPolygon.h
+++ b/platform/darwin/src/MGLPolygon.h
@@ -36,7 +36,7 @@ NS_ASSUME_NONNULL_BEGIN
@param count The number of items in the `coords` array.
@return A new polygon object.
*/
-+ (instancetype)polygonWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count NS_SWIFT_NAME(polygon(coordinates:count:));
++ (instancetype)polygonWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
/**
Creates and returns an `MGLPolygon` object from the specified set of
diff --git a/platform/darwin/src/MGLPolyline.h b/platform/darwin/src/MGLPolyline.h
index 6642afef7e..d0274b44e3 100644
--- a/platform/darwin/src/MGLPolyline.h
+++ b/platform/darwin/src/MGLPolyline.h
@@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
@param count The number of items in the `coords` array.
@return A new polyline object.
*/
-+ (instancetype)polylineWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count NS_SWIFT_NAME(polyline(coordinates:count:));
++ (instancetype)polylineWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
@end
diff --git a/platform/darwin/src/MGLRasterSource.mm b/platform/darwin/src/MGLRasterSource.mm
index 41b9a5b043..fc47c23853 100644
--- a/platform/darwin/src/MGLRasterSource.mm
+++ b/platform/darwin/src/MGLRasterSource.mm
@@ -1,18 +1,29 @@
#import "MGLRasterSource.h"
+#import "MGLMapView_Private.h"
#import "MGLSource_Private.h"
#import "MGLTileSet_Private.h"
#import "NSURL+MGLAdditions.h"
#include <mbgl/style/sources/raster_source.hpp>
+@interface MGLRasterSource ()
+
+@property (nonatomic) mbgl::style::RasterSource *rawSource;
+
+@end
+
@implementation MGLRasterSource
+{
+ std::unique_ptr<mbgl::style::RasterSource> _pendingSource;
+}
- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url tileSize:(CGFloat)tileSize
{
if (self = [super initWithIdentifier:identifier]) {
_URL = url;
_tileSize = tileSize;
+ [self commonInit];
}
return self;
}
@@ -23,11 +34,12 @@
{
_tileSet = tileSet;
_tileSize = tileSize;
+ [self commonInit];
}
return self;
}
-- (std::unique_ptr<mbgl::style::Source>)mbglSource
+- (void)commonInit
{
std::unique_ptr<mbgl::style::RasterSource> source;
@@ -42,10 +54,15 @@
source = std::make_unique<mbgl::style::RasterSource>(self.identifier.UTF8String,
self.tileSet.mbglTileset,
uint16_t(self.tileSize));
-
}
- return std::move(source);
+ _pendingSource = std::move(source);
+ self.rawSource = _pendingSource.get();
+}
+
+- (void)addToMapView:(MGLMapView *)mapView
+{
+ mapView.mbglMap->addSource(std::move(_pendingSource));
}
@end
diff --git a/platform/darwin/src/MGLSource.mm b/platform/darwin/src/MGLSource.mm
index 85bbc06342..1b889d44d7 100644
--- a/platform/darwin/src/MGLSource.mm
+++ b/platform/darwin/src/MGLSource.mm
@@ -2,27 +2,14 @@
#include <mbgl/style/source.hpp>
-@interface MGLSource ()
-
-@property (nonatomic) mbgl::style::Source *source;
-
-@end
-
@implementation MGLSource
-- (instancetype)initWithIdentifier:(NSString *)identifier {
+- (instancetype)initWithIdentifier:(NSString *)identifier
+{
if (self = [super init]) {
_identifier = identifier;
}
return self;
}
-- (std::unique_ptr<mbgl::style::Source>)mbglSource {
- [NSException raise:@"MGLAbstractClassException" format:
- @"The source %@ cannot be added to the style. "
- @"Make sure the source was created as a member of a concrete subclass of MGLSource.",
- NSStringFromClass(self)];
- return nil;
-}
-
@end
diff --git a/platform/darwin/src/MGLSource_Private.h b/platform/darwin/src/MGLSource_Private.h
index 2b8658b4cb..dff230ede5 100644
--- a/platform/darwin/src/MGLSource_Private.h
+++ b/platform/darwin/src/MGLSource_Private.h
@@ -3,10 +3,29 @@
#include <mbgl/mbgl.hpp>
#include <mbgl/style/source.hpp>
+@class MGLMapView;
+
@interface MGLSource (Private)
-- (std::unique_ptr<mbgl::style::Source>)mbglSource;
+/**
+ A raw pointer to the mbgl object, which is always initialized, either to the
+ value returned by `mbgl::Map getSource`, or for independently created objects,
+ to the pointer value held in `pendingSource`. In the latter case, this raw
+ pointer value stays even after ownership of the object is transferred via
+ `mbgl::Map addSource`.
+ */
+@property (nonatomic) mbgl::style::Source *rawSource;
-@property (nonatomic) mbgl::style::Source *source;
+/**
+ Adds the mbgl source that this object represents to the mbgl map.
+
+ Once a mbgl source is added, ownership of the object is transferred to the
+ `mbgl::Map` and this object no longer has an active unique_ptr reference to the
+ `mbgl::Source`. If this object's mbgl source is in that state, the mbgl source
+ can still be changed but the changes will not be visible until the `MGLSource`
+ is added back to the map via `-[MGLStyle addSource:]` and styled with a
+ `MGLLayer`.
+ */
+- (void)addToMapView:(MGLMapView *)mapView;
@end
diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm
index 3964b47ad6..a17b7d6b74 100644
--- a/platform/darwin/src/MGLStyle.mm
+++ b/platform/darwin/src/MGLStyle.mm
@@ -142,6 +142,7 @@ static NSURL *MGLStyleURL_emerald;
- (MGLSource *)sourceWithIdentifier:(NSString *)identifier
{
auto mbglSource = self.mapView.mbglMap->getSource(identifier.UTF8String);
+
if (!mbglSource) {
return nil;
}
@@ -159,8 +160,8 @@ static NSURL *MGLStyleURL_emerald;
NSAssert(NO, @"Unrecognized source type");
return nil;
}
-
- source.source = mbglSource;
+
+ source.rawSource = mbglSource;
return source;
}
@@ -205,12 +206,17 @@ static NSURL *MGLStyleURL_emerald;
- (void)addSource:(MGLSource *)source
{
- self.mapView.mbglMap->addSource(source.mbglSource);
+ [source addToMapView:self.mapView];
}
- (void)removeSource:(MGLSource *)source
{
self.mapView.mbglMap->removeSource(source.identifier.UTF8String);
+
+ // Once a mbgl source is removed from the map, ownership does not return
+ // to the MGL source. Therefore, the rawSource pointer is set to NULL
+ // so that the implementation of MGL source can avoid using it again.
+ source.rawSource = NULL;
}
- (NS_ARRAY_OF(NSString *) *)styleClasses
diff --git a/platform/darwin/src/MGLStyleValue.h b/platform/darwin/src/MGLStyleValue.h
index eb0eaf5340..ab5e76bbe3 100644
--- a/platform/darwin/src/MGLStyleValue.h
+++ b/platform/darwin/src/MGLStyleValue.h
@@ -68,7 +68,7 @@ NS_ASSUME_NONNULL_BEGIN
The `MGLStyleConstantValue` class takes a generic parameter `T` that indicates
the Foundation class being wrapped by this class.
*/
-@interface MGLStyleConstantValue<T> : MGLStyleValue
+@interface MGLStyleConstantValue<T> : MGLStyleValue<T>
#pragma mark Creating a Style Constant Value
@@ -111,7 +111,7 @@ NS_ASSUME_NONNULL_BEGIN
The `MGLStyleFunction` class takes a generic parameter `T` that indicates the
Foundation class being wrapped by this class.
*/
-@interface MGLStyleFunction<T> : MGLStyleValue
+@interface MGLStyleFunction<T> : MGLStyleValue<T>
#pragma mark Creating a Style Function
diff --git a/platform/darwin/src/MGLSymbolStyleLayer.h b/platform/darwin/src/MGLSymbolStyleLayer.h
index 3fcecedca3..9bd943a34e 100644
--- a/platform/darwin/src/MGLSymbolStyleLayer.h
+++ b/platform/darwin/src/MGLSymbolStyleLayer.h
@@ -388,7 +388,7 @@ typedef NS_ENUM(NSUInteger, MGLTextTranslateAnchor) {
/**
Value to use for a text label. Feature properties are specified using tokens like {field_name}.
- The default value of this property is an `MGLStyleValue` object containing the string ``. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing the empty string. Set this property to `nil` to reset it to the default value.
*/
@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *textField;
diff --git a/platform/darwin/src/MGLTypes.h b/platform/darwin/src/MGLTypes.h
index a3ea587add..e9e05bc684 100644
--- a/platform/darwin/src/MGLTypes.h
+++ b/platform/darwin/src/MGLTypes.h
@@ -21,7 +21,7 @@
NS_ASSUME_NONNULL_BEGIN
/** Indicates an error occurred in the Mapbox SDK. */
-extern NSString * const MGLErrorDomain;
+extern NSErrorDomain const MGLErrorDomain;
/** Error constants for the Mapbox SDK. */
typedef NS_ENUM(NSInteger, MGLErrorCode) {
@@ -97,3 +97,9 @@ NS_ASSUME_NONNULL_END
#define NS_MUTABLE_DICTIONARY_OF(ObjectClass...) NSMutableDictionary
#endif
#endif
+
+#if !defined(FOUNDATION_SWIFT_SDK_EPOCH_LESS_THAN) || FOUNDATION_SWIFT_SDK_EPOCH_LESS_THAN(8)
+ #define NS_STRING_ENUM
+ #define NS_EXTENSIBLE_STRING_ENUM
+ #define NSNotificationName NSString *
+#endif
diff --git a/platform/darwin/src/MGLVectorSource.mm b/platform/darwin/src/MGLVectorSource.mm
index 3597812359..995565419f 100644
--- a/platform/darwin/src/MGLVectorSource.mm
+++ b/platform/darwin/src/MGLVectorSource.mm
@@ -1,12 +1,22 @@
#import "MGLVectorSource.h"
+#import "MGLMapView_Private.h"
#import "MGLSource_Private.h"
#import "MGLTileSet_Private.h"
#import "NSURL+MGLAdditions.h"
#include <mbgl/style/sources/vector_source.hpp>
+@interface MGLVectorSource ()
+
+@property (nonatomic) mbgl::style::VectorSource *rawSource;
+
+@end
+
@implementation MGLVectorSource
+{
+ std::unique_ptr<mbgl::style::VectorSource> _pendingSource;
+}
static NSString *MGLVectorSourceType = @"vector";
@@ -15,6 +25,7 @@ static NSString *MGLVectorSourceType = @"vector";
if (self = [super initWithIdentifier:identifier])
{
_URL = url;
+ [self commonInit];
}
return self;
}
@@ -24,11 +35,12 @@ static NSString *MGLVectorSourceType = @"vector";
if (self = [super initWithIdentifier:identifier])
{
_tileSet = tileSet;
+ [self commonInit];
}
return self;
}
-- (std::unique_ptr<mbgl::style::Source>)mbglSource
+- (void)commonInit
{
std::unique_ptr<mbgl::style::VectorSource> source;
@@ -43,7 +55,13 @@ static NSString *MGLVectorSourceType = @"vector";
self.tileSet.mbglTileset);
}
- return std::move(source);
+ _pendingSource = std::move(source);
+ self.rawSource = _pendingSource.get();
+}
+
+- (void)addToMapView:(MGLMapView *)mapView
+{
+ mapView.mbglMap->addSource(std::move(_pendingSource));
}
@end
diff --git a/platform/darwin/test/MGLFeatureTests.mm b/platform/darwin/test/MGLFeatureTests.mm
index 18c3fd16c2..7f464aaab1 100644
--- a/platform/darwin/test/MGLFeatureTests.mm
+++ b/platform/darwin/test/MGLFeatureTests.mm
@@ -227,24 +227,6 @@
XCTAssertEqualObjects(geoJSONFeature[@"geometry"], expectedGeometry);
}
-- (void)testMultiPointFeatureGeoJSONDictionary {
- CLLocationCoordinate2D coord1 = { 0, 0 };
- CLLocationCoordinate2D coord2 = { 10, 10 };
- CLLocationCoordinate2D coord3 = { 0, 0 };
- CLLocationCoordinate2D coords[] = { coord1, coord2, coord3 };
- MGLMultiPointFeature *multiPointFeature = [MGLMultiPointFeature multiPointWithCoordinates:coords count:3];
-
- // A GeoJSON feature
- NSDictionary *geoJSONFeature = [multiPointFeature geoJSONDictionary];
-
- // it has the correct geometry
- NSDictionary *expectedGeometry = @{@"type": @"MultiPoint",
- @"coordinates": @[@[@(coord1.longitude), @(coord1.latitude)],
- @[@(coord2.longitude), @(coord2.latitude)],
- @[@(coord3.longitude), @(coord3.latitude)]]};
- XCTAssertEqualObjects(geoJSONFeature[@"geometry"], expectedGeometry);
-}
-
- (void)testMultiPolylineFeatureGeoJSONDictionary {
CLLocationCoordinate2D coord1 = { 0, 0 };
CLLocationCoordinate2D coord2 = { 10, 10 };
@@ -296,6 +278,25 @@
XCTAssertEqualObjects(geoJSONFeature[@"geometry"], expectedGeometry);
}
+- (void)testPointCollectionFeatureGeoJSONDictionary {
+ CLLocationCoordinate2D coord1 = { 0, 0 };
+ CLLocationCoordinate2D coord2 = { 10, 10 };
+ CLLocationCoordinate2D coord3 = { 0, 0 };
+ CLLocationCoordinate2D coords[] = { coord1, coord2, coord3 };
+ MGLPointCollectionFeature *pointCollectionFeature = [MGLPointCollectionFeature pointCollectionWithCoordinates:coords count:3];
+
+ // A GeoJSON feature
+ NSDictionary *geoJSONFeature = [pointCollectionFeature geoJSONDictionary];
+
+ // it has the correct geometry
+ NSDictionary *expectedGeometry = @{@"type": @"MultiPoint",
+ @"coordinates": @[@[@(coord1.longitude), @(coord1.latitude)],
+ @[@(coord2.longitude), @(coord2.latitude)],
+ @[@(coord3.longitude), @(coord3.latitude)]]};
+ XCTAssertEqualObjects(geoJSONFeature[@"geometry"], expectedGeometry);
+
+}
+
- (void)testShapeCollectionFeatureGeoJSONDictionary {
MGLPointAnnotation *pointFeature = [[MGLPointAnnotation alloc] init];
CLLocationCoordinate2D pointCoordinate = { 10, 10 };
diff --git a/platform/ios/test/MGLGeoJSONSourceTests.mm b/platform/darwin/test/MGLGeoJSONSourceTests.mm
index 40d8067985..be8bb143ce 100644
--- a/platform/ios/test/MGLGeoJSONSourceTests.mm
+++ b/platform/darwin/test/MGLGeoJSONSourceTests.mm
@@ -10,23 +10,17 @@
@interface MGLGeoJSONSourceTests : XCTestCase
@end
-@interface MGLPolygonFeature (Test)
-
-@property (nonatomic, copy, readwrite) NS_DICTIONARY_OF(NSString *, id) *attributes;
-
-@end
-
@implementation MGLGeoJSONSourceTests
- (void)testMGLGeoJSONSourceWithOptions {
NSURL *url = [NSURL URLWithString:@"http://www.mapbox.com/source"];
- NSDictionary *options = @{MGLGeoJSONClusterOption: @(YES),
- MGLGeoJSONClusterRadiusOption: @42,
- MGLGeoJSONClusterMaximumZoomLevelOption: @98,
- MGLGeoJSONMaximumZoomLevelOption: @99,
- MGLGeoJSONBufferOption: @1976,
- MGLGeoJSONToleranceOption: @0.42};
+ NSDictionary *options = @{MGLGeoJSONSourceOptionClustered: @YES,
+ MGLGeoJSONSourceOptionClusterRadius: @42,
+ MGLGeoJSONSourceOptionMaximumZoomLevelForClustering: @98,
+ MGLGeoJSONSourceOptionMaximumZoomLevel: @99,
+ MGLGeoJSONSourceOptionBuffer: @1976,
+ MGLGeoJSONSourceOptionSimplificationTolerance: @0.42};
MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" URL:url options:options];
auto mbglOptions = [source geoJSONOptions];
@@ -37,9 +31,8 @@
XCTAssertEqual(mbglOptions.buffer, 1976);
XCTAssertEqual(mbglOptions.tolerance, 0.42);
- options = @{MGLGeoJSONClusterOption: @"number 1"};
- source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" URL:url options:options];
- XCTAssertThrows([source geoJSONOptions]);
+ options = @{MGLGeoJSONSourceOptionClustered: @"number 1"};
+ XCTAssertThrows([[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" URL:url options:options]);
}
- (void)testMGLGeoJSONSourceWithData {
@@ -49,8 +42,6 @@
NSData *data = [geoJSON dataUsingEncoding:NSUTF8StringEncoding];
MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" geoJSONData:data options:nil];
- [source mbglSource];
-
XCTAssertNotNil(source.features);
XCTAssertEqual(source.features.count, 1);
XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLPolylineFeature class]]);
@@ -62,8 +53,6 @@
MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" features:@[polylineFeature] options:nil];
- std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
-
XCTAssertNotNil(source.features);
XCTAssertEqual(source.features.count, 1);
XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLPolylineFeature class]]);
@@ -101,8 +90,6 @@
MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" features:@[polygonFeature] options:nil];
- std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
-
XCTAssertNotNil(source.features);
XCTAssertEqual(source.features.count, 1);
MGLPolygonFeature *expectedPolygonFeature = (MGLPolygonFeature *)source.features.firstObject;
@@ -137,56 +124,7 @@
MGLPolygonFeature *polygonFeature = [MGLPolygonFeature polygonWithCoordinates:coordinates count:5 interiorPolygons:@[polygon]];
MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" features:@[polygonFeature] options:nil];
-
- std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
-
- XCTAssertNotNil(source.features);
- XCTAssertEqual(source.features.count, 1);
- XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLPolygonFeature class]]);
-}
-
-
-- (void)testMGLGeoJSONSourceWithMultiPointFeaturesUsingPolylines {
- CLLocationCoordinate2D coordinates[] = {
- CLLocationCoordinate2DMake(100.0, 0.0),
- CLLocationCoordinate2DMake(101.0, 0.0),
- CLLocationCoordinate2DMake(101.0, 1.0),
- CLLocationCoordinate2DMake(100.0, 1.0),
- CLLocationCoordinate2DMake(100.0, 0.0)};
-
- MGLMultiPointFeature *multiPointFeature = [MGLMultiPointFeature multiPointWithCoordinates:coordinates count:5];
-
- MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" features:@[multiPointFeature] options:nil];
-
- std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
-
- XCTAssertNotNil(source.features);
- XCTAssertEqual(source.features.count, 1);
- XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLMultiPointFeature class]]);
-}
-
-- (void)testMGLGeoJSONSourceWithMultiPointFeaturesUsingPolygons {
- CLLocationCoordinate2D coordinates[] = {
- CLLocationCoordinate2DMake(100.0, 0.0),
- CLLocationCoordinate2DMake(101.0, 0.0),
- CLLocationCoordinate2DMake(101.0, 1.0),
- CLLocationCoordinate2DMake(100.0, 1.0),
- CLLocationCoordinate2DMake(100.0, 0.0)};
-
- CLLocationCoordinate2D interiorCoordinates[] = {
- CLLocationCoordinate2DMake(100.2, 0.2),
- CLLocationCoordinate2DMake(100.8, 0.2),
- CLLocationCoordinate2DMake(100.8, 0.8),
- CLLocationCoordinate2DMake(100.2, 0.8),
- CLLocationCoordinate2DMake(100.2, 0.2)};
-
- MGLPolygon *polygon = [MGLPolygon polygonWithCoordinates:interiorCoordinates count:5];
-
- MGLMultiPointFeature *multiPointFeature = (MGLMultiPointFeature *)[MGLPolygonFeature polygonWithCoordinates:coordinates count:5 interiorPolygons:@[polygon]];
-
- MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" features:@[multiPointFeature] options:nil];
-
- std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
+
XCTAssertNotNil(source.features);
XCTAssertEqual(source.features.count, 1);
@@ -202,8 +140,6 @@
MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" features:@[multiPolylineFeature] options:nil];
- std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
-
XCTAssertNotNil(source.features);
XCTAssertEqual(source.features.count, 1);
XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLMultiPolylineFeature class]]);
@@ -233,8 +169,6 @@
MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" features:@[multiPolygonFeature] options:nil];
- std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
-
XCTAssertNotNil(source.features);
XCTAssertEqual(source.features.count, 1);
XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLMultiPolygonFeature class]]);
@@ -247,13 +181,26 @@
MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"souce-id" features:@[pointFeature] options:nil];
- std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
-
XCTAssertNotNil(source.features);
XCTAssertEqual(source.features.count, 1);
XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLPointFeature class]]);
}
+- (void)testMGLGeoJSONSourceWithPointCollectionFeature {
+ CLLocationCoordinate2D coordinates[] = {
+ CLLocationCoordinate2DMake(100.0, 0.0),
+ CLLocationCoordinate2DMake(101.0, 0.0),
+ CLLocationCoordinate2DMake(101.0, 1.0),
+ CLLocationCoordinate2DMake(100.0, 1.0),
+ CLLocationCoordinate2DMake(100.0, 0.0)};
+ MGLPointCollectionFeature *pointCollectionFeature = [MGLPointCollectionFeature pointCollectionWithCoordinates:coordinates count:5];
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"souce-id" features:@[pointCollectionFeature] options:nil];
+
+ XCTAssertNotNil(source.features);
+ XCTAssertEqual(source.features.count, 1);
+ XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLPointCollectionFeature class]]);
+}
+
- (void)testMGLGeoJSONSourceWithShapeCollectionFeatures {
CLLocationCoordinate2D coordinates[] = {
CLLocationCoordinate2DMake(100.0, 0.0),
@@ -280,18 +227,16 @@
MGLMultiPolylineFeature *multiPolylineFeature = [MGLMultiPolylineFeature multiPolylineWithPolylines:@[polylineFeature, polylineFeature]];
- MGLMultiPointFeature *multiPointFeature = (MGLMultiPointFeature *)[MGLPolygonFeature polygonWithCoordinates:coordinates count:5 interiorPolygons:@[polygon]];
+ MGLPointCollectionFeature *pointCollectionFeature = [MGLPointCollectionFeature pointCollectionWithCoordinates:coordinates count:5];
MGLPointFeature *pointFeature = [MGLPointFeature new];
pointFeature.coordinate = CLLocationCoordinate2DMake(100.2, 0.2);
- MGLShapeCollectionFeature *shapeCollectionFeature = [MGLShapeCollectionFeature shapeCollectionWithShapes:@[polygonFeature, polylineFeature, multiPolygonFeature, multiPolylineFeature, multiPointFeature, pointFeature]];
+ MGLShapeCollectionFeature *shapeCollectionFeature = [MGLShapeCollectionFeature shapeCollectionWithShapes:@[polygonFeature, polylineFeature, multiPolygonFeature, multiPolylineFeature, pointCollectionFeature, pointFeature]];
- MGLShapeCollectionFeature *shapeCollectionFeature_1 = [MGLShapeCollectionFeature shapeCollectionWithShapes:@[polygonFeature, polylineFeature, multiPolygonFeature, multiPolylineFeature, multiPointFeature, pointFeature, shapeCollectionFeature]];
+ MGLShapeCollectionFeature *shapeCollectionFeature_1 = [MGLShapeCollectionFeature shapeCollectionWithShapes:@[polygonFeature, polylineFeature, multiPolygonFeature, multiPolylineFeature, pointCollectionFeature, pointFeature, shapeCollectionFeature]];
- MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"" features:@[shapeCollectionFeature_1] options:nil];
-
- XCTAssertThrowsSpecificNamed([source mbglSource], NSException, @"Method unavailable");
+ XCTAssertThrowsSpecificNamed([[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" features:@[shapeCollectionFeature_1] options:nil], NSException, @"Method unavailable");
}
@end
diff --git a/platform/darwin/test/MGLOfflineStorageTests.m b/platform/darwin/test/MGLOfflineStorageTests.m
index 8400cb43cb..cd13a9262e 100644
--- a/platform/darwin/test/MGLOfflineStorageTests.m
+++ b/platform/darwin/test/MGLOfflineStorageTests.m
@@ -90,11 +90,11 @@
NSDictionary *userInfo = notification.userInfo;
XCTAssertNotNil(userInfo, @"Progress change notification should have a userInfo dictionary.");
- NSNumber *stateNumber = userInfo[MGLOfflinePackStateUserInfoKey];
+ NSNumber *stateNumber = userInfo[MGLOfflinePackUserInfoKeyState];
XCTAssert([stateNumber isKindOfClass:[NSNumber class]], @"Progress change notification’s state should be an NSNumber.");
XCTAssertEqual(stateNumber.integerValue, pack.state, @"State in a progress change notification should match the pack’s state.");
- NSValue *progressValue = userInfo[MGLOfflinePackProgressUserInfoKey];
+ NSValue *progressValue = userInfo[MGLOfflinePackUserInfoKeyProgress];
XCTAssert([progressValue isKindOfClass:[NSValue class]], @"Progress change notification’s progress should be an NSValue.");
XCTAssertEqualObjects(progressValue, [NSValue valueWithMGLOfflinePackProgress:pack.progress], @"Progress change notification’s progress should match pack’s progress.");
diff --git a/platform/darwin/test/MGLStyleLayerTests.m b/platform/darwin/test/MGLStyleLayerTests.m
index b16bcfed56..74c6b2f906 100644
--- a/platform/darwin/test/MGLStyleLayerTests.m
+++ b/platform/darwin/test/MGLStyleLayerTests.m
@@ -13,6 +13,7 @@
[vc.view addSubview:_mapView];
_mapView.delegate = self;
#else
+ [MGLAccountManager setAccessToken:@"pk.feedcafedeadbeefbadebede"];
NSWindowController *windowController = [[NSWindowController alloc] initWithWindowNibName:@"MGLStyleLayerTests" owner:self];
[windowController showWindow:nil];
#endif
diff --git a/platform/darwin/test/MGLStyleValueTests.swift b/platform/darwin/test/MGLStyleValueTests.swift
new file mode 100644
index 0000000000..f7bf343852
--- /dev/null
+++ b/platform/darwin/test/MGLStyleValueTests.swift
@@ -0,0 +1,36 @@
+import XCTest
+import Mapbox
+
+class MGLStyleValueTests: XCTestCase {
+ func testConstantValues() {
+ let geoJSONSource = MGLGeoJSONSource(identifier: "test", features: [], options: nil)
+ let symbolStyleLayer = MGLSymbolStyleLayer(identifier: "test", source: geoJSONSource)
+
+ // Boolean
+ symbolStyleLayer.iconAllowOverlap = MGLStyleConstantValue(rawValue: true)
+ XCTAssertEqual((symbolStyleLayer.iconAllowOverlap as! MGLStyleConstantValue<NSNumber>).rawValue, true)
+
+ // Number
+ symbolStyleLayer.iconHaloWidth = MGLStyleConstantValue(rawValue: 3)
+ XCTAssertEqual((symbolStyleLayer.iconHaloWidth as! MGLStyleConstantValue<NSNumber>).rawValue, 3)
+
+ // String
+ symbolStyleLayer.textField = MGLStyleConstantValue(rawValue: "{name}")
+ XCTAssertEqual((symbolStyleLayer.textField as! MGLStyleConstantValue<NSString>).rawValue, "{name}")
+ }
+
+ func testFunctions() {
+ let geoJSONSource = MGLGeoJSONSource(identifier: "test", features: [], options: nil)
+ let symbolStyleLayer = MGLSymbolStyleLayer(identifier: "test", source: geoJSONSource)
+
+ // Boolean
+ let stops: [NSNumber: MGLStyleValue<NSNumber>] = [
+ 1: MGLStyleValue(rawValue: true),
+ 2: MGLStyleValue(rawValue: false),
+ 3: MGLStyleValue(rawValue: true),
+ 4: MGLStyleValue(rawValue: false),
+ ]
+ symbolStyleLayer.iconAllowOverlap = MGLStyleFunction<NSNumber>(base: 1, stops: stops)
+ XCTAssertEqual((symbolStyleLayer.iconAllowOverlap as! MGLStyleFunction<NSNumber>), MGLStyleFunction(base: 1, stops: stops))
+ }
+}
diff --git a/platform/ios/test/MGLTileSetTests.mm b/platform/darwin/test/MGLTileSetTests.mm
index d77046928c..d77046928c 100644
--- a/platform/ios/test/MGLTileSetTests.mm
+++ b/platform/darwin/test/MGLTileSetTests.mm
diff --git a/platform/darwin/test/test-Bridging-Header.h b/platform/darwin/test/test-Bridging-Header.h
new file mode 100644
index 0000000000..e11d920b12
--- /dev/null
+++ b/platform/darwin/test/test-Bridging-Header.h
@@ -0,0 +1,3 @@
+//
+// Use this file to import your target's public headers that you would like to expose to Swift.
+//
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index b064c7181b..494adbda64 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -7,9 +7,10 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
### Packaging
* Xcode 7.3 or above is required for using this SDK. ([#6059](https://github.com/mapbox/mapbox-gl-native/issues/6059))
-* Fixed an issue with symbols not being properly stripped from the dynamic framework. The dSYM file included with the standard dynamic framework in previous releases (e.g., `mapbox-ios-sdk-3.3.4-dynamic.zip` or the `Mapbox-iOS-SDK` pod) could not be used to symbolicate crashes. ([#6531](https://github.com/mapbox/mapbox-gl-native/pull/6531))
+* Fixed an issue with symbols not being properly stripped from the dynamic framework. The dSYM file included with the standard dynamic framework in previous releases (e.g., `mapbox-ios-sdk-3.3.5-dynamic.zip` or the `Mapbox-iOS-SDK` pod) could not be used to symbolicate crashes. ([#6531](https://github.com/mapbox/mapbox-gl-native/pull/6531))
* Simulator architecture slices are included in the included dSYM file, allowing you to symbolicate crashes that occur in the Simulator. ([#5740](https://github.com/mapbox/mapbox-gl-native/pull/5740))
* Clarified that the `-ObjC` linker flag is required for linking against the static framework distribution of this SDK. ([#6213](https://github.com/mapbox/mapbox-gl-native/pull/6213))
+* Added documentation for the Info.plist keys used by this SDK. ([#6833](https://github.com/mapbox/mapbox-gl-native/pull/6833))
### Styles and data
@@ -18,8 +19,11 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* GeoJSON sources specified by the stylesheet at design time now support `cluster`, `clusterMaxZoom`, and `clusterRadius` attributes for clustering point features on the base map. ([#5724](https://github.com/mapbox/mapbox-gl-native/pull/5724))
* Added [quadkey](https://msdn.microsoft.com/en-us/library/bb259689.aspx) support and limited WMS support in raster tile URL templates. ([#5628](https://github.com/mapbox/mapbox-gl-native/pull/5628))
* TileJSON manifests can now specify `"scheme": "tms"` to indicate the use of [TMS](https://en.wikipedia.org/wiki/Tile_Map_Service) coordinates. ([#2270](https://github.com/mapbox/mapbox-gl-native/pull/2270))
+* Fixed an issue causing abstract MGLMultiPointFeature objects to be returned in feature query results. Now concrete MGLPointCollectionFeature objects are returned. ([#6742](https://github.com/mapbox/mapbox-gl-native/pull/6742))
* Fixed rendering artifacts and missing glyphs that occurred after viewing a large number of CJK characters on the map. ([#5908](https://github.com/mapbox/mapbox-gl-native/pull/5908))
* `-[MGLMapView resetPosition]` now resets to the current style’s default center coordinates, zoom level, direction, and pitch, if specified. ([#6127](https://github.com/mapbox/mapbox-gl-native/pull/6127))
+* Fixed an issue where feature querying sometimes failed to return the expected features when the map was tilted. ([#6773](https://github.com/mapbox/mapbox-gl-native/pull/6773))
+* MGLFeature’s `attributes` and `identifier` properties are now writable. ([#6728](https://github.com/mapbox/mapbox-gl-native/pull/6728))
* The `text-pitch-alignment` property is now supported in stylesheets for improved street label legibility on a tilted map. ([#5288](https://github.com/mapbox/mapbox-gl-native/pull/5288))
* The `icon-text-fit` and `icon-text-fit-padding` properties are now supported in stylesheets, allowing the background of a shield to automatically resize to fit the shield’s text. ([#5334](https://github.com/mapbox/mapbox-gl-native/pull/5334))
* The `circle-pitch-scale` property is now supported in stylesheets, allowing circle features in a tilted base map to scale or remain the same size as the viewing distance changes. ([#5576](https://github.com/mapbox/mapbox-gl-native/pull/5576))
@@ -31,6 +35,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* A source’s tiles are no longer rendered when the map is outside the source’s supported zoom levels. ([#6345](https://github.com/mapbox/mapbox-gl-native/pull/6345))
* Improved style parsing performance. ([#6170](https://github.com/mapbox/mapbox-gl-native/pull/6170))
* Improved feature querying performance. ([#6514](https://github.com/mapbox/mapbox-gl-native/pull/6514))
+* Fixed an issue where shapes that cannot currently be visually represented as annotations were still shown on the map as point annotations. ([#6764](https://github.com/mapbox/mapbox-gl-native/issues/6764))
### User location
@@ -43,16 +48,18 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
### Annotations
* MGLPolyline annotations and the exterior coordinates of MGLPolygon annotations are now able to be mutated, part or all, and changes are displayed immediately. ([#6565](https://github.com/mapbox/mapbox-gl-native/pull/6565))
+* Added new APIs to MGLMapView to query for visible annotations. Combined with `-[MGLMapView viewForAnnotation:]`, these APIs can be used to access all visible annotation views. ([6061](https://github.com/mapbox/mapbox-gl-native/pull/6061))
+* Fixed an issue causing offscreen annotation views to be updated even when they were in the reuse queue. ([#5987](https://github.com/mapbox/mapbox-gl-native/pull/5987))
* Fixed an issue preventing MGLAnnotationView from animating when its coordinate changes. ([#6215](https://github.com/mapbox/mapbox-gl-native/pull/6215))
* Fixed an issue causing the wrong annotation view to be selected when tapping an annotation view with a center offset applied. ([#5931](https://github.com/mapbox/mapbox-gl-native/pull/5931))
* Fixed an issue that assigned annotation views to polyline and polygon annotations. ([#5770](https://github.com/mapbox/mapbox-gl-native/pull/5770))
* Per documentation, the first and last coordinates in an MGLPolygon must be identical in order for the polygon to draw correctly. The same is true for an MGLPolygon’s interior polygon. ([#5514](https://github.com/mapbox/mapbox-gl-native/pull/5514))
* To make an MGLPolyline or MGLPolygon span the antimeridian, specify coordinates with longitudes greater than 180° or less than −180°. ([#6088](https://github.com/mapbox/mapbox-gl-native/pull/6088))
+* Deprecated `-[MGLMapViewDelegate mapView:alphaForShapeAnnotation:]` in favor of specifying an alpha component via `-[MGLMapViewDelegate mapView:strokeColorForShapeAnnotation:]` or `-[MGLMapViewDelegate mapView:fillColorForPolygonAnnotation:]`. ([#6706](https://github.com/mapbox/mapbox-gl-native/pull/6706))
+* Fixed an issue that caused an annotation view to disappear if it isn’t created using the annotation view reuse queue. ([#6485](https://github.com/mapbox/mapbox-gl-native/pull/6485))
+* Fixed an issue that could reset user-added transformations on annotation views. ([#6166](https://github.com/mapbox/mapbox-gl-native/pull/6166))
* Improved the performance of relocating a non-view-backed point annotation by changing its `coordinate` property. ([#5385](https://github.com/mapbox/mapbox-gl-native/pull/5385))
* Improved the precision of annotations at zoom levels greater than 18. ([#5517](https://github.com/mapbox/mapbox-gl-native/pull/5517))
-* Fixed an issue that could reset user-added transformations on annotation views. ([#6166](https://github.com/mapbox/mapbox-gl-native/pull/6166))
-* Fixed an issue that caused an annotation view to disappear if it isn’t created using the annotation view reuse queue. ([#6485](https://github.com/mapbox/mapbox-gl-native/pull/6485))
-* Deprecated `-[MGLMapViewDelegate mapView:alphaForShapeAnnotation:]` in favor of specifying an alpha component via `-[MGLMapViewDelegate mapView:strokeColorForShapeAnnotation:]` or `-[MGLMapViewDelegate mapView:fillColorForPolygonAnnotation:]`. ([#6706](https://github.com/mapbox/mapbox-gl-native/pull/6706))
### Networking and offline maps
@@ -69,6 +76,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
### Other changes
* As the user zooms in, tiles from lower zoom levels are scaled up until tiles for higher zoom levels are loaded. ([#5143](https://github.com/mapbox/mapbox-gl-native/pull/5143))
+* Notification names and user info keys are now string enumeration values for ease of use in Swift. ([#6794](https://github.com/mapbox/mapbox-gl-native/pull/6794))
* MGLMapDebugOverdrawVisualizationMask no longer has any effect in Release builds of the SDK. This debug mask has been disabled for performance reasons. ([#5555](https://github.com/mapbox/mapbox-gl-native/pull/5555))
* Fixed a typo in the documentation for the MGLCompassDirectionFormatter class. ([#5879](https://github.com/mapbox/mapbox-gl-native/pull/5879))
diff --git a/platform/ios/Mapbox-iOS-SDK-symbols.podspec b/platform/ios/Mapbox-iOS-SDK-symbols.podspec
index bbc0425088..e26de7915f 100644
--- a/platform/ios/Mapbox-iOS-SDK-symbols.podspec
+++ b/platform/ios/Mapbox-iOS-SDK-symbols.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |m|
m.name = 'Mapbox-iOS-SDK'
- m.version = '3.4.0-beta.1-symbols'
+ m.version = '3.4.0-beta.2-symbols'
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 Touch APIs.'
diff --git a/platform/ios/Mapbox-iOS-SDK.podspec b/platform/ios/Mapbox-iOS-SDK.podspec
index 77ada60fa4..6fd6d4b46f 100644
--- a/platform/ios/Mapbox-iOS-SDK.podspec
+++ b/platform/ios/Mapbox-iOS-SDK.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |m|
m.name = 'Mapbox-iOS-SDK'
- m.version = '3.4.0-beta.1'
+ m.version = '3.4.0-beta.2'
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 Touch APIs.'
diff --git a/platform/ios/app/Info.plist b/platform/ios/app/Info.plist
index 3602ab7964..043bebc926 100644
--- a/platform/ios/app/Info.plist
+++ b/platform/ios/app/Info.plist
@@ -51,5 +51,18 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
+ <key>NSAppTransportSecurity</key>
+ <dict>
+ <key>NSExceptionDomains</key>
+ <dict>
+ <key>stamen.com</key>
+ <dict>
+ <key>NSIncludesSubdomains</key>
+ <true/>
+ <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
+ <true/>
+ </dict>
+ </dict>
+ </dict>
</dict>
</plist>
diff --git a/platform/ios/app/MBXOfflinePacksTableViewController.m b/platform/ios/app/MBXOfflinePacksTableViewController.m
index 008d843b1e..7bceec7ef7 100644
--- a/platform/ios/app/MBXOfflinePacksTableViewController.m
+++ b/platform/ios/app/MBXOfflinePacksTableViewController.m
@@ -244,7 +244,7 @@ static NSString * const MBXOfflinePacksTableViewActiveCellReuseIdentifier = @"Ac
MGLOfflinePack *pack = notification.object;
NSAssert([pack isKindOfClass:[MGLOfflinePack class]], @"MGLOfflineStorage notification has a non-pack object.");
- NSError *error = notification.userInfo[MGLOfflinePackErrorUserInfoKey];
+ NSError *error = notification.userInfo[MGLOfflinePackUserInfoKeyError];
NSAssert([error isKindOfClass:[NSError class]], @"MGLOfflineStorage notification has a non-error error.");
NSString *message = [NSString stringWithFormat:@"Mapbox GL encountered an error while downloading the offline pack “%@”: %@", pack.name, error.localizedFailureReason];
@@ -261,7 +261,7 @@ static NSString * const MBXOfflinePacksTableViewActiveCellReuseIdentifier = @"Ac
MGLOfflinePack *pack = notification.object;
NSAssert([pack isKindOfClass:[MGLOfflinePack class]], @"MGLOfflineStorage notification has a non-pack object.");
- uint64_t maximumCount = [notification.userInfo[MGLOfflinePackMaximumCountUserInfoKey] unsignedLongLongValue];
+ uint64_t maximumCount = [notification.userInfo[MGLOfflinePackUserInfoKeyMaximumCount] unsignedLongLongValue];
NSLog(@"Offline pack “%@” reached limit of %llu tiles.", pack.name, maximumCount);
}
diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m
index 046f602384..a7ea429300 100644
--- a/platform/ios/app/MBXViewController.m
+++ b/platform/ios/app/MBXViewController.m
@@ -46,6 +46,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsAnnotationsRows) {
MBXSettingsAnnotations10000Sprites,
MBXSettingsAnnotationsTestShapes,
MBXSettingsAnnotationsCustomCallout,
+ MBXSettingsAnnotationsQueryAnnotations,
MBXSettingsAnnotationsRemoveAnnotations,
};
@@ -62,10 +63,19 @@ typedef NS_ENUM(NSInteger, MBXSettingsRuntimeStylingRows) {
MBXSettingsRuntimeStylingFilteredLines,
MBXSettingsRuntimeStylingNumericFilteredFill,
MBXSettingsRuntimeStylingStyleQuery,
+ MBXSettingsRuntimeStylingFeatureSource,
+ MBXSettingsRuntimeStylingPointCollection,
+ MBXSettingsRuntimeStylingUpdateGeoJSONSourceData,
+ MBXSettingsRuntimeStylingUpdateGeoJSONSourceURL,
+ MBXSettingsRuntimeStylingUpdateGeoJSONSourceFeatures,
+ MBXSettingsRuntimeStylingVectorSource,
+ MBXSettingsRuntimeStylingRasterSource,
+ MBXSettingsRuntimeStylingCountryLabels,
};
typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
- MBXSettingsMiscellaneousWorldTour = 0,
+ MBXSettingsMiscellaneousShowReuseQueueStats = 0,
+ MBXSettingsMiscellaneousWorldTour,
MBXSettingsMiscellaneousCustomUserDot,
MBXSettingsMiscellaneousPrintLogFile,
MBXSettingsMiscellaneousDeleteLogFile,
@@ -93,10 +103,21 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
UITableViewDataSource,
MGLMapViewDelegate>
+
@property (nonatomic) IBOutlet MGLMapView *mapView;
+@property (weak, nonatomic) IBOutlet UILabel *hudLabel;
@property (nonatomic) NSInteger styleIndex;
@property (nonatomic) BOOL debugLoggingEnabled;
@property (nonatomic) BOOL customUserLocationAnnnotationEnabled;
+@property (nonatomic) BOOL usingLocaleBasedCountryLabels;
+@property (nonatomic) BOOL reuseQueueStatsEnabled;
+
+@end
+
+@interface MGLMapView (MBXViewController)
+
+@property (nonatomic) BOOL usingLocaleBasedCountryLabels;
+@property (nonatomic) NSDictionary *annotationViewReuseQueueByIdentifier;
@end
@@ -130,12 +151,8 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
[self restoreState:nil];
self.debugLoggingEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"MGLMapboxMetricsDebugLoggingEnabled"];
-}
+ self.hudLabel.hidden = YES;
-- (void)viewDidAppear:(BOOL)animated
-{
- [super viewDidAppear:animated];
-
if ([MGLAccountManager accessToken].length)
{
self.styleIndex = -1;
@@ -289,6 +306,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
@"Add 10,000 Sprites",
@"Add Test Shapes",
@"Add Point With Custom Callout",
+ @"Query Annotations",
@"Remove Annotations",
]];
break;
@@ -306,9 +324,19 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
@"Style Lines With Filter",
@"Style Fill With Numeric Filter",
@"Style Query For GeoJSON",
+ @"Style Feature",
+ @"Style Dynamic Point Collection",
+ @"Update GeoJSON Source: Data",
+ @"Update GeoJSON Source: URL",
+ @"Update GeoJSON Source: Features",
+ @"Style Vector Source",
+ @"Style Raster Source",
+ [NSString stringWithFormat:@"Label Countries in %@", (_usingLocaleBasedCountryLabels ? @"Local Language" : [[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:[self bestLanguageForUser]])],
]];
break;
case MBXSettingsMiscellaneous:
+ [settingsTitles addObject:@"Show Reuse Queue Stats"];
+
[settingsTitles addObjectsFromArray:@[
@"Start World Tour",
[NSString stringWithFormat:@"%@ Custom User Dot", (_customUserLocationAnnnotationEnabled ? @"Disable" : @"Enable")],
@@ -321,6 +349,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
@"Delete Telemetry Logfile",
]];
};
+
break;
default:
NSAssert(NO, @"All settings sections should be implemented");
@@ -387,6 +416,9 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
case MBXSettingsAnnotationsCustomCallout:
[self addAnnotationWithCustomCallout];
break;
+ case MBXSettingsAnnotationsQueryAnnotations:
+ [self testQueryPointAnnotations];
+ break;
case MBXSettingsAnnotationsRemoveAnnotations:
[self.mapView removeAnnotations:self.mapView.annotations];
break;
@@ -434,6 +466,30 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
case MBXSettingsRuntimeStylingStyleQuery:
[self styleQuery];
break;
+ case MBXSettingsRuntimeStylingFeatureSource:
+ [self styleFeature];
+ break;
+ case MBXSettingsRuntimeStylingPointCollection:
+ [self styleDynamicPointCollection];
+ break;
+ case MBXSettingsRuntimeStylingUpdateGeoJSONSourceURL:
+ [self updateGeoJSONSourceURL];
+ break;
+ case MBXSettingsRuntimeStylingUpdateGeoJSONSourceData:
+ [self updateGeoJSONSourceData];
+ break;
+ case MBXSettingsRuntimeStylingUpdateGeoJSONSourceFeatures:
+ [self updateGeoJSONSourceFeatures];
+ break;
+ case MBXSettingsRuntimeStylingVectorSource:
+ [self styleVectorSource];
+ break;
+ case MBXSettingsRuntimeStylingRasterSource:
+ [self styleRasterSource];
+ break;
+ case MBXSettingsRuntimeStylingCountryLabels:
+ [self styleCountryLabelsLanguage];
+ break;
default:
NSAssert(NO, @"All runtime styling setting rows should be implemented");
break;
@@ -454,6 +510,12 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
case MBXSettingsMiscellaneousDeleteLogFile:
[self deleteTelemetryLogFile];
break;
+ case MBXSettingsMiscellaneousShowReuseQueueStats:
+ {
+ self.reuseQueueStatsEnabled = YES;
+ self.hudLabel.hidden = NO;
+ break;
+ }
default:
NSAssert(NO, @"All miscellaneous setting rows should be implemented");
break;
@@ -794,7 +856,6 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
});
}
-
- (void)styleQuery
{
CGRect queryRect = CGRectInset(self.mapView.bounds, 100, 200);
@@ -828,6 +889,247 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
});
}
+- (void)styleFeature
+{
+ self.mapView.zoomLevel = 10;
+ self.mapView.centerCoordinate = CLLocationCoordinate2DMake(51.068585180672635, -114.06074523925781);
+
+ CLLocationCoordinate2D leafCoords[] = {
+ CLLocationCoordinate2DMake(50.9683733218221,-114.07035827636719),
+ CLLocationCoordinate2DMake(51.02325750523972,-114.06967163085938),
+ CLLocationCoordinate2DMake(51.009434536947786,-114.14245605468749),
+ CLLocationCoordinate2DMake(51.030599281184124,-114.12597656249999),
+ CLLocationCoordinate2DMake(51.060386316691016,-114.21043395996094),
+ CLLocationCoordinate2DMake(51.063838646941576,-114.17816162109375),
+ CLLocationCoordinate2DMake(51.08152779888779,-114.19876098632812),
+ CLLocationCoordinate2DMake(51.08066507029602,-114.16854858398438),
+ CLLocationCoordinate2DMake(51.09662294502995,-114.17472839355469),
+ CLLocationCoordinate2DMake(51.07764539352731,-114.114990234375),
+ CLLocationCoordinate2DMake(51.13670896949613,-114.12391662597656),
+ CLLocationCoordinate2DMake(51.13369295212583,-114.09576416015624),
+ CLLocationCoordinate2DMake(51.17546878815025,-114.07585144042969),
+ CLLocationCoordinate2DMake(51.140155605265896,-114.04632568359375),
+ CLLocationCoordinate2DMake(51.15049396880196,-114.01542663574219),
+ CLLocationCoordinate2DMake(51.088860342359965,-114.00924682617186),
+ CLLocationCoordinate2DMake(51.12205789681453,-113.94813537597656),
+ CLLocationCoordinate2DMake(51.106539930027225,-113.94882202148438),
+ CLLocationCoordinate2DMake(51.117747873223344,-113.92616271972656),
+ CLLocationCoordinate2DMake(51.10093493903458,-113.92616271972656),
+ CLLocationCoordinate2DMake(51.10697105503078,-113.90625),
+ CLLocationCoordinate2DMake(51.09144802136697,-113.9117431640625),
+ CLLocationCoordinate2DMake(51.04916446529361,-113.97010803222655),
+ CLLocationCoordinate2DMake(51.045279344649146,-113.9398956298828),
+ CLLocationCoordinate2DMake(51.022825599852496,-114.06211853027344),
+ CLLocationCoordinate2DMake(51.045279344649146,-113.9398956298828),
+ CLLocationCoordinate2DMake(51.022825599852496,-114.06211853027344),
+ CLLocationCoordinate2DMake(51.022825599852496,-114.06280517578125),
+ CLLocationCoordinate2DMake(50.968805734317804,-114.06280517578125),
+ CLLocationCoordinate2DMake(50.9683733218221,-114.07035827636719),
+ };
+ NSUInteger coordsCount = sizeof(leafCoords) / sizeof(leafCoords[0]);
+
+ MGLPolygonFeature *feature = [MGLPolygonFeature polygonWithCoordinates:leafCoords count:coordsCount];
+ feature.identifier = @"leaf-feature";
+ feature.attributes = @{@"color": @"red"};
+
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"leaf-source" features:@[feature] options:nil];
+ [self.mapView.style addSource:source];
+
+ MGLFillStyleLayer *layer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"leaf-fill-layer" source:source];
+ layer.predicate = [NSPredicate predicateWithFormat:@"color = %@", @"red"];
+ MGLStyleValue *fillColor = [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor redColor]];
+ layer.fillColor = fillColor;
+ [self.mapView.style addLayer:layer];
+}
+
+- (void)updateGeoJSONSourceData
+{
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(40.329795743702064, -107.75390625) zoomLevel:11 animated:NO];
+
+ NSString *geoJSON = @"{\"type\": \"FeatureCollection\",\"features\": [{\"type\": \"Feature\",\"properties\": {},\"geometry\": {\"type\": \"LineString\",\"coordinates\": [[-107.75390625,40.329795743702064],[-104.34814453125,37.64903402157866]]}}]}";
+
+ NSData *data = [geoJSON dataUsingEncoding:NSUTF8StringEncoding];
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"mutable-data-source-id" geoJSONData:data options:nil];
+ [self.mapView.style addSource:source];
+
+ MGLLineStyleLayer *layer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"mutable-data-layer-id" source:source];
+ [self.mapView.style addLayer:layer];
+
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ NSString *geoJSON = @"{\"type\": \"FeatureCollection\",\"features\": [{\"type\": \"Feature\",\"properties\": {},\"geometry\": {\"type\": \"LineString\",\"coordinates\": [[-107.75390625,40.329795743702064],[-109.34814453125,37.64903402157866]]}}]}";
+ NSData *data = [geoJSON dataUsingEncoding:NSUTF8StringEncoding];
+
+ source.geoJSONData = data;
+ });
+}
+
+- (void)updateGeoJSONSourceURL
+{
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(48.668731, -122.857151) zoomLevel:11 animated:NO];
+
+ NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"polyline" ofType:@"geojson"];
+ NSURL *geoJSONURL = [NSURL fileURLWithPath:filePath];
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"mutable-data-source-url-id" URL:geoJSONURL options:nil];
+ [self.mapView.style addSource:source];
+
+ MGLLineStyleLayer *layer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"mutable-data-layer-url-id" source:source];
+ [self.mapView.style addLayer:layer];
+
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(41.563986787078704, -75.04843935793578) zoomLevel:8 animated:NO];
+
+ NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"threestates" ofType:@"geojson"];
+ NSURL *geoJSONURL = [NSURL fileURLWithPath:filePath];
+
+ source.URL = geoJSONURL;
+ });
+}
+
+- (void)updateGeoJSONSourceFeatures
+{
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(-41.1520, 288.6592) zoomLevel:10 animated:NO];
+
+ CLLocationCoordinate2D smallBox[] = {
+ {-41.14763798539186, 288.68019104003906},
+ {-41.140915920129665, 288.68019104003906},
+ {-41.140915920129665, 288.6887741088867},
+ {-41.14763798539186, 288.6887741088867},
+ {-41.14763798539186, 288.68019104003906}
+ };
+
+ CLLocationCoordinate2D largeBox[] = {
+ {-41.17710352162799, 288.67298126220703},
+ {-41.13962313627545, 288.67298126220703},
+ {-41.13962313627545, 288.7261962890625},
+ {-41.17710352162799, 288.7261962890625},
+ {-41.17710352162799, 288.67298126220703}
+ };
+
+ MGLPolygonFeature *smallBoxFeature = [MGLPolygonFeature polygonWithCoordinates:smallBox count:sizeof(smallBox)/sizeof(smallBox[0])];
+ MGLPolygonFeature *largeBoxFeature = [MGLPolygonFeature polygonWithCoordinates:largeBox count:sizeof(largeBox)/sizeof(largeBox[0])];
+
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"mutable-data-source-features-id" features:@[smallBoxFeature] options:nil];
+ [self.mapView.style addSource:source];
+
+ MGLFillStyleLayer *layer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"mutable-data-layer-features-id" source:source];
+ MGLStyleValue *fillColor = [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor redColor]];
+ layer.fillColor = fillColor;
+ [self.mapView.style addLayer:layer];
+
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ source.features = @[largeBoxFeature];
+ });
+}
+
+- (void)styleDynamicPointCollection
+{
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(36.9979, -109.0441) zoomLevel:14 animated:NO];
+ CLLocationCoordinate2D coordinates[] = {
+ {37.00145594210082, -109.04960632324219},
+ {37.00173012609867, -109.0404224395752},
+ {36.99453246847359, -109.04960632324219},
+ {36.99508088541243, -109.04007911682129},
+ };
+ MGLPointCollectionFeature *feature = [MGLPointCollectionFeature pointCollectionWithCoordinates:coordinates count:4];
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"wiggle-source" features:@[feature] options:nil];
+ [self.mapView.style addSource:source];
+
+ MGLCircleStyleLayer *layer = [[MGLCircleStyleLayer alloc] initWithIdentifier:@"wiggle-layer" source:source];
+ [self.mapView.style addLayer:layer];
+}
+
+- (void)styleVectorSource
+{
+ NSURL *url = [[NSURL alloc] initWithString:@"mapbox://mapbox.mapbox-terrain-v2"];
+ MGLVectorSource *vectorSource = [[MGLVectorSource alloc] initWithIdentifier:@"style-vector-source-id" URL:url];
+ [self.mapView.style addSource:vectorSource];
+
+ MGLBackgroundStyleLayer *backgroundLayer = [[MGLBackgroundStyleLayer alloc] initWithIdentifier:@"style-vector-background-layer-id"];
+ backgroundLayer.backgroundColor = [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor blackColor]];
+ [self.mapView.style addLayer:backgroundLayer];
+
+ MGLLineStyleLayer *lineLayer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"style-vector-line-layer-id" source:vectorSource];
+ lineLayer.sourceLayerIdentifier = @"contour";
+ NSUInteger lineJoinValue = MGLLineJoinRound;
+ lineLayer.lineJoin = [MGLStyleValue<NSValue *> valueWithRawValue:[NSValue value:&lineJoinValue withObjCType:@encode(MGLLineJoin)]];
+ NSUInteger lineCapValue = MGLLineCapRound;
+ lineLayer.lineCap = [MGLStyleValue<NSValue *> valueWithRawValue:[NSValue value:&lineCapValue withObjCType:@encode(MGLLineCap)]];
+ lineLayer.lineColor = [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor greenColor]];
+
+ [self.mapView.style addLayer:lineLayer];
+}
+
+- (void)styleRasterSource
+{
+ // 3rd party raster source requires NSAppTransportSecurity exception for stamen.com
+ MGLTileSet *rasterTileSet = [[MGLTileSet alloc] initWithTileURLTemplates:@[@"http://a.tile.stamen.com/terrain-background/{z}/{x}/{y}.jpg"]];
+ MGLRasterSource *rasterSource = [[MGLRasterSource alloc] initWithIdentifier:@"style-raster-source-id" tileSet:rasterTileSet tileSize:256];
+ [self.mapView.style addSource:rasterSource];
+
+ MGLRasterStyleLayer *rasterLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"style-raster-layer-id" source:rasterSource];
+ [self.mapView.style addLayer:rasterLayer];
+}
+
+-(void)styleCountryLabelsLanguage
+{
+ NSArray<NSString *> *labelLayers = @[
+ @"country-label-lg",
+ @"country-label-md",
+ @"country-label-sm",
+ ];
+ [self styleLabelLanguageForLayersNamed:labelLayers];
+}
+
+- (void)styleLabelLanguageForLayersNamed:(NSArray<NSString *> *)layers
+{
+ _usingLocaleBasedCountryLabels = !_usingLocaleBasedCountryLabels;
+ NSString *bestLanguageForUser = [NSString stringWithFormat:@"{name_%@}", [self bestLanguageForUser]];
+ NSString *language = _usingLocaleBasedCountryLabels ? bestLanguageForUser : @"{name}";
+
+ for (NSString *layerName in layers) {
+ MGLSymbolStyleLayer *layer = (MGLSymbolStyleLayer *)[self.mapView.style layerWithIdentifier:layerName];
+
+ if ([layer isKindOfClass:[MGLSymbolStyleLayer class]]) {
+ if ([layer.textField isKindOfClass:[MGLStyleConstantValue class]]) {
+ MGLStyleConstantValue *label = (MGLStyleConstantValue<NSString *> *)layer.textField;
+ if ([label.rawValue hasPrefix:@"{name"]) {
+ layer.textField = [MGLStyleValue valueWithRawValue:language];
+ }
+ } else if ([layer.textField isKindOfClass:[MGLStyleFunction class]]) {
+ MGLStyleFunction *function = (MGLStyleFunction<NSString *> *)layer.textField;
+ [function.stops enumerateKeysAndObjectsUsingBlock:^(id zoomLevel, id stop, BOOL *done) {
+ if ([stop isKindOfClass:[MGLStyleConstantValue class]]) {
+ MGLStyleConstantValue *label = (MGLStyleConstantValue<NSString *> *)stop;
+ if ([label.rawValue hasPrefix:@"{name"]) {
+ [function.stops setValue:[MGLStyleValue valueWithRawValue:language] forKey:zoomLevel];
+ }
+ }
+ }];
+ layer.textField = function;
+ }
+ } else {
+ NSLog(@"%@ is not a symbol style layer", layerName);
+ }
+ }
+}
+
+- (NSString *)bestLanguageForUser
+{
+ NSArray *supportedLanguages = @[ @"en", @"es", @"fr", @"de", @"ru", @"zh" ];
+ NSArray<NSString *> *preferredLanguages = [NSLocale preferredLanguages];
+ NSString *bestLanguage;
+
+ for (NSString *language in preferredLanguages) {
+ NSString *thisLanguage = [NSLocale localeWithLocaleIdentifier:language].languageCode;
+ if ([supportedLanguages containsObject:thisLanguage]) {
+ bestLanguage = thisLanguage;
+ break;
+ }
+ }
+
+ return bestLanguage ?: @"en";
+}
+
- (IBAction)startWorldTour
{
_isTouringWorld = YES;
@@ -875,6 +1177,20 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
self.mapView.userTrackingMode = MGLUserTrackingModeFollow;
}
+- (void)testQueryPointAnnotations {
+ NSNumber *visibleAnnotationCount = @(self.mapView.visibleAnnotations.count);
+ NSString *message;
+ if ([visibleAnnotationCount integerValue] == 1) {
+ message = [NSString stringWithFormat:@"There is %@ visible annotation.", visibleAnnotationCount];
+ } else {
+ message = [NSString stringWithFormat:@"There are %@ visible annotations.", visibleAnnotationCount];
+ }
+
+ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Visible Annotations" message:message preferredStyle:UIAlertControllerStyleAlert];
+ [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleCancel handler:nil]];
+ [self presentViewController:alertController animated:YES completion:nil];
+}
+
- (void)printTelemetryLogFile
{
NSString *fileContents = [NSString stringWithContentsOfFile:[self telemetryDebugLogFilePath] encoding:NSUTF8StringEncoding error:nil];
@@ -1208,4 +1524,24 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
point.coordinate = [self.mapView convertPoint:self.mapView.center toCoordinateFromView:self.mapView];
}
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style
+{
+ // Default Mapbox styles use {name_en} as their label language, which means
+ // that a device with an English-language locale is already effectively
+ // using locale-based country labels.
+ _usingLocaleBasedCountryLabels = [[self bestLanguageForUser] isEqualToString:@"en"];
+}
+
+- (void)mapViewRegionIsChanging:(MGLMapView *)mapView
+{
+ if (self.reuseQueueStatsEnabled) {
+ NSUInteger queuedAnnotations = 0;
+ for (NSArray *queue in self.mapView.annotationViewReuseQueueByIdentifier.allValues)
+ {
+ queuedAnnotations += queue.count;
+ }
+ self.hudLabel.text = [NSString stringWithFormat:@"Visible: %ld Queued: %ld", (long)mapView.visibleAnnotations.count, (long)queuedAnnotations];
+ }
+}
+
@end
diff --git a/platform/ios/app/Main.storyboard b/platform/ios/app/Main.storyboard
index 7d8b2c304f..5819f17edc 100644
--- a/platform/ios/app/Main.storyboard
+++ b/platform/ios/app/Main.storyboard
@@ -1,9 +1,11 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="PSe-Ot-7Ff">
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="PSe-Ot-7Ff">
<dependencies>
<deployment identifier="iOS"/>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
+ <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="Navigation items with more than one left or right bar item" minToolsVersion="7.0"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Map View Controller-->
@@ -15,24 +17,35 @@
<viewControllerLayoutGuide type="bottom" id="m8o-i7-QIy"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Z9X-fc-PUC">
- <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kNe-zV-9ha" customClass="MGLMapView">
- <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
- <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<gestureRecognizers/>
<connections>
<outlet property="delegate" destination="WaX-pd-UZQ" id="za0-3B-qR6"/>
<outletCollection property="gestureRecognizers" destination="lfd-mn-7en" appends="YES" id="0PH-gH-GRm"/>
</connections>
</view>
+ <label opaque="NO" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="58y-pX-YyB">
+ <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <constraints>
+ <constraint firstAttribute="width" constant="180" id="OL2-l5-I2f"/>
+ <constraint firstAttribute="height" constant="21" id="xHg-ye-wzT"/>
+ </constraints>
+ <fontDescription key="fontDescription" type="system" pointSize="8"/>
+ <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <nil key="highlightedColor"/>
+ </label>
</subviews>
- <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="kNe-zV-9ha" firstAttribute="leading" secondItem="Z9X-fc-PUC" secondAttribute="leading" id="53e-Tz-QxF"/>
<constraint firstItem="kNe-zV-9ha" firstAttribute="bottom" secondItem="m8o-i7-QIy" secondAttribute="top" id="Etp-BC-E1N"/>
<constraint firstAttribute="trailing" secondItem="kNe-zV-9ha" secondAttribute="trailing" id="MGr-8G-VEb"/>
+ <constraint firstItem="58y-pX-YyB" firstAttribute="trailing" secondItem="Z9X-fc-PUC" secondAttribute="trailingMargin" id="O3a-bR-boI"/>
+ <constraint firstItem="m8o-i7-QIy" firstAttribute="top" secondItem="58y-pX-YyB" secondAttribute="bottom" constant="20" id="cjh-ZS-Mv4"/>
<constraint firstItem="kNe-zV-9ha" firstAttribute="top" secondItem="Z9X-fc-PUC" secondAttribute="top" id="qMm-e9-jxH"/>
</constraints>
</view>
@@ -47,7 +60,7 @@
</connections>
</barButtonItem>
<button key="titleView" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="KsN-ny-Hou">
- <rect key="frame" x="180" y="7" width="240" height="30"/>
+ <rect key="frame" x="61" y="7" width="207" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
<state key="normal" title="Streets"/>
@@ -75,6 +88,7 @@
</rightBarButtonItems>
</navigationItem>
<connections>
+ <outlet property="hudLabel" destination="58y-pX-YyB" id="MEh-ir-3IH"/>
<outlet property="mapView" destination="kNe-zV-9ha" id="VNR-WO-1q4"/>
</connections>
</viewController>
@@ -85,60 +99,60 @@
</connections>
</pongPressGestureRecognizer>
</objects>
- <point key="canvasLocation" x="1366" y="350"/>
+ <point key="canvasLocation" x="1365.5999999999999" y="349.47526236881561"/>
</scene>
<!--Offline Packs-->
<scene sceneID="xIg-PA-7r3">
<objects>
<tableViewController id="7q0-lI-zqb" customClass="MBXOfflinePacksTableViewController" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="eeN-6b-zqe">
- <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
- <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="Inactive" editingAccessoryType="detailDisclosureButton" textLabel="JtH-Ce-MI5" detailTextLabel="tTJ-jv-U9v" style="IBUITableViewCellStyleSubtitle" id="fGu-Ys-Eh1">
- <rect key="frame" x="0.0" y="92" width="600" height="44"/>
+ <rect key="frame" x="0.0" y="92" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="fGu-Ys-Eh1" id="sUf-bc-8xG">
- <rect key="frame" x="0.0" y="0.0" width="600" height="43.5"/>
+ <frame key="frameInset" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="My Inactive Offline Pack" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="JtH-Ce-MI5">
- <rect key="frame" x="15" y="6" width="174.5" height="19.5"/>
+ <frame key="frameInset" minX="15" minY="6" width="174.5" height="19.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
- <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="456 resources (789 MB)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="tTJ-jv-U9v">
- <rect key="frame" x="15" y="25.5" width="128" height="13.5"/>
+ <frame key="frameInset" minX="15" minY="25.5" width="128" height="13.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
- <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="Active" editingAccessoryType="detailDisclosureButton" textLabel="9ZK-gS-wJ4" detailTextLabel="0xK-p8-Mmh" style="IBUITableViewCellStyleSubtitle" id="mKB-tz-Zfl">
- <rect key="frame" x="0.0" y="136" width="600" height="44"/>
+ <rect key="frame" x="0.0" y="136" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="mKB-tz-Zfl" id="nS3-aU-nBr">
- <rect key="frame" x="0.0" y="0.0" width="600" height="43.5"/>
+ <frame key="frameInset" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="My Active Offline Pack" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="9ZK-gS-wJ4">
- <rect key="frame" x="15" y="6" width="163" height="19.5"/>
+ <frame key="frameInset" minX="15" minY="6" width="163" height="19.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
- <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Downloading 123 of 456 resources… (789 MB downloaded)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="0xK-p8-Mmh">
- <rect key="frame" x="15" y="25.5" width="310.5" height="13.5"/>
+ <frame key="frameInset" minX="15" minY="25.5" width="310.5" height="13.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
- <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
@@ -189,5 +203,5 @@
<image name="TrackingLocationOffMask.png" width="23" height="23"/>
<image name="settings.png" width="28" height="28"/>
</resources>
- <color key="tintColor" red="0.12156862745098039" green="0.5490196078431373" blue="0.6705882352941176" alpha="1" colorSpace="calibratedRGB"/>
+ <color key="tintColor" red="0.12156862745098039" green="0.5490196078431373" blue="0.6705882352941176" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</document>
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index 3c19f5ea41..a78cf583cb 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -128,6 +128,11 @@
4018B1CA1CDC288E00F666AF /* MGLAnnotationView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4018B1C51CDC277F00F666AF /* MGLAnnotationView.h */; settings = {ATTRIBUTES = (Public, ); }; };
4018B1CB1CDC288E00F666AF /* MGLAnnotationView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4018B1C51CDC277F00F666AF /* MGLAnnotationView.h */; settings = {ATTRIBUTES = (Public, ); }; };
404326891D5B9B27007111BD /* MGLAnnotationContainerView_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 404326881D5B9B1A007111BD /* MGLAnnotationContainerView_Private.h */; };
+ 4049C29D1DB6CD6C00B3F799 /* MGLPointCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 4049C29B1DB6CD6C00B3F799 /* MGLPointCollection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 4049C29E1DB6CD6C00B3F799 /* MGLPointCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 4049C29B1DB6CD6C00B3F799 /* MGLPointCollection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 4049C29F1DB6CD6C00B3F799 /* MGLPointCollection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4049C29C1DB6CD6C00B3F799 /* MGLPointCollection.mm */; };
+ 4049C2A01DB6CD6C00B3F799 /* MGLPointCollection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4049C29C1DB6CD6C00B3F799 /* MGLPointCollection.mm */; };
+ 4049C2AC1DB6E05500B3F799 /* MGLPointCollection_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4049C2AB1DB6E05500B3F799 /* MGLPointCollection_Private.h */; };
404C26E21D89B877000AA13D /* MGLTileSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 404C26E01D89B877000AA13D /* MGLTileSet.h */; settings = {ATTRIBUTES = (Public, ); }; };
404C26E31D89B877000AA13D /* MGLTileSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 404C26E01D89B877000AA13D /* MGLTileSet.h */; settings = {ATTRIBUTES = (Public, ); }; };
404C26E41D89B877000AA13D /* MGLTileSet.mm in Sources */ = {isa = PBXBuildFile; fileRef = 404C26E11D89B877000AA13D /* MGLTileSet.mm */; };
@@ -169,6 +174,7 @@
DA1DC99B1CB6E064006E619F /* MBXViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DA1DC99A1CB6E064006E619F /* MBXViewController.m */; };
DA1DC99D1CB6E076006E619F /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA1DC99C1CB6E076006E619F /* Default-568h@2x.png */; };
DA1DC99F1CB6E088006E619F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA1DC99E1CB6E088006E619F /* Assets.xcassets */; };
+ DA2207BF1DC0805F0002F84D /* MGLStyleValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2207BE1DC0805F0002F84D /* MGLStyleValueTests.swift */; };
DA25D5C01CCD9F8400607828 /* Root.plist in Resources */ = {isa = PBXBuildFile; fileRef = DA25D5BF1CCD9F8400607828 /* Root.plist */; };
DA25D5C61CCDA06800607828 /* Root.strings in Resources */ = {isa = PBXBuildFile; fileRef = DA25D5C41CCDA06800607828 /* Root.strings */; };
DA25D5CD1CCDA11500607828 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = DA25D5B91CCD9EDE00607828 /* Settings.bundle */; };
@@ -555,14 +561,17 @@
4018B1C51CDC277F00F666AF /* MGLAnnotationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationView.h; sourceTree = "<group>"; };
402E9DE01CD2C76200FD4519 /* Mapbox.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Mapbox.playground; sourceTree = "<group>"; };
404326881D5B9B1A007111BD /* MGLAnnotationContainerView_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationContainerView_Private.h; sourceTree = "<group>"; };
+ 4049C29B1DB6CD6C00B3F799 /* MGLPointCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLPointCollection.h; sourceTree = "<group>"; };
+ 4049C29C1DB6CD6C00B3F799 /* MGLPointCollection.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLPointCollection.mm; sourceTree = "<group>"; };
+ 4049C2AB1DB6E05500B3F799 /* MGLPointCollection_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLPointCollection_Private.h; sourceTree = "<group>"; };
404C26E01D89B877000AA13D /* MGLTileSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLTileSet.h; sourceTree = "<group>"; };
404C26E11D89B877000AA13D /* MGLTileSet.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLTileSet.mm; sourceTree = "<group>"; };
404C26E61D89C515000AA13D /* MGLTileSet_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLTileSet_Private.h; sourceTree = "<group>"; };
- 4085AF081D933DEA00F11B22 /* MGLTileSetTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLTileSetTests.mm; sourceTree = "<group>"; };
+ 4085AF081D933DEA00F11B22 /* MGLTileSetTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLTileSetTests.mm; path = ../../darwin/test/MGLTileSetTests.mm; sourceTree = "<group>"; };
408AA8551DAEDA0800022900 /* NSDictionary+MGLAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+MGLAdditions.h"; sourceTree = "<group>"; };
408AA8561DAEDA0800022900 /* NSDictionary+MGLAdditions.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSDictionary+MGLAdditions.mm"; sourceTree = "<group>"; };
40CF6DBA1DAC3C1800A4D18B /* MGLShape_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLShape_Private.h; sourceTree = "<group>"; };
- 40CFA6501D787579008103BD /* MGLGeoJSONSourceTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLGeoJSONSourceTests.mm; sourceTree = "<group>"; };
+ 40CFA6501D787579008103BD /* MGLGeoJSONSourceTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLGeoJSONSourceTests.mm; path = ../../darwin/test/MGLGeoJSONSourceTests.mm; sourceTree = "<group>"; };
40EDA1BD1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationContainerView.h; sourceTree = "<group>"; };
40EDA1BE1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLAnnotationContainerView.m; sourceTree = "<group>"; };
40F8876F1D7A1DB8008ECB67 /* MGLGeoJSONSource_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLGeoJSONSource_Private.h; sourceTree = "<group>"; };
@@ -593,6 +602,8 @@
DA1DC99A1CB6E064006E619F /* MBXViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBXViewController.m; sourceTree = "<group>"; };
DA1DC99C1CB6E076006E619F /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
DA1DC99E1CB6E088006E619F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+ DA2207BD1DC0805F0002F84D /* test-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "test-Bridging-Header.h"; sourceTree = "<group>"; };
+ DA2207BE1DC0805F0002F84D /* MGLStyleValueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MGLStyleValueTests.swift; path = ../../darwin/test/MGLStyleValueTests.swift; sourceTree = "<group>"; };
DA25D5B91CCD9EDE00607828 /* Settings.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Settings.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
DA25D5BF1CCD9F8400607828 /* Root.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Root.plist; sourceTree = "<group>"; };
DA25D5C51CCDA06800607828 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Root.strings; sourceTree = "<group>"; };
@@ -877,9 +888,11 @@
357579811D502AD4000B822E /* Styling */ = {
isa = PBXGroup;
children = (
+ DA2207BD1DC0805F0002F84D /* test-Bridging-Header.h */,
3575798F1D513EF1000B822E /* Layers */,
35B8E08B1D6C8B5100E768D2 /* MGLFilterTests.mm */,
40CFA64E1D78754A008103BD /* Sources */,
+ DA2207BE1DC0805F0002F84D /* MGLStyleValueTests.swift */,
);
name = Styling;
sourceTree = "<group>";
@@ -1257,12 +1270,15 @@
DA8847E11CBAFA5100AB86E3 /* MGLGeometry.h */,
DA8848011CBAFA6200AB86E3 /* MGLGeometry_Private.h */,
DA8848021CBAFA6200AB86E3 /* MGLGeometry.mm */,
- DA8847E31CBAFA5100AB86E3 /* MGLMultiPoint.h */,
DA8848041CBAFA6200AB86E3 /* MGLMultiPoint_Private.h */,
+ DA8847E31CBAFA5100AB86E3 /* MGLMultiPoint.h */,
DA8848051CBAFA6200AB86E3 /* MGLMultiPoint.mm */,
DA8847E71CBAFA5100AB86E3 /* MGLOverlay.h */,
DA8847E81CBAFA5100AB86E3 /* MGLPointAnnotation.h */,
DA88480B1CBAFA6200AB86E3 /* MGLPointAnnotation.mm */,
+ 4049C29B1DB6CD6C00B3F799 /* MGLPointCollection.h */,
+ 4049C2AB1DB6E05500B3F799 /* MGLPointCollection_Private.h */,
+ 4049C29C1DB6CD6C00B3F799 /* MGLPointCollection.mm */,
DA8847E91CBAFA5100AB86E3 /* MGLPolygon.h */,
DA88480C1CBAFA6200AB86E3 /* MGLPolygon.mm */,
DA8847EA1CBAFA5100AB86E3 /* MGLPolyline.h */,
@@ -1410,6 +1426,7 @@
DA8847F01CBAFA5100AB86E3 /* MGLAnnotation.h in Headers */,
7E016D841D9E890300A29A21 /* MGLPolygon+MGLAdditions.h in Headers */,
400533011DB0862B0069F638 /* NSArray+MGLAdditions.h in Headers */,
+ 4049C29D1DB6CD6C00B3F799 /* MGLPointCollection.h in Headers */,
DA88483E1CBAFB8500AB86E3 /* MGLMapView+MGLCustomStyleLayerAdditions.h in Headers */,
40CF6DBB1DAC3C6600A4D18B /* MGLShape_Private.h in Headers */,
4018B1CA1CDC288E00F666AF /* MGLAnnotationView.h in Headers */,
@@ -1449,6 +1466,7 @@
35136D4C1D4277FC00C20EFD /* MGLSource.h in Headers */,
3566C76C1D4A8DFA008152BC /* MGLRasterSource.h in Headers */,
DA8847F91CBAFA5100AB86E3 /* MGLPolygon.h in Headers */,
+ 4049C2AC1DB6E05500B3F799 /* MGLPointCollection_Private.h in Headers */,
DA8847F81CBAFA5100AB86E3 /* MGLPointAnnotation.h in Headers */,
353933F21D3FB753003F57D7 /* MGLCircleStyleLayer.h in Headers */,
DA8847F31CBAFA5100AB86E3 /* MGLMultiPoint.h in Headers */,
@@ -1493,6 +1511,7 @@
DABFB85E1CBE99E500D62B32 /* MGLAnnotation.h in Headers */,
DABFB8641CBE99E500D62B32 /* MGLOfflineStorage.h in Headers */,
DAD165791CF4CDFF001FF4B9 /* MGLShapeCollection.h in Headers */,
+ 4049C29E1DB6CD6C00B3F799 /* MGLPointCollection.h in Headers */,
3566C7671D4A77BA008152BC /* MGLGeoJSONSource.h in Headers */,
DA35A29F1CC9E94C00E826B2 /* MGLCoordinateFormatter.h in Headers */,
DABFB8711CBE9A0F00D62B32 /* MGLMapView+MGLCustomStyleLayerAdditions.h in Headers */,
@@ -1699,6 +1718,7 @@
};
DA2E88501CC036F400F24E7B = {
CreatedOnToolsVersion = 7.3;
+ LastSwiftMigration = 0800;
};
DA8847D11CBAF91600AB86E3 = {
CreatedOnToolsVersion = 7.3;
@@ -1868,6 +1888,7 @@
357579851D502AF5000B822E /* MGLSymbolStyleLayerTests.m in Sources */,
357579871D502AFE000B822E /* MGLLineStyleLayerTests.m in Sources */,
357579891D502B06000B822E /* MGLCircleStyleLayerTests.m in Sources */,
+ DA2207BF1DC0805F0002F84D /* MGLStyleValueTests.swift in Sources */,
40CFA6511D7875BB008103BD /* MGLGeoJSONSourceTests.mm in Sources */,
DA35A2C51CCA9F8300E826B2 /* MGLClockDirectionFormatterTests.m in Sources */,
35B8E08C1D6C8B5100E768D2 /* MGLFilterTests.mm in Sources */,
@@ -1943,6 +1964,7 @@
35D13AC51D3D19DD00AFB4E0 /* MGLFillStyleLayer.mm in Sources */,
DA8848241CBAFA6200AB86E3 /* MGLOfflineStorage.mm in Sources */,
DA88482A1CBAFA6200AB86E3 /* MGLTilePyramidOfflineRegion.mm in Sources */,
+ 4049C29F1DB6CD6C00B3F799 /* MGLPointCollection.mm in Sources */,
35136D3F1D42273000C20EFD /* MGLLineStyleLayer.mm in Sources */,
DA88481A1CBAFA6200AB86E3 /* MGLAccountManager.m in Sources */,
3510FFFB1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm in Sources */,
@@ -2014,6 +2036,7 @@
35D13AC61D3D19DD00AFB4E0 /* MGLFillStyleLayer.mm in Sources */,
DAA4E42A1CBB730400178DFB /* NSProcessInfo+MGLAdditions.m in Sources */,
DAA4E4211CBB730400178DFB /* MGLOfflineStorage.mm in Sources */,
+ 4049C2A01DB6CD6C00B3F799 /* MGLPointCollection.mm in Sources */,
35136D401D42273000C20EFD /* MGLLineStyleLayer.mm in Sources */,
DAA4E42F1CBB730400178DFB /* MGLCompactCalloutView.m in Sources */,
3510FFFC1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm in Sources */,
@@ -2264,6 +2287,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 55D8C9941D0F133500F42F10 /* config.xcconfig */;
buildSettings = {
+ CLANG_ENABLE_MODULES = YES;
HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)";
INFOPLIST_FILE = test/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
@@ -2276,6 +2300,9 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.test;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "test/test-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 3.0;
};
name = Debug;
};
@@ -2283,6 +2310,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 55D8C9941D0F133500F42F10 /* config.xcconfig */;
buildSettings = {
+ CLANG_ENABLE_MODULES = YES;
HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)";
INFOPLIST_FILE = test/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
@@ -2295,6 +2323,8 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.test;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "test/test-Bridging-Header.h";
+ SWIFT_VERSION = 3.0;
};
name = Release;
};
diff --git a/platform/ios/jazzy.yml b/platform/ios/jazzy.yml
index c41dddc899..c19d9e3883 100644
--- a/platform/ios/jazzy.yml
+++ b/platform/ios/jazzy.yml
@@ -34,6 +34,7 @@ custom_categories:
- MGLMultiPolygon
- MGLMultiPolyline
- MGLPointAnnotation
+ - MGLPointCollection
- MGLPolygon
- MGLPolyline
- MGLOverlay
@@ -44,9 +45,9 @@ custom_categories:
- name: Map Data
children:
- MGLFeature
- - MGLMultiPointFeature
- MGLMultiPolygonFeature
- MGLMultiPolylineFeature
+ - MGLPointCollectionFeature
- MGLPointFeature
- MGLPolygonFeature
- MGLPolylineFeature
diff --git a/platform/ios/scripts/deploy-packages.sh b/platform/ios/scripts/deploy-packages.sh
index 51b90a545f..8ad5e7abb1 100755
--- a/platform/ios/scripts/deploy-packages.sh
+++ b/platform/ios/scripts/deploy-packages.sh
@@ -43,7 +43,7 @@ buildPackageStyle() {
github-release upload \
--tag "ios-v${PUBLISH_VERSION}" \
--name ${file_name} \
- --file "${BINARY_DIRECTORY}/${file_name}"
+ --file "${BINARY_DIRECTORY}/${file_name}" > /dev/null
fi
}
@@ -58,9 +58,6 @@ BINARY_DIRECTORY=${BINARY_DIRECTORY:-build/ios/deploy}
GITHUB_RELEASE=${GITHUB_RELEASE:-true}
PUBLISH_PRE_FLAG=''
-rm -rf ${BINARY_DIRECTORY}
-mkdir -p ${BINARY_DIRECTORY}
-
if [[ ${GITHUB_RELEASE} = "true" ]]; then
GITHUB_RELEASE=true # Assign bool, not just a string
@@ -98,6 +95,7 @@ git checkout ${VERSION_TAG}
step "Deploying version ${PUBLISH_VERSION}…"
make clean && make distclean
+mkdir -p ${BINARY_DIRECTORY}
if [[ "${GITHUB_RELEASE}" == true ]]; then
step "Create GitHub release…"
@@ -116,4 +114,4 @@ buildPackageStyle "iframework" "symbols-dynamic"
buildPackageStyle "iframework SYMBOLS=NO" "dynamic"
buildPackageStyle "ifabric" "fabric"
-step "Finished deploying ${PUBLISH_VERSION}"
+step "Finished deploying ${PUBLISH_VERSION} in $(($SECONDS / 60)) minutes and $(($SECONDS % 60)) seconds"
diff --git a/platform/ios/src/MGLMapView.h b/platform/ios/src/MGLMapView.h
index 57b74daa04..e467495a4a 100644
--- a/platform/ios/src/MGLMapView.h
+++ b/platform/ios/src/MGLMapView.h
@@ -893,13 +893,22 @@ IB_DESIGNABLE
@property (nonatomic, readonly, nullable) NS_ARRAY_OF(id <MGLAnnotation>) *annotations;
/**
+ The complete list of annotations associated with the receiver that are
+ currently visible.
+
+ The objects in this array must adopt the `MGLAnnotation` protocol. If no
+ annotations are associated with the map view or if no annotations associated
+ with the map view are currently visible, the value of this property is `nil`.
+ */
+@property (nonatomic, readonly, nullable) NS_ARRAY_OF(id <MGLAnnotation>) *visibleAnnotations;
+
+/**
Adds an annotation to the map view.
- @note `MGLMultiPolyline`, `MGLMultiPolygon`, and `MGLShapeCollection` objects
- cannot be added to the map view at this time. Nor can `MGLMultiPoint`
- objects that are not instances of `MGLPolyline` or `MGLPolygon`. Any
- multipoint, multipolyline, multipolygon, or shape collection object that is
- specified is silently ignored.
+ @note `MGLMultiPolyline`, `MGLMultiPolygon`, `MGLShapeCollection`, and
+ `MGLPointCollection` objects cannot be added to the map view at this time.
+ Any multipoint, multipolyline, multipolygon, shape or point collection
+ object that is specified is silently ignored.
@param annotation The annotation object to add to the receiver. This object
must conform to the `MGLAnnotation` protocol. The map view retains the
@@ -987,6 +996,17 @@ IB_DESIGNABLE
*/
- (nullable __kindof MGLAnnotationView *)dequeueReusableAnnotationViewWithIdentifier:(NSString *)identifier;
+/**
+ Returns the list of annotations associated with the receiver that intersect with
+ the given rectangle.
+
+ @param rect A rectangle expressed in the map view’s coordinate system.
+ @return An array of objects that adopt the `MGLAnnotation` protocol or `nil` if
+ no annotations associated with the map view are currently visible in the
+ rectangle.
+ */
+- (nullable NS_ARRAY_OF(id <MGLAnnotation>) *)visibleAnnotationsInRect:(CGRect)rect;
+
#pragma mark Managing Annotation Selections
/**
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index d392849522..466912c217 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -129,7 +129,10 @@ enum { MGLAnnotationTagNotFound = UINT32_MAX };
/// Mapping from an annotation tag to metadata about that annotation, including
/// the annotation itself.
-typedef std::map<MGLAnnotationTag, MGLAnnotationContext> MGLAnnotationContextMap;
+typedef std::unordered_map<MGLAnnotationTag, MGLAnnotationContext> MGLAnnotationTagContextMap;
+
+/// Mapping from an annotation object to an annotation tag.
+typedef std::map<id<MGLAnnotation>, MGLAnnotationTag> MGLAnnotationObjectTagMap;
/// Initializes the run loop shim that lives on the main thread.
void MGLinitializeRunLoop() {
@@ -254,6 +257,7 @@ public:
@property (nonatomic) MGLMapViewProxyAccessibilityElement *mapViewProxyAccessibilityElement;
@property (nonatomic) MGLAnnotationContainerView *annotationContainerView;
@property (nonatomic) MGLUserLocation *userLocation;
+@property (nonatomic) NS_MUTABLE_DICTIONARY_OF(NSString *, NS_MUTABLE_ARRAY_OF(MGLAnnotationView *) *) *annotationViewReuseQueueByIdentifier;
@end
@@ -267,10 +271,11 @@ public:
NS_MUTABLE_ARRAY_OF(NSURL *) *_bundledStyleURLs;
- MGLAnnotationContextMap _annotationContextsByAnnotationTag;
+ MGLAnnotationTagContextMap _annotationContextsByAnnotationTag;
+ MGLAnnotationObjectTagMap _annotationTagsByAnnotation;
+
/// Tag of the selected annotation. If the user location annotation is selected, this ivar is set to `MGLAnnotationTagNotFound`.
MGLAnnotationTag _selectedAnnotationTag;
- NS_MUTABLE_DICTIONARY_OF(NSString *, NS_MUTABLE_ARRAY_OF(MGLAnnotationView *) *) *_annotationViewReuseQueueByIdentifier;
BOOL _userLocationAnnotationIsSelected;
/// Size of the rectangle formed by unioning the maximum slop area around every annotation image and annotation image view.
@@ -426,6 +431,7 @@ public:
// Set up annotation management and selection state.
_annotationImagesByIdentifier = [NSMutableDictionary dictionary];
_annotationContextsByAnnotationTag = {};
+ _annotationTagsByAnnotation = {};
_annotationViewReuseQueueByIdentifier = [NSMutableDictionary dictionary];
_selectedAnnotationTag = MGLAnnotationTagNotFound;
_annotationsNearbyLastTap = {};
@@ -2819,6 +2825,35 @@ public:
return [NSArray arrayWithObjects:&annotations[0] count:annotations.size()];
}
+- (nullable NS_ARRAY_OF(id <MGLAnnotation>) *)visibleAnnotations
+{
+ return [self visibleAnnotationsInRect:self.bounds];
+}
+
+- (nullable NS_ARRAY_OF(id <MGLAnnotation>) *)visibleAnnotationsInRect:(CGRect)rect
+{
+ if (_annotationContextsByAnnotationTag.empty())
+ {
+ return nil;
+ }
+
+ std::vector<MGLAnnotationTag> annotationTags = [self annotationTagsInRect:rect];
+ if (annotationTags.size())
+ {
+ NSMutableArray *annotations = [NSMutableArray arrayWithCapacity:annotationTags.size()];
+
+ for (auto const& annotationTag: annotationTags)
+ {
+ MGLAnnotationContext annotationContext = _annotationContextsByAnnotationTag[annotationTag];
+ [annotations addObject:annotationContext.annotation];
+ }
+
+ return [annotations copy];
+ }
+
+ return nil;
+}
+
/// Returns the annotation assigned the given tag. Cheap.
- (id <MGLAnnotation>)annotationWithTag:(MGLAnnotationTag)tag
{
@@ -2878,13 +2913,6 @@ public:
if ([annotation isKindOfClass:[MGLMultiPoint class]])
{
- // Actual multipoints aren’t supported as annotations.
- if ([annotation isMemberOfClass:[MGLMultiPoint class]]
- || [annotation isMemberOfClass:[MGLMultiPointFeature class]])
- {
- continue;
- }
-
// The polyline or polygon knows how to style itself (with the map view’s help).
MGLMultiPoint *multiPoint = (MGLMultiPoint *)annotation;
if (!multiPoint.pointCount) {
@@ -2899,8 +2927,9 @@ public:
[(NSObject *)annotation addObserver:self forKeyPath:@"coordinates" options:0 context:(void *)(NSUInteger)annotationTag];
}
else if ( ! [annotation isKindOfClass:[MGLMultiPolyline class]]
- || ![annotation isKindOfClass:[MGLMultiPolygon class]]
- || ![annotation isKindOfClass:[MGLShapeCollection class]])
+ && ![annotation isKindOfClass:[MGLMultiPolygon class]]
+ && ![annotation isKindOfClass:[MGLShapeCollection class]]
+ && ![annotation isKindOfClass:[MGLPointCollection class]])
{
MGLAnnotationView *annotationView;
NSString *symbolName;
@@ -2972,6 +3001,7 @@ public:
context.viewReuseIdentifier = annotationView.reuseIdentifier;
}
+ _annotationTagsByAnnotation[annotation] = annotationTag;
_annotationContextsByAnnotationTag[annotationTag] = context;
if ([annotation isKindOfClass:[NSObject class]]) {
@@ -3068,9 +3098,7 @@ public:
- (nullable MGLAnnotationView *)viewForAnnotation:(id<MGLAnnotation>)annotation
{
- MGLAnnotationTag annotationTag = [self annotationTagForAnnotation:annotation];
- if (annotationTag == MGLAnnotationTagNotFound) return nil;
-
+ MGLAnnotationTag annotationTag = _annotationTagsByAnnotation.at(annotation);
MGLAnnotationContext &annotationContext = _annotationContextsByAnnotationTag.at(annotationTag);
return annotationContext.annotationView;
}
@@ -3171,6 +3199,16 @@ public:
MGLAnnotationContext &annotationContext = _annotationContextsByAnnotationTag.at(annotationTag);
MGLAnnotationView *annotationView = annotationContext.annotationView;
+
+ if (annotationContext.viewReuseIdentifier)
+ {
+ NSMutableArray *annotationViewReuseQueue = [self annotationViewReuseQueueForIdentifier:annotationContext.viewReuseIdentifier];
+ if (![annotationViewReuseQueue containsObject:annotationView])
+ {
+ [annotationViewReuseQueue removeObject:annotationView];
+ }
+ }
+
annotationView.annotation = nil;
[annotationView removeFromSuperview];
@@ -3180,6 +3218,7 @@ public:
}
_annotationContextsByAnnotationTag.erase(annotationTag);
+ _annotationTagsByAnnotation.erase(annotation);
if ([annotation isKindOfClass:[NSObject class]] && ![annotation isKindOfClass:[MGLMultiPoint class]])
{
@@ -4614,49 +4653,89 @@ public:
[CATransaction begin];
[CATransaction setDisableActions:YES];
- for (auto &pair : _annotationContextsByAnnotationTag)
+ // If the map is pitched consider the viewport to be exactly the same as the bounds.
+ // Otherwise, add a small buffer.
+ CGFloat widthAdjustment = self.camera.pitch > 0.0 ? 0.0 : -_largestAnnotationViewSize.width * 2.0;
+ CGFloat heightAdjustment = self.camera.pitch > 0.0 ? 0.0 : -_largestAnnotationViewSize.height * 2.0;
+ CGRect viewPort = CGRectInset(self.bounds, widthAdjustment, heightAdjustment);
+
+ NSArray *visibleAnnotations = [self visibleAnnotationsInRect:viewPort];
+ NSMutableArray *offscreenAnnotations = [self.annotations mutableCopy];
+ [offscreenAnnotations removeObjectsInArray:visibleAnnotations];
+
+ // Update the center of visible annotation views
+ for (id<MGLAnnotation> annotation in visibleAnnotations)
{
- CGRect viewPort = CGRectInset(self.bounds,
- -_largestAnnotationViewSize.width / 2.0 - MGLAnnotationUpdateViewportOutset.width / 2.0,
- -_largestAnnotationViewSize.height / 2.0 - MGLAnnotationUpdateViewportOutset.width);
-
- MGLAnnotationContext &annotationContext = pair.second;
- MGLAnnotationView *annotationView = annotationContext.annotationView;
-
// Defer to the shape/polygon styling delegate methods
- if ([annotationContext.annotation isKindOfClass:[MGLMultiPoint class]])
+ if ([annotation isKindOfClass:[MGLMultiPoint class]])
{
continue;
}
+ // Get the annotation tag then use it to get the context. This avoids the expensive lookup
+ // by tag in `annotationTagForAnnotation:`
+ MGLAnnotationTag annotationTag = _annotationTagsByAnnotation.at(annotation);
+ MGLAnnotationContext &annotationContext = _annotationContextsByAnnotationTag.at(annotationTag);
+
+ MGLAnnotationView *annotationView = annotationContext.annotationView;
if (!annotationView)
{
+ // This will dequeue views if the delegate implements the dequeue call
MGLAnnotationView *annotationView = [self annotationViewForAnnotation:annotationContext.annotation];
+
if (annotationView)
{
annotationView.mapView = self;
- annotationView.center = [self convertCoordinate:annotationContext.annotation.coordinate toPointToView:self];
annotationContext.annotationView = annotationView;
+ // New annotation (created because there is nothing to dequeue) may not have been added to the
+ // container view yet. Add them here.
if (!annotationView.superview) {
[self.annotationContainerView insertSubview:annotationView atIndex:0];
}
}
- else
- {
- // if there is no annotationView at this point then we are dealing with a sprite backed annotation
- continue;
- }
}
- bool annotationViewIsVisible = CGRectContainsRect(viewPort, annotationView.frame);
- if (!annotationViewIsVisible && annotationContext.viewReuseIdentifier)
+ if (annotationView)
{
- [self enqueueAnnotationViewForAnnotationContext:annotationContext];
+ annotationView.center = [self convertCoordinate:annotationContext.annotation.coordinate toPointToView:self];
}
- else
+ }
+
+ CGPoint upperLeft = {_largestAnnotationViewSize.width,_largestAnnotationViewSize.height};
+ CGPoint lowerRight = {CGRectGetWidth(self.bounds) + _largestAnnotationViewSize.width,
+ CGRectGetHeight(self.bounds) + _largestAnnotationViewSize.height};
+
+ CLLocationCoordinate2D upperLeftCoordinate = [self convertPoint:upperLeft toCoordinateFromView:self];
+ CLLocationCoordinate2D lowerRightCoordinate = [self convertPoint:lowerRight toCoordinateFromView:self];
+
+ // Enqueue (and move if required) offscreen annotation views
+ for (id<MGLAnnotation> annotation in offscreenAnnotations)
+ {
+ CLLocationCoordinate2D coordinate = annotation.coordinate;
+ MGLAnnotationTag annotationTag = _annotationTagsByAnnotation.at(annotation);
+ MGLAnnotationContext &annotationContext = _annotationContextsByAnnotationTag.at(annotationTag);
+ UIView *annotationView = annotationContext.annotationView;
+
+ if (annotationView)
{
- annotationView.center = [self convertCoordinate:annotationContext.annotation.coordinate toPointToView:self];
+ // Every so often (1 out of 1000 frames?) the mbgl query mechanism fails. This logic spot checks the
+ // offscreenAnnotations values -- if they are actually still on screen then the view center is
+ // moved and the enqueue operation is avoided. This allows us to keep the performance benefit of
+ // using the mbgl query result. It also forces views that have just gone offscreen to be cleared
+ // fully from view.
+ if ((coordinate.latitude > upperLeftCoordinate.latitude || coordinate.latitude < lowerRightCoordinate.latitude) ||
+ (coordinate.longitude < upperLeftCoordinate.longitude || coordinate.longitude > lowerRightCoordinate.longitude))
+ {
+ CGRect adjustedFrame = annotationView.frame;
+ adjustedFrame.origin.x = -CGRectGetWidth(adjustedFrame) * 2.0;
+ annotationView.frame = adjustedFrame;
+ [self enqueueAnnotationViewForAnnotationContext:annotationContext];
+ }
+ else
+ {
+ annotationView.center = [self convertCoordinate:annotationContext.annotation.coordinate toPointToView:self];
+ }
}
}
@@ -4669,10 +4748,9 @@ public:
if (!annotationView) return;
- annotationView.annotation = nil;
-
if (annotationContext.viewReuseIdentifier)
{
+ annotationView.annotation = nil;
NSMutableArray *annotationViewReuseQueue = [self annotationViewReuseQueueForIdentifier:annotationContext.viewReuseIdentifier];
if (![annotationViewReuseQueue containsObject:annotationView])
{
diff --git a/platform/ios/src/Mapbox.h b/platform/ios/src/Mapbox.h
index 04892eb6a1..c2fda1be1f 100644
--- a/platform/ios/src/Mapbox.h
+++ b/platform/ios/src/Mapbox.h
@@ -27,6 +27,7 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[];
#import "MGLOfflineStorage.h"
#import "MGLOverlay.h"
#import "MGLPointAnnotation.h"
+#import "MGLPointCollection.h"
#import "MGLPolygon.h"
#import "MGLPolyline.h"
#import "MGLShape.h"
diff --git a/platform/ios/test/test-Bridging-Header.h b/platform/ios/test/test-Bridging-Header.h
new file mode 100644
index 0000000000..e11d920b12
--- /dev/null
+++ b/platform/ios/test/test-Bridging-Header.h
@@ -0,0 +1,3 @@
+//
+// Use this file to import your target's public headers that you would like to expose to Swift.
+//
diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md
index 56f5f7d307..9f08e5de9d 100644
--- a/platform/macos/CHANGELOG.md
+++ b/platform/macos/CHANGELOG.md
@@ -7,6 +7,7 @@
* Fixed an issue causing code signing failures and bloating the framework. ([#5850](https://github.com/mapbox/mapbox-gl-native/pull/5850))
* Xcode 7.3 or higher is now required for using this SDK. ([#6059](https://github.com/mapbox/mapbox-gl-native/issues/6059))
* Fixed an issue with symbols not being properly stripped from the dynamic framework when built with `make xpackage SYMBOLS=NO`. ([#6531](https://github.com/mapbox/mapbox-gl-native/pull/6531))
+* Added documentation for the Info.plist keys used by this SDK. ([#6833](https://github.com/mapbox/mapbox-gl-native/pull/6833))
### Styles and data
@@ -14,8 +15,11 @@
* MGLMapView’s `styleURL` property can now be set to an absolute file URL. ([#6026](https://github.com/mapbox/mapbox-gl-native/pull/6026))
* GeoJSON sources specified by the stylesheet at design time now support `cluster`, `clusterMaxZoom`, and `clusterRadius` attributes for clustering point features on the base map. ([#5724](https://github.com/mapbox/mapbox-gl-native/pull/5724))
* TileJSON manifests can now specify `"scheme": "tms"` to indicate the use of [TMS](https://en.wikipedia.org/wiki/Tile_Map_Service) coordinates. ([#2270](https://github.com/mapbox/mapbox-gl-native/pull/2270))
+* Fixed an issue causing abstract `MGLMultiPointFeature` objects to be returned in feature query results. Now concrete `MGLPointCollectionFeature` objects are returned. ([#6742](https://github.com/mapbox/mapbox-gl-native/pull/6742))
* Fixed rendering artifacts and missing glyphs that occurred after viewing a large number of CJK characters on the map. ([#5908](https://github.com/mapbox/mapbox-gl-native/pull/5908))
* Fixed an issue where the style zoom levels were not respected when deciding when to render a layer. ([#5811](https://github.com/mapbox/mapbox-gl-native/issues/5811))
+* Fixed an issue where feature querying sometimes failed to return the expected features when the map was tilted. ([#6773](https://github.com/mapbox/mapbox-gl-native/pull/6773))
+* MGLFeature’s `attributes` and `identifier` properties are now writable. ([#6728](https://github.com/mapbox/mapbox-gl-native/pull/6728))
* If MGLMapView is unable to obtain or parse a style, it now calls its delegate’s `-mapViewDidFailLoadingMap:withError:` method. ([#6145](https://github.com/mapbox/mapbox-gl-native/pull/6145))
* Added the `-[MGLMapViewDelegate mapView:didFinishLoadingStyle:]` delegate method, which offers the earliest opportunity to modify the layout or appearance of the current style before the map view is displayed to the user. ([#6636](https://github.com/mapbox/mapbox-gl-native/pull/6636))
* Fixed an issue causing stepwise zoom functions to be misinterpreted. ([#6328](https://github.com/mapbox/mapbox-gl-native/pull/6328))
@@ -23,14 +27,17 @@
* Fixed crashes that could occur when loading a malformed stylesheet. ([#5736](https://github.com/mapbox/mapbox-gl-native/pull/5736))
* Improved style parsing performance. ([#6170](https://github.com/mapbox/mapbox-gl-native/pull/6170))
* Improved feature querying performance. ([#6514](https://github.com/mapbox/mapbox-gl-native/pull/6514))
+* Fixed an issue where shapes that cannot currently be visually represented as annotations were still shown on the map as point annotations. ([#6764](https://github.com/mapbox/mapbox-gl-native/issues/6764))
### Annotations
* Added `showAnnotations:animated:` and `showAnnotations:edgePadding:animated:`, which moves the map viewport to show the specified annotations. ([#5749](https://github.com/mapbox/mapbox-gl-native/pull/5749))
* MGLPolyline annotations and the exterior coordinates of MGLPolygon annotations are now able to be mutated, part or all, and changes are displayed immediately. ([#6565](https://github.com/mapbox/mapbox-gl-native/pull/6565))
+* Added new APIs to MGLMapView to query for visible annotations. ([6061](https://github.com/mapbox/mapbox-gl-native/pull/6061))
+* Deprecated `-[MGLMapViewDelegate mapView:alphaForShapeAnnotation:]` in favor of specifying an alpha component via `-[MGLMapViewDelegate mapView:strokeColorForShapeAnnotation:]` or `-[MGLMapViewDelegate mapView:fillColorForPolygonAnnotation:]`. ([#6706](https://github.com/mapbox/mapbox-gl-native/pull/6706))
* To make an MGLPolyline or MGLPolygon span the antimeridian, specify coordinates with longitudes greater than 180° or less than −180°. ([#6088](https://github.com/mapbox/mapbox-gl-native/pull/6088))
+* Fixed an issue where placing a point annotation on Null Island also placed a duplicate annotation on its antipode. ([#3563](https://github.com/mapbox/mapbox-gl-native/pull/3563))
* Improved the precision of annotations at zoom levels greater than 18. ([#5517](https://github.com/mapbox/mapbox-gl-native/pull/5517))
-* Deprecated `-[MGLMapViewDelegate mapView:alphaForShapeAnnotation:]` in favor of specifying an alpha component via `-[MGLMapViewDelegate mapView:strokeColorForShapeAnnotation:]` or `-[MGLMapViewDelegate mapView:fillColorForPolygonAnnotation:]`. ([#6706](https://github.com/mapbox/mapbox-gl-native/pull/6706))
### Networking and offline maps
@@ -46,6 +53,7 @@
### Other changes
* Fixed an issue where the map view’s center would always be calculated as if the view occupied the entire window. ([#6102](https://github.com/mapbox/mapbox-gl-native/pull/6102))
+* Notification names and user info keys are now string enumeration values for ease of use in Swift. ([#6794](https://github.com/mapbox/mapbox-gl-native/pull/6794))
* Fixed a typo in the documentation for the MGLCompassDirectionFormatter class. ([#5879](https://github.com/mapbox/mapbox-gl-native/pull/5879))
## 0.2.1 - July 19, 2016
diff --git a/platform/macos/jazzy.yml b/platform/macos/jazzy.yml
index 6909e14385..42f978283e 100644
--- a/platform/macos/jazzy.yml
+++ b/platform/macos/jazzy.yml
@@ -30,6 +30,7 @@ custom_categories:
- MGLMultiPolygon
- MGLMultiPolyline
- MGLPointAnnotation
+ - MGLPointCollection
- MGLPolygon
- MGLPolyline
- MGLOverlay
@@ -37,11 +38,11 @@ custom_categories:
- MGLShapeCollection
- name: Map Data
children:
- - MGLFeature
- - MGLMultiPointFeature
+ - MGLFeature
- MGLMultiPolygonFeature
- MGLMultiPolylineFeature
- - MGLPointFeature
+ - MGLPointCollectionFeature
+ - MGLPointFeature
- MGLPolygonFeature
- MGLPolylineFeature
- MGLShapeCollectionFeature
diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj
index eedad040b0..194d543f82 100644
--- a/platform/macos/macos.xcodeproj/project.pbxproj
+++ b/platform/macos/macos.xcodeproj/project.pbxproj
@@ -40,6 +40,8 @@
35C5D84A1D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35C5D8461D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.mm */; };
35D65C5A1D65AD5500722C23 /* NSDate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35D65C581D65AD5500722C23 /* NSDate+MGLAdditions.h */; };
35D65C5B1D65AD5500722C23 /* NSDate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35D65C591D65AD5500722C23 /* NSDate+MGLAdditions.mm */; };
+ 4049C2A51DB6CE7F00B3F799 /* MGLPointCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 4049C2A11DB6CE7800B3F799 /* MGLPointCollection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 4049C2AD1DB8020600B3F799 /* MGLPointCollection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4049C2A71DB6D09B00B3F799 /* MGLPointCollection.mm */; };
408AA85B1DAEECFE00022900 /* MGLShape_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 408AA85A1DAEECF100022900 /* MGLShape_Private.h */; };
408AA8651DAEEE3400022900 /* MGLPolygon+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 408AA8601DAEED3300022900 /* MGLPolygon+MGLAdditions.h */; };
408AA8661DAEEE3600022900 /* MGLPolyline+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 408AA8611DAEED3300022900 /* MGLPolyline+MGLAdditions.h */; };
@@ -55,6 +57,7 @@
558F18221D0B13B100123F46 /* libmbgl-loop.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 558F18211D0B13B000123F46 /* libmbgl-loop.a */; };
55D9B4B11D005D3900C1CCE2 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 55D9B4B01D005D3900C1CCE2 /* libz.tbd */; };
DA0CD58E1CF56F5800A5F5A5 /* MGLFeatureTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA0CD58D1CF56F5800A5F5A5 /* MGLFeatureTests.mm */; };
+ DA2207BC1DC076940002F84D /* MGLStyleValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2207BB1DC076940002F84D /* MGLStyleValueTests.swift */; };
DA2DBBCB1D51E30A00D38FF9 /* MGLStyleLayerTests.xib in Resources */ = {isa = PBXBuildFile; fileRef = DA2DBBCA1D51E30A00D38FF9 /* MGLStyleLayerTests.xib */; };
DA35A2A41CC9EB1A00E826B2 /* MGLCoordinateFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = DA35A2A31CC9EB1A00E826B2 /* MGLCoordinateFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; };
DA35A2A61CC9EB2700E826B2 /* MGLCoordinateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = DA35A2A51CC9EB2700E826B2 /* MGLCoordinateFormatter.m */; };
@@ -79,6 +82,19 @@
DA839EA01CC2E3400062CAFB /* MapDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = DA839E9E1CC2E3400062CAFB /* MapDocument.xib */; };
DA839EA21CC2E3400062CAFB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA839EA11CC2E3400062CAFB /* Assets.xcassets */; };
DA839EA51CC2E3400062CAFB /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = DA839EA31CC2E3400062CAFB /* MainMenu.xib */; };
+ DA87A9981DC9D88400810D09 /* MGLGeoJSONSourceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA87A9961DC9D88400810D09 /* MGLGeoJSONSourceTests.mm */; };
+ DA87A9991DC9D88400810D09 /* MGLTileSetTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA87A9971DC9D88400810D09 /* MGLTileSetTests.mm */; };
+ DA87A99C1DC9D8DD00810D09 /* MGLGeoJSONSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA87A99B1DC9D8DD00810D09 /* MGLGeoJSONSource_Private.h */; };
+ DA87A99D1DC9DB2E00810D09 /* MGLStyleLayerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2DBBC81D51E26600D38FF9 /* MGLStyleLayerTests.m */; };
+ DA87A99E1DC9DC2100810D09 /* MGLFilterTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35C5D84B1D6DD75B00E95907 /* MGLFilterTests.mm */; };
+ DA87A9A01DC9DC6200810D09 /* MGLValueEvaluator.h in Headers */ = {isa = PBXBuildFile; fileRef = DA87A99F1DC9DC6200810D09 /* MGLValueEvaluator.h */; };
+ DA87A9A11DC9DCB400810D09 /* MGLRuntimeStylingHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8F257B1D51C5F40010E6B5 /* MGLRuntimeStylingHelper.m */; };
+ DA87A9A21DC9DCF100810D09 /* MGLFillStyleLayerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8F25741D51C5F40010E6B5 /* MGLFillStyleLayerTests.m */; };
+ DA87A9A31DCACC5000810D09 /* MGLRasterStyleLayerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8F25751D51C5F40010E6B5 /* MGLRasterStyleLayerTests.m */; };
+ DA87A9A41DCACC5000810D09 /* MGLSymbolStyleLayerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8F25761D51C5F40010E6B5 /* MGLSymbolStyleLayerTests.m */; };
+ DA87A9A51DCACC5000810D09 /* MGLLineStyleLayerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8F25771D51C5F40010E6B5 /* MGLLineStyleLayerTests.m */; };
+ DA87A9A61DCACC5000810D09 /* MGLCircleStyleLayerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8F25781D51C5F40010E6B5 /* MGLCircleStyleLayerTests.m */; };
+ DA87A9A71DCACC5000810D09 /* MGLBackgroundStyleLayerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8F25791D51C5F40010E6B5 /* MGLBackgroundStyleLayerTests.m */; };
DA8933A51CCD287300E68420 /* MGLAnnotationCallout.xib in Resources */ = {isa = PBXBuildFile; fileRef = DA8933A71CCD287300E68420 /* MGLAnnotationCallout.xib */; };
DA8933AE1CCD290700E68420 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DA8933AB1CCD290700E68420 /* Localizable.strings */; };
DA8933B51CCD2C2500E68420 /* Foundation.strings in Resources */ = {isa = PBXBuildFile; fileRef = DA8933B31CCD2C2500E68420 /* Foundation.strings */; };
@@ -249,6 +265,8 @@
35C5D84B1D6DD75B00E95907 /* MGLFilterTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLFilterTests.mm; sourceTree = "<group>"; };
35D65C581D65AD5500722C23 /* NSDate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+MGLAdditions.h"; sourceTree = "<group>"; };
35D65C591D65AD5500722C23 /* NSDate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSDate+MGLAdditions.mm"; sourceTree = "<group>"; };
+ 4049C2A11DB6CE7800B3F799 /* MGLPointCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLPointCollection.h; sourceTree = "<group>"; };
+ 4049C2A71DB6D09B00B3F799 /* MGLPointCollection.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLPointCollection.mm; sourceTree = "<group>"; };
405C03961DB0004E001AC280 /* NSImage+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSImage+MGLAdditions.h"; sourceTree = "<group>"; };
405C03971DB0004E001AC280 /* NSImage+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSImage+MGLAdditions.mm"; sourceTree = "<group>"; };
408AA85A1DAEECF100022900 /* MGLShape_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLShape_Private.h; sourceTree = "<group>"; };
@@ -267,6 +285,8 @@
55D9B4B01D005D3900C1CCE2 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
55FE0E8D1D100A0900FD240B /* config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = config.xcconfig; path = ../../build/macos/config.xcconfig; sourceTree = "<group>"; };
DA0CD58D1CF56F5800A5F5A5 /* MGLFeatureTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLFeatureTests.mm; path = ../../darwin/test/MGLFeatureTests.mm; sourceTree = "<group>"; };
+ DA2207BA1DC076930002F84D /* test-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "test-Bridging-Header.h"; sourceTree = "<group>"; };
+ DA2207BB1DC076940002F84D /* MGLStyleValueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MGLStyleValueTests.swift; sourceTree = "<group>"; };
DA2DBBC71D51E26600D38FF9 /* MGLStyleLayerTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGLStyleLayerTests.h; path = ../darwin/test/MGLStyleLayerTests.h; sourceTree = SOURCE_ROOT; };
DA2DBBC81D51E26600D38FF9 /* MGLStyleLayerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLStyleLayerTests.m; path = ../darwin/test/MGLStyleLayerTests.m; sourceTree = SOURCE_ROOT; };
DA2DBBCA1D51E30A00D38FF9 /* MGLStyleLayerTests.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MGLStyleLayerTests.xib; sourceTree = "<group>"; };
@@ -297,6 +317,10 @@
DA839EA11CC2E3400062CAFB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
DA839EA41CC2E3400062CAFB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
DA839EA61CC2E3400062CAFB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ DA87A9961DC9D88400810D09 /* MGLGeoJSONSourceTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLGeoJSONSourceTests.mm; sourceTree = "<group>"; };
+ DA87A9971DC9D88400810D09 /* MGLTileSetTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLTileSetTests.mm; sourceTree = "<group>"; };
+ DA87A99B1DC9D8DD00810D09 /* MGLGeoJSONSource_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLGeoJSONSource_Private.h; sourceTree = "<group>"; };
+ DA87A99F1DC9DC6200810D09 /* MGLValueEvaluator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLValueEvaluator.h; sourceTree = "<group>"; };
DA8933A61CCD287300E68420 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MGLAnnotationCallout.xib; sourceTree = "<group>"; };
DA8933AC1CCD290700E68420 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = "<group>"; };
DA8933B41CCD2C2500E68420 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Foundation.strings; sourceTree = "<group>"; };
@@ -496,6 +520,7 @@
DA8F25951D51CAC70010E6B5 /* MGLVectorSource.h */,
DA8F25961D51CAC70010E6B5 /* MGLVectorSource.mm */,
352742871D4C245800A1ECE6 /* MGLGeoJSONSource.h */,
+ DA87A99B1DC9D8DD00810D09 /* MGLGeoJSONSource_Private.h */,
352742881D4C245800A1ECE6 /* MGLGeoJSONSource.mm */,
352742831D4C244700A1ECE6 /* MGLRasterSource.h */,
352742841D4C244700A1ECE6 /* MGLRasterSource.mm */,
@@ -577,6 +602,15 @@
name = "Supporting Files";
sourceTree = "<group>";
};
+ DA87A99A1DC9D88800810D09 /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ DA87A9961DC9D88400810D09 /* MGLGeoJSONSourceTests.mm */,
+ DA87A9971DC9D88400810D09 /* MGLTileSetTests.mm */,
+ );
+ name = Sources;
+ sourceTree = "<group>";
+ };
DA8933A81CCD28D100E68420 /* Kit Resources */ = {
isa = PBXGroup;
children = (
@@ -601,6 +635,7 @@
DA8F257C1D51C5F40010E6B5 /* Layers */ = {
isa = PBXGroup;
children = (
+ DA2207BA1DC076930002F84D /* test-Bridging-Header.h */,
DA2DBBC71D51E26600D38FF9 /* MGLStyleLayerTests.h */,
DA2DBBC81D51E26600D38FF9 /* MGLStyleLayerTests.m */,
DA8F25741D51C5F40010E6B5 /* MGLFillStyleLayerTests.m */,
@@ -620,7 +655,9 @@
isa = PBXGroup;
children = (
DA8F257C1D51C5F40010E6B5 /* Layers */,
+ DA87A99A1DC9D88800810D09 /* Sources */,
35C5D84B1D6DD75B00E95907 /* MGLFilterTests.mm */,
+ DA2207BB1DC076940002F84D /* MGLStyleValueTests.swift */,
);
name = Styling;
path = ../../darwin/test;
@@ -665,24 +702,26 @@
isa = PBXGroup;
children = (
DAE6C34B1CC31E0400DB3429 /* MGLAnnotation.h */,
- DACC22121CF3D3E200D220D9 /* MGLFeature.h */,
DACC22171CF3D4F700D220D9 /* MGLFeature_Private.h */,
+ DACC22121CF3D3E200D220D9 /* MGLFeature.h */,
DACC22131CF3D3E200D220D9 /* MGLFeature.mm */,
- DAE6C34C1CC31E0400DB3429 /* MGLGeometry.h */,
DAE6C36C1CC31E2A00DB3429 /* MGLGeometry_Private.h */,
+ DAE6C34C1CC31E0400DB3429 /* MGLGeometry.h */,
DAE6C36D1CC31E2A00DB3429 /* MGLGeometry.mm */,
- DAE6C34E1CC31E0400DB3429 /* MGLMultiPoint.h */,
DAE6C36F1CC31E2A00DB3429 /* MGLMultiPoint_Private.h */,
+ DAE6C34E1CC31E0400DB3429 /* MGLMultiPoint.h */,
DAE6C3701CC31E2A00DB3429 /* MGLMultiPoint.mm */,
DAE6C3521CC31E0400DB3429 /* MGLOverlay.h */,
DAE6C3531CC31E0400DB3429 /* MGLPointAnnotation.h */,
DAE6C3761CC31E2A00DB3429 /* MGLPointAnnotation.mm */,
+ 4049C2A11DB6CE7800B3F799 /* MGLPointCollection.h */,
+ 4049C2A71DB6D09B00B3F799 /* MGLPointCollection.mm */,
DAE6C3541CC31E0400DB3429 /* MGLPolygon.h */,
DAE6C3771CC31E2A00DB3429 /* MGLPolygon.mm */,
DAE6C3551CC31E0400DB3429 /* MGLPolyline.h */,
DAE6C3781CC31E2A00DB3429 /* MGLPolyline.mm */,
- DAE6C3561CC31E0400DB3429 /* MGLShape.h */,
408AA85A1DAEECF100022900 /* MGLShape_Private.h */,
+ DAE6C3561CC31E0400DB3429 /* MGLShape.h */,
DAE6C3791CC31E2A00DB3429 /* MGLShape.mm */,
DAD165721CF4CD7A001FF4B9 /* MGLShapeCollection.h */,
DAD165731CF4CD7A001FF4B9 /* MGLShapeCollection.m */,
@@ -813,6 +852,7 @@
DAE6C37A1CC31E2A00DB3429 /* MGLStyle.mm */,
DAE6C3591CC31E0400DB3429 /* MGLTypes.h */,
DAE6C37C1CC31E2A00DB3429 /* MGLTypes.m */,
+ DA87A99F1DC9DC6200810D09 /* MGLValueEvaluator.h */,
);
name = Foundation;
path = ../darwin/src;
@@ -889,6 +929,7 @@
DAE6C3691CC31E0400DB3429 /* MGLTypes.h in Headers */,
DAE6C3991CC31E2A00DB3429 /* NSException+MGLAdditions.h in Headers */,
DA8F25871D51C9E10010E6B5 /* MGLBackgroundStyleLayer.h in Headers */,
+ 4049C2A51DB6CE7F00B3F799 /* MGLPointCollection.h in Headers */,
30E5781B1DAA857E0050F07E /* NSImage+MGLAdditions.h in Headers */,
DAE6C3661CC31E0400DB3429 /* MGLShape.h in Headers */,
DA551B831DB496AC0009AFAF /* MGLTileSet_Private.h in Headers */,
@@ -907,6 +948,7 @@
DA8F25B21D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.h in Headers */,
DAE6C38E1CC31E2A00DB3429 /* MGLOfflineStorage_Private.h in Headers */,
408AA8661DAEEE3600022900 /* MGLPolyline+MGLAdditions.h in Headers */,
+ DA87A9A01DC9DC6200810D09 /* MGLValueEvaluator.h in Headers */,
DAE6C3601CC31E0400DB3429 /* MGLOfflineRegion.h in Headers */,
DAE6C3681CC31E0400DB3429 /* MGLTilePyramidOfflineRegion.h in Headers */,
DA35A2CF1CCAAED300E826B2 /* NSValue+MGLAdditions.h in Headers */,
@@ -920,6 +962,7 @@
35602C001D3EA9B40050646F /* MGLForegroundStyleLayer.h in Headers */,
DAE6C35D1CC31E0400DB3429 /* MGLMapCamera.h in Headers */,
DAE6C3B41CC31EF300DB3429 /* MGLCompassCell.h in Headers */,
+ DA87A99C1DC9D8DD00810D09 /* MGLGeoJSONSource_Private.h in Headers */,
3537CA741D3F93A600380318 /* MGLStyle_Private.h in Headers */,
DA8F259A1D51CAD00010E6B5 /* MGLSource_Private.h in Headers */,
DA8F25931D51CA750010E6B5 /* MGLSymbolStyleLayer.h in Headers */,
@@ -1034,6 +1077,7 @@
};
DAE6C3301CC30DB200DB3429 = {
CreatedOnToolsVersion = 7.3;
+ LastSwiftMigration = 0800;
};
};
};
@@ -1146,6 +1190,7 @@
DAE6C3BA1CC31EF300DB3429 /* MGLOpenGLLayer.mm in Sources */,
DAE6C38A1CC31E2A00DB3429 /* MGLMultiPoint.mm in Sources */,
DAE6C3961CC31E2A00DB3429 /* MGLTypes.m in Sources */,
+ 4049C2AD1DB8020600B3F799 /* MGLPointCollection.mm in Sources */,
DA35A2A61CC9EB2700E826B2 /* MGLCoordinateFormatter.m in Sources */,
352742821D4C243B00A1ECE6 /* MGLSource.mm in Sources */,
DAE6C3881CC31E2A00DB3429 /* MGLMapCamera.mm in Sources */,
@@ -1181,14 +1226,26 @@
files = (
DA35A2C21CCA9F4A00E826B2 /* MGLClockDirectionFormatterTests.m in Sources */,
DAE6C3D41CC34C9900DB3429 /* MGLOfflineRegionTests.m in Sources */,
+ DA87A9A11DC9DCB400810D09 /* MGLRuntimeStylingHelper.m in Sources */,
DAE6C3D61CC34C9900DB3429 /* MGLStyleTests.mm in Sources */,
DA35A2B61CCA14D700E826B2 /* MGLCompassDirectionFormatterTests.m in Sources */,
DAE6C3D21CC34C9900DB3429 /* MGLGeometryTests.mm in Sources */,
+ DA87A9A41DCACC5000810D09 /* MGLSymbolStyleLayerTests.m in Sources */,
DAE6C3D51CC34C9900DB3429 /* MGLOfflineStorageTests.m in Sources */,
+ DA87A9A61DCACC5000810D09 /* MGLCircleStyleLayerTests.m in Sources */,
+ DA87A99D1DC9DB2E00810D09 /* MGLStyleLayerTests.m in Sources */,
+ DA87A99E1DC9DC2100810D09 /* MGLFilterTests.mm in Sources */,
DD58A4C91D822C6700E1F038 /* MGLExpressionTests.mm in Sources */,
+ DA87A9A71DCACC5000810D09 /* MGLBackgroundStyleLayerTests.m in Sources */,
DAE6C3D31CC34C9900DB3429 /* MGLOfflinePackTests.m in Sources */,
+ DA87A9A51DCACC5000810D09 /* MGLLineStyleLayerTests.m in Sources */,
+ DA87A9A31DCACC5000810D09 /* MGLRasterStyleLayerTests.m in Sources */,
+ DA87A9991DC9D88400810D09 /* MGLTileSetTests.mm in Sources */,
DA35A2A81CC9F41600E826B2 /* MGLCoordinateFormatterTests.m in Sources */,
+ DA87A9981DC9D88400810D09 /* MGLGeoJSONSourceTests.mm in Sources */,
+ DA87A9A21DC9DCF100810D09 /* MGLFillStyleLayerTests.m in Sources */,
DA0CD58E1CF56F5800A5F5A5 /* MGLFeatureTests.mm in Sources */,
+ DA2207BC1DC076940002F84D /* MGLStyleValueTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1457,6 +1514,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 55FE0E8D1D100A0900FD240B /* config.xcconfig */;
buildSettings = {
+ CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)";
INFOPLIST_FILE = test/Info.plist;
@@ -1469,6 +1527,9 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.test;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "../darwin/test/test-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 3.0;
};
name = Debug;
};
@@ -1476,6 +1537,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 55FE0E8D1D100A0900FD240B /* config.xcconfig */;
buildSettings = {
+ CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
HEADER_SEARCH_PATHS = "$(mbgl_core_INCLUDE_DIRECTORIES)";
INFOPLIST_FILE = test/Info.plist;
@@ -1488,6 +1550,8 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.test;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "../darwin/test/test-Bridging-Header.h";
+ SWIFT_VERSION = 3.0;
};
name = Release;
};
diff --git a/platform/macos/src/MGLMapView.h b/platform/macos/src/MGLMapView.h
index 3499671ff1..3dbbbe3d82 100644
--- a/platform/macos/src/MGLMapView.h
+++ b/platform/macos/src/MGLMapView.h
@@ -569,6 +569,16 @@ IB_DESIGNABLE
- (void)addAnnotations:(NS_ARRAY_OF(id <MGLAnnotation>) *)annotations;
/**
+ The complete list of annotations associated with the receiver that are
+ currently visible.
+
+ The objects in this array must adopt the `MGLAnnotation` protocol. If no
+ annotations are associated with the map view or if no annotations associated
+ with the map view are currently visible, the value of this property is `nil`.
+ */
+@property (nonatomic, readonly, nullable) NS_ARRAY_OF(id <MGLAnnotation>) *visibleAnnotations;
+
+/**
Removes an annotation from the map view, deselecting it if it is selected.
Removing an annotation object dissociates it from the map view entirely,
@@ -608,6 +618,17 @@ IB_DESIGNABLE
*/
- (nullable MGLAnnotationImage *)dequeueReusableAnnotationImageWithIdentifier:(NSString *)identifier;
+/**
+ Returns the list of annotations associated with the receiver that intersect with
+ the given rectangle.
+
+ @param rect A rectangle expressed in the map view’s coordinate system.
+ @return An array of objects that adopt the `MGLAnnotation` protocol or `nil` if
+ no annotations associated with the map view are currently visible in the
+ rectangle.
+ */
+- (nullable NS_ARRAY_OF(id <MGLAnnotation>) *)visibleAnnotationsInRect:(CGRect)rect;
+
#pragma mark Managing Annotation Selections
/**
diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm
index 45208408fe..02f96ac3ff 100644
--- a/platform/macos/src/MGLMapView.mm
+++ b/platform/macos/src/MGLMapView.mm
@@ -108,7 +108,7 @@ enum { MGLAnnotationTagNotFound = UINT32_MAX };
/// Mapping from an annotation tag to metadata about that annotation, including
/// the annotation itself.
-typedef std::unordered_map<MGLAnnotationTag, MGLAnnotationContext> MGLAnnotationContextMap;
+typedef std::unordered_map<MGLAnnotationTag, MGLAnnotationContext> MGLAnnotationTagContextMap;
/// Returns an NSImage for the default marker image.
NSImage *MGLDefaultMarkerImage() {
@@ -171,7 +171,7 @@ public:
CGFloat _pitchAtBeginningOfGesture;
BOOL _didHideCursorDuringGesture;
- MGLAnnotationContextMap _annotationContextsByAnnotationTag;
+ MGLAnnotationTagContextMap _annotationContextsByAnnotationTag;
MGLAnnotationTag _selectedAnnotationTag;
MGLAnnotationTag _lastSelectedAnnotationTag;
/// Size of the rectangle formed by unioning the maximum slop area around every annotation image.
@@ -1623,6 +1623,35 @@ public:
return [NSArray arrayWithObjects:&annotations[0] count:annotations.size()];
}
+- (nullable NS_ARRAY_OF(id <MGLAnnotation>) *)visibleAnnotations
+{
+ return [self visibleFeaturesInRect:self.bounds];
+}
+
+- (nullable NS_ARRAY_OF(id <MGLAnnotation>) *)visibleAnnotationsInRect:(CGRect)rect
+{
+ if (_annotationContextsByAnnotationTag.empty())
+ {
+ return nil;
+ }
+
+ std::vector<MGLAnnotationTag> annotationTags = [self annotationTagsInRect:rect];
+ if (annotationTags.size())
+ {
+ NSMutableArray *annotations = [NSMutableArray arrayWithCapacity:annotationTags.size()];
+
+ for (auto const& annotationTag: annotationTags)
+ {
+ MGLAnnotationContext annotationContext = _annotationContextsByAnnotationTag[annotationTag];
+ [annotations addObject:annotationContext.annotation];
+ }
+
+ return [annotations copy];
+ }
+
+ return nil;
+}
+
/// Returns the annotation assigned the given tag. Cheap.
- (id <MGLAnnotation>)annotationWithTag:(MGLAnnotationTag)tag {
if (!_annotationContextsByAnnotationTag.count(tag)) {
@@ -1666,12 +1695,6 @@ public:
NSAssert([annotation conformsToProtocol:@protocol(MGLAnnotation)], @"Annotation does not conform to MGLAnnotation");
if ([annotation isKindOfClass:[MGLMultiPoint class]]) {
- // Actual multipoints aren’t supported as annotations.
- if ([annotation isMemberOfClass:[MGLMultiPoint class]]
- || [annotation isMemberOfClass:[MGLMultiPointFeature class]]) {
- continue;
- }
-
// The multipoint knows how to style itself (with the map view’s help).
MGLMultiPoint *multiPoint = (MGLMultiPoint *)annotation;
if (!multiPoint.pointCount) {
@@ -1685,8 +1708,9 @@ public:
[(NSObject *)annotation addObserver:self forKeyPath:@"coordinates" options:0 context:(void *)(NSUInteger)annotationTag];
} else if (![annotation isKindOfClass:[MGLMultiPolyline class]]
- || ![annotation isKindOfClass:[MGLMultiPolygon class]]
- || ![annotation isKindOfClass:[MGLShapeCollection class]]) {
+ && ![annotation isKindOfClass:[MGLMultiPolygon class]]
+ && ![annotation isKindOfClass:[MGLShapeCollection class]]
+ && ![annotation isKindOfClass:[MGLPointCollection class]]) {
MGLAnnotationImage *annotationImage = nil;
if (delegateHasImagesForAnnotations) {
annotationImage = [self.delegate mapView:self imageForAnnotation:annotation];
diff --git a/platform/macos/src/Mapbox.h b/platform/macos/src/Mapbox.h
index 67e3775100..cfddfe6e89 100644
--- a/platform/macos/src/Mapbox.h
+++ b/platform/macos/src/Mapbox.h
@@ -24,6 +24,7 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[];
#import "MGLOfflineStorage.h"
#import "MGLOverlay.h"
#import "MGLPointAnnotation.h"
+#import "MGLPointCollection.h"
#import "MGLPolygon.h"
#import "MGLPolyline.h"
#import "MGLShape.h"
diff --git a/platform/macos/src/NSColor+MGLAdditions.mm b/platform/macos/src/NSColor+MGLAdditions.mm
index e347fd1798..2a55af5cad 100644
--- a/platform/macos/src/NSColor+MGLAdditions.mm
+++ b/platform/macos/src/NSColor+MGLAdditions.mm
@@ -13,7 +13,7 @@
+ (NSColor *)mgl_colorWithColor:(mbgl::Color)color
{
- return [NSColor colorWithRed:color.r green:color.g blue:color.b alpha:color.a];
+ return [NSColor colorWithCalibratedRed:color.r green:color.g blue:color.b alpha:color.a];
}
- (mbgl::style::PropertyValue<mbgl::Color>)mgl_colorPropertyValue