Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[macos] Added option to localize labels
Browse files Browse the repository at this point in the history
Added a setting to macosapp to change all symbol layers in the current style to use the preferred language if available. If the setting is off, change all symbol layers to use local languages.
  • Loading branch information
1ec5 committed Nov 28, 2016
1 parent f611355 commit 83e134e
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 0 deletions.
21 changes: 21 additions & 0 deletions platform/macos/app/Base.lproj/MainMenu.xib
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,27 @@
<action selector="toggleLayers:" target="-1" id="YdA-Mr-MHi"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="8aO-Nm-fxF"/>
<menuItem title="Labels In" id="M7v-B1-vo3">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Labels In" id="gOc-5u-4v5">
<items>
<menuItem title="Local Language" id="hTL-wF-DEs">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="setLabelLanguage:" target="-1" id="Zc4-TL-Cxe"/>
</connections>
</menuItem>
<menuItem title="Preferred Language" tag="1" id="PkP-Ne-ISX">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="setLabelLanguage:" target="-1" id="7Io-iF-xf8"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="qTh-Hu-dGV"/>
</items>
</menu>
</menuItem>
Expand Down
69 changes: 69 additions & 0 deletions platform/macos/app/MapDocument.m
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ @implementation MapDocument {
NSUInteger _droppedPinCounter;
NSNumberFormatter *_spellOutNumberFormatter;

BOOL _isLocalizingLabels;
BOOL _showsToolTipsOnDroppedPins;
BOOL _randomizesCursorsOnDroppedPins;
BOOL _isTouringWorld;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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<NSString *> *)layer.textField rawValue];
textField = [nameTokenExpression stringByReplacingMatchesInString:textField
options:0
range:NSMakeRange(0, textField.length)
withTemplate:preferredNameToken];
layer.textField = [MGLStyleValue<NSString *> valueWithRawValue: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;
textField = [nameTokenExpression stringByReplacingMatchesInString:textField
options:0
range:NSMakeRange(0, textField.length)
withTemplate:preferredNameToken];
stops[zoomLevel] = [MGLStyleValue<NSString *> 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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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 <MGLAnnotation>)annotation {
return YES;
}
Expand Down

0 comments on commit 83e134e

Please sign in to comment.