summaryrefslogtreecommitdiff
path: root/platform/darwin/src
diff options
context:
space:
mode:
authorFabian Guerra <fabian.guerra@mapbox.com>2018-01-04 12:55:19 -0600
committerFabian Guerra <fabian.guerra@mapbox.com>2018-01-04 12:55:19 -0600
commit187b6dc31cf281b5157de1acd92f3e8ef9d0acf9 (patch)
tree1d9eaac5d1e8393d8fd665aa678581a6086a9eb6 /platform/darwin/src
parentc62b0af24fc76b4bb2eb34100611dd3ee9ee5536 (diff)
parent760ef23ac3faf4437cadb52983383c9501336964 (diff)
downloadqtlocation-mapboxgl-187b6dc31cf281b5157de1acd92f3e8ef9d0acf9.tar.gz
Merge branch 'release-agua' into masterupstream/fabian-merge-release-agua
# Conflicts: # circle.yml # cmake/core-files.cmake # platform/android/CHANGELOG.md # platform/android/MapboxGLAndroidSDK/build.gradle # platform/android/MapboxGLAndroidSDK/gradle.properties # platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraChangeDispatcher.java # platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java # platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java # platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/text/LocalGlyphRasterizer.java # platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/BitmapUtils.java # platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml # platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DebugModeActivity.java # platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/LocalGlyphActivity.java # platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java # platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_local_glyph.xml # platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml # platform/darwin/src/MGLMapSnapshotter.mm # platform/darwin/src/MGLRendererConfiguration.h # platform/ios/CHANGELOG.md # platform/ios/DEVELOPING.md # platform/ios/INSTALL.md # platform/ios/README.md # platform/ios/resources/bg.lproj/Localizable.strings # platform/ios/resources/es.lproj/Localizable.strings # platform/ios/resources/vi.lproj/Localizable.strings # platform/ios/src/MGLMapView.mm # platform/macos/macos.xcodeproj/project.pbxproj # src/mbgl/text/glyph_manager.cpp
Diffstat (limited to 'platform/darwin/src')
-rw-r--r--platform/darwin/src/MGLAttributionInfo.h30
-rw-r--r--platform/darwin/src/MGLAttributionInfo.mm28
-rw-r--r--platform/darwin/src/MGLImageSource.h5
-rw-r--r--platform/darwin/src/MGLMapSnapshotter.h114
-rw-r--r--platform/darwin/src/MGLMapSnapshotter.mm267
-rw-r--r--platform/darwin/src/MGLOpenGLStyleLayer.mm6
-rw-r--r--platform/darwin/src/MGLStyle.mm2
-rw-r--r--platform/darwin/src/MGLStyle_Private.h2
8 files changed, 263 insertions, 191 deletions
diff --git a/platform/darwin/src/MGLAttributionInfo.h b/platform/darwin/src/MGLAttributionInfo.h
index 031a10060f..1de37c3b24 100644
--- a/platform/darwin/src/MGLAttributionInfo.h
+++ b/platform/darwin/src/MGLAttributionInfo.h
@@ -8,6 +8,24 @@
NS_ASSUME_NONNULL_BEGIN
/**
+ The attribution info is represented in the longest format available.
+ */
+typedef NS_ENUM(NSUInteger, MGLAttributionInfoStyle) {
+ /**
+ Specifies a short attribution info style.
+ */
+ MGLAttributionInfoStyleShort = 1,
+ /**
+ Specifies a medium attribution info style.
+ */
+ MGLAttributionInfoStyleMedium,
+ /**
+ Specifies a long attribution info style.
+ */
+ MGLAttributionInfoStyleLong
+};
+
+/**
Information about an attribution statement, usually a copyright or trademark
statement, associated with a map content source.
*/
@@ -59,6 +77,18 @@ MGL_EXPORT
*/
- (nullable NSURL *)feedbackURLAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel;
+/**
+ Returns a copy of the current `title` formatted accordingly to `style`.
+
+ Example: If the `style` property is set to `MGLAttributionInfoStyleShort` and the
+ `title` property is set to `OpenStreetMap`, then this method returns `OSM`.
+
+ @param style The attribution info style.
+
+ @return The `NSAttributedString` styled title.
+ */
+- (NSAttributedString *)titleWithStyle:(MGLAttributionInfoStyle)style;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLAttributionInfo.mm b/platform/darwin/src/MGLAttributionInfo.mm
index ce63a25422..73147270c1 100644
--- a/platform/darwin/src/MGLAttributionInfo.mm
+++ b/platform/darwin/src/MGLAttributionInfo.mm
@@ -127,6 +127,15 @@
return self;
}
+- (id)copyWithZone:(nullable NSZone *)zone
+{
+ MGLAttributionInfo *info = [[[self class] allocWithZone:zone] initWithTitle:_title
+ URL:_URL];
+ info.feedbackLink = _feedbackLink;
+
+ return info;
+}
+
- (nullable NSURL *)feedbackURLAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel {
return [self feedbackURLForStyleURL:nil atCenterCoordinate:centerCoordinate zoomLevel:zoomLevel direction:0 pitch:0];
}
@@ -160,6 +169,25 @@
return components.URL;
}
+- (NSAttributedString *)titleWithStyle:(MGLAttributionInfoStyle)style
+{
+ NSString *openStreetMap = NSLocalizedStringWithDefaultValue(@"OSM_FULL_NAME", @"Foundation", nil, @"OpenStreetMap", @"OpenStreetMap full name attribution");
+ NSString *OSM = NSLocalizedStringWithDefaultValue(@"OSM_SHORT_NAME", @"Foundation", nil, @"OSM", @"OpenStreetMap short name attribution");
+
+ NSMutableAttributedString *title = [[NSMutableAttributedString alloc] initWithAttributedString:self.title];
+ [title removeAttribute:NSUnderlineStyleAttributeName range:NSMakeRange(0, [title.string length])];
+
+ BOOL isAbbreviated = (style == MGLAttributionInfoStyleShort);
+
+ if ([title.string rangeOfString:@"OpenStreetMap"].location != NSNotFound) {
+ [title.mutableString replaceOccurrencesOfString:@"OpenStreetMap" withString:isAbbreviated ? OSM : openStreetMap
+ options:NSCaseInsensitiveSearch
+ range:NSMakeRange(0, [title.mutableString length])];
+ }
+
+ return title;
+}
+
- (BOOL)isEqual:(id)object {
return [object isKindOfClass:[self class]] && [[object title] isEqual:self.title] && [[object URL] isEqual:self.URL];
}
diff --git a/platform/darwin/src/MGLImageSource.h b/platform/darwin/src/MGLImageSource.h
index 5088f6bac0..21487d9739 100644
--- a/platform/darwin/src/MGLImageSource.h
+++ b/platform/darwin/src/MGLImageSource.h
@@ -38,11 +38,8 @@ MGL_EXPORT
bottomLeft: CLLocationCoordinate2D(latitude: 37.936, longitude: -80.425),
bottomRight: CLLocationCoordinate2D(latitude: 37.936, longitude: -71.516),
topRight: CLLocationCoordinate2D(latitude: 46.437, longitude: -71.516))
- let source = MGLImageSource(identifier: "radar-source", coordinateQuad: coordinates, url: URL(string: "https://www.mapbox.com/mapbox-gl-js/assets/radar.gif")!)
+ let source = MGLImageSource(identifier: "radar", coordinateQuad: coordinates, url: URL(string: "https://www.mapbox.com/mapbox-gl-js/assets/radar.gif")!)
mapView.style?.addSource(source)
-
- let layer = MGLRasterStyleLayer(identifier: "radar-layer", source: source)
- style.addLayer(layer)
```
*/
MGL_EXPORT
diff --git a/platform/darwin/src/MGLMapSnapshotter.h b/platform/darwin/src/MGLMapSnapshotter.h
index 541bc68b93..426ab1bb00 100644
--- a/platform/darwin/src/MGLMapSnapshotter.h
+++ b/platform/darwin/src/MGLMapSnapshotter.h
@@ -14,9 +14,10 @@ MGL_EXPORT
/**
Creates a set of options with the minimum required information.
- @param styleURL URL of the map style to snapshot. The URL may be a full HTTP or HTTPS URL,
- a Mapbox URL indicating the style’s map ID (`mapbox://styles/{user}/{style`}), or a path
- to a local file relative to the application’s resource path. Specify `nil` for the default style.
+ @param styleURL URL of the map style to snapshot. The URL may be a full HTTP or
+ HTTPS URL, a Mapbox URL indicating the style’s map ID
+ (`mapbox://styles/{user}/{style}`), or a path to a local file relative to
+ the application’s resource path. Specify `nil` for the default style.
@param size The image size.
*/
- (instancetype)initWithStyleURL:(nullable NSURL *)styleURL camera:(MGLMapCamera *)camera size:(CGSize)size;
@@ -31,17 +32,18 @@ MGL_EXPORT
/**
The zoom level.
- The default zoom level is 0. If this property is non-zero and the camera property
- is non-nil, the camera’s altitude is ignored in favor of this property’s value.
+ The default zoom level is 0. If this property is non-zero and the camera
+ property is non-nil, the camera’s altitude is ignored in favor of this
+ property’s value.
*/
@property (nonatomic) double zoomLevel;
/**
A camera representing the viewport visible in the snapshot.
- If this property is non-nil and the `coordinateBounds` property is set to a non-empty
- coordinate bounds, the camera’s center coordinate and altitude are ignored in favor
- of the `coordinateBounds` property.
+ If this property is non-nil and the `coordinateBounds` property is set to a
+ non-empty coordinate bounds, the camera’s center coordinate and altitude are
+ ignored in favor of the `coordinateBounds` property.
*/
@property (nonatomic) MGLMapCamera *camera;
@@ -78,24 +80,26 @@ MGL_EXPORT
#if TARGET_OS_IPHONE
/**
- Converts the specified map coordinate to a point in the coordinate space of the image.
+ Converts the specified map coordinate to a point in the coordinate space of the
+ image.
*/
- (CGPoint)pointForCoordinate:(CLLocationCoordinate2D)coordinate;
/**
The image of the map’s content.
*/
-@property(nonatomic, readonly) UIImage *image;
+@property (nonatomic, readonly) UIImage *image;
#else
/**
- Converts the specified map coordinate to a point in the coordinate space of the image.
+ Converts the specified map coordinate to a point in the coordinate space of the
+ image.
*/
- (NSPoint)pointForCoordinate:(CLLocationCoordinate2D)coordinate;
/**
The image of the map’s content.
*/
-@property(nonatomic, readonly) NSImage *image;
+@property (nonatomic, readonly) NSImage *image;
#endif
@end
@@ -103,13 +107,33 @@ MGL_EXPORT
/**
A block to processes the result or error of a snapshot request.
- @param snapshot The `MGLMapSnapshot` that was generated or `nil` if an error occurred.
+ @param snapshot The `MGLMapSnapshot` that was generated or `nil` if an error
+ occurred.
@param error The error that occured or `nil` when successful.
*/
typedef void (^MGLMapSnapshotCompletionHandler)(MGLMapSnapshot* _Nullable snapshot, NSError* _Nullable error);
/**
- An immutable utility object for capturing map-based images.
+ An `MGLMapSnapshotter` generates static raster images of the map. Each snapshot
+ image depicts a portion of a map defined by an `MGLMapSnapshotOptions` object
+ you provide. The snapshotter generates an `MGLMapSnapshot` object
+ asynchronously, passing it into a completion handler once tiles and other
+ resources needed for the snapshot are finished loading.
+
+ You can change the snapshotter’s options at any time and reuse the snapshotter
+ for multiple distinct snapshots; however, the snapshotter can only generate one
+ snapshot at a time. If you need to generate multiple snapshots concurrently,
+ create multiple snapshotter objects.
+
+ For an interactive map, use the `MGLMapView` class. Both `MGLMapSnapshotter`
+ and `MGLMapView` are compatible with offline packs managed by the
+ `MGLOfflineStorage` class.
+
+ From a snapshot, you can obtain an image and convert geographic coordinates to
+ the image’s coordinate space in order to superimpose markers and overlays. If
+ you do not need offline map functionality, you can use the `Snapshot` class in
+ [MapboxStatic.swift](https://github.com/mapbox/MapboxStatic.swift/) to generate
+ static map images with overlays.
### Example
@@ -121,18 +145,25 @@ typedef void (^MGLMapSnapshotCompletionHandler)(MGLMapSnapshot* _Nullable snapsh
let snapshotter = MGLMapSnapshotter(options: options)
snapshotter.start { (snapshot, error) in
- if error != nil {
- // error handler
- } else {
- // image handler
+ if let error = error {
+ fatalError(error.localizedDescription)
}
+
+ image = snapshot?.image
}
```
*/
MGL_EXPORT
@interface MGLMapSnapshotter : NSObject
-- (instancetype)initWithOptions:(MGLMapSnapshotOptions*)options;
+/**
+ Initializes and returns a map snapshotter object that produces snapshots
+ according to the given options.
+
+ @param options The options to use when generating a map snapshot.
+ @return An initialized map snapshotter.
+ */
+- (instancetype)initWithOptions:(MGLMapSnapshotOptions *)options;
/**
Starts the snapshot creation and executes the specified block with the result.
@@ -142,7 +173,8 @@ MGL_EXPORT
- (void)startWithCompletionHandler:(MGLMapSnapshotCompletionHandler)completionHandler;
/**
- Starts the snapshot creation and executes the specified block with the result on the specified queue.
+ Starts the snapshot creation and executes the specified block with the result
+ on the specified queue.
@param queue The queue to handle the result on.
@param completionHandler The block to handle the result in.
@@ -152,49 +184,15 @@ MGL_EXPORT
/**
Cancels the snapshot creation request, if any.
- Once you call this method, you cannot resume the snapshot. In order to obtain the
- snapshot, create a new `MGLMapSnapshotter` object.
+ Once you call this method, you cannot resume the snapshot. In order to obtain
+ the snapshot, create a new `MGLMapSnapshotter` object.
*/
- (void)cancel;
/**
- The zoom level.
-
- The default zoom level is 0. If this property is non-zero and the camera property
- is non-nil, the camera’s altitude is ignored in favor of this property’s value.
- */
-@property (nonatomic) double zoomLevel;
-
-/**
- A camera representing the viewport visible in the snapshot.
-
- If this property is non-nil and the `coordinateBounds` property is set to a non-empty
- coordinate bounds, the camera’s center coordinate and altitude are ignored in favor
- of the `coordinateBounds` property.
- */
-@property (nonatomic) MGLMapCamera *camera;
-
-/**
- The coordinate rectangle that encompasses the bounds to capture.
-
- If this property is non-empty and the camera property is non-nil, the camera’s
- center coordinate and altitude are ignored in favor of this property’s value.
- */
-@property (nonatomic) MGLCoordinateBounds coordinateBounds;
-
-/**
- URL of the map style to snapshot.
-
- The URL may be a full HTTP or HTTPS URL, a Mapbox URL indicating the style’s
- map ID (`mapbox://styles/{user}/{style`}), or a path to a local file relative
- to the application’s resource path. Specify `nil` for the default style.
- */
-@property (nonatomic, nullable) NSURL *styleURL;
-
-/**
- The size of the output image, measured in points.
+ The options to use when generating a map snapshot.
*/
-@property (nonatomic) CGSize size;
+@property (nonatomic) MGLMapSnapshotOptions *options;
/**
Indicates whether a snapshot is currently being generated.
diff --git a/platform/darwin/src/MGLMapSnapshotter.mm b/platform/darwin/src/MGLMapSnapshotter.mm
index 346666cf80..967706ac2e 100644
--- a/platform/darwin/src/MGLMapSnapshotter.mm
+++ b/platform/darwin/src/MGLMapSnapshotter.mm
@@ -61,6 +61,7 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
@implementation MGLMapSnapshot {
mbgl::MapSnapshotter::PointForFn _pointForFn;
}
+
- (instancetype)initWithImage:(nullable MGLImage *)image scale:(CGFloat)scale pointForFn:(mbgl::MapSnapshotter::PointForFn)pointForFn
{
self = [super init];
@@ -80,7 +81,7 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
@end
@interface MGLMapSnapshotter()
-@property (nonatomic) MGLMapSnapshotOptions *options;
+
@end
@implementation MGLMapSnapshotter {
@@ -88,46 +89,16 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
std::shared_ptr<mbgl::ThreadPool> _mbglThreadPool;
std::unique_ptr<mbgl::MapSnapshotter> _mbglMapSnapshotter;
std::unique_ptr<mbgl::Actor<mbgl::MapSnapshotter::Callback>> _snapshotCallback;
+ NS_ARRAY_OF(MGLAttributionInfo *) *_attributionInfo;
}
- (instancetype)initWithOptions:(MGLMapSnapshotOptions *)options
{
self = [super init];
if (self) {
- _options = options;
+ [self setOptions:options];
_loading = false;
-
- mbgl::DefaultFileSource *mbglFileSource = [MGLOfflineStorage sharedOfflineStorage].mbglFileSource;
- _mbglThreadPool = mbgl::sharedThreadPool();
-
- std::string styleURL = std::string([options.styleURL.absoluteString UTF8String]);
-
- // Size; taking into account the minimum texture size for OpenGL ES
- // For non retina screens the ratio is 1:1 MGLSnapshotterMinimumPixelSize
- mbgl::Size size = {
- static_cast<uint32_t>(MAX(options.size.width, MGLSnapshotterMinimumPixelSize)),
- static_cast<uint32_t>(MAX(options.size.height, MGLSnapshotterMinimumPixelSize))
- };
-
- float pixelRatio = MAX(options.scale, 1);
-
- // Camera options
- mbgl::CameraOptions cameraOptions;
- if (CLLocationCoordinate2DIsValid(options.camera.centerCoordinate)) {
- cameraOptions.center = MGLLatLngFromLocationCoordinate2D(options.camera.centerCoordinate);
- }
- cameraOptions.angle = MAX(0, options.camera.heading) * mbgl::util::DEG2RAD;
- cameraOptions.zoom = MAX(0, options.zoomLevel);
- cameraOptions.pitch = MAX(0, options.camera.pitch);
-
- // Region
- mbgl::optional<mbgl::LatLngBounds> coordinateBounds;
- if (!MGLCoordinateBoundsIsEmpty(options.coordinateBounds)) {
- coordinateBounds = MGLLatLngBoundsFromCoordinateBounds(options.coordinateBounds);
- }
-
- // Create the snapshotter
- _mbglMapSnapshotter = std::make_unique<mbgl::MapSnapshotter>(*mbglFileSource, *_mbglThreadPool, styleURL, size, pixelRatio, cameraOptions, coordinateBounds);
+
}
return self;
}
@@ -167,14 +138,7 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
[infos growArrayByAddingAttributionInfosFromArray:tileSetInfos];
}
- CGSize attributionBackgroundSize = CGSizeMake(10, 0);
- for (MGLAttributionInfo *info in infos) {
- if (info.isFeedbackLink) {
- continue;
- }
- attributionBackgroundSize.width += [info.title size].width + 10;
- attributionBackgroundSize.height = MAX([info.title size].height, attributionBackgroundSize.height);
- }
+ _attributionInfo = infos;
if (mbglError) {
NSString *description = @(mbgl::util::toString(mbglError).c_str());
@@ -198,11 +162,29 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
dispatch_queue_t workQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(workQueue, ^{
#if TARGET_OS_IPHONE
- UIImage *logoImage = [UIImage imageNamed:@"mapbox" inBundle:[NSBundle mgl_frameworkBundle] compatibleWithTraitCollection:nil];
+ MGLAttributionInfoStyle attributionInfoStyle = MGLAttributionInfoStyleLong;
+ for (NSUInteger styleValue = MGLAttributionInfoStyleLong; styleValue >= MGLAttributionInfoStyleShort; styleValue--) {
+ attributionInfoStyle = (MGLAttributionInfoStyle)styleValue;
+ CGSize attributionSize = [self attributionSizeWithLogoStyle:attributionInfoStyle sourceAttributionStyle:attributionInfoStyle];
+ if (attributionSize.width <= mglImage.size.width) {
+ break;
+ }
+ }
+
+ UIImage *logoImage = [self logoImageWithStyle:attributionInfoStyle];
+ CGSize attributionBackgroundSize = [self attributionTextSizeWithStyle:attributionInfoStyle];
CGRect logoImageRect = CGRectMake(MGLLogoImagePosition.x, mglImage.size.height - (MGLLogoImagePosition.y + logoImage.size.height), logoImage.size.width, logoImage.size.height);
- CGRect attributionBackgroundFrame = CGRectMake(mglImage.size.width - 10 - attributionBackgroundSize.width,
- logoImageRect.origin.y + (logoImageRect.size.height / 2) - (attributionBackgroundSize.height / 2) + 1,
+ CGPoint attributionOrigin = CGPointMake(mglImage.size.width - 10 - attributionBackgroundSize.width,
+ logoImageRect.origin.y + (logoImageRect.size.height / 2) - (attributionBackgroundSize.height / 2) + 1);
+ if (!logoImage) {
+ CGSize defaultLogoSize = [self mapboxLongStyleLogo].size;
+ logoImageRect = CGRectMake(0, mglImage.size.height - (MGLLogoImagePosition.y + defaultLogoSize.height), 0, defaultLogoSize.height);
+ attributionOrigin = CGPointMake(10, logoImageRect.origin.y + (logoImageRect.size.height / 2) - (attributionBackgroundSize.height / 2) + 1);
+ }
+
+ CGRect attributionBackgroundFrame = CGRectMake(attributionOrigin.x,
+ attributionOrigin.y,
attributionBackgroundSize.width,
attributionBackgroundSize.height);
CGPoint attributionTextPosition = CGPointMake(attributionBackgroundFrame.origin.x + 10,
@@ -231,20 +213,39 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
[blurredAttributionBackground drawInRect:attributionBackgroundFrame];
- [self drawAttributionText:infos origin:attributionTextPosition];
+ [self drawAttributionTextWithStyle:attributionInfoStyle origin:attributionTextPosition];
UIImage *compositedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
#else
- NSImage *logoImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mgl_frameworkBundle] pathForResource:@"mapbox" ofType:@"pdf"]];
- NSImage *sourceImage = mglImage;
-
NSSize targetSize = NSMakeSize(self.options.size.width, self.options.size.height);
NSRect targetFrame = NSMakeRect(0, 0, targetSize.width, targetSize.height);
+
+ MGLAttributionInfoStyle attributionInfoStyle = MGLAttributionInfoStyleLong;
+ for (NSUInteger styleValue = MGLAttributionInfoStyleLong; styleValue >= MGLAttributionInfoStyleShort; styleValue--) {
+ attributionInfoStyle = (MGLAttributionInfoStyle)styleValue;
+ CGSize attributionSize = [self attributionSizeWithLogoStyle:attributionInfoStyle sourceAttributionStyle:attributionInfoStyle];
+ if (attributionSize.width <= mglImage.size.width) {
+ break;
+ }
+ }
+
+ NSImage *logoImage = [self logoImageWithStyle:attributionInfoStyle];
+ CGSize attributionBackgroundSize = [self attributionTextSizeWithStyle:attributionInfoStyle];
+ NSImage *sourceImage = mglImage;
+
CGRect logoImageRect = CGRectMake(MGLLogoImagePosition.x, MGLLogoImagePosition.y, logoImage.size.width, logoImage.size.height);
- CGRect attributionBackgroundFrame = CGRectMake(targetFrame.size.width - 10 - attributionBackgroundSize.width,
- MGLLogoImagePosition.y + 1,
+ CGPoint attributionOrigin = CGPointMake(targetFrame.size.width - 10 - attributionBackgroundSize.width,
+ MGLLogoImagePosition.y + 1);
+ if (!logoImage) {
+ CGSize defaultLogoSize = [self mapboxLongStyleLogo].size;
+ logoImageRect = CGRectMake(0, MGLLogoImagePosition.y, 0, defaultLogoSize.height);
+ attributionOrigin = CGPointMake(10, attributionOrigin.y);
+ }
+
+ CGRect attributionBackgroundFrame = CGRectMake(attributionOrigin.x,
+ attributionOrigin.y,
attributionBackgroundSize.width,
attributionBackgroundSize.height);
CGPoint attributionTextPosition = CGPointMake(attributionBackgroundFrame.origin.x + 10,
@@ -261,7 +262,9 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
[sourceImageRep drawInRect: targetFrame];
- [logoImage drawInRect:logoImageRect];
+ if (logoImage) {
+ [logoImage drawInRect:logoImageRect];
+ }
NSBitmapImageRep *attributionBackground = [[NSBitmapImageRep alloc] initWithFocusedViewRect:attributionBackgroundFrame];
@@ -271,7 +274,7 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
[blurredAttributionBackground drawInRect:attributionBackgroundFrame];
- [self drawAttributionText:infos origin:attributionTextPosition];
+ [self drawAttributionTextWithStyle:attributionInfoStyle origin:attributionTextPosition];
[compositedImage unlockFocus];
@@ -290,15 +293,16 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
});
}
-- (void)drawAttributionText:(NSArray *)attributionInfo origin:(CGPoint)origin
+- (void)drawAttributionTextWithStyle:(MGLAttributionInfoStyle)attributionInfoStyle origin:(CGPoint)origin
{
- for (MGLAttributionInfo *info in attributionInfo) {
+ for (MGLAttributionInfo *info in _attributionInfo) {
if (info.isFeedbackLink) {
continue;
}
- [info.title drawAtPoint:origin];
+ NSAttributedString *attribution = [info titleWithStyle:attributionInfoStyle];
+ [attribution drawAtPoint:origin];
- origin.x += [info.title size].width + 10;
+ origin.x += [attribution size].width + 10;
}
}
@@ -324,10 +328,8 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
MGLImage *image;
#if TARGET_OS_IPHONE
-
image = [UIImage imageWithCGImage:cgimg];
#else
-
image = [[NSImage alloc] initWithCGImage:cgimg size:[backgroundImage extent].size];
#endif
@@ -335,87 +337,110 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
return image;
}
-- (void)cancel
+- (MGLImage *)logoImageWithStyle:(MGLAttributionInfoStyle)style
{
- _snapshotCallback.reset();
- _mbglMapSnapshotter.reset();
-}
-
-- (NSURL *)styleURL
-{
- NSString *styleURLString = @(_mbglMapSnapshotter->getStyleURL().c_str());
- return styleURLString.length ? [NSURL URLWithString:styleURLString] : nil;
+ MGLImage *logoImage;
+ switch (style) {
+ case MGLAttributionInfoStyleLong:
+ logoImage = [self mapboxLongStyleLogo];
+ break;
+ case MGLAttributionInfoStyleMedium:
+#if TARGET_OS_IPHONE
+ logoImage = [UIImage imageNamed:@"mapbox_helmet" inBundle:[NSBundle mgl_frameworkBundle] compatibleWithTraitCollection:nil];
+#else
+ logoImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mgl_frameworkBundle] pathForResource:@"mapbox_helmet" ofType:@"pdf"]];
+#endif
+ break;
+ case MGLAttributionInfoStyleShort:
+ logoImage = nil;
+ break;
+ }
+ return logoImage;
}
-- (void)setStyleURL:(NSURL *)url
+- (MGLImage *)mapboxLongStyleLogo
{
- _mbglMapSnapshotter->setStyleURL(std::string([url.absoluteString UTF8String]));
+ MGLImage *logoImage;
+#if TARGET_OS_IPHONE
+ logoImage =[UIImage imageNamed:@"mapbox" inBundle:[NSBundle mgl_frameworkBundle] compatibleWithTraitCollection:nil];
+#else
+ logoImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mgl_frameworkBundle] pathForResource:@"mapbox" ofType:@"pdf"]];
+#endif
+ return logoImage;
}
-- (CGSize)size
+- (CGSize)attributionSizeWithLogoStyle:(MGLAttributionInfoStyle)logoStyle sourceAttributionStyle:(MGLAttributionInfoStyle)attributionStyle
{
- mbgl::Size size = _mbglMapSnapshotter->getSize();
- return CGSizeMake(size.width, size.height);
+ MGLImage *logoImage = [self logoImageWithStyle:logoStyle];
+
+ CGSize attributionBackgroundSize = [self attributionTextSizeWithStyle:attributionStyle];
+
+ CGSize attributionSize = CGSizeZero;
+
+ if (logoImage) {
+ attributionSize.width = MGLLogoImagePosition.x + logoImage.size.width + 10;
+ }
+ attributionSize.width = attributionSize.width + 10 + attributionBackgroundSize.width + 10;
+ attributionSize.height = MAX(logoImage.size.height, attributionBackgroundSize.height);
+
+ return attributionSize;
}
-- (void)setSize:(CGSize)size
+- (CGSize)attributionTextSizeWithStyle:(MGLAttributionInfoStyle)attributionStyle
{
- _mbglMapSnapshotter->setSize({
- static_cast<uint32_t>(MAX(size.width, MGLSnapshotterMinimumPixelSize)),
- static_cast<uint32_t>(MAX(size.height, MGLSnapshotterMinimumPixelSize))
- });
+ CGSize attributionBackgroundSize = CGSizeMake(10, 0);
+ for (MGLAttributionInfo *info in _attributionInfo) {
+ if (info.isFeedbackLink) {
+ continue;
+ }
+ CGSize attributionSize = [info titleWithStyle:attributionStyle].size;
+ attributionBackgroundSize.width += attributionSize.width + 10;
+ attributionBackgroundSize.height = MAX(attributionSize.height, attributionBackgroundSize.height);
+ }
+
+ return attributionBackgroundSize;
}
-- (MGLMapCamera *)camera
+- (void)cancel
{
- mbgl::CameraOptions cameraOptions = _mbglMapSnapshotter->getCameraOptions();
- CGFloat pitch = *cameraOptions.pitch;
- CLLocationDirection heading = mbgl::util::wrap(*cameraOptions.angle, 0., 360.);
- CLLocationDistance distance = MGLAltitudeForZoomLevel(*cameraOptions.zoom, pitch, cameraOptions.center->latitude(), [self size]);
- return [MGLMapCamera cameraLookingAtCenterCoordinate:MGLLocationCoordinate2DFromLatLng(*cameraOptions.center)
- fromDistance:distance
- pitch:pitch
- heading:heading];
+ _snapshotCallback.reset();
+ _mbglMapSnapshotter.reset();
}
-- (void)setCamera:(MGLMapCamera *)camera
+- (void)setOptions:(MGLMapSnapshotOptions *)options
{
+ _options = options;
+ mbgl::DefaultFileSource *mbglFileSource = [MGLOfflineStorage sharedOfflineStorage].mbglFileSource;
+ _mbglThreadPool = mbgl::sharedThreadPool();
+
+ std::string styleURL = std::string([options.styleURL.absoluteString UTF8String]);
+
+ // Size; taking into account the minimum texture size for OpenGL ES
+ // For non retina screens the ratio is 1:1 MGLSnapshotterMinimumPixelSize
+ mbgl::Size size = {
+ static_cast<uint32_t>(MAX(options.size.width, MGLSnapshotterMinimumPixelSize)),
+ static_cast<uint32_t>(MAX(options.size.height, MGLSnapshotterMinimumPixelSize))
+ };
+
+ float pixelRatio = MAX(options.scale, 1);
+
+ // Camera options
mbgl::CameraOptions cameraOptions;
- CLLocationCoordinate2D center;
- if (CLLocationCoordinate2DIsValid(camera.centerCoordinate)) {
- cameraOptions.center = MGLLatLngFromLocationCoordinate2D(camera.centerCoordinate);
- center = camera.centerCoordinate;
- } else {
- // Center is optional, but always set.
- center = MGLLocationCoordinate2DFromLatLng(*_mbglMapSnapshotter->getCameraOptions().center);
+ if (CLLocationCoordinate2DIsValid(options.camera.centerCoordinate)) {
+ cameraOptions.center = MGLLatLngFromLocationCoordinate2D(options.camera.centerCoordinate);
}
+ cameraOptions.angle = MAX(0, options.camera.heading) * mbgl::util::DEG2RAD;
+ cameraOptions.zoom = MAX(0, options.zoomLevel);
+ cameraOptions.pitch = MAX(0, options.camera.pitch);
- cameraOptions.angle = MAX(0, camera.heading) * mbgl::util::DEG2RAD;
- cameraOptions.zoom = MAX(0, MGLZoomLevelForAltitude(camera.altitude, camera.pitch, center.latitude, [self size]));
- cameraOptions.pitch = MAX(0, camera.pitch);
-}
-
-- (double)zoomLevel
-{
- mbgl::CameraOptions cameraOptions = _mbglMapSnapshotter->getCameraOptions();
- return MGLAltitudeForZoomLevel(*cameraOptions.zoom, *cameraOptions.pitch, cameraOptions.center->latitude(), [self size]);
-}
-
-- (void)setZoomLevel:(double)zoomLevel
-{
- mbgl::CameraOptions cameraOptions = _mbglMapSnapshotter->getCameraOptions();
- cameraOptions.zoom = zoomLevel;
- _mbglMapSnapshotter->setCameraOptions(cameraOptions);
-}
-
-- (MGLCoordinateBounds)coordinateBounds
-{
- return MGLCoordinateBoundsFromLatLngBounds(_mbglMapSnapshotter->getRegion());
-}
-
-- (void)setCoordinateBounds:(MGLCoordinateBounds)coordinateBounds
-{
- _mbglMapSnapshotter->setRegion(MGLLatLngBoundsFromCoordinateBounds(coordinateBounds));
+ // Region
+ mbgl::optional<mbgl::LatLngBounds> coordinateBounds;
+ if (!MGLCoordinateBoundsIsEmpty(options.coordinateBounds)) {
+ coordinateBounds = MGLLatLngBoundsFromCoordinateBounds(options.coordinateBounds);
+ }
+
+ // Create the snapshotter
+ _mbglMapSnapshotter = std::make_unique<mbgl::MapSnapshotter>(*mbglFileSource, *_mbglThreadPool, styleURL, size, pixelRatio, cameraOptions, coordinateBounds);
}
@end
diff --git a/platform/darwin/src/MGLOpenGLStyleLayer.mm b/platform/darwin/src/MGLOpenGLStyleLayer.mm
index 36a3c20c97..8933a77382 100644
--- a/platform/darwin/src/MGLOpenGLStyleLayer.mm
+++ b/platform/darwin/src/MGLOpenGLStyleLayer.mm
@@ -47,7 +47,7 @@ void MGLDrawCustomStyleLayer(void *context, const mbgl::style::CustomLayerRender
when creating an OpenGL style layer.
*/
void MGLFinishCustomStyleLayer(void *context) {
- MGLOpenGLStyleLayer *layer = (__bridge MGLOpenGLStyleLayer *)context;
+ MGLOpenGLStyleLayer *layer = (__bridge_transfer MGLOpenGLStyleLayer *)context;
[layer willMoveFromMapView:layer.style.mapView];
}
@@ -101,7 +101,7 @@ void MGLFinishCustomStyleLayer(void *context) {
MGLPrepareCustomStyleLayer,
MGLDrawCustomStyleLayer,
MGLFinishCustomStyleLayer,
- (__bridge void *)self);
+ (__bridge_retained void *)self);
return self = [super initWithPendingLayer:std::move(layer)];
}
@@ -116,9 +116,7 @@ void MGLFinishCustomStyleLayer(void *context) {
[NSException raise:@"MGLLayerReuseException"
format:@"%@ cannot be added to more than one MGLStyle at a time.", self];
}
- _style.openGLLayers[self.identifier] = nil;
_style = style;
- _style.openGLLayers[self.identifier] = self;
}
- (void)addToStyle:(MGLStyle *)style belowLayer:(MGLStyleLayer *)otherLayer {
diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm
index f04ae2b104..5221e838f8 100644
--- a/platform/darwin/src/MGLStyle.mm
+++ b/platform/darwin/src/MGLStyle.mm
@@ -77,7 +77,6 @@
@property (nonatomic, readonly, weak) MGLMapView *mapView;
@property (nonatomic, readonly) mbgl::style::Style *rawStyle;
@property (readonly, copy, nullable) NSURL *URL;
-@property (nonatomic, readwrite, strong) NS_MUTABLE_DICTIONARY_OF(NSString *, MGLOpenGLStyleLayer *) *openGLLayers;
@property (nonatomic) NS_MUTABLE_DICTIONARY_OF(NSString *, NS_DICTIONARY_OF(NSObject *, MGLTextLanguage *) *) *localizedLayersByIdentifier;
@end
@@ -169,7 +168,6 @@ static NSURL *MGLStyleURL_trafficNight;
if (self = [super init]) {
_mapView = mapView;
_rawStyle = rawStyle;
- _openGLLayers = [NSMutableDictionary dictionary];
_localizedLayersByIdentifier = [NSMutableDictionary dictionary];
}
return self;
diff --git a/platform/darwin/src/MGLStyle_Private.h b/platform/darwin/src/MGLStyle_Private.h
index e5bd79dc02..4cbe953a44 100644
--- a/platform/darwin/src/MGLStyle_Private.h
+++ b/platform/darwin/src/MGLStyle_Private.h
@@ -26,8 +26,6 @@ namespace mbgl {
- (nullable NS_ARRAY_OF(MGLAttributionInfo *) *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor;
-@property (nonatomic, readonly, strong) NS_MUTABLE_DICTIONARY_OF(NSString *, MGLOpenGLStyleLayer *) *openGLLayers;
-
- (void)setStyleClasses:(NS_ARRAY_OF(NSString *) *)appliedClasses transitionDuration:(NSTimeInterval)transitionDuration;
@end