Merge branch 'release-ios-v3.4.0' into 1ec5-release-ios-v3.4.0-beta.2-master

This commit is contained in:
Minh Nguyễn
2016-11-03 13:16:27 -07:00
52 changed files with 1259 additions and 374 deletions

View File

@@ -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
/**

View File

@@ -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 {

View File

@@ -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

View File

@@ -6,34 +6,39 @@ 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

View File

@@ -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];
}
return std::move(source);
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);
_features = MGLFeaturesFromMBGLFeatures(featureCollection);
}
@end

View File

@@ -1,3 +1,4 @@
#import "MGLGeoJSONSource.h"
#import "MGLGeoJSONSource_Private.h"
#include <mbgl/style/sources/geojson_source.hpp>

View File

@@ -6,24 +6,15 @@
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.

View File

@@ -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 = %@>",

View File

@@ -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

View File

@@ -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";
const NSNotificationName MGLOfflinePackProgressChangedNotification = @"MGLOfflinePackProgressChanged";
const NSNotificationName MGLOfflinePackErrorNotification = @"MGLOfflinePackError";
const NSNotificationName MGLOfflinePackMaximumMapboxTilesReachedNotification = @"MGLOfflinePackMaximumMapboxTilesReached";
NSString * const MGLOfflinePackStateUserInfoKey = @"State";
NSString * const MGLOfflinePackProgressUserInfoKey = @"Progress";
NSString * const MGLOfflinePackErrorUserInfoKey = @"Error";
NSString * const MGLOfflinePackMaximumCountUserInfoKey = @"MaximumCount";
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),
}];
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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