📦🤗 npm-friendly fork of [jawj/OverlappingMarkerSpiderfier](https://github.com/jawj/OverlappingMarkerSpiderfier). [![version](https://img.shields.io/npm/v/overlapping-marker-spiderfier-leaflet.svg)](https://www.npmjs.com/package/overlapping-marker-spiderfier-leaflet) [![downloads](https://img.shields.io/npm/dt/overlapping-marker-spiderfier-leaflet.svg)](http://npm-stat.com/charts.html?package=overlapping-marker-spiderfier-leaflet) ![MIT License](https://img.shields.io/github/license/mashape/apistatus.svg) Overlapping Marker Spiderfier for Leaflet ========================================= **Ever noticed how, in [Google Earth](http://earth.google.com), marker pins that overlap each other spring apart gracefully when you click them, so you can pick the one you meant?** **And ever noticed how, when using the [Leaflet API](http://leaflet.cloudmade.com), the same thing doesn't happen?** This code makes Leaflet map markers behave in that Google Earth way (minus the animation). Small numbers of markers (yes, up to 8) spiderfy into a circle. Larger numbers fan out into a more space-efficient spiral. The compiled code has no dependencies beyond Leaflet. And it's under 3K when compiled out of [CoffeeScript](http://jashkenas.github.com/coffee-script/), minified with Google's [Closure Compiler](http://code.google.com/closure/compiler/) and gzipped. It's a port of my [original library for the Google Maps API](https://github.com/jawj/OverlappingMarkerSpiderfier). (Since the Leaflet API doesn't let us observe all the event types that the Google one does, the main difference between the original and the port is this: you must first call `unspiderfy` if and when you want to move a marker in the Leaflet version). ### Doesn't clustering solve this problem? You may have seen the marker clustering libraries, which also help deal with markers that are close together. That might be what you want. However, it probably **isn't** what you want (or isn't the only thing you want) if you have markers that could be in the exact same location, or close enough to overlap even at the maximum zoom level. In that case, clustering won't help your users see and/or click on the marker they're looking for. Demo ---- See the [demo map](http://jawj.github.com/OverlappingMarkerSpiderfier-Leaflet/demo.html) (the data is random: reload the map to reposition the markers). Download -------- Download [the compiled, minified JS source](https://unpkg.com/overlapping-marker-spiderfier-leaflet@latest). Or download it from npm: `npm isntall -S overlapping-marker-spiderfier-leaflet` or `yarn add overlapping-marker-spiderfier-leaflet` How to use ---------- See the [demo map source](http://github.com/jawj/OverlappingMarkerSpiderfier-Leaflet/blob/gh-pages/demo.html), or follow along here for a slightly simpler usage with commentary. Create your map like normal (using the beautiful [Stamen watercolour OSM map](http://maps.stamen.com/#watercolor)): ```javascript var map = new L.Map('map_canvas', {center: new L.LatLng(51.505, -0.09), zoom: 13}); var layer = new L.StamenTileLayer('watercolor'); map.addLayer(layer); ``` Create an `OverlappingMarkerSpiderfier` instance: ```javascript var oms = new OverlappingMarkerSpiderfier(map); ``` Instead of adding click listeners to your markers directly via `marker.addEventListener` or `marker.on`, add a global listener on the `OverlappingMarkerSpiderfier` instance instead. The listener will be passed the clicked marker as its first argument. ```javascript var popup = new L.Popup(); oms.addListener('click', function(marker) { popup.setContent(marker.desc); popup.setLatLng(marker.getLatLng()); map.openPopup(popup); }); ``` You can also add listeners on the `spiderfy` and `unspiderfy` events, which will be passed an array of the markers affected. In this example, we observe only the `spiderfy` event, using it to close any open `InfoWindow`: ```javascript oms.addListener('spiderfy', function(markers) { map.closePopup(); }); ``` Finally, tell the `OverlappingMarkerSpiderfier` instance about each marker as you add it, using the `addMarker` method: ```javascript for (var i = 0; i < window.mapData.length; i ++) { var datum = window.mapData[i]; var loc = new L.LatLng(datum.lat, datum.lon); var marker = new L.Marker(loc); marker.desc = datum.d; map.addLayer(marker); oms.addMarker(marker); // <-- here } ``` Docs ---- ### Loading The Leaflet `L` object must be available when this code runs --- i.e. put the Leaflet API \