Review: Our Experience with OpenLayers3
We needed an open source, flexible mapping library with a large feature-set, that would be robust enough to use on a large-scale data visualization project. We tried OpenLayers3.
Recently we developed a large-scale data visualization tool that explores the health and status of wild salmon in British Columbia. As with any ecosystem, the interactions are complex, time based, and interconnected. For people to gain meaningful insight, they need to see overarching views as well as be able to explore in detail.
Much of the data was map-based and we knew that we would need to find a solution that was flexible and sophisticated, and one that we could ultimately modify to fit the project’s unique requirements. We chose OpenLayers3 (OL3).
For those unfamiliar with it, OL3 is an open source mapping library which targets HTML5. It can pull tiles from a variety of providers (we used MapBox because their tools facilitate customization) as well as create vector layers using several formats (we used GeoJSON). It has solid community support, code quality and documentation, all of which are essential when developing a project with complexity.
In most cases we found OL3 to be fast. The load speed of tiles was underwhelming, although we attribute that to a combination of Mapbox’s service, and our occasional need to load several tile layers simultaneously for some presentations.
We ran into rendering bottlenecks when our maps used polygons with many vertices (~10,000), and as a result, needed to make several changes to the code. One was dropping the use of the multiply composite operation. The combination of many vertices and multiply significantly slowed rendering, especially in Firefox. Another was debouncing tests for mouse interaction. This increased performance, and while we still encountered bottlenecks in some instances, it was well within an acceptable limit.
When designing a usable map it is important to minimize visual complexity by creating clear relationships (e.g. colors and textures have unambiguous meaning) and hierarchy (e.g. prominent features are not lost amidst minutiae). We ran into two complications while adjusting the style and appearance of Open Layers maps to match our aesthetic and functional goals.
First, our design called for transparent color regions with a map shape knockout.
Second, some areas of the map needed to be rendered with pattern fills. We found a GitHub thread about potential implementations of that feature, and we ultimately needed to create a version that was merged into OpenLayers. As of version 3.14 fill colors are overloaded to allow pattern and gradient fills:
We love contributing to open source, and our contributions have been added to OL3 so that others can make use of the feature.
One of our project requirements was the ability to export maps as PDFs; and since we did not want duplicate code, we chose to produce these in the browser rather than on the server. A rough export to image and inclusion via PDFKit was simple. In making it work smoothly there were two issues that cropped up. Both of them stemmed from the fact that OL3 is primarily built to view maps in browser.
Issue 1: Tile Loading
When exporting an image of each map you need to make sure that all assets are loaded before rendering. For us, much of the loading was outside of OpenLayers (GeoJSON, icons and other data). However, making sure all tiles had loaded proved more difficult — and this actually ended up being the most significant issue stemming from our use of OL3.
Since OL3 automatically loads tiles, the example technique requires immediately watching the map load status on construction. In our context, the map tiles were created several layers of abstraction away from the knowledge that they needed their load status to be observed — so we looked elsewhere. Polling (ugly) of tile source load state proved unreliable, so we ended up watching load status of all our tiles regardless of context.
Additionally, tiles in maps not attached to the HTML Document would sometimes fail to start loading and we were unable to isolate the cause. Eventually we discovered that setting the zoom level triggered their loading, and so we built a patch around that.
Issue 2: Pixel Ratio
Many devices now have device pixel ratios greater than one (e.g. Retina Display). OpenLayers default behavior is to use a larger canvas to back these displays. On these devices, that results in a larger image and an unexpected layout in the PDF. After several attempts to work around this, we discovered the pixelRatio option, which overrides the device default. Kudos to the OL3 contributors for this feature. It was very helpful.
Overall, we were pleased with OpenLayers3. It is a flexible mapping library with a large feature-set. As with anything of its scale and complexity there were a few surprises, but nothing that was insurmountable, and nothing that would keep us from using OpenLayers on our next mapping project.