-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Make places and roads accessible to VoiceOver #9950
Conversation
1464eac
to
66e0f5b
Compare
9cfa995
to
e7112fb
Compare
e7112fb
to
d913f4b
Compare
I’m not very familiar with VoiceOver, but in terms of usability:
|
typedef struct { | ||
MGLLocationRadians latitude; | ||
MGLLocationRadians longitude; | ||
} MGLRadianCoordinate2D; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the difference between this struct and https://github.com/mapbox/mapbox-gl-native/blob/master/platform/darwin/src/MGLGeometry_Private.h#L17?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I completely forgot we had implemented this in #9110. Yes, I’ll add this to the to-do list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually it was #8713 😜
MGLLocationRadians longitude; | ||
} MGLRadianCoordinate2D; | ||
|
||
MGLRadianCoordinate2D MGLRadianCoordinate2DMake(MGLLocationRadians latitude, MGLLocationRadians longitude) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have defined this function in https://github.com/mapbox/mapbox-gl-native/blob/master/platform/darwin/src/MGLGeometry_Private.h#L25
} | ||
|
||
/** Returns the direction from one coordinate to another. */ | ||
CLLocationDirection MGLDirectionBetweenCoordinates(CLLocationCoordinate2D firstCoordinate, CLLocationCoordinate2D secondCoordinate) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tapping an element isn’t the normal mode of operation for VoiceOver. When the focus goes back to the first element on screen (which just happens to be the Settings button in iosapp), swipe rightward repeatedly to navigate through the accessibility elements. For best results, enable user location tracking.
I wonder how this compares to master with VoiceOver enabled. Unfortunately, it is expected that performance with VoiceOver enabled is poorer than with VoiceOver disabled when there are many accessibility elements. In particular, the only difference between no annotations and 100 view-backed annotations should be the cost of querying the map for visible annotations; the map view leaves the annotation views in charge of providing accessibility information about themselves. |
One thing I need to look into is that, after zooming in or out, the listed places and roads sometimes reflect the previous zoom level. I think this may be a race condition where feature querying kicks off before the map finishes loading at the new zoom level. |
Fixed in 8e135a8. |
54bb912
to
0546cda
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍🏼
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.
Split out a separate header for the various accessibility elements tied to MGLMapView. Wrap place features in accessibility elements and insert them into the narration order after the visible annotations but before the attribution button. Refactored MGLMapView’s accessibility code to rely on ranges to avoid off-by-one errors.
Post a layout change notification when fully finishing a map render.
Also created a new MGLPlaceFeatureAccessibilityElement class.
Sort annotation accessibility elements by screen distance, not the hypotenuse of coordinates, which can yield incorrect results when the map is rotated or tilted or when the user is located at high latitudes. Sort place feature accessibility elements by screen distance as well.
…eature accessibility element
Improved accessibility performance after changing the map camera. MGLMapView no longer queries the map for place features once per place feature.
Wrap visible road features in accessibility elements described by the road name, route number, and general direction of travel.
Also fixed an issue causing road feature accessibility elements to get treated like place feature accessibility elements.
Announce the direction of a divided road based on the direction of its first polyline.
A 100-millisecond delay is enough for the post-zooming announcement to reflect the new zoom level rather than the previous zoom level.
Adopted MGLGeometry_Private.h in the accessibility code, forcing a conversion to Objective-C++. Avoid inlining some of the more complex geometric functions.
0546cda
to
b8e7ef5
Compare
NSLocale.scriptCode is only set when the locale identifier explicitly specifies a script. Use NSOrthography to identify the dominant orthography regardless of locale. Also added a unit test of feature accessibility element labels.
A road feature’s accessibility value now indicates whether the road is a one-way road.
After zooming in or out using VoiceOver’s one-finger upward or downward swipe gestures, MGLMapView now summarize the visible places and roads in addition to announcing the new zoom level. The places and roads are all part of the list of accessibility elements within the map view’s container, so the user can now navigate among these features to get a better sense of the map’s contents.
“Café du Monde: cafe”
“Orleans Ave: divided road, northwest to southeast”
“Denali: mountain, 20,313 feet”
These features work in any style that uses the Mapbox Streets source in at least one layer, and it’s mostly localizable (although some parts of the readout are dependent on open-ended OpenStreetMap tags, which are in English). For screen recordings of these features, see this blog post.
Along the way, the annotation accessibility element code has been refactored for better reliability, and the annotations are now sorted by proper geographic distance.
There remain a few problems with this feature, primarily that some of the roads seem to go in and out of the container chain:More to come:
Fixes #4821.
/cc @fabian-guerra @friedbunny