summaryrefslogtreecommitdiff
path: root/platform/darwin/src/MGLStyle.mm
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2018-04-16 15:24:33 -0700
committerGitHub <noreply@github.com>2018-04-16 15:24:33 -0700
commite16ce7d87954e86542e5ef142dbd3aa2e7bc30e4 (patch)
tree2bbb764024ea4bb9f4121ba3356b6ae19622a4e4 /platform/darwin/src/MGLStyle.mm
parent62dd097328c1776cd62208baf6e46b1cd4154a52 (diff)
downloadqtlocation-mapboxgl-e16ce7d87954e86542e5ef142dbd3aa2e7bc30e4.tar.gz
Localize expressions more thoroughly (#11651)
* [ios] Removed changelog entry for Terrarium The broader feature is new to v4.0.0 as well. * [ios, macos] Localize expressions more thoroughly Replaced the MGLStyle.localizesLabels property with a -localizeLabelsIntoLocale: method that allows the caller to specify the locale to localize into. Also exposed a per-expression localization method for developers who want to vary behavior from layer to layer. * [macos] Offer English labels if preferred language is unsupported * [ios, macos] Removed dead code * [ios] Use new localization method in iosapp * [ios, macos] Fixed local name labels * [ios, macos] Convert tokens to key path expressions in stop dictionaries * [ios, macos] Streamlined token upgrading Separated token upgrading into a separate process that only happens as part of the MGLSymbolStyleLayer.text and MGLSymbolStyleLayer.iconImageName properties’ getters, so that it’s easy to remove later when mbgl changes obviate this workaround. Removed the replacesTokens parameter to the expression localization methods. * [ios, macos] Preserve whitespace between tokens * [ios, macos] Moved token replacement to a consistent category Fixed a build warning. * [ios, macos] Replace tokens in all string-typed getters For consistency, replace tokens with key paths in all string-typed style paint and layout properties. * [ios, macos] Test token replacement Added tests for replacement of tokens with key paths in expressions. Fixed token replacement for raw strings in stop dictionaries. Avoid sticking a single string inside an mgl_join: call. * [ios, macos] Test token replacement, localization Added unit tests of token replacement and localization of expressions. Only NSExpression is responsible for resolving the preferred language now, since NSLocale tends to tack a region code onto the locale identifier and the NSExpression method can be called independently anyways. Added a private variation of +[MGLVectorTileSource preferredMapboxStreetsLanguage] that takes an array of preferred languages. Fixed localization of non-expressions in stop dictionaries. * [ios, macos] Dictionary keys aren’t necessarily zoom levels
Diffstat (limited to 'platform/darwin/src/MGLStyle.mm')
-rw-r--r--platform/darwin/src/MGLStyle.mm82
1 files changed, 18 insertions, 64 deletions
diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm
index 0162dbd354..867ac6c451 100644
--- a/platform/darwin/src/MGLStyle.mm
+++ b/platform/darwin/src/MGLStyle.mm
@@ -570,73 +570,27 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles,
#pragma mark Mapbox Streets source introspection
-- (void)setLocalizesLabels:(BOOL)localizesLabels
-{
- if (_localizesLabels != localizesLabels) {
- _localizesLabels = localizesLabels;
- } else {
- return;
- }
+- (void)localizeLabelsIntoLocale:(nullable NSLocale *)locale {
+ NSSet<MGLVectorTileSource *> *streetsSources =
+ [self.sources filteredSetUsingPredicate:
+ [NSPredicate predicateWithBlock:^BOOL(MGLVectorTileSource * _Nullable source, NSDictionary<NSString *, id> * _Nullable bindings) {
+ return [source isKindOfClass:[MGLVectorTileSource class]] && [source isMapboxStreets];
+ }]];
+ NSSet<NSString *> *streetsSourceIdentifiers = [streetsSources valueForKey:@"identifier"];
- if (_localizesLabels) {
- NSString *preferredLanguage = [MGLVectorTileSource preferredMapboxStreetsLanguage];
- NSMutableDictionary *localizedKeysByKeyBySourceIdentifier = [NSMutableDictionary dictionary];
- for (MGLSymbolStyleLayer *layer in self.layers) {
- if (![layer isKindOfClass:[MGLSymbolStyleLayer class]]) {
- continue;
- }
-
- MGLVectorTileSource *source = (MGLVectorTileSource *)[self sourceWithIdentifier:layer.sourceIdentifier];
- if (![source isKindOfClass:[MGLVectorTileSource class]] || !source.mapboxStreets) {
- continue;
- }
-
- NSDictionary *localizedKeysByKey = localizedKeysByKeyBySourceIdentifier[layer.sourceIdentifier];
- if (!localizedKeysByKey) {
- localizedKeysByKey = localizedKeysByKeyBySourceIdentifier[layer.sourceIdentifier] = [source localizedKeysByKeyForPreferredLanguage:preferredLanguage];
- }
-
- NSString *(^stringByLocalizingString)(NSString *) = ^ NSString * (NSString *string) {
- NSMutableString *localizedString = string.mutableCopy;
- [localizedKeysByKey enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull localizedKey, BOOL * _Nonnull stop) {
- NSAssert([key isKindOfClass:[NSString class]], @"key is not a string");
- NSAssert([localizedKey isKindOfClass:[NSString class]], @"localizedKey is not a string");
- [localizedString replaceOccurrencesOfString:[NSString stringWithFormat:@"{%@}", key]
- withString:[NSString stringWithFormat:@"{%@}", localizedKey]
- options:0
- range:NSMakeRange(0, localizedString.length)];
- }];
- return localizedString;
- };
-
- if (layer.text.expressionType == NSConstantValueExpressionType) {
- NSString *textField = layer.text.constantValue;
- NSString *localizingString = stringByLocalizingString(textField);
- if (![textField isEqualToString:localizingString]) {
- MGLTextLanguage *textLanguage = [[MGLTextLanguage alloc] initWithTextLanguage:textField
- updatedTextField:localizingString];
- [self.localizedLayersByIdentifier setObject:@{ textField : textLanguage } forKey:layer.identifier];
- layer.text = [NSExpression expressionForConstantValue:localizingString];
- }
- }
+ for (MGLSymbolStyleLayer *layer in self.layers) {
+ if (![layer isKindOfClass:[MGLSymbolStyleLayer class]]) {
+ continue;
+ }
+ if (![streetsSourceIdentifiers containsObject:layer.sourceIdentifier]) {
+ continue;
}
- } else {
- [self.localizedLayersByIdentifier enumerateKeysAndObjectsUsingBlock:^(NSString *identifier, NSDictionary<NSObject *, MGLTextLanguage *> *textFields, BOOL *done) {
- MGLSymbolStyleLayer *layer = (MGLSymbolStyleLayer *)[self.mapView.style layerWithIdentifier:identifier];
-
- if (layer.text.expressionType == NSConstantValueExpressionType) {
- NSString *textField = layer.text.constantValue;
- [textFields enumerateKeysAndObjectsUsingBlock:^(NSObject *originalLanguage, MGLTextLanguage *textLanguage, BOOL *done) {
- if ([textLanguage.updatedTextField isEqualToString:textField]) {
- layer.text = [NSExpression expressionForConstantValue:textLanguage.originalTextField];
- }
- }];
-
- }
- }];
-
- self.localizedLayersByIdentifier = [NSMutableDictionary dictionary];
+ NSExpression *text = layer.text;
+ NSExpression *localizedText = [text mgl_expressionLocalizedIntoLocale:locale];
+ if (![localizedText isEqual:text]) {
+ layer.text = localizedText;
+ }
}
}