summaryrefslogtreecommitdiff
path: root/platform/darwin/src
diff options
context:
space:
mode:
authorIvo van Dongen <info@ivovandongen.nl>2018-03-27 00:39:59 +0300
committerIvo van Dongen <ivovandongen@users.noreply.github.com>2018-08-20 22:49:01 +0300
commitca0f2f925d38c190957241f7fa2375a90fa87f45 (patch)
tree92b642bb87e1fd25e22bc9458ae6c7155237472f /platform/darwin/src
parent4fedcf8d061d835e71df80dbc20a32ee4ec8fd21 (diff)
downloadqtlocation-mapboxgl-ca0f2f925d38c190957241f7fa2375a90fa87f45.tar.gz
[darwin] arbitrary offline region geometries
Diffstat (limited to 'platform/darwin/src')
-rw-r--r--platform/darwin/src/MGLOfflinePack.mm21
-rw-r--r--platform/darwin/src/MGLOfflineRegion.h15
-rw-r--r--platform/darwin/src/MGLOfflineRegion_Private.h9
-rw-r--r--platform/darwin/src/MGLOfflineStorage.mm2
-rw-r--r--platform/darwin/src/MGLShapeOfflineRegion.h72
-rw-r--r--platform/darwin/src/MGLShapeOfflineRegion.mm120
-rw-r--r--platform/darwin/src/MGLShapeOfflineRegion_Private.h22
-rw-r--r--platform/darwin/src/MGLTilePyramidOfflineRegion.h14
-rw-r--r--platform/darwin/src/MGLTilePyramidOfflineRegion.mm5
-rw-r--r--platform/darwin/src/MGLTilePyramidOfflineRegion_Private.h22
10 files changed, 275 insertions, 27 deletions
diff --git a/platform/darwin/src/MGLOfflinePack.mm b/platform/darwin/src/MGLOfflinePack.mm
index 7bbc681c88..bafb976585 100644
--- a/platform/darwin/src/MGLOfflinePack.mm
+++ b/platform/darwin/src/MGLOfflinePack.mm
@@ -3,6 +3,9 @@
#import "MGLOfflineStorage_Private.h"
#import "MGLOfflineRegion_Private.h"
#import "MGLTilePyramidOfflineRegion.h"
+#import "MGLTilePyramidOfflineRegion_Private.h"
+#import "MGLShapeOfflineRegion.h"
+#import "MGLShapeOfflineRegion_Private.h"
#import "NSValue+MGLAdditions.h"
@@ -27,6 +30,12 @@ const MGLExceptionName MGLInvalidOfflinePackException = @"MGLInvalidOfflinePackE
} \
} while (NO);
+@interface MGLTilePyramidOfflineRegion () <MGLOfflineRegion_Private, MGLTilePyramidOfflineRegion_Private>
+@end
+
+@interface MGLShapeOfflineRegion () <MGLOfflineRegion_Private, MGLShapeOfflineRegion_Private>
+@end
+
class MBGLOfflineRegionObserver : public mbgl::OfflineRegionObserver {
public:
MBGLOfflineRegionObserver(MGLOfflinePack *pack_) : pack(pack_) {}
@@ -78,7 +87,17 @@ private:
const mbgl::OfflineRegionDefinition &regionDefinition = _mbglOfflineRegion->getDefinition();
NSAssert([MGLTilePyramidOfflineRegion conformsToProtocol:@protocol(MGLOfflineRegion_Private)], @"MGLTilePyramidOfflineRegion should conform to MGLOfflineRegion_Private.");
- return [(id <MGLOfflineRegion_Private>)[MGLTilePyramidOfflineRegion alloc] initWithOfflineRegionDefinition:regionDefinition];
+ NSAssert([MGLShapeOfflineRegion conformsToProtocol:@protocol(MGLOfflineRegion_Private)], @"MGLShapeOfflineRegion should conform to MGLOfflineRegion_Private.");
+
+
+
+ return regionDefinition.match(
+ [&] (const mbgl::OfflineTilePyramidRegionDefinition def){
+ return (id <MGLOfflineRegion>)[[MGLTilePyramidOfflineRegion alloc] initWithOfflineRegionDefinition:def];
+ },
+ [&] (const mbgl::OfflineGeometryRegionDefinition& def){
+ return (id <MGLOfflineRegion>)[[MGLShapeOfflineRegion alloc] initWithOfflineRegionDefinition:def];
+ });
}
- (NSData *)context {
diff --git a/platform/darwin/src/MGLOfflineRegion.h b/platform/darwin/src/MGLOfflineRegion.h
index fe0ab6cb7f..3e0f485e2c 100644
--- a/platform/darwin/src/MGLOfflineRegion.h
+++ b/platform/darwin/src/MGLOfflineRegion.h
@@ -4,12 +4,21 @@ NS_ASSUME_NONNULL_BEGIN
/**
An object conforming to the `MGLOfflineRegion` protocol determines which
- resources are required by an `MGLOfflinePack` object. At present, only
- instances of `MGLTilePyramidOfflineRegion` may be used as `MGLOfflinePack`
- regions, but additional conforming implementations may be added in the future.
+ resources are required by an `MGLOfflinePack` object.
*/
@protocol MGLOfflineRegion <NSObject>
+/**
+ URL of the style whose resources are required for offline viewing.
+
+ In addition to the JSON stylesheet, different styles may require different font
+ glyphs, sprite sheets, and other resources.
+
+ The URL may be a full HTTP or HTTPS URL or a Mapbox URL indicating the style’s
+ map ID (`mapbox://styles/{user}/{style}`).
+ */
+@property (nonatomic, readonly) NSURL *styleURL;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLOfflineRegion_Private.h b/platform/darwin/src/MGLOfflineRegion_Private.h
index b1dec8dd64..c1f3fd5200 100644
--- a/platform/darwin/src/MGLOfflineRegion_Private.h
+++ b/platform/darwin/src/MGLOfflineRegion_Private.h
@@ -9,15 +9,6 @@ NS_ASSUME_NONNULL_BEGIN
@protocol MGLOfflineRegion_Private <MGLOfflineRegion>
/**
- Initializes and returns an offline region backed by the given C++ region
- definition object.
-
- @param definition A reference to an offline region definition backing the
- offline region.
- */
-- (instancetype)initWithOfflineRegionDefinition:(const mbgl::OfflineRegionDefinition &)definition;
-
-/**
Creates and returns a C++ offline region definition corresponding to the
receiver.
*/
diff --git a/platform/darwin/src/MGLOfflineStorage.mm b/platform/darwin/src/MGLOfflineStorage.mm
index 05e1b06338..93a6da36c4 100644
--- a/platform/darwin/src/MGLOfflineStorage.mm
+++ b/platform/darwin/src/MGLOfflineStorage.mm
@@ -285,7 +285,7 @@ const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegio
return;
}
- const mbgl::OfflineTilePyramidRegionDefinition regionDefinition = [(id <MGLOfflineRegion_Private>)region offlineRegionDefinition];
+ const mbgl::OfflineRegionDefinition regionDefinition = [(id <MGLOfflineRegion_Private>)region offlineRegionDefinition];
mbgl::OfflineRegionMetadata metadata(context.length);
[context getBytes:&metadata[0] length:metadata.size()];
self.mbglFileSource->createOfflineRegion(regionDefinition, metadata, [&, completion](mbgl::expected<mbgl::OfflineRegion, std::exception_ptr> mbglOfflineRegion) {
diff --git a/platform/darwin/src/MGLShapeOfflineRegion.h b/platform/darwin/src/MGLShapeOfflineRegion.h
new file mode 100644
index 0000000000..ac54dc137b
--- /dev/null
+++ b/platform/darwin/src/MGLShapeOfflineRegion.h
@@ -0,0 +1,72 @@
+#import <Foundation/Foundation.h>
+
+#import "MGLFoundation.h"
+#import "MGLOfflineRegion.h"
+#import "MGLShape.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ An offline region defined by a style URL, geographic shape, and
+ range of zoom levels.
+
+ This class requires fewer resources than MGLTilePyramidOfflineRegion
+ for irregularly shaped regions.
+ */
+MGL_EXPORT
+@interface MGLShapeOfflineRegion : NSObject <MGLOfflineRegion, NSSecureCoding, NSCopying>
+
+/**
+ The shape for the geographic region covered by the downloaded
+ tiles.
+ */
+@property (nonatomic, readonly) MGLShape *shape;
+
+/**
+ The minimum zoom level for which to download tiles and other resources.
+
+ For more information about zoom levels, `-[MGLMapView zoomLevel]`.
+ */
+@property (nonatomic, readonly) double minimumZoomLevel;
+
+/**
+ The maximum zoom level for which to download tiles and other resources.
+
+ For more information about zoom levels, `-[MGLMapView zoomLevel]`.
+ */
+@property (nonatomic, readonly) double maximumZoomLevel;
+
+- (instancetype)init NS_UNAVAILABLE;
+
+/**
+ Initializes a newly created offline region with the given style URL, geometry,
+ and range of zoom levels.
+
+ This is the designated initializer for `MGLShapeOfflineRegion`.
+
+ @param styleURL URL of the map style for which to download resources. The URL
+ may be a full HTTP or HTTPS URL or a Mapbox URL indicating the style’s map
+ ID (`mapbox://styles/{user}/{style}`). Specify `nil` for the default style.
+ Relative file URLs cannot be used as offline style URLs. To download the
+ online resources required by a local style, specify a URL to an online copy
+ of the style.
+ @param shape The shape of the geographic region to be covered by
+ the downloaded tiles.
+ @param minimumZoomLevel The minimum zoom level to be covered by the downloaded
+ tiles. This parameter should be set to at least 0 but no greater than the
+ value of the `maximumZoomLevel` parameter. For each required tile source, if
+ this parameter is set to a value less than the tile source’s minimum zoom
+ level, the download covers zoom levels down to the tile source’s minimum
+ zoom level.
+ @param maximumZoomLevel The maximum zoom level to be covered by the downloaded
+ tiles. This parameter should be set to at least the value of the
+ `minimumZoomLevel` parameter. For each required tile source, if this
+ parameter is set to a value greater than the tile source’s minimum zoom
+ level, the download covers zoom levels up to the tile source’s maximum zoom
+ level.
+ */
+- (instancetype)initWithStyleURL:(nullable NSURL *)styleURL shape:(MGLShape *)shape fromZoomLevel:(double)minimumZoomLevel toZoomLevel:(double)maximumZoomLevel NS_DESIGNATED_INITIALIZER;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLShapeOfflineRegion.mm b/platform/darwin/src/MGLShapeOfflineRegion.mm
new file mode 100644
index 0000000000..e1393f1199
--- /dev/null
+++ b/platform/darwin/src/MGLShapeOfflineRegion.mm
@@ -0,0 +1,120 @@
+#import "MGLShapeOfflineRegion.h"
+
+#if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
+ #import <Cocoa/Cocoa.h>
+#else
+ #import <UIKit/UIKit.h>
+#endif
+
+#import "MGLOfflineRegion_Private.h"
+#import "MGLShapeOfflineRegion_Private.h"
+#import "MGLFeature_Private.h"
+#import "MGLShape_Private.h"
+#import "MGLStyle.h"
+
+@interface MGLShapeOfflineRegion () <MGLOfflineRegion_Private, MGLShapeOfflineRegion_Private>
+
+@end
+
+@implementation MGLShapeOfflineRegion {
+ NSURL *_styleURL;
+}
+
+@synthesize styleURL = _styleURL;
+
++ (BOOL)supportsSecureCoding {
+ return YES;
+}
+
+- (instancetype)init {
+ [NSException raise:@"Method unavailable"
+ format:
+ @"-[MGLShapeOfflineRegion init] is unavailable. "
+ @"Use -initWithStyleURL:shape:fromZoomLevel:toZoomLevel: instead."];
+ return nil;
+}
+
+- (instancetype)initWithStyleURL:(NSURL *)styleURL shape:(MGLShape *)shape fromZoomLevel:(double)minimumZoomLevel toZoomLevel:(double)maximumZoomLevel {
+ if (self = [super init]) {
+ if (!styleURL) {
+ styleURL = [MGLStyle streetsStyleURLWithVersion:MGLStyleDefaultVersion];
+ }
+
+ if (!styleURL.scheme) {
+ [NSException raise:@"Invalid style URL" format:
+ @"%@ does not support setting a relative file URL as the style URL. "
+ @"To download the online resources required by this style, "
+ @"specify a URL to an online copy of this style. "
+ @"For Mapbox-hosted styles, use the mapbox: scheme.",
+ NSStringFromClass([self class])];
+ }
+
+ _styleURL = styleURL;
+ _shape = shape;
+ _minimumZoomLevel = minimumZoomLevel;
+ _maximumZoomLevel = maximumZoomLevel;
+ }
+ return self;
+}
+
+- (instancetype)initWithOfflineRegionDefinition:(const mbgl::OfflineGeometryRegionDefinition &)definition {
+ NSURL *styleURL = [NSURL URLWithString:@(definition.styleURL.c_str())];
+ MGLShape *shape = MGLShapeFromGeoJSON(definition.geometry);
+ return [self initWithStyleURL:styleURL shape:shape fromZoomLevel:definition.minZoom toZoomLevel:definition.maxZoom];
+}
+
+- (const mbgl::OfflineRegionDefinition)offlineRegionDefinition {
+#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
+ const float scaleFactor = [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale];
+#elif TARGET_OS_MAC
+ const float scaleFactor = [NSScreen mainScreen].backingScaleFactor;
+#endif
+ return mbgl::OfflineGeometryRegionDefinition(_styleURL.absoluteString.UTF8String,
+ _shape.geometryObject,
+ _minimumZoomLevel, _maximumZoomLevel,
+ scaleFactor);
+}
+
+- (nullable instancetype)initWithCoder:(NSCoder *)coder {
+ NSURL *styleURL = [coder decodeObjectForKey:@"styleURL"];
+ MGLShape * shape = [coder decodeObjectForKey:@"shape"];
+ double minimumZoomLevel = [coder decodeDoubleForKey:@"minimumZoomLevel"];
+ double maximumZoomLevel = [coder decodeDoubleForKey:@"maximumZoomLevel"];
+
+ return [self initWithStyleURL:styleURL shape:shape fromZoomLevel:minimumZoomLevel toZoomLevel:maximumZoomLevel];
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder
+{
+ [coder encodeObject:_styleURL forKey:@"styleURL"];
+ [coder encodeObject:_shape forKey:@"shape"];
+ [coder encodeDouble:_maximumZoomLevel forKey:@"maximumZoomLevel"];
+ [coder encodeDouble:_minimumZoomLevel forKey:@"minimumZoomLevel"];
+}
+
+- (id)copyWithZone:(nullable NSZone *)zone {
+ return [[[self class] allocWithZone:zone] initWithStyleURL:_styleURL shape:_shape fromZoomLevel:_minimumZoomLevel toZoomLevel:_maximumZoomLevel];
+}
+
+- (BOOL)isEqual:(id)other {
+ if (other == self) {
+ return YES;
+ }
+ if (![other isKindOfClass:[self class]]) {
+ return NO;
+ }
+
+ MGLShapeOfflineRegion *otherRegion = other;
+ return (_minimumZoomLevel == otherRegion->_minimumZoomLevel
+ && _maximumZoomLevel == otherRegion->_maximumZoomLevel
+ && _shape.geometryObject == otherRegion->_shape.geometryObject
+ && [_styleURL isEqual:otherRegion->_styleURL]);
+}
+
+- (NSUInteger)hash {
+ return (_styleURL.hash
+ + _shape.hash
+ + @(_minimumZoomLevel).hash + @(_maximumZoomLevel).hash);
+}
+
+@end
diff --git a/platform/darwin/src/MGLShapeOfflineRegion_Private.h b/platform/darwin/src/MGLShapeOfflineRegion_Private.h
new file mode 100644
index 0000000000..2ab44ad405
--- /dev/null
+++ b/platform/darwin/src/MGLShapeOfflineRegion_Private.h
@@ -0,0 +1,22 @@
+#import <Foundation/Foundation.h>
+
+#import "MGLOfflineRegion.h"
+
+#include <mbgl/storage/offline.hpp>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol MGLShapeOfflineRegion_Private <MGLOfflineRegion>
+
+/**
+ Initializes and returns an offline region backed by the given C++ region
+ definition object.
+
+ @param definition A reference to an offline region definition backing the
+ offline region.
+ */
+- (instancetype)initWithOfflineRegionDefinition:(const mbgl::OfflineGeometryRegionDefinition &)definition;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLTilePyramidOfflineRegion.h b/platform/darwin/src/MGLTilePyramidOfflineRegion.h
index 31e5a41920..4fbb68dbc6 100644
--- a/platform/darwin/src/MGLTilePyramidOfflineRegion.h
+++ b/platform/darwin/src/MGLTilePyramidOfflineRegion.h
@@ -9,22 +9,14 @@ NS_ASSUME_NONNULL_BEGIN
/**
An offline region defined by a style URL, geographic coordinate bounds, and
range of zoom levels.
+
+ To minimize the resources required by an irregularly shaped offline region,
+ use the MGLShapeOfflineRegion class instead.
*/
MGL_EXPORT
@interface MGLTilePyramidOfflineRegion : NSObject <MGLOfflineRegion, NSSecureCoding, NSCopying>
/**
- URL of the style whose resources are required for offline viewing.
-
- In addition to the JSON stylesheet, different styles may require different font
- glyphs, sprite sheets, and other resources.
-
- The URL may be a full HTTP or HTTPS URL or a Mapbox URL indicating the style’s
- map ID (`mapbox://styles/{user}/{style}`).
- */
-@property (nonatomic, readonly) NSURL *styleURL;
-
-/**
The coordinate bounds for the geographic region covered by the downloaded
tiles.
*/
diff --git a/platform/darwin/src/MGLTilePyramidOfflineRegion.mm b/platform/darwin/src/MGLTilePyramidOfflineRegion.mm
index 7333703267..0766d224da 100644
--- a/platform/darwin/src/MGLTilePyramidOfflineRegion.mm
+++ b/platform/darwin/src/MGLTilePyramidOfflineRegion.mm
@@ -5,10 +5,11 @@
#endif
#import "MGLOfflineRegion_Private.h"
+#import "MGLTilePyramidOfflineRegion_Private.h"
#import "MGLGeometry_Private.h"
#import "MGLStyle.h"
-@interface MGLTilePyramidOfflineRegion () <MGLOfflineRegion_Private>
+@interface MGLTilePyramidOfflineRegion () <MGLOfflineRegion_Private, MGLTilePyramidOfflineRegion_Private>
@end
@@ -52,7 +53,7 @@
return self;
}
-- (instancetype)initWithOfflineRegionDefinition:(const mbgl::OfflineRegionDefinition &)definition {
+- (instancetype)initWithOfflineRegionDefinition:(const mbgl::OfflineTilePyramidRegionDefinition &)definition {
NSURL *styleURL = [NSURL URLWithString:@(definition.styleURL.c_str())];
MGLCoordinateBounds bounds = MGLCoordinateBoundsFromLatLngBounds(definition.bounds);
return [self initWithStyleURL:styleURL bounds:bounds fromZoomLevel:definition.minZoom toZoomLevel:definition.maxZoom];
diff --git a/platform/darwin/src/MGLTilePyramidOfflineRegion_Private.h b/platform/darwin/src/MGLTilePyramidOfflineRegion_Private.h
new file mode 100644
index 0000000000..90d8e05477
--- /dev/null
+++ b/platform/darwin/src/MGLTilePyramidOfflineRegion_Private.h
@@ -0,0 +1,22 @@
+#import <Foundation/Foundation.h>
+
+#import "MGLOfflineRegion.h"
+
+#include <mbgl/storage/offline.hpp>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol MGLTilePyramidOfflineRegion_Private <MGLOfflineRegion>
+
+/**
+ Initializes and returns an offline region backed by the given C++ region
+ definition object.
+
+ @param definition A reference to an offline region definition backing the
+ offline region.
+ */
+- (instancetype)initWithOfflineRegionDefinition:(const mbgl::OfflineTilePyramidRegionDefinition &)definition;
+
+@end
+
+NS_ASSUME_NONNULL_END