diff options
author | Minh Nguyễn <mxn@1ec5.org> | 2016-12-23 00:38:26 -0800 |
---|---|---|
committer | Minh Nguyễn <mxn@1ec5.org> | 2017-07-14 12:41:00 -0700 |
commit | 3830f6878c8d83eb411981496e55451c94f75489 (patch) | |
tree | f41542fce4927b0c68638a420b992444c1c0206a | |
parent | a019f26d99449d6b9fb9a03471c90443f8d033b7 (diff) | |
download | qtlocation-mapboxgl-upstream/1ec5-hani-switch-demo.tar.gz |
[ios, macos] Force Chinese labelsupstream/1ec5-hani-switch-demo
Force labels to be displayed in Chinese. The toggle for localizing or not localizing labels now switches between Traditional Chinese and Simplified Chinese by piggybacking on the text-transform property, which is implemented using NSString APIs.
-rw-r--r-- | platform/darwin/src/string_nsstring.mm | 10 | ||||
-rw-r--r-- | platform/ios/app/MBXViewController.m | 106 | ||||
-rw-r--r-- | platform/macos/app/MapDocument.m | 35 |
3 files changed, 70 insertions, 81 deletions
diff --git a/platform/darwin/src/string_nsstring.mm b/platform/darwin/src/string_nsstring.mm index 08f9aeccef..a50cce488e 100644 --- a/platform/darwin/src/string_nsstring.mm +++ b/platform/darwin/src/string_nsstring.mm @@ -10,9 +10,8 @@ std::string uppercase(const std::string &string) { length:string.size() encoding:NSUTF8StringEncoding freeWhenDone:NO]; - NSString *uppercase = [original uppercaseString]; - const std::string result{[uppercase cStringUsingEncoding : NSUTF8StringEncoding], - [uppercase lengthOfBytesUsingEncoding:NSUTF8StringEncoding]}; + NSString *uppercase = [[original uppercaseString] stringByApplyingTransform:@"Hans-Hant" reverse:NO]; + const std::string result{ uppercase.UTF8String }; return result; } @@ -21,9 +20,8 @@ std::string lowercase(const std::string &string) { length:string.size() encoding:NSUTF8StringEncoding freeWhenDone:NO]; - NSString *lowercase = [original lowercaseString]; - const std::string result{[lowercase cStringUsingEncoding : NSUTF8StringEncoding], - [lowercase lengthOfBytesUsingEncoding:NSUTF8StringEncoding]}; + NSString *lowercase = [[original lowercaseString] stringByApplyingTransform:@"Hant-Hans" reverse:NO]; + const std::string result{ lowercase.UTF8String }; return result; } diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index 29c5c65012..3885947cdd 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -118,7 +118,6 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) { @property (nonatomic) NSInteger styleIndex; @property (nonatomic) BOOL debugLoggingEnabled; @property (nonatomic) BOOL customUserLocationAnnnotationEnabled; -@property (nonatomic) BOOL usingLocaleBasedCountryLabels; @property (nonatomic) BOOL reuseQueueStatsEnabled; @property (nonatomic) BOOL showZoomLevelEnabled; @@ -126,7 +125,6 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) { @interface MGLMapView (MBXViewController) -@property (nonatomic) BOOL usingLocaleBasedCountryLabels; @property (nonatomic) NSDictionary *annotationViewReuseQueueByIdentifier; @end @@ -134,6 +132,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) { @implementation MBXViewController { BOOL _isTouringWorld; + BOOL _isTraditional; } #pragma mark - Setup & Teardown @@ -324,7 +323,8 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) { @"Remove Annotations", ]]; break; - case MBXSettingsRuntimeStyling: + case MBXSettingsRuntimeStyling: { + NSLocale *locale = [NSLocale localeWithLocaleIdentifier:[NSBundle mainBundle].developmentLocalization]; [settingsTitles addObjectsFromArray:@[ @"Add Building Extrusions", @"Style Water With Function", @@ -347,11 +347,12 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) { @"Style Vector Source", @"Style Raster Source", @"Style Image Source", - [NSString stringWithFormat:@"Label Countries in %@", (_usingLocaleBasedCountryLabels ? @"Local Language" : [[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:[self bestLanguageForUser]])], + [NSString stringWithFormat:@"Label Countries in %@", [[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:_isTraditional ? @"zh-Hans" : @"zh-Hant"]], @"Add Route Line", @"Dynamically Style Polygon", ]]; break; + } case MBXSettingsMiscellaneous: [settingsTitles addObjectsFromArray:@[ [NSString stringWithFormat:@"%@ Reuse Queue Stats", (_reuseQueueStatsEnabled ? @"Hide" :@"Show")], @@ -591,7 +592,8 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) { [self styleImageSource]; break; case MBXSettingsRuntimeStylingCountryLabels: - [self styleCountryLabelsLanguage]; + _isTraditional = !_isTraditional; + [self updateLabels]; break; case MBXSettingsRuntimeStylingRouteLine: [self styleRouteLine]; @@ -1346,16 +1348,6 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) { } } --(void)styleCountryLabelsLanguage -{ - NSArray<NSString *> *labelLayers = @[ - @"country-label-lg", - @"country-label-md", - @"country-label-sm", - ]; - [self styleLabelLanguageForLayersNamed:labelLayers]; -} - - (void)styleRouteLine { CLLocationCoordinate2D coords[] = { @@ -1436,55 +1428,44 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) { [self.mapView.style addLayer:fillStyleLayer]; } -- (void)styleLabelLanguageForLayersNamed:(NSArray<NSString *> *)layers +- (void)updateLabels { - _usingLocaleBasedCountryLabels = !_usingLocaleBasedCountryLabels; - NSString *bestLanguageForUser = [NSString stringWithFormat:@"{name_%@}", [self bestLanguageForUser]]; - NSString *language = _usingLocaleBasedCountryLabels ? bestLanguageForUser : @"{name}"; - - for (NSString *layerName in layers) { - MGLSymbolStyleLayer *layer = (MGLSymbolStyleLayer *)[self.mapView.style layerWithIdentifier:layerName]; - - if ([layer isKindOfClass:[MGLSymbolStyleLayer class]]) { - if ([layer.text isKindOfClass:[MGLConstantStyleValue class]]) { - MGLConstantStyleValue *label = (MGLConstantStyleValue<NSString *> *)layer.text; - if ([label.rawValue hasPrefix:@"{name"]) { - layer.text = [MGLStyleValue valueWithRawValue:language]; - } - } - else if ([layer.text isKindOfClass:[MGLCameraStyleFunction class]]) { - MGLCameraStyleFunction *function = (MGLCameraStyleFunction<NSString *> *)layer.text; - NSMutableDictionary *stops = function.stops.mutableCopy; - [stops enumerateKeysAndObjectsUsingBlock:^(NSNumber *zoomLevel, MGLConstantStyleValue<NSString *> *stop, BOOL *done) { - if ([stop.rawValue hasPrefix:@"{name"]) { - stops[zoomLevel] = [MGLStyleValue<NSString *> valueWithRawValue:language]; - } - }]; - function.stops = stops; - layer.text = function; - } - } else { - NSLog(@"%@ is not a symbol style layer", layerName); + for (MGLSymbolStyleLayer *layer in self.mapView.style.layers) { + if (![layer isKindOfClass:[MGLSymbolStyleLayer class]]) { + continue; } - } -} - -- (NSString *)bestLanguageForUser -{ - // https://www.mapbox.com/vector-tiles/mapbox-streets-v7/#overview - NSArray *supportedLanguages = @[ @"ar", @"en", @"es", @"fr", @"de", @"pt", @"ru", @"zh", @"zh-Hans" ]; - NSArray<NSString *> *preferredLanguages = [NSBundle preferredLocalizationsFromArray:supportedLanguages forPreferences:[NSLocale preferredLanguages]]; - NSString *mostSpecificLanguage; - - for (NSString *language in preferredLanguages) - { - if (language.length > mostSpecificLanguage.length) - { - mostSpecificLanguage = language; + + NSString *(^stringByLocalizingString)(NSString *) = ^ NSString * (NSString *string) { + return [[string stringByReplacingOccurrencesOfString:@"{name}" withString:@"{name_zh}"] + stringByReplacingOccurrencesOfString:@"{name_en}" withString:@"{name_zh}"]; + }; + + if ([layer.textField isKindOfClass:[MGLStyleConstantValue class]]) { + NSString *textField = [(MGLStyleConstantValue<NSString *> *)layer.textField rawValue]; + layer.textField = [MGLStyleValue<NSString *> valueWithRawValue:stringByLocalizingString(textField)]; + } else if ([layer.textField isKindOfClass:[MGLStyleFunction class]]) { + MGLStyleFunction *function = (MGLStyleFunction<NSString *> *)layer.textField; + NSMutableDictionary *stops = function.stops.mutableCopy; + [stops enumerateKeysAndObjectsUsingBlock:^(NSNumber *zoomLevel, MGLStyleConstantValue<NSString *> *stop, BOOL *done) { + NSString *textField = stop.rawValue; + stops[zoomLevel] = [MGLStyleValue<NSString *> valueWithRawValue:stringByLocalizingString(textField)]; + }]; + function.stops = stops; + layer.textField = function; + } + + if ([layer.textTransform isKindOfClass:[MGLStyleConstantValue class]]) { + layer.textTransform = [MGLStyleValue<NSValue *> valueWithRawValue:[NSValue valueWithMGLTextTransform:_isTraditional ? MGLTextTransformUppercase : MGLTextTransformLowercase]]; + } else if ([layer.textTransform isKindOfClass:[MGLStyleFunction class]]) { + MGLStyleFunction *function = (MGLStyleFunction<NSValue *> *)layer.textTransform; + NSMutableDictionary *stops = function.stops.mutableCopy; + [stops enumerateKeysAndObjectsUsingBlock:^(NSNumber *zoomLevel, MGLStyleConstantValue<NSValue *> *stop, BOOL *done) { + stops[zoomLevel] = [MGLStyleValue<NSValue *> valueWithRawValue:[NSValue valueWithMGLTextTransform:_isTraditional ? MGLTextTransformUppercase : MGLTextTransformLowercase]]; + }]; + function.stops = stops; + layer.textTransform = function; } } - - return mostSpecificLanguage ?: @"en"; } - (IBAction)startWorldTour @@ -1896,10 +1877,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) { - (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style { - // Default Mapbox styles use {name_en} as their label language, which means - // that a device with an English-language locale is already effectively - // using locale-based country labels. - _usingLocaleBasedCountryLabels = [[self bestLanguageForUser] isEqualToString:@"en"]; + [self updateLabels]; } - (void)mapViewRegionIsChanging:(MGLMapView *)mapView diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index 94bf18dea1..cc5d5d0f97 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -66,8 +66,8 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio NSPoint _mouseLocationForMapViewContextMenu; NSUInteger _droppedPinCounter; NSNumberFormatter *_spellOutNumberFormatter; - - BOOL _isLocalizingLabels; + + BOOL _isTraditional; BOOL _showsToolTipsOnDroppedPins; BOOL _randomizesCursorsOnDroppedPins; BOOL _isTouringWorld; @@ -127,12 +127,12 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio - (void)window:(NSWindow *)window willEncodeRestorableState:(NSCoder *)state { [state encodeObject:self.mapView.styleURL forKey:@"MBXMapViewStyleURL"]; - [state encodeBool:_isLocalizingLabels forKey:@"MBXLocalizeLabels"]; + [state encodeBool:_isTraditional forKey:@"MBXLocalizeLabels"]; } - (void)window:(NSWindow *)window didDecodeRestorableState:(NSCoder *)state { self.mapView.styleURL = [state decodeObjectForKey:@"MBXMapViewStyleURL"]; - _isLocalizingLabels = [state decodeBoolForKey:@"MBXLocalizeLabels"]; + _isTraditional = [state decodeBoolForKey:@"MBXLocalizeLabels"]; } #pragma mark Services @@ -339,13 +339,13 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio } - (IBAction)setLabelLanguage:(NSMenuItem *)sender { - _isLocalizingLabels = sender.tag; + _isTraditional = sender.tag; [self reload:sender]; } - (void)updateLabels { MGLStyle *style = self.mapView.style; - NSString *preferredLanguage = _isLocalizingLabels ? [MGLVectorSource preferredMapboxStreetsLanguage] : nil; + NSString *preferredLanguage = @"zh"; NSMutableDictionary *localizedKeysByKeyBySourceIdentifier = [NSMutableDictionary dictionary]; for (MGLSymbolStyleLayer *layer in style.layers) { if (![layer isKindOfClass:[MGLSymbolStyleLayer class]]) { @@ -389,6 +389,18 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio function.stops = stops; layer.text = function; } + + if ([layer.textTransform isKindOfClass:[MGLStyleConstantValue class]]) { + layer.textTransform = [MGLStyleValue<NSValue *> valueWithRawValue:[NSValue valueWithMGLTextTransform:_isTraditional ? MGLTextTransformUppercase : MGLTextTransformLowercase]]; + } else if ([layer.textTransform isKindOfClass:[MGLStyleFunction class]]) { + MGLStyleFunction *function = (MGLStyleFunction<NSValue *> *)layer.textTransform; + NSMutableDictionary *stops = function.stops.mutableCopy; + [stops enumerateKeysAndObjectsUsingBlock:^(NSNumber *zoomLevel, MGLStyleConstantValue<NSValue *> *stop, BOOL *done) { + stops[zoomLevel] = [MGLStyleValue<NSValue *> valueWithRawValue:[NSValue valueWithMGLTextTransform:_isTraditional ? MGLTextTransformUppercase : MGLTextTransformLowercase]]; + }]; + function.stops = stops; + layer.textTransform = function; + } } } @@ -795,7 +807,7 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio NSString *title; for (id <MGLFeature> feature in features) { if (!title) { - title = [feature attributeForKey:@"name_en"] ?: [feature attributeForKey:@"name"]; + title = [feature attributeForKey:@"name_zh"] ?: [feature attributeForKey:@"name"]; } } @@ -903,11 +915,12 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio return self.styleLayersTableView.clickedRow >= 0 || self.styleLayersTableView.selectedRow >= 0; } if (menuItem.action == @selector(setLabelLanguage:)) { - menuItem.state = menuItem.tag == _isLocalizingLabels ? NSOnState: NSOffState; + menuItem.state = menuItem.tag == _isTraditional ? NSOnState: NSOffState; + NSLocale *locale = [NSLocale localeWithLocaleIdentifier:[NSBundle mainBundle].developmentLocalization]; if (menuItem.tag) { - NSLocale *locale = [NSLocale localeWithLocaleIdentifier:[NSBundle mainBundle].developmentLocalization]; - NSString *preferredLanguage = [MGLVectorSource preferredMapboxStreetsLanguage]; - menuItem.title = [locale displayNameForKey:NSLocaleIdentifier value:preferredLanguage]; + menuItem.title = [locale displayNameForKey:NSLocaleIdentifier value:@"zh-Hant"]; + } else { + menuItem.title = [locale displayNameForKey:NSLocaleIdentifier value:@"zh-Hans"]; } return YES; } |