diff --git a/platform/macos/app/Base.lproj/MainMenu.xib b/platform/macos/app/Base.lproj/MainMenu.xib
index 4efb8d4c46f..cb9905d4a1c 100644
--- a/platform/macos/app/Base.lproj/MainMenu.xib
+++ b/platform/macos/app/Base.lproj/MainMenu.xib
@@ -434,6 +434,27 @@
+
+
+
diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m
index c05a85f9601..d2e6a0f810c 100644
--- a/platform/macos/app/MapDocument.m
+++ b/platform/macos/app/MapDocument.m
@@ -64,6 +64,7 @@ @implementation MapDocument {
NSUInteger _droppedPinCounter;
NSNumberFormatter *_spellOutNumberFormatter;
+ BOOL _isLocalizingLabels;
BOOL _showsToolTipsOnDroppedPins;
BOOL _randomizesCursorsOnDroppedPins;
BOOL _isTouringWorld;
@@ -123,10 +124,12 @@ - (void)userDefaultsDidChange:(NSNotification *)notification {
- (void)window:(NSWindow *)window willEncodeRestorableState:(NSCoder *)state {
[state encodeObject:self.mapView.styleURL forKey:@"MBXMapViewStyleURL"];
+ [state encodeBool:_isLocalizingLabels forKey:@"MBXLocalizeLabels"];
}
- (void)window:(NSWindow *)window didDecodeRestorableState:(NSCoder *)state {
self.mapView.styleURL = [state decodeObjectForKey:@"MBXMapViewStyleURL"];
+ _isLocalizingLabels = [state decodeBoolForKey:@"MBXLocalizeLabels"];
}
#pragma mark Services
@@ -325,6 +328,60 @@ - (void)deleteStyleLayersAtArrangedObjectIndexes:(NSIndexSet *)indices {
[self.styleLayersArrayController removeObjectsAtArrangedObjectIndexes:indices];
}
+- (IBAction)setLabelLanguage:(NSMenuItem *)sender {
+ _isLocalizingLabels = sender.tag;
+ [self updateLabels];
+}
+
+- (void)updateLabels {
+ NSString *preferredLanguageCode = self.preferredLanguageCode;
+ NSString *preferredNameToken = _isLocalizingLabels ? [NSString stringWithFormat:@"{name_%@}", preferredLanguageCode] : @"{name}";
+ NSRegularExpression *nameTokenExpression = [NSRegularExpression regularExpressionWithPattern:@"\\{name(?:_\\w{2})?\\}" options:0 error:NULL];
+
+ for (MGLSymbolStyleLayer *layer in self.mapView.style.layers) {
+ if (![layer isKindOfClass:[MGLSymbolStyleLayer class]]) {
+ continue;
+ }
+
+ if ([layer.textField isKindOfClass:[MGLStyleConstantValue class]]) {
+ NSString *textField = [(MGLStyleConstantValue *)layer.textField rawValue];
+ textField = [nameTokenExpression stringByReplacingMatchesInString:textField
+ options:0
+ range:NSMakeRange(0, textField.length)
+ withTemplate:preferredNameToken];
+ layer.textField = [MGLStyleValue valueWithRawValue:textField];
+ } else if ([layer.textField isKindOfClass:[MGLStyleFunction class]]) {
+ MGLStyleFunction *function = (MGLStyleFunction *)layer.textField;
+ NSMutableDictionary *stops = function.stops.mutableCopy;
+ [stops enumerateKeysAndObjectsUsingBlock:^(NSNumber *zoomLevel, MGLStyleConstantValue *stop, BOOL *done) {
+ NSString *textField = stop.rawValue;
+ textField = [nameTokenExpression stringByReplacingMatchesInString:textField
+ options:0
+ range:NSMakeRange(0, textField.length)
+ withTemplate:preferredNameToken];
+ stops[zoomLevel] = [MGLStyleValue valueWithRawValue:textField];
+ }];
+ function.stops = stops;
+ layer.textField = function;
+ }
+ }
+}
+
+- (NSString *)preferredLanguageCode {
+ // Languages supported by Mapbox Streets v10.
+ NSSet *supportedLanguages = [NSSet setWithObjects:@"en", @"es", @"fr", @"de", @"ru", @"zh", nil];
+ NSArray *preferredLanguages = [NSLocale preferredLanguages];
+
+ for (NSString *language in preferredLanguages) {
+ NSString *languageCode = [[NSLocale localeWithLocaleIdentifier:language] objectForKey:NSLocaleLanguageCode];
+ if ([supportedLanguages containsObject:languageCode]) {
+ return languageCode;
+ }
+ }
+
+ return @"en";
+}
+
- (void)applyPendingState {
if (_inheritedStyleURL) {
self.mapView.styleURL = _inheritedStyleURL;
@@ -736,6 +793,14 @@ - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
if (menuItem.action == @selector(deleteStyleLayers:)) {
return self.styleLayersTableView.clickedRow >= 0 || self.styleLayersTableView.selectedRow >= 0;
}
+ if (menuItem.action == @selector(setLabelLanguage:)) {
+ menuItem.state = menuItem.tag == _isLocalizingLabels ? NSOnState: NSOffState;
+ if (menuItem.tag) {
+ NSLocale *locale = [NSLocale localeWithLocaleIdentifier:[NSBundle mainBundle].developmentLocalization];
+ menuItem.title = [locale displayNameForKey:NSLocaleIdentifier value:self.preferredLanguageCode];
+ }
+ return YES;
+ }
if (menuItem.action == @selector(manipulateStyle:)) {
return YES;
}
@@ -922,6 +987,10 @@ - (BOOL)splitView:(NSSplitView *)splitView shouldCollapseSubview:(NSView *)subvi
#pragma mark MGLMapViewDelegate methods
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
+ [self updateLabels];
+}
+
- (BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id )annotation {
return YES;
}