Breaking Dependence on Vendor Map APIs with Leaflet

A colleague had a question about porting a map written using Bing Maps AJAX 6.2 to Bing Maps AJAX V7. The existing map shows coverage areas that, when highlighted, highlight a corresponding item in a price list. The problem was that the mouse events didn’t work the same in the new version. I’ve become a bit of a Leaflet evangelist these days, so I showed them how to do it using Leaflet and the Leaflet-pip library instead. You can see the demo, pictured below, at this URL: http://exploringspatial.com/#demo/7. It’s a fun little interactive map.

Screenshot of Shape Event Demo

Screenshot of Shape Event Demo

I grabbed a GeoJSON file of Kansas counties from CivicDashboards for the shapes to be highlighted. There was also a requirement that hovering the mouse above overlapping shapes highlight all of the overlapping shapes, not just the top shape, so I added several large circles to my map representing Kansas universities. The list of county names to the left of the map is meant to represent the price list on my colleague’s map.

Hovering the mouse over a name in the list of counties highlights the corresponding county shape on the map and vice versa. Hovering over the university circles not only highlights the circle , but also the county shape underneath that circle.

The demo came together quickly since I was using Leaflet’s L.geoJson() layer for the county shapes, as I have done in several previous demos. There were just a couple of things that slowed me down: scrolling the list of county names to the highlighted name when hovering over a county shape on the map and propagating the mouse events to all overlapping shapes.

Scrolling Long Lists

Automatically scrolling to a highlighted name should have been easy, but it took me a bit to get it right. I worked up a proof-of-concept in JSFiddle first. You can find the POC code here: http://jsfiddle.net/stevecmitchell/5y1c3xsh/.  The code in my map demo is even shorter than my proof-of-concept on JSFiddle.

Propagating Mouse Events

I used mouseover and mouseout event handlers on the county shapes and college circles to handle highlighting. The problem was that when the circle received the mouse event the county underneath the circle did not receive an event, so it never got highlighted.

I posted a question to the Leaflet forum and was sent a solution in JSFiddle by user “ghybs”, https://github.com/ghybs, that used the leaflet-pip plugin. The leaflet-pip plugin was written by Tom McWright of Mapbox. It, in turn, credits an algorithm documented at Rensselaer Polytechnic Institute in Troy, NY.

Long story short, I added a mousemove listener to the college circles on the map. When the mouse moves over a circle the mousemove event handler uses leaflet-pip to find the county shape containing the point of the mouse event and then explicitly fires the mouseover event of the matching county shape.

Using leaflet-pip.pointInLayer

Using leaflet-pip.pointInLayer

I did not take the time to implement the event propagation the other direction. When you hover over a county name in the list, which highlights a county shape on the map, the college circle above it is not highlighted. This could be done… but I’ve invested enough time in this demo, so I didn’t do that.

I love this plugin. It is useful and easy to use. This gave me an idea for my next demo which will use leaflet-pip to demonstrate a “50-State Marathon Club” style map. You’ve seen them before. People who are trying to run a half or full marathon in all 50-states, or all seven continents, use them to track their progress.

The bulk of the code for this demo can be found here:

https://github.com/smitchell/exploringspatial/blob/master/js/views/maps/CountiesMapLayerView.js


					
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s