diff options
author | Fabian Guerra <fabian.guerra@mapbox.com> | 2017-11-13 17:29:54 -0500 |
---|---|---|
committer | Fabian Guerra Soto <fabian.guerra@mapbox.com> | 2017-11-17 16:40:12 -0500 |
commit | 5eb050dc35d3d780136806aee0f72bae592011a4 (patch) | |
tree | 3c8fc29b92cc9acd89c3f35b756905068025b690 /platform/darwin | |
parent | 84fbb7c5767c6ba18992bcfff0f9a76e202a3ea3 (diff) | |
download | qtlocation-mapboxgl-5eb050dc35d3d780136806aee0f72bae592011a4.tar.gz |
[ios, macos] Update the attribution format for small snapshots.
Diffstat (limited to 'platform/darwin')
-rw-r--r-- | platform/darwin/src/MGLAttributionInfo.mm | 9 | ||||
-rw-r--r-- | platform/darwin/src/MGLMapSnapshotter.mm | 150 |
2 files changed, 130 insertions, 29 deletions
diff --git a/platform/darwin/src/MGLAttributionInfo.mm b/platform/darwin/src/MGLAttributionInfo.mm index 770aeb25e7..92fb9b689f 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]; } diff --git a/platform/darwin/src/MGLMapSnapshotter.mm b/platform/darwin/src/MGLMapSnapshotter.mm index dea93eba34..31b3ed41d6 100644 --- a/platform/darwin/src/MGLMapSnapshotter.mm +++ b/platform/darwin/src/MGLMapSnapshotter.mm @@ -27,6 +27,24 @@ const CGPoint MGLLogoImagePosition = CGPointMake(8, 8); const CGFloat MGLSnapshotterMinimumPixelSize = 64; +@interface MGLSnapshotAttributionOptions : NSObject +#if TARGET_OS_IPHONE +@property (nonatomic) UIImage *logoImage; +#else +@property (nonatomic) NSImage *logoImage; +#endif + +@property (nonatomic) CGSize attributionBackgroundSize; + +@property (nonatomic) NS_ARRAY_OF(MGLAttributionInfo *) *attributionInfo; + +@end + +@implementation MGLSnapshotAttributionOptions +@end + + + @implementation MGLMapSnapshotOptions - (instancetype _Nonnull)initWithStyleURL:(nullable NSURL *)styleURL camera:(MGLMapCamera *)camera size:(CGSize) size @@ -61,6 +79,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]; @@ -88,6 +107,7 @@ 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; + CGFloat _defaultLogoHeight; } - (instancetype)initWithOptions:(MGLMapSnapshotOptions *)options @@ -167,15 +187,6 @@ 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); - } - if (mbglError) { NSString *description = @(mbgl::util::toString(mbglError).c_str()); NSDictionary *userInfo = @{NSLocalizedDescriptionKey: description}; @@ -198,20 +209,28 @@ 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]; + MGLSnapshotAttributionOptions *option = [self attributionOptionsForSize:mglImage.size attributionInfo:infos]; + UIImage *logoImage = option.logoImage; 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, - attributionBackgroundSize.width, - attributionBackgroundSize.height); + CGPoint attributionOrigin = CGPointMake(mglImage.size.width - 10 - option.attributionBackgroundSize.width, + logoImageRect.origin.y + (logoImageRect.size.height / 2) - (option.attributionBackgroundSize.height / 2) + 1); + if (!logoImage) { + logoImageRect = CGRectMake(0, mglImage.size.height - (MGLLogoImagePosition.y + _defaultLogoHeight), 0, _defaultLogoHeight); + attributionOrigin = CGPointMake(10, logoImageRect.origin.y + (logoImageRect.size.height / 2) - (option.attributionBackgroundSize.height / 2) + 1); + } + + CGRect attributionBackgroundFrame = CGRectMake(attributionOrigin.x, + attributionOrigin.y, + option.attributionBackgroundSize.width, + option.attributionBackgroundSize.height); CGPoint attributionTextPosition = CGPointMake(attributionBackgroundFrame.origin.x + 10, attributionBackgroundFrame.origin.y - 1); CGRect cropRect = CGRectMake(attributionBackgroundFrame.origin.x * mglImage.scale, attributionBackgroundFrame.origin.y * mglImage.scale, - attributionBackgroundSize.width * mglImage.scale, - attributionBackgroundSize.height * mglImage.scale); + option.attributionBackgroundSize.width * mglImage.scale, + option.attributionBackgroundSize.height * mglImage.scale); UIGraphicsBeginImageContextWithOptions(mglImage.size, NO, self.options.scale); @@ -231,24 +250,32 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64; [blurredAttributionBackground drawInRect:attributionBackgroundFrame]; - [self drawAttributionText:infos origin:attributionTextPosition]; + [self drawAttributionText:option.attributionInfo 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); + MGLSnapshotAttributionOptions *option = [self attributionOptionsForSize:targetSize attributionInfo:infos]; + NSImage *logoImage = option.logoImage; + 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, - attributionBackgroundSize.width, - attributionBackgroundSize.height); + CGPoint attributionOrigin = CGPointMake(targetFrame.size.width - 10 - option.attributionBackgroundSize.width, + MGLLogoImagePosition.y + 1); + if (!logoImage) { + logoImageRect = CGRectMake(0, MGLLogoImagePosition.y, 0, _defaultLogoHeight); + attributionOrigin = CGPointMake(10, attributionOrigin.y); + } + + CGRect attributionBackgroundFrame = CGRectMake(attributionOrigin.x, + attributionOrigin.y, + option.attributionBackgroundSize.width, + option.attributionBackgroundSize.height); CGPoint attributionTextPosition = CGPointMake(attributionBackgroundFrame.origin.x + 10, - logoImageRect.origin.y + (logoImageRect.size.height / 2) - (attributionBackgroundSize.height / 2)); + logoImageRect.origin.y + (logoImageRect.size.height / 2) - (option.attributionBackgroundSize.height / 2)); NSImage *compositedImage = nil; @@ -261,7 +288,9 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64; [sourceImageRep drawInRect: targetFrame]; - [logoImage drawInRect:logoImageRect]; + if (logoImage) { + [logoImage drawInRect:logoImageRect]; + } NSBitmapImageRep *attributionBackground = [[NSBitmapImageRep alloc] initWithFocusedViewRect:attributionBackgroundFrame]; @@ -271,7 +300,7 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64; [blurredAttributionBackground drawInRect:attributionBackgroundFrame]; - [self drawAttributionText:infos origin:attributionTextPosition]; + [self drawAttributionText:option.attributionInfo origin:attributionTextPosition]; [compositedImage unlockFocus]; @@ -323,14 +352,77 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64; CGImageRef cgimg = [ctx createCGImage:blurredImage fromRect:[backgroundImage extent]]; #if TARGET_OS_IPHONE - return [UIImage imageWithCGImage:cgimg]; #else - return [[NSImage alloc] initWithCGImage:cgimg size:[backgroundImage extent].size]; #endif } +- (MGLSnapshotAttributionOptions *)attributionOptionsForSize:(CGSize)snapshotSize attributionInfo:(NSArray *)attributionInfo +{ + NSMutableArray *options = [NSMutableArray array]; + MGLSnapshotAttributionOptions *largeLogoAttribution = [self attributionOptionsForAttributionInfo:attributionInfo abbreviated:NO]; +#if TARGET_OS_IPHONE + largeLogoAttribution.logoImage = [UIImage imageNamed:@"mapbox" inBundle:[NSBundle mgl_frameworkBundle] compatibleWithTraitCollection:nil]; +#else + largeLogoAttribution.logoImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mgl_frameworkBundle] pathForResource:@"mapbox" ofType:@"pdf"]]; +#endif + _defaultLogoHeight = largeLogoAttribution.logoImage.size.height; + + MGLSnapshotAttributionOptions *smallLogoAttribution = [self attributionOptionsForAttributionInfo:attributionInfo abbreviated:NO]; +#if TARGET_OS_IPHONE + smallLogoAttribution.logoImage = [UIImage imageNamed:@"mapbox_helmet" inBundle:[NSBundle mgl_frameworkBundle] compatibleWithTraitCollection:nil]; +#else + smallLogoAttribution.logoImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mgl_frameworkBundle] pathForResource:@"mapbox_helmet" ofType:@"pdf"]]; +#endif + + MGLSnapshotAttributionOptions *noLogoAttribution = [self attributionOptionsForAttributionInfo:attributionInfo abbreviated:YES]; + + [options addObject:largeLogoAttribution]; + [options addObject:smallLogoAttribution]; + [options addObject:noLogoAttribution]; + + for (MGLSnapshotAttributionOptions *attributionOptions in options) { + // -[Mapbox Logo]-[Attribution Background]- + CGFloat origin = attributionOptions.logoImage ? MGLLogoImagePosition.x : 0; + CGFloat width = origin + attributionOptions.logoImage.size.width + 10 + attributionOptions.attributionBackgroundSize.width + 10; + if (width <= snapshotSize.width) { + return attributionOptions; + } + } + + return noLogoAttribution; +} + +- (MGLSnapshotAttributionOptions *)attributionOptionsForAttributionInfo:(NSArray *)attributionInfo abbreviated:(BOOL)isAbbreviated +{ + NSString *openStreetMap = NSLocalizedStringWithDefaultValue(@"OSM_FULL_NAME", nil, nil, @"OpenStreetMap", @"OpenStreetMap full name attribution"); + NSString *OSM = NSLocalizedStringWithDefaultValue(@"OSM_SHORT_NAME", nil, nil, @"OSM", @"OpenStreetMap short name attribution"); + NSMutableArray *infos = [NSMutableArray array]; + CGSize attributionBackgroundSize = CGSizeMake(10, 0); + for (MGLAttributionInfo *info in attributionInfo) { + if (info.isFeedbackLink) { + continue; + } + MGLAttributionInfo *attribution = [info copy]; + NSMutableAttributedString *title = [[NSMutableAttributedString alloc] initWithAttributedString:info.title]; + [title removeAttribute:NSUnderlineStyleAttributeName range:NSMakeRange(0, [title.string length])]; + if ([title.string rangeOfString:@"OpenStreetMap"].location != NSNotFound) { + [title.mutableString replaceOccurrencesOfString:@"OpenStreetMap" withString:isAbbreviated ? OSM : openStreetMap options:NSCaseInsensitiveSearch range:NSMakeRange(0, [title.mutableString length])]; + } + attribution.title = title; + attributionBackgroundSize.width += [attribution.title size].width + 10; + attributionBackgroundSize.height = MAX([attribution.title size].height, attributionBackgroundSize.height); + [infos addObject:attribution]; + } + + MGLSnapshotAttributionOptions *attributionOptions = [[MGLSnapshotAttributionOptions alloc] init]; + attributionOptions.attributionBackgroundSize = attributionBackgroundSize; + attributionOptions.attributionInfo = infos; + + return attributionOptions; +} + - (void)cancel { _snapshotCallback.reset(); |