From 7a0785665b855ce65c5a5a774a2a5447e2fba636 Mon Sep 17 00:00:00 2001 From: Fabian Guerra Date: Mon, 31 Jul 2017 17:14:32 -0400 Subject: [ios, macos] Add suport for stop localization. --- platform/darwin/src/MGLStyle.h | 2 +- platform/darwin/src/MGLStyle.mm | 70 +++++++++++++++++++++++++++--------- platform/ios/CHANGELOG.md | 7 ++-- platform/ios/app/MBXViewController.m | 5 +-- platform/macos/CHANGELOG.md | 2 +- platform/macos/app/MapDocument.m | 2 +- 6 files changed, 64 insertions(+), 24 deletions(-) diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h index c3a9732242..8c009d22c6 100644 --- a/platform/darwin/src/MGLStyle.h +++ b/platform/darwin/src/MGLStyle.h @@ -610,7 +610,7 @@ MGL_EXPORT */ @property (nonatomic, strong) MGLLight *light; -#pragma mark Style's localization +#pragma mark Localizing Map Content /** A Boolean value that determines whether the style attempts to localize labels in diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm index d7e0197c35..1e0a2e02b7 100644 --- a/platform/darwin/src/MGLStyle.mm +++ b/platform/darwin/src/MGLStyle.mm @@ -49,12 +49,34 @@ #import "NSImage+MGLAdditions.h" #endif +/** + Model class for localization changes. + */ +@interface MGLTextLanguage: NSObject +@property (strong, nonatomic) NSString *originalTextField; +@property (strong, nonatomic) NSString *updatedTextField; + +- (instancetype)initWithTextLanguage:(NSString *)originalTextField updatedTextField:(NSString *)updatedTextField; + +@end + +@implementation MGLTextLanguage +- (instancetype)initWithTextLanguage:(NSString *)originalTextField updatedTextField:(NSString *)updatedTextField +{ + if (self = [super init]) { + _originalTextField = originalTextField; + _updatedTextField = updatedTextField; + } + return self; +} +@end + @interface MGLStyle() @property (nonatomic, readwrite, weak) MGLMapView *mapView; @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(NSString *, NSString*) *) *localizedLayersByIdentifier; +@property (nonatomic) NS_MUTABLE_DICTIONARY_OF(NSString *, NS_DICTIONARY_OF(NSObject *, MGLTextLanguage *) *) *localizedLayersByIdentifier; @end @@ -657,54 +679,68 @@ static NSURL *MGLStyleURL_emerald; NSString *textField = [(MGLConstantStyleValue *)layer.text rawValue]; NSString *localizingString = stringByLocalizingString(textField); if (![textField isEqualToString:localizingString]) { - [self.localizedLayersByIdentifier setObject:@{ textField : localizingString } forKey:layer.identifier]; + MGLTextLanguage *textLanguage = [[MGLTextLanguage alloc] initWithTextLanguage:textField + updatedTextField:localizingString]; + [self.localizedLayersByIdentifier setObject:@{ textField : textLanguage } forKey:layer.identifier]; layer.text = [MGLStyleValue valueWithRawValue:localizingString]; } } else if ([layer.text isKindOfClass:[MGLCameraStyleFunction class]]) { MGLCameraStyleFunction *function = (MGLCameraStyleFunction *)layer.text; NSMutableDictionary *stops = function.stops.mutableCopy; + NSMutableDictionary *cameraStops = [NSMutableDictionary dictionary]; [stops enumerateKeysAndObjectsUsingBlock:^(NSNumber *zoomLevel, MGLConstantStyleValue *stop, BOOL *done) { NSString *textField = stop.rawValue; NSString *localizingString = stringByLocalizingString(textField); if (![textField isEqualToString:localizingString]) { - [self.localizedLayersByIdentifier setObject:@{ textField : localizingString } forKey:layer.identifier]; + MGLTextLanguage *textLanguage = [[MGLTextLanguage alloc] initWithTextLanguage:textField + updatedTextField:localizingString]; + [cameraStops setObject:textLanguage forKey:zoomLevel]; stops[zoomLevel] = [MGLStyleValue valueWithRawValue:localizingString]; } }]; + if (cameraStops.count > 0) { + [self.localizedLayersByIdentifier setObject:cameraStops forKey:layer.identifier]; + } function.stops = stops; layer.text = function; } } } else { - for (NSString *identifier in self.localizedLayersByIdentifier) { + + [self.localizedLayersByIdentifier enumerateKeysAndObjectsUsingBlock:^(NSString *identifier, NSDictionary *textFields, BOOL *done) { MGLSymbolStyleLayer *layer = (MGLSymbolStyleLayer *)[self.mapView.style layerWithIdentifier:identifier]; - NSDictionary *languages = [self.localizedLayersByIdentifier objectForKey:identifier]; - NSString *originalLanguage = [languages allKeys].firstObject; - NSString *changedLanguage = [languages objectForKey:originalLanguage]; if ([layer.text isKindOfClass:[MGLConstantStyleValue class]]) { NSString *textField = [(MGLConstantStyleValue *)layer.text rawValue]; - if ([changedLanguage isEqualToString:textField]) { - layer.text = [MGLStyleValue valueWithRawValue:originalLanguage]; - } - + [textFields enumerateKeysAndObjectsUsingBlock:^(NSObject *originalLanguage, MGLTextLanguage *textLanguage, BOOL *done) { + if ([textLanguage.updatedTextField isEqualToString:textField]) { + layer.text = [MGLStyleValue valueWithRawValue:textLanguage.originalTextField]; + } + }]; + } else if ([layer.text isKindOfClass:[MGLCameraStyleFunction class]]) { MGLCameraStyleFunction *function = (MGLCameraStyleFunction *)layer.text; NSMutableDictionary *stops = function.stops.mutableCopy; - [stops enumerateKeysAndObjectsUsingBlock:^(NSNumber *zoomLevel, MGLConstantStyleValue *stop, BOOL *done) { - NSString *textField = stop.rawValue; - if ([changedLanguage isEqualToString:textField]) { - stops[zoomLevel] = [MGLStyleValue valueWithRawValue:originalLanguage]; + [textFields enumerateKeysAndObjectsUsingBlock:^(NSObject *zoomKey, MGLTextLanguage *textLanguage, BOOL *done) { + if ([zoomKey isKindOfClass:[NSNumber class]]) { + NSNumber *zoomLevel = (NSNumber*)zoomKey; + MGLConstantStyleValue *stop = [stops objectForKey:zoomLevel]; + NSString *textField = stop.rawValue; + if ([textLanguage.updatedTextField isEqualToString:textField]) { + stops[zoomLevel] = [MGLStyleValue valueWithRawValue:textLanguage.originalTextField]; + } } - }]; + function.stops = stops; layer.text = function; } - } + + }]; + self.localizedLayersByIdentifier = [NSMutableDictionary dictionary]; } } diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 0e1c1b746e..8d1ed2b805 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -2,12 +2,15 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONTRIBUTING.md](../../CONTRIBUTING.md) to get started. -## 3.6.1 +## 3.6.2 + +* Added an MGLStyle.localizesLabels property, off by default, that localizes any Mapbox Streets–sourced symbol layer into the user’s preferred language. ([#9582](https://github.com/mapbox/mapbox-gl-native/pull/9582)) + +## 3.6.1 - July 28, 2017 * Reduced the size of the dynamic framework by optimizing symbol visibility. ([#7604](https://github.com/mapbox/mapbox-gl-native/pull/7604)) * Fixed an issue where the attribution button would have its custom tint color reset when the map view received a tint color change notification, such as when an alert controller was presented. ([#9598](https://github.com/mapbox/mapbox-gl-native/pull/9598)) * Improved the behavior of zoom gestures when the map reaches the minimum zoom limit. ([#9626](https://github.com/mapbox/mapbox-gl-native/pull/9626)) -* Added support to adapt Mapbox Streets–sourced layers for user preferred language. ([#9582](https://github.com/mapbox/mapbox-gl-native/pull/9582)) * Bitcode symbol maps (.bcsymbolmap files) are now included with the dynamic framework. ([#9613](https://github.com/mapbox/mapbox-gl-native/pull/9613)) ## 3.6.0 - June 29, 2017 diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index 7d9f3cbd31..ebbc218017 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -343,7 +343,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) { @"Update Shape Source: Features", @"Style Vector Source", @"Style Raster Source", - [NSString stringWithFormat:@"Label Countries in %@", (_usingLocaleBasedCountryLabels ? @"Local Language" : [[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:[self bestLanguageForUser]])], + [NSString stringWithFormat:@"Show Labels in %@", (_usingLocaleBasedCountryLabels ? @"Local Language" : [[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:[self bestLanguageForUser]])], @"Add Route Line", @"Dynamically Style Polygon", ]]; @@ -1274,7 +1274,8 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) { -(void)styleCountryLabelsLanguage { - [self.mapView.style setLocalizesLabels:YES]; + _usingLocaleBasedCountryLabels = !_usingLocaleBasedCountryLabels; + self.mapView.style.localizesLabels = _usingLocaleBasedCountryLabels; } - (void)styleRouteLine diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index b9b87fee7a..1af3c03d68 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -2,7 +2,7 @@ ## 0.5.1 -* Added support to adapt Mapbox Streets–sourced layers for user preferred language. ([#9582](https://github.com/mapbox/mapbox-gl-native/pull/9582)) +* Added an MGLStyle.localizesLabels property, off by default, that localizes any Mapbox Streets–sourced symbol layer into the user’s preferred language. ([#9582](https://github.com/mapbox/mapbox-gl-native/pull/9582)) ## 0.5.0 diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index 0cda78b5fa..1d22295f50 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -344,7 +344,7 @@ NS_ARRAY_OF(id ) *MBXFlattenedShapes(NS_ARRAY_OF(id