Merge pull request #8 from usds/geospatial_comparison

Adding first Architecture Decision Record (ADR) to decide on a visualization library
This commit is contained in:
Nat Hillard 2021-05-04 10:46:34 -04:00 committed by GitHub
commit ab6b57271b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 297 additions and 0 deletions

1
.adr-dir Normal file
View file

@ -0,0 +1 @@
docs/decisions

View file

@ -0,0 +1,19 @@
# 1. Record architecture decisions
Date: 2021-04-21
## Status
Accepted
## Context
We need to record the architectural decisions made on this project.
## Decision
We will use Architecture Decision Records, as [described by Michael Nygard](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions).
## Consequences
See Michael Nygard's article, linked above. For a lightweight ADR toolset, see Nat Pryce's [adr-tools](https://github.com/npryce/adr-tools).

View file

@ -0,0 +1,182 @@
# Mapping Visualization Library
- Status: draft
- Deciders: Lucas Brown, Shelby Switzer, Nat Hillard
- Date: 2021-04-21
- Tags: frontend
Technical Story: [#7](https://github.com/usds/environmental-justice/issues/7)
## Context and Problem Statement
In order to visualize the metrics of the Justice 40 initiative, we need a client-side mapping solution. This solution should should reflect the values of our initiative, and it should reflect and respond to the diverse needs of our users.
**Team Values**: The solution should be open-source, modular, and adopt modern best practices.
**User needs**: The solution should be performant, accessible, internationalized/localized, and minimize data usage.
We provide more detail on these factors below.
## Decision Drivers
### Team Values
- **Open source** : Our technology choices should "default to open" as detailed in the [Digital Services Playbook](https://playbook.cio.gov/#play13), in order to encourage community contribution, minimize vendor lock-in, and lower the barrier to entry to participate in the development of the tool. Ideally such a solution should be be true [Free and Open Source Software](https://en.wikipedia.org/wiki/Free_and_open-source_software), licensed for use, copy, and modification as well as source code-visible.
- **Ease of implementation** : In the name of welcoming a large body of open-source contributors, our implementation should not require too significant insider knowledge of mapping or GIS systems. At the same time, more advanced functionality should be familiar to those who do have such backgrounds, to enable them to contribute expertise where warranted. Additionally, it should be possible to get an environment up and running locally without a necessary API key or other paid plan.
- **Modular** : we should minimize vendor lock-in and allow for mixing and matching solutions from different providers -- from server-vended tiling solutions to tile storage and basemaps -- in order to optimize user experience and find the best tool for the job at all layers of the stack.
- **Modern** : the library should allow for its work to be done entirely in the browser; it should provide the ability to load on demand (in binary, protobuf [format](https://github.com/mapbox/vector-tile-spec)) and visualize so-called [vector tiles](https://en.wikipedia.org/wiki/Vector_tiles) to make use of the rendering power of [WebGL](https://www.khronos.org/webgl/); and it should provide for client-side dynamic map styling according to relevant [standards](https://docs.mapbox.com/mapbox-gl-js/style-spec/) as opposed to just server-side pre-rendering of raster tiles.
### User Needs
- **Performant** : Library should be performant on a range of device types, enabling fast load times and ease of navigation in a highly-complex rendering environment where there may be hundreds of thousands of features.
- **Accessible** : the implementation we build with this library must be compliant according to [section 508](https://www.section508.gov/) of the Rehabilitation Act [(29 U.S.C. § 794d)](https://www.govinfo.gov/content/pkg/USCODE-2011-title29/html/USCODE-2011-title29-chap16-subchapV-sec794d.htm), as well as [Section 501](https://www.eeoc.gov/statutes/rehabilitation-act-1973) guidance regarding Reasonable Accommodation per US federal government legal requirements. Ideally it should adopt [Web Content Accessibility Guidelines](https://www.w3.org/WAI/standards-guidelines/wcag/) to at least the AA level. The library our solution builds upon should provide some of this out of the box.
- **Internationalized/Localized** : Nearly [22%](https://data.census.gov/cedsci/table?q=B16001&hidePreview=false&tid=ACSDT1Y2017.B16001&vintage=2018) of the US population speaks a language other than English at home. Our mapping solution should be familiar and easy to use by this population.
- **Minimizes network usage** : Where possible, we should seek to minimize network usage to ensure lower data usage costs and faster load times.
## Considered Options
1. [Mapbox GL JS](https://github.com/mapbox/mapbox-gl-js) - v2.2.0 (3/25/21)
2. [MapLibre GL JS](https://github.com/maplibre/maplibre-gl-js) - v1.14.0 (3/24/21)
3. [Leaflet](https://github.com/Leaflet/Leaflet) - v1.7.1 (9/4/20) + [Leaflet.VectorGrid](https://github.com/Leaflet/Leaflet.VectorGrid) - v1.3.0 (2017)
4. [OpenLayers](https://github.com/openlayers/openlayers) - v6.5.0 (12/27/20)
5. [ArcGIS API for Javascript](https://developers.arcgis.com/javascript/latest/) - v4.18 (12/2020)
## Not Considered Options
- Non-ArcGIS-JS-API Esri [products](https://www.esri.com/en-us/arcgis/products/index) - The focus of this investigation is web APIs that can be incorporated into a website and rendered as part of a cloud-based, modular web-development flow. Additionally, these are not open source.
- [Google Maps Platform](https://developers.google.com/maps)/[Bing Maps APIs](https://www.microsoft.com/en-us/maps/choose-your-bing-maps-api) - These mapping are also closed source and proprietary, and do not allow for significant customization or visualization of the sort we would need for this product
- [d3.js](https://d3js.org/) - though impressive in its offerings and performance, d3 appears more oriented to more general-purpose infographic use than a mapping-specific product requiring significant GIS-adjacent features. We may consider aspects of D3 for particular chart renderings.
## Decision Outcome
**OpenLayers** ([Source](https://github.com/openlayers/openlayers) - v6.5.0 (12/27/20)). This library is completely free and open-source, modular, and modern. As a modern, well-typed and well-documented javascript library, it is approachable, yet offers a full-featured and familiar interface as well for those with a background in GIS systems. As it is free to use, anyone could clone our source and run our project locally without payment or registration. Additionally, it has relatively good performance for large feature sets, despite not using WebGL for rendering.
### Positive Consequences
- **Licensing** : OpenLayers is BSD 2-Clause [licensed](https://github.com/openlayers/openlayers/blob/main/LICENSE.md)
- **More fully featured** : OpenLayers has a number of GIS features that other web-based tools do not. A somewhat older [analysis](https://link.springer.com/article/10.1007/s10109-017-0248-z) done in 2017 concluded that when compared to a set of considered features, OpenLayers 3 had a relatively large number of supported overall GIS features:
![GIS Feature set](GIS_Features.png)
- **Popularity** : OpenLayers is second only to Leaflet in the number of Github [stars](https://github.com/openlayers/openlayers/stargazers) it has received, close to 8000
- **Performance** :
- The below chart comes from an September 2020 [study](https://doi.org/10.3390/ijgi9100563). The purpose of this study was to compare OpenLayers to Mapbox-GL-JS and Leaflet (both raster and vector tile variants) as the potential basis for a Life Quality Index for 55,000+ census radius jurisdictions in Argentina.
![Execution Time](ExecutionTime.png) ([Source](https://doi.org/10.3390/ijgi9100563))
In this chart, the two letters following the library name are for basemap layer and feature layer. Further, "R" is "raster" and "V" is vector, and lower numbers indicate faster load times. "OpenLayersRR" and "OpenLayersRV", (signifying a raster base layer and vector feature layer), performed quite well across all device types compared to other libraries.
- We also performed local testing using puppeteer and web performance APIs, tested against a choropleth map of the cenus block groups, which represents a likely usecase for us. The results were as follows:
![Choropleth Map Performance](ChoroplethMapPerformance.png) ([Source](Maryland.csv))
Testing and results can be found on the `client_perf` [branch](https://github.com/usds/justice40-tool/tree/client_perf) in this repository.
- Finally, we tested these mapping solutions against a large dataset with many features, a map of national highways, at a lower zoom level. The tiles were still loaded on-demand, but the greater detail and number of features meant a more difficult render. Trends seemed similar to the above, with the exception of Leaflet:
![Highways Map Performance](HighwayMapPerformance.png) ([Source](Highways.csv))
Notes:
- OL+MB did not file the `tiledidload` event and thus there was not a separate measure for style loaded
- Apparent performance was different from measured/reported overall, particularly when it comes to zoom performance. This is an area to dig into further and measured at a later time to understand better.
- **Data Usage** : The same study above also analyzed the amount of data usage for each of the libraries under investigation, and the result was the below chart (Lower values are better). OpenLayers overall performed quite well
![Data Usage](NetworkTraffic.png) ([Source](https://doi.org/10.3390/ijgi9100563))
### Negative Consequences
- **Learning Curve** : A [recent survey](https://pea.lib.pte.hu/bitstream/handle/pea/23611/farkas-gabor-phd-2020.pdf?sequence=1) ranking various mapping libraries ranked OpenLayers as "Hard" in a scale from "Basic" to "Very Hard", and furthermore calculated "Approximate Learning Curve for Javascript", by which it was on the harder end as well (more detail in paper):
![Difficulty Ranking](DifficultyRanking.png) ([Source](https://pea.lib.pte.hu/bitstream/handle/pea/23611/farkas-gabor-phd-2020.pdf?sequence=1))
This is part of the tradeoff in the library's large feature set. Anecdotally, however, for the purpose of a simple choropleth map, implementation felt similar to other libraries.
- **Modern Stack** : OpenLayers requires a [plugin](https://github.com/openlayers/ol-mapbox-style) for the combination of MVT vector tiles and Mapbox GL Styles, though it does support it.
- **Rendering** : According to [geoapify](https://www.geoapify.com/mapbox-gl-new-license-and-6-free-alternatives), it has 'slightly less "polished" rendering quality and performance' compared to Mapbox/MapLibre GL. This is partly related to the fact that it does not yet support using WebGL for rendering anything more than points ([source](https://openlayers.org/workshop/en/webgl/points.html)).
## Observations
- **Accessibility**
- Accessibility for web mapping technology in general is [not](https://wcag-maps.nicchan.me/) [good](https://sparkgeo.com/blog/the-accessibility-of-web-maps/). As of now, the default 2D visualizations in and of themselves do not provide explicit 508 compliance, and there is no official accessibilty [statement](https://www.w3.org/WAI/planning/statements/) for OpenLayers.
- According to a recent exhaustive WCAG 2.1 [evaluation](https://github.com/Malvoz/web-maps-wcag-evaluation/) that compared several map providers, though almost all web maps performed [poorly](https://wcag-maps.nicchan.me/), OpenLayers came out in the middle of the pack:
![Accessibility](WGAC2.1SuccessCount.png) (Source: original [here](./AccessibilityComparison.tsv), based on data [here](https://github.com/Malvoz/web-maps-wcag-evaluation/))
This chart counts the number of successful WCAG 2.1 criteria from the above-linked study.
- Mitigations:
- According to at least one accessibility [expert](http://stackoverflow.com/questions/15659051/google-maps-508-accessibility-without-styles/16060809#16060809), it is sufficient for compliance reasons to provide an alternative means of viewing the same information provided by the map, perhaps in a table or other format. This is a common solution to this problem.
- Though the library itself does not provide an accessibility guarantee, many of the 508 and WCAG standards are a matter of how you _use_ a particular library - e.g. ensuring proper color contrast, providing alternative markers not based on coloration, and providing text highlighting. We can guarantee that these are in place and ensure an accessibility audit of our featureset before release alongside user testing with low-vision and visually-impaired users directly.
## Pros and Cons of the Other Options
### Mapbox-GL JS
[Source](https://docs.mapbox.com/mapbox-gl-js/api/) - v2.2.0 (3/29/21)
#### Mapbox-GL JS Pros
- **Performance** : As can be seen in the above charts, Mapbox performed quite well in performance tests, in some instances performing the best of the examined options.
- **Data Usage**: In the data usage chart above, MapboxRV and MapboxVV also do quite well in the category of data usage.
- **Modern stack**: Mapbox supports WebGL rendering, vector tiles, and standardized tile styling
- **Modularity**: Mapbox interoperates with various basemap providers, and thanks to the open-sourcing of both its [vector tile format](https://docs.mapbox.com/vector-tiles/specification/) and its [styling language](https://docs.mapbox.com/mapbox-gl-js/style-spec/), there are a [number](https://github.com/mapbox/awesome-vector-tiles) of tools, libraries, and frameworks that easily interoperate with this solution.]
- **(Relative) Accessibility** : Mapbox-GL-JS came out 4th out of 12 in the above accessibility analysis. Mapbox also released several [patches](https://github.com/mapbox/mapbox-gl-js/pulls?q=is%3Apr++accessibility+) recently to address the issues that were found and are actively working on this.
- **Localization** : Through the mapbox-gl-language [plugin](https://github.com/mapbox/mapbox-gl-language/), it is possible to dynamically change the language of mapbox-provided basemaps to other languages. Additionally, they have a plugin for displaying [RTL languages](https://github.com/mapbox/mapbox-gl-rtl-text), and the [ability](https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions/#types-number-format) to format numbers according to locale conventions.
- **Popularity** : According to [NPM Trends](https://www.npmtrends.com/mapbox-gl-vs-leaflet-vs-ol-vs-arcgis-js-api-vs-maplibre-gl) Mapbox-GL is the most downloaded package among those considered. More info [here](https://www.geoapify.com/map-libraries-comparison-leaflet-vs-mapbox-gl-vs-openlayers-trends-and-statistics)
![Download Stats](MapDownloadCount.png)
#### Mapbox-GL JS Cons
- **Licensing** : Mapbox's December 2020 [announcement](https://github.com/mapbox/mapbox-gl-js/releases/tag/v2.0.0) of version 2.0 of their software changed ther license to proprietary and changed their pricing scheme to cover tiles loaded from outside of their service. This decision was met with [some criticism](https://joemorrison.medium.com/death-of-an-open-source-business-model-62bc227a7e9b) in the open-source mapping community.
- **Library Size** : Mapbox-GL is one of the larger libraries considered as far as filesize, coming in at 214.1 KB ([Source](https://www.npmtrends.com/mapbox-gl-vs-leaflet-vs-ol-vs-arcgis-js-api-vs-maplibre-gl))
- **Pricing** : As of version 2.0.0, Mapbox [charges](https://www.mapbox.com/pricing/#maploads) per "map load", defined as "every time Mapbox GL JS initializes on a webpage or in a web app". Up to 50,000 loads per month are free, and beyond this pricing varies. Users are likely to do a number of loads per sitting, however, so this is something we will need to consider, even in a relatively low-traffic tool.
### MapLibre-GL-JS
[Source](https://github.com/maplibre/maplibre-gl-js) - v1.14.0 (3/24/21)
MapLibre is a fork of Mapbox 1.13.0 that preserves the older BSD 3-clause license.
#### MapLibre-GL-JS Pros
- **Everything above** : Being a fork of Mapbox GL JS (though an earlier version), MapLibre has all of the benefits of Mapbox called out above
- **Licensing** : Returns to 3-Clause BSD [License](https://github.com/maplibre/maplibre-gl-js/blob/main/LICENSE.txt) means true FOSS licensing, as well as free operation
#### MapLibre-GL-JS Cons
- **Maturity** : This library is still quite young, having been formed only mid-December last year
- **Licensing Complications** : There may be licensing or legal challenges from Mapbox around the use of this tool
- **Component-based Wrappers** : Though supported by [react-map-gl](https://github.com/visgl/react-map-gl), there is not yet as full-featured support for MapLibre-GL in other component-based wrapper libraries
- **Backwards Compatibility** : There is an [issue](https://github.com/maplibre/maplibre-gl-js/pull/21) open now discussing the possibility of breaking backwards compatibility as part of a MapLibre 2.0 release. In practice this would mean we would not be able to use layers created within Mapbox in MapLibre tooling.
- **New Features** : There is not yet clarity on how and when this library would be updated and what its upcoming feature roadmap looks like
### Leaflet
[Source](https://github.com/Leaflet/Leaflet) - v1.7.1 (9/4/20) + [Leaflet.VectorGrid](https://github.com/Leaflet/Leaflet.VectorGrid) - v1.3.0 (2017)
Leaflet is a popular open-source mapping visualization library that has been around since 2010.
#### Leaflet Pros
- **Popularity** : Leaflet has by far the largest number of [stars](https://github.com/Leaflet/Leaflet/stargazers) on Gitbub (30,500 at the time of writing)
- **Modularity** : Leaflet has a [number](https://leafletjs.com/plugins.html) of plugins that augment its functionality, including [Leaflet.VectorGrid](https://github.com/Leaflet/Leaflet.VectorGrid) which enables Vector Tiles
- **License** : Leaflet is BSD 2-Clause [licensed](https://github.com/Leaflet/Leaflet/blob/master/LICENSE)
#### Leaflet Cons
- **Performance** : As seen above, Leaflet performance is quite poor across device types, relative to other libraries, even with the vector plugin
- **Modern Stack** : The lack of out-of-the-box vector tile support and the necessity of another library opens the possibility for version requirement mismatches and security vulnerabilities. Additionally, the last update to the VectorGrid plugin was a [year ago](https://github.com/Leaflet/Leaflet.VectorGrid/commits/master).
### ArcGIS API for Javascript
[Source](https://developers.arcgis.com/javascript/latest/) - v4.18 (12/2020)
#### ArcGIS API for Javascript Pros
- **Accessibility** : ArcGIS provides regularly-updated accessibility [conformance reports](https://www.esri.com/en-us/legal/accessibility/conformance-reports) detailing their products' conformance with 508 standards.
- Note: These audits are not all up to date - the ArcGIS online evaluation was last completed in September 2018
- Anecdotally, screen readers still struggle to read content without annotations - the onus is still on the map creator to ensure proper compliance.
- **Internationalization/Localization** : the API has its own `intl` module, described [here](https://developers.arcgis.com/javascript/latest/api-reference/esri-intl.html)
- Note: The default ES6 `Intl` module appears to do all of the things described above without need for further modificaiton
- **Name recognition** : Esri in general holds "approximately 43% of the global market share and estimated annual revenues of approximately $1.1 Billion, from roughly 300,000 customers" ([source](https://digital.hbs.edu/platform-digit/submission/esri-and-arcgis/])). Relatedly, Esri tools interoperate well with other Esri tools, and their ecosystem is large.
- Note: according to [one analysis](https://www.datanyze.com/market-share/mapping-and-gis--121) specifically the ArcGIS Web API holds only 0.48% of the marketshare overall.
- **Modularity** : As seen in ArcGIS [documentation](https://developers.arcgis.com/documentation/), Esri interoperates with Leaflet (through a custom fork), Mapbox GL JS, and OpenLayers.
#### ArcGIS API for Javascript Cons
- **License** : Most importantly, though Esri maintains a [handful](https://www.esri.com/en-us/arcgis/open-vision/initiatives/open-source) of open-source tools, ArcGIS API for JS itself, as well as many other tools within the Esri / ArcGIS portfolio, is [closed source](https://github.com/Esri/arcgis-js-api/blob/master/copyright.txt) and proprietary, hosting only minified versions of their software and not encouraging community contribution or feedback beyond forum contributions.
- **Complexity** : The feature set comes with the tradeoff of greater complexity in implementation for ArcGIS as well. Additionally, many more advanced features of the ArcGIS API require you to utilize the Dojo framework and/or Dijit components (see examples [here](https://developers.arcgis.com/javascript/latest/sample-code/widgets-frameworks-react/)), a requirement not held by other frameworks.
- **Modern** : ArcGIS-JS-API only recently got support for ES Modules in version 4.19 ([source](https://developers.arcgis.com/javascript/latest/release-notes/)). Additionally, many examples from earlier versions are still common, including in the ArcGIS API for JS documentation [itself](https://developers.arcgis.com/javascript/latest/get-started/), which still uses HTML includes. There are recently some newer [examples](https://github.com/Esri/jsapi-resources/tree/master/esm-samples) in github, but they also seem to have been recently added.
## Appendix A: Other comparisons
There are a handful of other similar comparisons out there, here are some references:
- Geoapify comparison ([Source](https://www.geoapify.com/mapbox-gl-new-license-and-6-free-alternatives))
![Geoapify Comparison](GeoapifyComparison.png)
- Flatlogic [Comparison](https://flatlogic.com/blog/top-mapping-and-maps-api/)
## Appendix B: Further Reading
- [Malvoz's WCAG 2.1 Summary](https://github.com/Malvoz/web-maps-wcag-evaluation/blob/master/README.md)

View file

@ -0,0 +1,12 @@
(From https://github.com/Malvoz/web-maps-wcag-evaluation/blob/master/README.md) 1.1.1 Non-text Content (A) Result 1.1.1 Non-text Content (A) Notes 1.3.1 Info and Relationships (A) Result 1.3.1 Info and Relationships (A) Notes 1.4.3 Contrast (Minimum) Result 1.4.3 Contrast (Minimum) Notes 2.1.1 Keyboard (A) Result 2.1.1 Keyboard (A) Notes 2.1.2 No Keyboard Trap (A) Result 2.1.4 Character Key Shortcuts (A) Result 2.1.4 Character Key Shortcuts (A) Notes 2.4.3 Focus Order (A) Result 2.4.3 Focus Order (A) Notes 2.4.7 Focus Visible (AA) Result 2.4.7 Focus Visible (AA) Notes 2.5.5 Target Size (AAA) Result 2.5.5 Target Size (AAA) Notes 3.1.2 Language of Parts (AA) Result 3.2.2 On Input (A) Result 3.2.5 Change on Request (AAA) Result 3.2.5 Change on Request (AAA) Notes 4.1.2 Name, Role, Value (A) Result 4.1.2 Name, Role, Value (A) Notes Success Count
Google Maps embed 0 The image depicting "Google" (logo) is neither hidden from ATs nor has a text alternative. 0 The zoom controls' disabled state cannot be programmatically determined. 0 The "View larger map" link has a contrast ratio of 3.79. Some map text (i.e. ocean labels) do not mean the minimum contrast ratio. 0 Map display is not pannable using a keyboard. Control to toggle between "Satellite imagery" and "Street map" is not keyboard operable. 1 N/A (No single key shortcuts available.) 0 ChromeVox (no announcement) "Terms of use link" "View larger map link" "Zoom in button" "Zoom out button" (no announcement) NVDA "Google Maps frame clickable" "Terms of use link" "clickable View larger map link" "Zoom in button Zoom in" "Zoom out button Zoom out" "clickable" 0 2 tab stops without focus indicators. 0 4/4 targets are too small. 0 1 0 Both the "View larger map" link and the "Terms of Use" link open in new windows without warning. The "View larger map" link is especially unexpected as stylistically, it resembles a button, not a link. 0 The "map component" (<div tabindex="0">, which acts as a control to zoom the map display) is missing name and role. Control to toggle between "Satellite imagery" and "Street map" is missing name and role. 2
Google Maps Platform API 0 The link that opens a new window to view the current location (in "Street view") is visually presented as an icon, but is missing a text alternative. 0 The web map's semantic structure as a distinct piece of content cannot be programmatically determined. The zoom controls' disabled state cannot be programmatically determined. The fullscreen control's pressed state cannot be programmatically determined. 0 The "View larger map" link has a contrast ratio of 3.79. Some map text (i.e. ocean labels) do not mean the minimum contrast ratio. 0 Control to initiate "Street view" (so called "Pegman") is only draggable using a mouse, and not keyboard operable. The "Labels" toggle is only accessible in a drop-down after hovering a mouse pointer over the "Satellite" button. The "Terrain" toggle is only accessible in a drop-down after hovering a mouse pointer over the "Map" button. Control to exit "Street view" (<div jsaction="closeControl.click">) is not keyboard operable. 1 1 0 ChromeVox (no announcement) "Open this area in Google Maps, opens a new window link" "Terms of use link" "Toggle fullscreen view button" "Zoom in button" "Zoom out button" "Show street map button pressed" "Show satellite imagery button not pressed" NVDA "clickable" "Open this area in Google Maps, opens a new window link" "Terms of use link" "Toggle fullscreen view button toggle fullscreen view" "Zoom in button zoom in" "Zoom out button zoom out" "clickable Show street map toggle button pressed show street map" "clickable Show satellite imagery toggle button not pressed show satellite imagery" 0 13 tab stops without focus indicators (in "Street view"). 0 14/14 targets are too small. 0 0 0 The "Terms of Use" link opens in new window without warning. The Google logo link contains the screen reader label "Open this area in Google Maps", which does give the user sufficient warning, as it may open in the native Maps app on mobile. 0 The "map component" (<div tabindex="0">, which acts as control to both zoom and pan the map display) is missing name and role. Control to exit "Street view" (<div jsaction="closeControl.click">) is missing name and role. Control to reset the bearing (in "Street view") is missing name. Control to rotate the bearing counter-clockwise (in "Street view") is missing name. Control to rotate the bearing clockwise (in "Street view") is missing name. 2
MapKit JS (Apple Maps) API 0 The control to change/reset the bearing has a child node with the text character "N" to convey "North", it is presumably decorative but is not hidden from ATs. 0 The web map's semantic structure as a distinct piece of content cannot be programmatically determined. 0 Some map labels (i.e. bodies of water, minor street labels) do not meet the minimum contrast ratio. 0 Map display is not pannable using a keyboard. 1 N/A (No single key shortcuts available.) 1 ChromeVox (no announcement) (no announcement) (no announcement) (no announcement) (no announcement) (no announcement) (The browser extension cannot read the Shadow DOM because shadowRoot.mode is closed.) NVDA "Change the map type button collapsed change the map type" "0 degrees 0 degrees slider N" "Zoom in button zoom in" "Zoom out button zoom out" "Legal button" 1 0 5/6 targets are too small. 0 1 0 The "Legal" link is incorrectly marked up as a button (role="button"), opens in new tab without warning. 0 Control to rotate/reset the bearing is missing role. (Note: there are two separate controls providing the same functionality, for clarification, this refers to <div tabindex="0"> and not the <input type="range" aria-label="{x} degrees"> control.) 4
TomTom Maps SDK for Web 0 Character "×" of the control to close the copyright message dialog is decorative but is not hidden from ATs. 0 The web map's semantic structure as a distinct piece of content cannot be programmatically determined. The zoom controls' disabled state cannot be programmatically determined. 0 Some map labels (i.e. buildings) do not meet the minimum contrast ratio. 0 Control to open the copyright message dialog is not keyboard accessible. Control to close the copyright message dialog is not keyboard accessible. 1 1 1 ChromeVox "Map zoom in zoom out copyright 1992 to 2020 TomTom" "Map" "zoom in button" "zoom out button" NVDA "clickable map graphic zoom in button zoom in zoom out button zoom out clickable copyright 1992 to 2020 TomTom" (no announcement) "Zoom in button zoom in" "Zoom out button zoom out" 0 2 tab stops without focus indicators. 0 3/3 targets are too small. 0 0 1 0 The "map component" (<div tabindex="0">, which acts as a control to both zoom and pan the map display) is missing name and role. Control to open the copyright message dialog is missing role. Control to close the copyright message dialog is missing name and role. 4
OpenLayers API 0 Characters "+" and "" of the zoom controls are decorative but are not hidden from ATs. 0 The web map's semantic structure as a distinct piece of content cannot be programmatically determined. The zoom controls' disabled state cannot be programmatically determined. 0 Some map labels (i.e. regional/districts) do not meet the minimum contrast ratio (uses OpenStreetMap tiles). 1 1 0 Both the arrow keys (used to pan the map display) as well as the keyboard shortcuts + and - (to zoom) can be activated despite unrelated components having focus. 1 ChromeVox "Plus button" "Minus button" "OpenStreetMap link list item-list with 1 items" NVDA "clickable Plus button zoom in" "button Zoom out" "list with 1 items OpenStreetMap link" 1 0 2/2 targets are too small. 0 1 0 The "OpenStreetMap" link opens in a new tab without warning. 0 Controls to zoom in and zoom out do not have proper names (while the titles "Zoom in" and "Zoom out" are appropriate, the child text nodes "+" and "" takes precedence in this case, according to the accessible name and description computation, and is announced as "button plus" and "button minus" in ChromeVox, for example). 5
Bing Maps Control API 1 0 The web map's semantic structure as a distinct piece of content cannot be programmatically determined. Scale bars/rulers are missing contextual information (alternatively should be hidden from ATs). The "Reset orientation" control's disabled state cannot be programmatically determined. The "Locate me" control's pressed state cannot be programmatically determined. 0 Some map labels (i.e. bodies of water, district labels) do not meet the minimum contrast ratio. 0 Control to toggle area labels under "Bird's Eye view" is not keyboard accessible (has tabindex="-1"). 1 1 1 ChromeVox "Bing Maps interact to see more" "menu collapsed" "Locate me button" "Current level 1 zoom in button" "Bing Maps link" "Terms link" NVDA "clickable Bing Maps interact to see more" "Current map type: Road, view Aerial, Bird's Eye and more menu" "Locate me button locate me" "Current level 1 zoom in button zoom in" "Bing Maps link" "Terms link terms" 1 0 9/14 targets are too small. 0 1 0 Both the Bing Maps logo and the "Terms" link open in new windows without warning. 0 The "map component" (<div tabindex="0">, which acts as a control to both zoom and pan the map display) is missing role. Control to toggle area labels under "Bird's Eye view" is missing name. 6
OpenStreetMap embed 1 0 The zoom controls' disabled state cannot be programmatically determined. 0 Some map labels (i.e. regional/districts) do not meet the minimum contrast ratio (uses OpenStreetMap tiles). 1 1 1 1 ChromeVox "Zoom in zoom out report a problem copyright OpenStreetMap contributors" "Zoom in button" "Zoom out button" "Report a problem" "OpenStreetMap" NVDA "OpenStreetMap frame clickable zoom in zoom out report a problem copyright OpenStreetMap contributors zoom in button zoom in zoom out button zoom out clickable report a problem link copyright OpenStreetMap link contributors" "Zoom in button zoom in" "Zoom out button zoom out" "clickable Report a problem link" "OpenStreetMap link" 0 1 tab stop without focus indicator. 4 tab stops where focus indicators aren't persistently visible. 0 2/2 targets are too small. 0 1 0 The "Report a problem" and "OpenStreetMap" links open in a new tab without warning. 0 The "map component" (<div tabindex="0">, which acts as a control to both zoom and pan the map display) is missing name and role. 6
MapBox GL JS API 1 0 The web map's semantic structure as a distinct piece of content cannot be programmatically determined. 1 0 Control to display attribution and feedback links is not keyboard accessible. [Github PR] 1 1 1 ChromeVox "Map" "MapBox logo link" NVDA "clickable map graphic" "MapBox logo link" 0 1 tab stop without focus indicator. [Github PR] 0 2/2 targets are too small. 0 1 0 Mapbox logo link opens in a new tab without warning. 0 The "map component" (<canvas tabindex="0">, which acts as a control to both zoom and pan the map display) is missing role. [Github PR] Control to display attribution and feedback links is missing name and role. [Github PR] 6
Leaflet JS API 1 0 The web map's semantic structure as a distinct piece of content cannot be programmatically determined. [Github issue] The zoom controls' disabled state cannot be programmatically determined. [Github issue] 0 Some map labels (i.e. regional/districts) do not meet the minimum contrast ratio (uses OpenStreetMap tiles). 1 1 1 1 ChromeVox "Zoom in zoom out Leaflet map data copyright OpenStreetMap contributors" "Zoom in button" "Zoom out button" "Leaflet link" "OpenStreetMap link" NVDA "clickable Zoom in zoom out Leaflet map data copyright OpenStreetMap contributors zoom in button zoom in zoom out button Zoom out clickable Leaflet link a JS library for interactive maps map data copyright OpenStreetMap link contributors" "Zoom in button zoom in" "Zoom out button zoom out" "clickable Leaflet link a JS library for interactive maps" "OpenStreetMap link" 0 1 tab stop without focus indicator. 4 tab stops where focus indicators aren't persistently visible. [Github issue] 0 2/2 targets are too small. 0 1 1 0 The "map component" (<div tabindex="0">, which acts as a control to both zoom and pan the map display) is missing name and role. [Github issue] 7
MapBox Studio embed 1 0 The "Zoom out" control's disabled state cannot be programmatically determined. [Github PR] 1 0 Control to display attribution and feedback links is not keyboard accessible. [Github PR] 1 1 1 ChromeVox "Map" "Search edit text" "Zoom in button" "Zoom out button" "Reset bearing to north button" "MapBox logo link" NVDA "MapBox Studio frame clickable map graphic" "Search edit blank" "Zoom in button zoom in" "Zoom out button zoom out" "Reset bearing to north button reset bearing to north" "MapBox logo link" 0 1 tab stop without focus indicator. [Github PR] 0 7/7 targets are too small. 1 1 0 Mapbox logo link opens in a new tab without warning. 0 The "map component" (<canvas tabindex="0">, which acts as a control to both zoom and pan the map display) is missing role. [Github PR] Control to display attribution and feedback links is missing name and role. [Github PR] 7
Bing Maps embed 1 0 Scale bars/rulers are missing contextual information (alternatively should be hidden from ATs). 0 Some map labels (i.e. bodies of water, district labels) do not meet the minimum contrast ratio. 1 1 1 1 ChromeVox "Bing Maps interact to see more" "Current level 1 zoom in button" "Bing Maps link" "Terms link" NVDA "Bing Maps frame clickable Bing Maps interact to see more" "Current level 1 zoom in button zoom in" "Bing Maps link" "Terms link terms" 1 0 3/3 targets are too small. 1 1 0 Both the Bing Maps logo and the "Terms" link open in new windows without warning. 0 The "map component" (<div tabindex="0">, which acts as a control to both zoom and pan the map display) is missing role. 8
Can't render this file because it contains an unexpected character in line 2 and column 41.

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 KiB

View file

@ -0,0 +1,5 @@
,OpenLayers,OpenLayers+MB,OpenLayers+React,Leaflet,Mapbox,Mapbox React
Style Loaded,300.22,1195.81,331.85,4460.74,225.97,577.28
Map Idle,1039.56,1195.63,1184.71,126.85,3837.53,2146.08
DOM Interactive,126.88,137.59,193.75,131.33,154.01,262.01
DOM complete,132.70,138.13,193.89,240.13,176.06,353.36
1 OpenLayers OpenLayers+MB OpenLayers+React Leaflet Mapbox Mapbox React
2 Style Loaded 300.22 1195.81 331.85 4460.74 225.97 577.28
3 Map Idle 1039.56 1195.63 1184.71 126.85 3837.53 2146.08
4 DOM Interactive 126.88 137.59 193.75 131.33 154.01 262.01
5 DOM complete 132.70 138.13 193.89 240.13 176.06 353.36

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

View file

@ -0,0 +1,5 @@
,OpenLayers,OpenLayers+MB,OpenLayers+React,Leaflet,Mapbox,Mapbox React
Style Loaded,408.89,383.19,439.83,1782.45,147.41,0.00
Map Idle,207.23,1263.27,1318.54,120.00,1970.86,1659.42
DOM Interactive,146.15,108.78,171.48,124.38,143.74,269.40
DOM complete,146.45,109.33,171.69,160.65,166.53,374.69
1 OpenLayers OpenLayers+MB OpenLayers+React Leaflet Mapbox Mapbox React
2 Style Loaded 408.89 383.19 439.83 1782.45 147.41 0.00
3 Map Idle 207.23 1263.27 1318.54 120.00 1970.86 1659.42
4 DOM Interactive 146.15 108.78 171.48 124.38 143.74 269.40
5 DOM complete 146.45 109.33 171.69 160.65 166.53 374.69

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View file

@ -0,0 +1,73 @@
# [short title of solved problem and solution]
- Status: [draft | proposed | rejected | accepted | deprecated | … | superseded by [xxx](yyyymmdd-xxx.md)] <!-- optional -->
- Deciders: [list everyone involved in the decision] <!-- optional -->
- Date: [YYYY-MM-DD when the decision was last updated] <!-- optional. To customize the ordering without relying on Git creation dates and filenames -->
- Tags: [space and/or comma separated list of tags] <!-- optional -->
Technical Story: [description | ticket/issue URL] <!-- optional -->
## Context and Problem Statement
[Describe the context and problem statement, e.g., in free form using two to three sentences. You may want to articulate the problem in form of a question.]
## Decision Drivers <!-- optional -->
- [driver 1, e.g., a force, facing concern, …]
- [driver 2, e.g., a force, facing concern, …]
- … <!-- numbers of drivers can vary -->
## Considered Options
- [option 1]
- [option 2]
- [option 3]
- … <!-- numbers of options can vary -->
## Decision Outcome
Chosen option: "[option 1]", because [justification. e.g., only option, which meets k.o. criterion decision driver | which resolves force force | … | comes out best (see below)].
### Positive Consequences <!-- optional -->
- [e.g., improvement of quality attribute satisfaction, follow-up decisions required, …]
- …
### Negative Consequences <!-- optional -->
- [e.g., compromising quality attribute, follow-up decisions required, …]
- …
## Pros and Cons of the Options <!-- optional -->
### [option 1]
[example | description | pointer to more information | …] <!-- optional -->
- Good, because [argument a]
- Good, because [argument b]
- Bad, because [argument c]
- … <!-- numbers of pros and cons can vary -->
### [option 2]
[example | description | pointer to more information | …] <!-- optional -->
- Good, because [argument a]
- Good, because [argument b]
- Bad, because [argument c]
- … <!-- numbers of pros and cons can vary -->
### [option 3]
[example | description | pointer to more information | …] <!-- optional -->
- Good, because [argument a]
- Good, because [argument b]
- Bad, because [argument c]
- … <!-- numbers of pros and cons can vary -->
## Links <!-- optional -->
- [Link type](link to adr) <!-- example: Refined by [xxx](yyyymmdd-xxx.md) -->
- … <!-- numbers of links can vary -->