summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2017-09-09 15:13:52 -0700
committerMinh Nguyễn <mxn@1ec5.org>2017-11-02 15:19:53 -0700
commit0983893ca511a2bb157c41a7c173511c5a4a45f7 (patch)
treef9b2118d46bb979859695ac11bcc98e96a84c294
parentd9fe24176153f14d1c101f48993860ee776cbfb0 (diff)
downloadqtlocation-mapboxgl-0983893ca511a2bb157c41a7c173511c5a4a45f7.tar.gz
[ios] Summarize places, roads after zooming with VoiceOver
After zooming, MGLMapView’s accessibility value now indicates the number of visible roads and lists out a few places visible in the current viewport, starting with the features at the highest z-index (not necessarily the largest or the closest to the center of the view). Avoid saying that no annotations are visible.
-rw-r--r--platform/darwin/src/MGLStyle.mm27
-rw-r--r--platform/darwin/src/MGLStyle_Private.h9
-rw-r--r--platform/ios/resources/Base.lproj/Localizable.strings16
-rw-r--r--platform/ios/resources/en.lproj/Localizable.stringsdict38
-rw-r--r--platform/ios/src/MGLMapView.mm57
5 files changed, 127 insertions, 20 deletions
diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm
index 52efc7a85a..244fb94ef9 100644
--- a/platform/darwin/src/MGLStyle.mm
+++ b/platform/darwin/src/MGLStyle.mm
@@ -638,7 +638,7 @@ static NSURL *MGLStyleURL_trafficNight;
self.URL ? [NSString stringWithFormat:@"\"%@\"", self.URL] : self.URL];
}
-#pragma mark Style language preferences
+#pragma mark Mapbox Streets source introspection
- (void)setLocalizesLabels:(BOOL)localizesLabels
{
@@ -749,4 +749,29 @@ static NSURL *MGLStyleURL_trafficNight;
}
}
+- (NS_SET_OF(MGLVectorSource *) *)mapboxStreetsSources {
+ return [self.sources objectsPassingTest:^BOOL (__kindof MGLVectorSource * _Nonnull source, BOOL * _Nonnull stop) {
+ return [source isKindOfClass:[MGLVectorSource class]] && source.mapboxStreets;
+ }];
+}
+
+- (NS_ARRAY_OF(MGLStyleLayer *) *)placeStyleLayers {
+ NSSet *streetsSourceIdentifiers = [self.mapboxStreetsSources valueForKey:@"identifier"];
+
+ NSSet *placeSourceLayerIdentifiers = [NSSet setWithObjects:@"marine_label", @"country_label", @"state_label", @"place_label", @"water_label", @"poi_label", @"rail_station_label", @"mountain_peak_label", nil];
+ NSPredicate *isPlacePredicate = [NSPredicate predicateWithBlock:^BOOL (MGLVectorStyleLayer * _Nullable layer, NSDictionary<NSString *, id> * _Nullable bindings) {
+ return [layer isKindOfClass:[MGLVectorStyleLayer class]] && [streetsSourceIdentifiers containsObject:layer.sourceIdentifier] && [placeSourceLayerIdentifiers containsObject:layer.sourceLayerIdentifier];
+ }];
+ return [self.layers filteredArrayUsingPredicate:isPlacePredicate];
+}
+
+- (NS_ARRAY_OF(MGLStyleLayer *) *)roadStyleLayers {
+ NSSet *streetsSourceIdentifiers = [self.mapboxStreetsSources valueForKey:@"identifier"];
+
+ NSPredicate *isPlacePredicate = [NSPredicate predicateWithBlock:^BOOL (MGLVectorStyleLayer * _Nullable layer, NSDictionary<NSString *, id> * _Nullable bindings) {
+ return [layer isKindOfClass:[MGLVectorStyleLayer class]] && [streetsSourceIdentifiers containsObject:layer.sourceIdentifier] && [layer.sourceLayerIdentifier isEqualToString:@"road_label"];
+ }];
+ return [self.layers filteredArrayUsingPredicate:isPlacePredicate];
+}
+
@end
diff --git a/platform/darwin/src/MGLStyle_Private.h b/platform/darwin/src/MGLStyle_Private.h
index 92b08e844b..e5bd79dc02 100644
--- a/platform/darwin/src/MGLStyle_Private.h
+++ b/platform/darwin/src/MGLStyle_Private.h
@@ -14,6 +14,8 @@ namespace mbgl {
@class MGLAttributionInfo;
@class MGLMapView;
@class MGLOpenGLStyleLayer;
+@class MGLVectorSource;
+@class MGLVectorStyleLayer;
@interface MGLStyle (Private)
@@ -30,4 +32,11 @@ namespace mbgl {
@end
+@interface MGLStyle (MGLStreetsAdditions)
+
+@property (nonatomic, readonly, copy) NS_ARRAY_OF(MGLVectorStyleLayer *) *placeStyleLayers;
+@property (nonatomic, readonly, copy) NS_ARRAY_OF(MGLVectorStyleLayer *) *roadStyleLayers;
+
+@end
+
NS_ASSUME_NONNULL_END
diff --git a/platform/ios/resources/Base.lproj/Localizable.strings b/platform/ios/resources/Base.lproj/Localizable.strings
index 3f59262d71..815f7a3498 100644
--- a/platform/ios/resources/Base.lproj/Localizable.strings
+++ b/platform/ios/resources/Base.lproj/Localizable.strings
@@ -34,6 +34,9 @@
/* Accessibility label */
"INFO_A11Y_LABEL" = "About this map";
+/* List separator */
+"LIST_SEPARATOR" = ", ";
+
/* User-friendly error description */
"LOAD_MAP_FAILED_DESC" = "The map failed to load because an unknown error occurred.";
@@ -46,8 +49,17 @@
/* Accessibility label */
"MAP_A11Y_LABEL" = "Map";
-/* Map accessibility value */
-"MAP_A11Y_VALUE" = "Zoom %1$dx\n%2$ld annotation(s) visible";
+/* Map accessibility value; {number of visible annotations} */
+"MAP_A11Y_VALUE_ANNOTATIONS" = "%ld annotation(s) visible.";
+
+/* Map accessibility value; {list of visible places} */
+"MAP_A11Y_VALUE_PLACES" = "Places visible: %@.";
+
+/* Map accessibility value; {number of visible roads} */
+"MAP_A11Y_VALUE_ROADS" = "%ld road(s) visible.";
+
+/* Map accessibility value; {zoom level} */
+"MAP_A11Y_VALUE_ZOOM" = "Zoom %dx.";
/* User-friendly error description */
"PARSE_STYLE_FAILED_DESC" = "The map failed to load because the style is corrupted.";
diff --git a/platform/ios/resources/en.lproj/Localizable.stringsdict b/platform/ios/resources/en.lproj/Localizable.stringsdict
index e849318fe5..435b7bdfe8 100644
--- a/platform/ios/resources/en.lproj/Localizable.stringsdict
+++ b/platform/ios/resources/en.lproj/Localizable.stringsdict
@@ -2,22 +2,26 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
- <key>MAP_A11Y_VALUE</key>
+ <key>MAP_A11Y_VALUE_ANNOTATIONS</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
- <string>%#@level@
-%#@count@</string>
- <key>level</key>
+ <string>%#@count@</string>
+ <key>count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
- <string>d</string>
+ <string>ld</string>
<key>one</key>
- <string>Zoom %dx</string>
+ <string>%d annotation visible</string>
<key>other</key>
- <string>Zoom %dx</string>
+ <string>%d annotations visible</string>
</dict>
+ </dict>
+ <key>MAP_A11Y_VALUE_ROADS</key>
+ <dict>
+ <key>NSStringLocalizedFormatKey</key>
+ <string>%#@count@</string>
<key>count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
@@ -25,9 +29,25 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
- <string>%d annotation visible</string>
+ <string>%d road visible</string>
<key>other</key>
- <string>%d annotations visible</string>
+ <string>%d roads visible</string>
+ </dict>
+ </dict>
+ <key>MAP_A11Y_VALUE_ZOOM</key>
+ <dict>
+ <key>NSStringLocalizedFormatKey</key>
+ <string>%#@level@</string>
+ <key>level</key>
+ <dict>
+ <key>NSStringFormatSpecTypeKey</key>
+ <string>NSStringPluralRuleType</string>
+ <key>NSStringFormatValueTypeKey</key>
+ <string>d</string>
+ <key>one</key>
+ <string>Zoom %dx</string>
+ <key>other</key>
+ <string>Zoom %dx</string>
</dict>
</dict>
</dict>
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index ed51754b0a..630688f05a 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -43,6 +43,7 @@
#import "MGLFoundation_Private.h"
#import "MGLRendererFrontend.h"
+#import "MGLVectorSource+MGLAdditions.h"
#import "NSBundle+MGLAdditions.h"
#import "NSDate+MGLAdditions.h"
#import "NSException+MGLAdditions.h"
@@ -2355,8 +2356,53 @@ public:
- (NSString *)accessibilityValue
{
+ NSMutableArray *facts = [NSMutableArray array];
+
double zoomLevel = round(self.zoomLevel + 1);
- return [NSString stringWithFormat:NSLocalizedStringWithDefaultValue(@"MAP_A11Y_VALUE", nil, nil, @"Zoom %dx\n%ld annotation(s) visible", @"Map accessibility value"), (int)zoomLevel, (long)self.accessibilityAnnotationCount];
+ [facts addObject:[NSString stringWithFormat:NSLocalizedStringWithDefaultValue(@"MAP_A11Y_VALUE_ZOOM", nil, nil, @"Zoom %dx.", @"Map accessibility value; {zoom level}"), (int)zoomLevel]];
+
+ NSInteger annotationCount = self.accessibilityAnnotationCount;
+ if (annotationCount) {
+ [facts addObject:[NSString stringWithFormat:NSLocalizedStringWithDefaultValue(@"MAP_A11Y_VALUE_ANNOTATIONS", nil, nil, @"%ld annotation(s) visible.", @"Map accessibility value; {number of visible annotations}"), (long)self.accessibilityAnnotationCount]];
+ }
+
+ NSArray *placeFeatures = self.visiblePlaceFeatures;
+ if (placeFeatures.count) {
+ NSMutableArray *placesArray = [NSMutableArray arrayWithCapacity:placeFeatures.count];
+ NSMutableSet *placesSet = [NSMutableSet setWithCapacity:placeFeatures.count];
+ for (id <MGLFeature> placeFeature in placeFeatures.reverseObjectEnumerator) {
+ NSString *name = [placeFeature attributeForKey:@"name"];
+ if (![placesSet containsObject:name]) {
+ [placesArray addObject:name];
+ [placesSet addObject:name];
+ }
+ if (placesArray.count >= 3) {
+ break;
+ }
+ }
+ NSString *placesString = [placesArray componentsJoinedByString:NSLocalizedStringWithDefaultValue(@"LIST_SEPARATOR", nil, nil, @", ", @"List separator")];
+ [facts addObject:[NSString stringWithFormat:NSLocalizedStringWithDefaultValue(@"MAP_A11Y_VALUE_PLACES", nil, nil, @"Places visible: %@.", @"Map accessibility value; {list of visible places}"), placesString]];
+ }
+
+ NSArray *roadFeatures = self.visibleRoadFeatures;
+ if (roadFeatures.count) {
+ [facts addObject:[NSString stringWithFormat:NSLocalizedStringWithDefaultValue(@"MAP_A11Y_VALUE_ROADS", nil, nil, @"%ld road(s) visible.", @"Map accessibility value; {number of visible roads}"), roadFeatures.count]];
+ }
+
+ NSString *value = [facts componentsJoinedByString:@" "];
+ return value;
+}
+
+- (NS_ARRAY_OF(id <MGLFeature>) *)visiblePlaceFeatures
+{
+ NSArray *placeStyleLayerIdentifiers = [self.style.placeStyleLayers valueForKey:@"identifier"];
+ return [self visibleFeaturesInRect:self.bounds inStyleLayersWithIdentifiers:[NSSet setWithArray:placeStyleLayerIdentifiers]];
+}
+
+- (NS_ARRAY_OF(id <MGLFeature>) *)visibleRoadFeatures
+{
+ NSArray *roadStyleLayerIdentifiers = [self.style.roadStyleLayers valueForKey:@"identifier"];
+ return [self visibleFeaturesInRect:self.bounds inStyleLayersWithIdentifiers:[NSSet setWithArray:roadStyleLayerIdentifiers]];
}
- (CGRect)accessibilityFrame
@@ -2390,14 +2436,9 @@ public:
{
if (self.calloutViewForSelectedAnnotation)
{
- return 2 /* selectedAnnotationCalloutView, mapViewProxyAccessibilityElement */;
- }
- NSInteger count = self.accessibilityAnnotationCount + 2 /* compass, attributionButton */;
- if (self.userLocationAnnotationView)
- {
- count++;
+ return 2 /* calloutViewForSelectedAnnotation, mapViewProxyAccessibilityElement */;
}
- return count;
+ return !!self.userLocationAnnotationView + self.accessibilityAnnotationCount + self.visiblePlaceFeatures.count + 2 /* compass, attributionButton */;
}
- (NSInteger)accessibilityAnnotationCount