All examples By author By category About

ramnathv

Leaflet Routing Machine with rCharts

Leaflet Routing Machine Plugin

I saw the following issue posted to the rMaps github repo today.

I am new to using rMaps and leaflet. I would like to plot the route between two locations. The leaflet routing machine plugin allows us to do this (https://github.com/perliedman/leaflet-routing-machine). I am not quite sure how to use the functions addAssets() and setTemplate() to be able to use this plugin.

This was a good exercise for me to test whether these newly introduced mechanisms addAssets and setTemplate would allow one to easily extend the base leaflet binding in rMaps.

Let us start by creating the base map.

map = Leaflet$new()
map$setView(c(40.73846, -73.99413), 16)
map$tileLayer(provider = 'Stamen.TonerLite')
map

At this point, you should be able to view this map in your chosen viewer.

simplemap

We now want to add a route between the following waypoints. I have chosen the data structure to be an unnamed list of vectors, since it converts easily to the JSON structure expected by by routing plugin.

mywaypoints = list(c(40.74119, -73.9925), c(40.73573, -73.99302))

In order to use the routing plugin, we first need to add the required js/css assets. I introduced the addAssets method in the dev version of rCharts precisely to serve this need (NOTE: It is currently a little buggy in terms of order in which the assets are specified, but I will take care of that this week).

map$addAssets(
  css = "http://www.liedman.net/leaflet-routing-machine/dist/leaflet-routing-machine.css",
  jshead = "http://www.liedman.net/leaflet-routing-machine/dist/leaflet-routing-machine.min.js"
)

All that is left to do now is to add the javascript snippet that would add these waypoints to the map. If you visit the github page of the routing plugin, you will notice that all I have done is replaced the hardcoded waypoints with a placeholder, which I will fill using data from R.

routingTemplate =  "
  <script>
   var mywaypoints = %s
   L.Routing.control({
     waypoints: [
       L.latLng.apply(null, mywaypoints[0]),
       L.latLng.apply(null, mywaypoints[1])
    ]
   }).addTo(map);
  </script>
"

So how do we inject this snippet into our HTML. This was the idea behind the afterScript template. (NOTE: The name indicates that this snippet will be added after the script used to generate the base map. I am open to suggestions for a name that would be more indicative of this argument). I use sprintf to populate the placeholder in the template, and convert waypoints to JSON before invoking it.

map$setTemplate(afterScript = sprintf(routingTemplate, RJSONIO::toJSON(mywaypoints))

At this point, typing map in your R console should give you the following map. Click on the map to be taken to a full page interactive version, where you can see the routing directions as well.

map_with_routing.

You can download the full code here.