diff options
-rw-r--r-- | platform/darwin/src/MGLOfflineStorage.mm | 54 | ||||
-rw-r--r-- | platform/darwin/src/MGLPolygon.mm | 7 | ||||
-rw-r--r-- | platform/darwin/src/MGLPolyline.mm | 7 | ||||
-rw-r--r-- | platform/darwin/src/MGLShapeCollection.mm | 3 | ||||
-rw-r--r-- | platform/darwin/src/MGLStyle.mm | 69 | ||||
-rw-r--r-- | platform/ios/CHANGELOG.md | 60 |
6 files changed, 147 insertions, 53 deletions
diff --git a/platform/darwin/src/MGLOfflineStorage.mm b/platform/darwin/src/MGLOfflineStorage.mm index 608be18db9..b9f81ca69a 100644 --- a/platform/darwin/src/MGLOfflineStorage.mm +++ b/platform/darwin/src/MGLOfflineStorage.mm @@ -7,12 +7,22 @@ #import "MGLOfflinePack_Private.h" #import "MGLOfflineRegion_Private.h" #import "MGLTilePyramidOfflineRegion.h" +#import "MGLShapeOfflineRegion.h" #import "NSBundle+MGLAdditions.h" #import "NSValue+MGLAdditions.h" +#import "NSDate+MGLAdditions.h" +#import "NSData+MGLAdditions.h" +#import "MGLLoggingConfiguration_Private.h" + +#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR +#import "MMEConstants.h" +#import "MGLMapboxEvents.h" +#endif #include <mbgl/actor/actor.hpp> #include <mbgl/actor/scheduler.hpp> #include <mbgl/storage/resource_transform.hpp> +#include <mbgl/util/chrono.hpp> #include <mbgl/util/run_loop.hpp> #include <mbgl/util/string.hpp> @@ -78,6 +88,7 @@ const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegio #endif - (void)setDelegate:(id<MGLOfflineStorageDelegate>)newValue { + MGLLogDebug(@"Setting delegate: %@", newValue); _delegate = newValue; if ([self.delegate respondsToSelector:@selector(offlineStorage:URLForResourceOfKind:withURL:)]) { _mbglResourceTransform = std::make_unique<mbgl::Actor<mbgl::ResourceTransform>>(*mbgl::Scheduler::GetCurrent(), [offlineStorage = self](auto kind_, const std::string&& url_) -> std::string { @@ -267,6 +278,7 @@ const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegio #pragma mark Offline merge methods - (void)addContentsOfFile:(NSString *)filePath withCompletionHandler:(MGLBatchedOfflinePackAdditionCompletionHandler)completion { + MGLLogDebug(@"Adding contentsOfFile: %@ completionHandler: %@", filePath, completion); NSURL *fileURL = [NSURL fileURLWithPath:filePath]; [self addContentsOfURL:fileURL withCompletionHandler:completion]; @@ -274,7 +286,7 @@ const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegio } - (void)addContentsOfURL:(NSURL *)fileURL withCompletionHandler:(MGLBatchedOfflinePackAdditionCompletionHandler)completion { - + MGLLogDebug(@"Adding contentsOfURL: %@ completionHandler: %@", fileURL, completion); NSFileManager *fileManager = [NSFileManager defaultManager]; if (!fileURL.isFileURL) { @@ -350,6 +362,7 @@ const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegio #pragma mark Pack management methods - (void)addPackForRegion:(id <MGLOfflineRegion>)region withContext:(NSData *)context completionHandler:(MGLOfflinePackAdditionCompletionHandler)completion { + MGLLogDebug(@"Adding packForRegion: %@ contextLength: %lu completionHandler: %@", region, (unsigned long)context.length, completion); __weak MGLOfflineStorage *weakSelf = self; [self _addPackForRegion:region withContext:context completionHandler:^(MGLOfflinePack * _Nullable pack, NSError * _Nullable error) { pack.state = MGLOfflinePackStateInactive; @@ -358,6 +371,17 @@ const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegio if (completion) { completion(pack, error); } + + #if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR + NSMutableDictionary *offlineDownloadStartEventAttributes = [NSMutableDictionary dictionaryWithObject:MMEventTypeOfflineDownloadStart forKey:MMEEventKeyEvent]; + + if ([region conformsToProtocol:@protocol(MGLOfflineRegion_Private)]) { + NSDictionary *regionAttributes = ((id<MGLOfflineRegion_Private>)region).offlineStartEventAttributes; + [offlineDownloadStartEventAttributes addEntriesFromDictionary:regionAttributes]; + } + + [MGLMapboxEvents pushEvent:MMEventTypeOfflineDownloadStart withAttributes:offlineDownloadStartEventAttributes]; + #endif }]; } @@ -389,6 +413,7 @@ const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegio } - (void)removePack:(MGLOfflinePack *)pack withCompletionHandler:(MGLOfflinePackRemovalCompletionHandler)completion { + MGLLogDebug(@"Removing pack: %@ completionHandler: %@", pack, completion); [[self mutableArrayValueForKey:@"packs"] removeObject:pack]; [self _removePack:pack withCompletionHandler:^(NSError * _Nullable error) { if (completion) { @@ -421,6 +446,7 @@ const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegio } - (void)reloadPacks { + MGLLogInfo(@"Reloading packs."); [self getPacksWithCompletionHandler:^(NS_ARRAY_OF(MGLOfflinePack *) *packs, __unused NSError * _Nullable error) { for (MGLOfflinePack *pack in self.packs) { [pack invalidate]; @@ -454,6 +480,7 @@ const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegio } - (void)setMaximumAllowedMapboxTiles:(uint64_t)maximumCount { + MGLLogDebug(@"Setting maximumAllowedMapboxTiles: %lu", (unsigned long)maximumCount); _mbglFileSource->setOfflineMapboxTileCountLimit(maximumCount); } @@ -470,4 +497,29 @@ const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegio return attributes.fileSize; } +- (void)preloadData:(NSData *)data forURL:(NSURL *)url modificationDate:(nullable NSDate *)modified expirationDate:(nullable NSDate *)expires eTag:(nullable NSString *)eTag mustRevalidate:(BOOL)mustRevalidate { + mbgl::Resource resource(mbgl::Resource::Kind::Unknown, url.absoluteString.UTF8String); + mbgl::Response response; + response.data = std::make_shared<std::string>(static_cast<const char*>(data.bytes), data.length); + response.mustRevalidate = mustRevalidate; + + if (eTag) { + response.etag = std::string(eTag.UTF8String); + } + + if (modified) { + response.modified = mbgl::Timestamp() + std::chrono::duration_cast<mbgl::Seconds>(MGLDurationFromTimeInterval(modified.timeIntervalSince1970)); + } + + if (expires) { + response.expires = mbgl::Timestamp() + std::chrono::duration_cast<mbgl::Seconds>(MGLDurationFromTimeInterval(expires.timeIntervalSince1970)); + } + + _mbglFileSource->put(resource, response); +} + +- (void)putResourceWithUrl:(NSURL *)url data:(NSData *)data modified:(nullable NSDate *)modified expires:(nullable NSDate *)expires etag:(nullable NSString *)etag mustRevalidate:(BOOL)mustRevalidate { + [self preloadData:data forURL:url modificationDate:modified expirationDate:expires eTag:etag mustRevalidate:mustRevalidate]; +} + @end diff --git a/platform/darwin/src/MGLPolygon.mm b/platform/darwin/src/MGLPolygon.mm index 2af768d514..ce5309e41f 100644 --- a/platform/darwin/src/MGLPolygon.mm +++ b/platform/darwin/src/MGLPolygon.mm @@ -2,6 +2,7 @@ #import "MGLMultiPoint_Private.h" #import "MGLGeometry_Private.h" +#import "MGLLoggingConfiguration_Private.h" #import "MGLFeature.h" @@ -21,6 +22,7 @@ } - (instancetype)initWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count interiorPolygons:(NSArray<MGLPolygon *> *)interiorPolygons { + MGLLogDebug(@"Initializing with %lu coordinates and %lu interiorPolygons.", (unsigned long)count, (unsigned long)interiorPolygons); if (self = [super initWithCoordinates:coords count:count]) { if (interiorPolygons.count) { _interiorPolygons = interiorPolygons; @@ -30,6 +32,7 @@ } - (instancetype)initWithCoder:(NSCoder *)decoder { + MGLLogInfo(@"Initializng with coder."); self = [super initWithCoder:decoder]; if (self) { _interiorPolygons = [decoder decodeObjectOfClass:[NSArray class] forKey:@"interiorPolygons"]; @@ -114,7 +117,7 @@ for (MGLPolygon *interiorPolygon in self.interiorPolygons) { NSMutableArray *interiorRing = [NSMutableArray array]; - for (int index = 0; index < interiorPolygon.pointCount; index++) { + for (NSUInteger index = 0; index < interiorPolygon.pointCount; index++) { CLLocationCoordinate2D coordinate = interiorPolygon.coordinates[index]; [interiorRing addObject:@[@(coordinate.longitude), @(coordinate.latitude)]]; } @@ -143,6 +146,7 @@ } - (instancetype)initWithPolygons:(NS_ARRAY_OF(MGLPolygon *) *)polygons { + MGLLogDebug(@"Initializing with %lu polygons.", (unsigned long)polygons.count); if (self = [super init]) { _polygons = polygons; @@ -157,6 +161,7 @@ } - (instancetype)initWithCoder:(NSCoder *)decoder { + MGLLogInfo(@"Initializing with coder."); if (self = [super initWithCoder:decoder]) { _polygons = [decoder decodeObjectOfClass:[NSArray class] forKey:@"polygons"]; } diff --git a/platform/darwin/src/MGLPolyline.mm b/platform/darwin/src/MGLPolyline.mm index 26e3518cd8..ad5255e89e 100644 --- a/platform/darwin/src/MGLPolyline.mm +++ b/platform/darwin/src/MGLPolyline.mm @@ -4,6 +4,7 @@ #import "MGLGeometry_Private.h" #import "MGLFeature.h" +#import "MGLLoggingConfiguration_Private.h" #import <mbgl/util/geojson.hpp> #import <mapbox/polylabel.hpp> @@ -64,7 +65,7 @@ - (CLLocationCoordinate2D)coordinate { NSUInteger count = self.pointCount; - NSAssert(count > 0, @"Polyline must have coordinates"); + MGLAssert(count > 0, @"Polyline must have coordinates"); CLLocationCoordinate2D *coordinates = self.coordinates; CLLocationDistance middle = [self length] / 2.0; @@ -138,6 +139,7 @@ } - (instancetype)initWithPolylines:(NS_ARRAY_OF(MGLPolyline *) *)polylines { + MGLLogDebug(@"Initializing with %lu polylines.", (unsigned long)polylines.count); if (self = [super init]) { _polylines = polylines; @@ -152,6 +154,7 @@ } - (instancetype)initWithCoder:(NSCoder *)decoder { + MGLLogInfo(@"Initializing with coder."); if (self = [super initWithCoder:decoder]) { _polylines = [decoder decodeObjectOfClass:[NSArray class] forKey:@"polylines"]; } @@ -184,7 +187,7 @@ - (CLLocationCoordinate2D)coordinate { MGLPolyline *polyline = self.polylines.firstObject; CLLocationCoordinate2D *coordinates = polyline.coordinates; - NSAssert([polyline pointCount] > 0, @"Polyline must have coordinates"); + MGLAssert([polyline pointCount] > 0, @"Polyline must have coordinates"); CLLocationCoordinate2D firstCoordinate = coordinates[0]; return firstCoordinate; diff --git a/platform/darwin/src/MGLShapeCollection.mm b/platform/darwin/src/MGLShapeCollection.mm index 454b0d47f1..604c81bff2 100644 --- a/platform/darwin/src/MGLShapeCollection.mm +++ b/platform/darwin/src/MGLShapeCollection.mm @@ -2,6 +2,7 @@ #import "MGLShape_Private.h" #import "MGLFeature.h" +#import "MGLLoggingConfiguration_Private.h" #import <mbgl/style/conversion/geojson.hpp> @@ -12,6 +13,7 @@ } - (instancetype)initWithShapes:(NS_ARRAY_OF(MGLShape *) *)shapes { + MGLLogDebug(@"Initializing with %lu shapes.", (unsigned long)shapes.count); if (self = [super init]) { _shapes = shapes.copy; } @@ -19,6 +21,7 @@ } - (instancetype)initWithCoder:(NSCoder *)decoder { + MGLLogInfo(@"Initializing with coder."); if (self = [super initWithCoder:decoder]) { _shapes = [decoder decodeObjectOfClass:[NSArray class] forKey:@"shapes"]; } diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm index 5915280f04..024a161aff 100644 --- a/platform/darwin/src/MGLStyle.mm +++ b/platform/darwin/src/MGLStyle.mm @@ -13,6 +13,7 @@ #import "MGLRasterStyleLayer.h" #import "MGLBackgroundStyleLayer.h" #import "MGLOpenGLStyleLayer.h" +#import "MGLStyleLayerManager.h" #import "MGLSource.h" #import "MGLSource_Private.h" @@ -25,22 +26,13 @@ #import "MGLImageSource.h" #import "MGLAttributionInfo_Private.h" +#import "MGLLoggingConfiguration_Private.h" #include <mbgl/map/map.hpp> #include <mbgl/util/default_styles.hpp> #include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/style/light.hpp> -#include <mbgl/style/layers/fill_layer.hpp> -#include <mbgl/style/layers/fill_extrusion_layer.hpp> -#include <mbgl/style/layers/line_layer.hpp> -#include <mbgl/style/layers/symbol_layer.hpp> -#include <mbgl/style/layers/raster_layer.hpp> -#include <mbgl/style/layers/heatmap_layer.hpp> -#include <mbgl/style/layers/hillshade_layer.hpp> -#include <mbgl/style/layers/circle_layer.hpp> -#include <mbgl/style/layers/background_layer.hpp> -#include <mbgl/style/layers/custom_layer.hpp> #include <mbgl/style/sources/geojson_source.hpp> #include <mbgl/style/sources/vector_source.hpp> #include <mbgl/style/sources/raster_source.hpp> @@ -128,11 +120,13 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, #pragma mark - - (instancetype)initWithRawStyle:(mbgl::style::Style *)rawStyle mapView:(MGLMapView *)mapView { + MGLLogInfo(@"Initializing %@ with mapView: %@", NSStringFromClass([self class]), mapView); if (self = [super init]) { _mapView = mapView; _rawStyle = rawStyle; _openGLLayers = [NSMutableDictionary dictionary]; _localizedLayersByIdentifier = [NSMutableDictionary dictionary]; + MGLLogDebug(@"Initializing with style name: %@ mapView: %@", self.name, mapView); } return self; } @@ -159,6 +153,7 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, } - (void)setSources:(NS_SET_OF(__kindof MGLSource *) *)sources { + MGLLogDebug(@"Setting: %lu sources", sources.count); for (MGLSource *source in self.sources) { [self removeSource:source]; } @@ -177,6 +172,7 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, - (MGLSource *)sourceWithIdentifier:(NSString *)identifier { + MGLLogDebug(@"Querying source with identifier: %@", identifier); auto rawSource = self.rawStyle->getSource(identifier.UTF8String); return rawSource ? [self sourceFromMBGLSource:rawSource] : nil; @@ -206,6 +202,7 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, - (void)addSource:(MGLSource *)source { + MGLLogDebug(@"Adding source: %@", source); if (!source.rawSource) { [NSException raise:NSInvalidArgumentException format: @"The source %@ cannot be added to the style. " @@ -222,15 +219,23 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, - (void)removeSource:(MGLSource *)source { + [self removeSource:source error:nil]; +} + +- (BOOL)removeSource:(MGLSource *)source error:(NSError * __nullable * __nullable)outError { + MGLLogDebug(@"Removing source: %@", source); + if (!source.rawSource) { [NSException raise:NSInvalidArgumentException format: @"The source %@ cannot be removed from the style. " @"Make sure the source was created as a member of a concrete subclass of MGLSource.", source]; } - [source removeFromMapView:self.mapView]; + + return [source removeFromMapView:self.mapView error:outError]; } + - (nullable NSArray<MGLAttributionInfo *> *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor { // It’d be incredibly convenient to use -sources here, but this operation // depends on the sources being sorted in ascending order by creation, as @@ -263,6 +268,7 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, } - (void)setLayers:(NS_ARRAY_OF(__kindof MGLStyleLayer *) *)layers { + MGLLogDebug(@"Setting: %lu layers", layers.count); for (MGLStyleLayer *layer in self.layers) { [self removeLayer:layer]; } @@ -351,40 +357,19 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, return layer; } - if (auto fillLayer = rawLayer->as<mbgl::style::FillLayer>()) { - return [[MGLFillStyleLayer alloc] initWithRawLayer:fillLayer]; - } else if (auto fillExtrusionLayer = rawLayer->as<mbgl::style::FillExtrusionLayer>()) { - return [[MGLFillExtrusionStyleLayer alloc] initWithRawLayer:fillExtrusionLayer]; - } else if (auto lineLayer = rawLayer->as<mbgl::style::LineLayer>()) { - return [[MGLLineStyleLayer alloc] initWithRawLayer:lineLayer]; - } else if (auto symbolLayer = rawLayer->as<mbgl::style::SymbolLayer>()) { - return [[MGLSymbolStyleLayer alloc] initWithRawLayer:symbolLayer]; - } else if (auto rasterLayer = rawLayer->as<mbgl::style::RasterLayer>()) { - return [[MGLRasterStyleLayer alloc] initWithRawLayer:rasterLayer]; - } else if (auto heatmapLayer = rawLayer->as<mbgl::style::HeatmapLayer>()) { - return [[MGLHeatmapStyleLayer alloc] initWithRawLayer:heatmapLayer]; - } else if (auto hillshadeLayer = rawLayer->as<mbgl::style::HillshadeLayer>()) { - return [[MGLHillshadeStyleLayer alloc] initWithRawLayer:hillshadeLayer]; - } else if (auto circleLayer = rawLayer->as<mbgl::style::CircleLayer>()) { - return [[MGLCircleStyleLayer alloc] initWithRawLayer:circleLayer]; - } else if (auto backgroundLayer = rawLayer->as<mbgl::style::BackgroundLayer>()) { - return [[MGLBackgroundStyleLayer alloc] initWithRawLayer:backgroundLayer]; - } else if (auto customLayer = rawLayer->as<mbgl::style::CustomLayer>()) { - return [[MGLOpenGLStyleLayer alloc] initWithRawLayer:customLayer]; - } else { - NSAssert(NO, @"Unrecognized layer type"); - return nil; - } + return mbgl::LayerManagerDarwin::get()->createPeer(rawLayer); } - (MGLStyleLayer *)layerWithIdentifier:(NSString *)identifier { + MGLLogDebug(@"Querying layerWithIdentifier: %@", identifier); auto mbglLayer = self.rawStyle->getLayer(identifier.UTF8String); return mbglLayer ? [self layerFromMBGLLayer:mbglLayer] : nil; } - (void)removeLayer:(MGLStyleLayer *)layer { + MGLLogDebug(@"Removing layer: %@", layer); if (!layer.rawLayer) { [NSException raise:NSInvalidArgumentException format: @"The style layer %@ cannot be removed from the style. " @@ -398,6 +383,7 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, - (void)addLayer:(MGLStyleLayer *)layer { + MGLLogDebug(@"Adding layer: %@", layer); if (!layer.rawLayer) { [NSException raise:NSInvalidArgumentException format: @"The style layer %@ cannot be added to the style. " @@ -419,6 +405,7 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, - (void)insertLayer:(MGLStyleLayer *)layer belowLayer:(MGLStyleLayer *)sibling { + MGLLogDebug(@"Inseting layer: %@ belowLayer: %@", layer, sibling); if (!layer.rawLayer) { [NSException raise:NSInvalidArgumentException format: @@ -443,6 +430,7 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, } - (void)insertLayer:(MGLStyleLayer *)layer aboveLayer:(MGLStyleLayer *)sibling { + MGLLogDebug(@"Inseting layer: %@ aboveLayer: %@", layer, sibling); if (!layer.rawLayer) { [NSException raise:NSInvalidArgumentException format: @@ -461,8 +449,8 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, auto layers = self.rawStyle->getLayers(); std::string siblingIdentifier = sibling.identifier.UTF8String; NSUInteger index = 0; - for (auto layer : layers) { - if (layer->getID() == siblingIdentifier) { + for (auto siblingLayer : layers) { + if (siblingLayer->getID() == siblingIdentifier) { break; } index++; @@ -482,9 +470,9 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, [NSException raise:MGLRedundantLayerIdentifierException format:@"%s", err.what()]; } } else { - MGLStyleLayer *sibling = [self layerFromMBGLLayer:layers.at(index + 1)]; + MGLStyleLayer *nextSibling = [self layerFromMBGLLayer:layers.at(index + 1)]; try { - [layer addToStyle:self belowLayer:sibling]; + [layer addToStyle:self belowLayer:nextSibling]; } catch (std::runtime_error & err) { [NSException raise:MGLRedundantLayerIdentifierException format:@"%s", err.what()]; } @@ -496,6 +484,7 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, - (void)setImage:(MGLImage *)image forName:(NSString *)name { + MGLLogDebug(@"Setting image: %@ forName: %@", image, name); if (!image) { [NSException raise:NSInvalidArgumentException format:@"Cannot assign nil image to “%@”.", name]; @@ -510,6 +499,7 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, - (void)removeImageForName:(NSString *)name { + MGLLogDebug(@"Removing imageForName: %@", name); if (!name) { [NSException raise:NSInvalidArgumentException format:@"Cannot remove image with nil name."]; @@ -520,6 +510,7 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, - (MGLImage *)imageForName:(NSString *)name { + MGLLogDebug(@"Querying imageForName: %@", name); if (!name) { [NSException raise:NSInvalidArgumentException format:@"Cannot get image with nil name."]; diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index e37fddc859..a661c8baee 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -5,36 +5,76 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Restored iOS 8 support for the Mapbox Maps SDK for iOS. ([#13036](https://github.com/mapbox/mapbox-gl-native/pull/13036)) +## master +* `MGLMapSnapshotter` now follows "MGLIdeographicFontFamilyName" app setting to reduce font data usage while snapshotting CJK maps [#13427](https://github.com/mapbox/mapbox-gl-native/pull/13427) + +## 4.7.0 + +* Fixed an issue where the `{prefix}` token in tile URL templates was evaluated incorrectly when requesting a source’s tiles. ([#13429](https://github.com/mapbox/mapbox-gl-native/pull/13429)) +* Renamed `-[MGLOfflineStorage putResourceWithUrl:data:modified:expires:etag:mustRevalidate:]` to `-[MGLOfflineStorage preloadData:forURL:modificationDate:expirationDate:eTag:mustRevalidate:]`. ([#13318](https://github.com/mapbox/mapbox-gl-native/pull/13318)) +* Fixed sporadic crash when using `MGLMapSnapshotter`. ([#13300](https://github.com/mapbox/mapbox-gl-native/pull/13300)) +* Added `MGLLoggingConfiguration` and `MGLLoggingBlockHandler` that handle error and fault events produced by the SDK. ([#13235](https://github.com/mapbox/mapbox-gl-native/pull/13235)) +* This SDK’s dynamic framework now has a bundle identifier of `com.mapbox.Mapbox`. ([#12857](https://github.com/mapbox/mapbox-gl-native/pull/12857)) +* Modified the behavior of the map view so that programmatic camera transitions can no longer be interrupted by user interaction when `MGLMapView.zoomEnabled`, `MGLMapView.rotateEnabled`, `MGLMapView.scrollEnabled`, and `MGLMapView.pitchEnabled` are set to false. ([#13362](https://github.com/mapbox/mapbox-gl-native/pull/13362)) +* Fixed random crashes during app termination. ([#13367](https://github.com/mapbox/mapbox-gl-native/pull/13367)) +* Added `-[MGLStyle removeSource:error:]` that returns a `BOOL` indicating success (and an optional `NSError` in case of failure). ([#13399](https://github.com/mapbox/mapbox-gl-native/pull/13399)) +* Added support for setting `MGLCollisionBehaviorPre4_0` in `NSUserDefaults`. ([#13426](https://github.com/mapbox/mapbox-gl-native/pull/13426)) + + +## 4.6.0 - November 7, 2018 + +### Styles and rendering + +* `MGLSymbolStyleLayer.text` can now be set to rich text with varying fonts and text sizes. ([#12624](https://github.com/mapbox/mapbox-gl-native/pull/12624)) +* Fixed a crash when using the `MGL_LET`, `MGL_MATCH`, `MGL_IF`, or `MGL_FUNCTION` functions without a colon inside an `NSExpression` or `NSPredicate` format string. ([#13189](https://github.com/mapbox/mapbox-gl-native/pull/13189)) +* Fixed a crash setting the `MGLLineStyleLayer.lineGradient` property to an expression containing the `$lineProgress` variable. Added an `NSExpression.lineProgressVariableExpression` class property that returns an expression for the `$lineProgress` variable. ([#13192](https://github.com/mapbox/mapbox-gl-native/pull/13192)) +* Feature querying can now return point features represented by icons that have both the `MGLSymbolStyleLayer.iconRotation` and `MGLSymbolStyleLayer.iconOffset` properties applied. ([#13105](https://github.com/mapbox/mapbox-gl-native/pull/13105)) +* Fixed an issue where polygons crossing tile boundaries could be improperly clipped. ([#13231](https://github.com/mapbox/mapbox-gl-native/pull/13231)) + +### Offline maps + +* Network requests by `MGLMapView` are now prioritized over offline pack downloads. ([#13019](https://github.com/mapbox/mapbox-gl-native/pull/13019)) +* Added the `-[MGLOfflineStorage putResourceWithUrl:data:modified:expires:etag:mustRevalidate:]` method to allow pre-warming of the ambient cache. ([#13119](https://github.com/mapbox/mapbox-gl-native/pull/13119)) + +### Other changes + +* Fixed an issue where the map view could not be panned after setting `MGLMapView.visibleCoordinateBounds` to a coordinate bounds that spanned exactly the longitudes −180° and 180°. ([#13006](https://github.com/mapbox/mapbox-gl-native/pull/13006)) +* Fixed an issue where snapshots had the wrong heading and pitch. ([#13123](https://github.com/mapbox/mapbox-gl-native/pull/13123)) +* Fixed an issue where `-[MGLMapViewDelegate mapView:shouldChangeFromCamera:toCamera:]` was called with an incorrectly rotated `newCamera` when the user rotated the map. ([#13123](https://github.com/mapbox/mapbox-gl-native/pull/13123)) + ## 4.5.0 - October 10, 2018 ### Styles and rendering * Added support for 120 frames per second on capable devices. ([#12979](https://github.com/mapbox/mapbox-gl-native/pull/12979)) * Added an `MGLSymbolStyleLayer.symbolZOrder` property for forcing point features in a symbol layer to be layered in the same order that they are specified in the layer’s associated source. ([#12783](https://github.com/mapbox/mapbox-gl-native/pull/12783)) -* Fixed a crash when a style layer `*-pattern` property evaluates to nil for a particular feature. ([#12896](https://github.com/mapbox/mapbox-gl-native/pull/12896)) +* Fixed a crash when the `MGLBackgroundStyleLayer.backgroundPattern`, `MGLFillExtrusionStyleLayer.fillExtrusionPattern`, `MGLFillStyleLayer.fillPattern`, or `MGLLineStyleLayer.linePattern` property evaluates to `nil` for a particular feature. ([#12896](https://github.com/mapbox/mapbox-gl-native/pull/12896)) * Fixed an issue with view annotations (including the user location annotation) and the GL map lagging relative to each other. ([#12895](https://github.com/mapbox/mapbox-gl-native/pull/12895)) -* Fixed an issue where fill and line layers would occasionally flicker on zoom ([#12982](https://github.com/mapbox/mapbox-gl-native/pull/12982)) +* Fixed an issue where features in `MGLFillStyleLayer` and `MGLLineStyleLayer` would occasionally flicker when zooming in and out. ([#12982](https://github.com/mapbox/mapbox-gl-native/pull/12982)) +* Fixed a crash when casting a `UIColor` to a `UIColor` inside an `NSExpression`. ([#12864](https://github.com/mapbox/mapbox-gl-native/pull/12864)) +* `NIL` cast to an `NSNumber` now evaluates to 0 inside an `NSExpression`. ([#12864](https://github.com/mapbox/mapbox-gl-native/pull/12864)) +* Fixed a crash when applying the `to-array` operator to an empty array inside a JSON expression. ([#12864](https://github.com/mapbox/mapbox-gl-native/pull/12864)) +* Added the `MGLCollisionBehaviorPre4_0` Info.plist key to restore the collision detection behavior in version 3.7 of the SDK. ([#12941](https://github.com/mapbox/mapbox-gl-native/pull/12941)) ### User location -* Added `-[MGLMapViewDelegate mapViewUserLocationAnchorPoint:]` to customize the position of the user location annotation.. ([#12907](https://github.com/mapbox/mapbox-gl-native/pull/12907)) -* Marked `-[MGLMapView setUserLocationVerticalAlignment:]` as deprecated. Use `-[MGLMapViewDelegate mapViewUserLocationAnchorPoint:]` instead. ([#12907](https://github.com/mapbox/mapbox-gl-native/pull/12907)) -* Added the `-[MGLMapView updateUserLocationAnnotationView]` and `-[MGLMapView updateUserLocationAnnotationView:animated:]` methods to update the position of the user location annotation between location updates. ([#12907](https://github.com/mapbox/mapbox-gl-native/pull/12907)) + +* Added `-[MGLMapViewDelegate mapViewUserLocationAnchorPoint:]` to customize the position of the user location annotation. ([#12907](https://github.com/mapbox/mapbox-gl-native/pull/12907)) +* Marked `MGLMapView.userLocationVerticalAlignment` as deprecated. Use `-[MGLMapViewDelegate mapViewUserLocationAnchorPoint:]` instead. ([#12907](https://github.com/mapbox/mapbox-gl-native/pull/12907)) +* Added the `-[MGLMapView updateUserLocationAnnotationView]` and `-[MGLMapView updateUserLocationAnnotationViewAnimatedWithDuration:]` methods to update the position of the user location annotation between location updates. ([#12907](https://github.com/mapbox/mapbox-gl-native/pull/12907)) * Fixed an issue where the user location annotation was positioned incorrectly when the map view had a left or right content inset. ([#12907](https://github.com/mapbox/mapbox-gl-native/pull/12907)) ### Offline maps * Added `-[MGLOfflineStorage addContentsOfFile:withCompletionHandler:]` and `-[MGLOfflineStorage addContentsOfURL:withCompletionHandler:]` methods to add pregenerated offline packs to offline storage. ([#12791](https://github.com/mapbox/mapbox-gl-native/pull/12791)) -* Fixed an issue where some tiles weren't rendered correctly when no internet connectivity was available ([#12931](https://github.com/mapbox/mapbox-gl-native/pull/12931)) +* Fixed an issue where some tiles were rendered incorrectly when the device was unable to connect to the Internet. ([#12931](https://github.com/mapbox/mapbox-gl-native/pull/12931)) ### Other changes -* Added `MGLAltitudeForZoomLevel` and `MGLZoomLevelForAltitude` to public API for conversion between zoom levels and altitudes. ([#12986](https://github.com/mapbox/mapbox-gl-native/pull/12986)) +* Added `MGLAltitudeForZoomLevel()` and `MGLZoomLevelForAltitude()` methods for converting between zoom levels used by `MGLMapView` and altitudes used by `MGLMapCamera`. ([#12986](https://github.com/mapbox/mapbox-gl-native/pull/12986)) * Deprecated the `+[MGLMapCamera cameraLookingAtCenterCoordinate:fromDistance:pitch:heading:]` method in favor of `+[MGLMapCamera cameraLookingAtCenterCoordinate:altitude:pitch:heading:]` and `+[MGLMapCamera cameraLookingAtCenterCoordinate:acrossDistance:pitch:heading:]`. ([#12966](https://github.com/mapbox/mapbox-gl-native/pull/12966)) * Fixed an issue where `+[MGLMapCamera cameraLookingAtCenterCoordinate:fromEyeCoordinate:eyeAltitude:]` created a camera looking from the wrong eye coordinate. ([#12966](https://github.com/mapbox/mapbox-gl-native/pull/12966)) * Added an `MGLMapCamera.viewingDistance` property based on the existing `MGLMapCamera.altitude` property. ([#12966](https://github.com/mapbox/mapbox-gl-native/pull/12966)) * Fixed an issue where `-[MGLMapSnapshotter startWithQueue:completionHandler:]` failed to call its completion handler in some cases. ([#12355](https://github.com/mapbox/mapbox-gl-native/pull/12355)) -* Fixed bugs in coercion expression operators ("to-array" applied to empty arrays, "to-color" applied to colors, and "to-number" applied to null) [#12864](https://github.com/mapbox/mapbox-gl-native/pull/12864) -* Added the `MGLCollisionBehaviorPre4_0` Info.plist key for applications that require the collision detection behavior in version v3.7 of the SDK. ([#12941](https://github.com/mapbox/mapbox-gl-native/pull/12941)) * Fixed an issue where symbols from the events library could be duplicated when the maps SDK was used in conjunction with another Mapbox framework. ([#13008](https://github.com/mapbox/mapbox-gl-native/pull/13008)) ## 4.4.1 - September 13, 2018 @@ -49,7 +89,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * When a symbol in an `MGLSymbolStyleLayer` has both an icon and text, both are shown or hidden together based on available space. ([#12521](https://github.com/mapbox/mapbox-gl-native/pull/12521)) * Invalid values of `MGLSymbolStyleLayer.textFontNames` are treated as warnings instead of errors. ([#12414](https://github.com/mapbox/mapbox-gl-native/pull/12414)) * Added an `MGLLineStyleLayer.lineGradient` property that can be used to define a gradient with which to color a line feature. ([#12575](https://github.com/mapbox/mapbox-gl-native/pull/12575)) -* The `MGLLineStyleLayer.linePattern`, `MGLFillStyleLayer.fillPattern`, and `MGLFillStyleLayer.fillExtrusionPattern` properties can now be set to expressions that refer to feature attributes. ([#12284](https://github.com/mapbox/mapbox-gl-native/pull/12284)) +* The `MGLLineStyleLayer.linePattern`, `MGLFillStyleLayer.fillPattern`, and `MGLFillExtrusionStyleLayer.fillExtrusionPattern` properties can now be set to expressions that refer to feature attributes. ([#12284](https://github.com/mapbox/mapbox-gl-native/pull/12284)) * Reduced the amount of memory consumed by font data after changing the style. ([#12414](https://github.com/mapbox/mapbox-gl-native/pull/12414)) * `-[MGLShapeSource initWithIdentifier:shape:options:]` warns about possible attribute loss when passing in an `MGLShapeCollection` object. ([#12625](https://github.com/mapbox/mapbox-gl-native/pull/12625)) * Added an `MGLShapeSourceOptionLineDistanceMetrics` option that enables or disables calculating line distance metrics. ([#12604](https://github.com/mapbox/mapbox-gl-native/pull/12604)) |