Bhaskar Karambelkar's Blog

Leaflet Diary: Chapter 1, Plugins Galore

 

Tags: r r-stats rstats GIS leaflet Leaflet-Diary


This is the second blog entry in my series ‘Leaflet-Diary’, the first entry was nothing more than me announcing to the world that I’m contracting with RStudio for adding new features to the Leaflet package. This one is about what has been done so far and what’s cooking.

TL;DR

  • All existing plugins have been upgraded to their respective latest versions.
  • R counterparts to any missing or new features of these plugins have also been added.
  • I’ve introduced additional functionality in some plugins not available before.

You can try out the new stuff today by building the Leaflet package from source using devtools::install_github('rstudio/leaflet'). For a full list of changes see the pull request #293. Also the examples folder has lots of new examples. You can see working sample code at my Rpubs page.

Long Read

My plan of attack was, before adding any new features or fixing any bugs upgrade the Leaflet javascript library and existing plugins to their respective latest stable versions. The reasoning being, Leaflet javascript (henceforth LeafletJS) in the current R package is version 0.7.3. The current stable version of LeafletJS is 0.7.7. (LeafletJS 1.0 is not yet production ready.) The 0.7.7 version has seen a lot of fixes and performance improvements over 0.7.3, not to mention 0.7.3 was released way back in May, 23 2014. Similarly the various plugins that were bundled with the R package (see below) were also quite old and their respective current stable versions have seen similar performance and feature improvements. So it made sense to bring everything in the R package up to date. And that is exactly what I’ve been doing for the last 2 weeks (including weekends).

I’ve broken down my task in two phases, phase 1: upgrade plugins (now complete) and phase 2: upgrade LeafletJS (in progress). The reason I upgraded the plugins before LeafletJS was simply because I was more familiar with the plugin handling code than the core Leaflet code. There was a risk of some upgraded plugins not working under 0.7.3 and requiring 0.7.7, but I was willing to take that risk.

Leaflet Providers Plugin

The Leaflet Providers plugin, which provides a convenient way to add existing free tile providers has been upgraded (See commit bcd9adf for details). Of noteworthy, was the removal of MapQuest provider (Issue #219) due to MapQuest closing free access. After upgrading this plugin I saw a chance to improve the R part. Instead of having to provide the provider name in the addProviderTiles call, I created a R list called providers pre-populated with Names of existing providers and base-map variants if any.

So now instead of

leaflet() %>% addProviderTiles("Stamen.Toner")

you can do

leaflet() %>% addProviderTiles(providers$Stamen.Toner)

At first this looks like more typing, but a) you can put RStudio’s auto-complete to work for you and, b) you don’t have to remember all the providers and their variants, and there are roughly 110 of them (I checked). For a complete example of this along with code see my Rpubs: leaflet-providers entry.

Leaflet.Label Plugin

The Leaflet.Label plugin allows you to add static or on-hover labels to your markers, polylines, and polygons. This plugin was upgraded to the latest version (See commits ca2f5a5 & 8bddd82). In addition I also merged two pull requests on the original plugin repo and introduced some new features of my own. Now with the new version you get…


Label's w/o box.

Customizable text size.

Directional Labels.

Stylized labels.

Markers w/o the icon.

I believe these new features make the plugin even more useful for your interactive mapping needs. See this Rpubs: Leaflet-Label entry for details and code samples.

Leaflet-Omnivore Plugin

The Leaflet-Omnivore plugin by Mapbox allows you to overlay GeoJSON, TopoJSON, WKT, KML, GPX files on the Leaflet map. I have upgraded this plugin to the latest version (See commit 5abd3f4). I didn’t see much changed w.r.t. the older plugin, but staying current is always a better option. For now even if the plugin is upgraded I haven’t yet added the R API to add WKT/KML/GPX files. There is a need to support these file formats in the R package via more idiomatic R APIs. The current approach to add GeoJSON/TopoJSON is also not the most ideal one. So stay tuned for more updates on this.

For what it’s worth do check out my example of handling GeoJSON using the geojsonio package over at Rpubs: leaflet-geojson. I like this approach more than the omnivore plugin based approach because it’s much easy to add markers/polylines/polygons and style them using data with this approach than leaflet native approach.

Leaflet Measure Plugin

The Leaflet Measure is a very useful plugin that enables you to add a controller on your map which can be used to measure distances between points or areas of a polygon. I upgraded it to the latest version (See commit c58926f). The new version supports localization in certain locales, which goes nicely with OpenStreetMaps (OSM) base-map layer which uses localized labels. e.g. below you see the plugin displaying the options and text in German.

For details see my Rpubs: leaflet-measure entry.

MiniMap Plugin

The Minimap plugin was by far the most fun and most challenging to work on. I had implemented a rudimentary example of it a while ago, but it had a fixed base-map. What I wanted was an ability to sync the mini-map’s tile layer with the base-map’s. And there’s a restriction in LeafletJS in that no two map’s can share layers. Finally I was able to achieve it albeit using some native Javascript code. And solving that problem also allowed me to solve another interesting use case of showing markers in both base-map and mini-map. See commits 8eb9daa, d5250ca & f3924772 Here’s a sample of what can be done now.

For a full list of possibilities check out my Rpubs: Minimap entry.

Simple-Graticule & Graticule Plugins

I had implemented the Simple Graticule plugin, but when I did upgrade it this time, I realized that it is meant only for L.CRS.Simple, but there is a proper Graticule plugin too, so I included it in this round too. See commit 727dd47 for details.

Check out the Rpubs: Graticule and Rpubs: Simple Graticule entries for code samples.

Marker Clusters Plugin

Finally we come to my favorite of all, the Marker Cluster plugin. This plugin was way overdue for an upgrade and I found two very useful sub-plugins, the layer support sub-plugin & the freezable sub-plugin. The former makes marker clustering work along with layers and layer-controllers, so you can add your markers to different layers and show/hide these layers using a layer controller and the marker cluster plugin will update it’s clusters accordingly. The later allows you to freeze/unfreeze clustering at a specific zoom level. I believe these were worth additions to what is an already very useful plugin. For the code curious see commit b6c980.

For code samples and some spiffy clustering check out the Rpubs: Marker Cluster entry.

End of Phase 1

This concludes my two weeks of development. For most part the coding was grunt work and involved taking what has already been built in Javascript and making it available in R. The challenge was to make the new stuff available in as idiomatic way as possible to R. I did have to scratch my head a few times, especially with the mini-map syncing with base-map examples. In addition to these changes, I have also added two new plugins but they are not merged in the code base yet. More on them in the next post. If you like what you see or have comments/questions/critiques don’t hesitate to contact me via Twitter or open an issue over at Github. In the mean time happy mapping.