With last week’s release of MapBox.js 1.0, adding vector data to your MapBox map is a lot easier. A sophisticated example of mapping with vector data is Hipmunk’s hotel search. This post walks you though how to build your own neighborhood map combining MapBox Streets tiles and vector data from New York City’s Open Data portal.
An example of Hipmunk’s technique. Notice how easy it is to read the labels and see the neighborhood information.
The cool guys at Hipmunk wanted to layer neighborhood data onto MapBox maps in a way that retained the polished look of MapBox Streets, without disorienting users by covering up street and area labels. To achieve this, Hipmunk used a custom MapBox Streets that had a transparent land layer on top of their vector neighborhood layer, which allows the data below to show through.
This technique is only possible with MapBox Streets, which unlike other web maps offers custom styles for map features that can be used separately or composited together. Hipmunk’s finished map offers a seamless experience where vector layers dynamically highlight areas of interest on the rendered tile-based map:
Create your own neighborhood map with MapBox.js
The Hipmunk team used the open source Leaflet map library to create this map. Now that MapBox.js is based on Leaflet, you can take the same approach directly with MapBox.js. Here is how:
1) Create a new map on MapBox.com
2) In the customize panel, turn off the Land layer
Removing the land layer. The gridded pattern denotes transparency.
3) Set up the head
of your HTML document. Here we define the map size, load MapBox.js 1.0 javascript and CSS files and the vector data, nycneighborhoods.js
. For this example we are using New York City neighborhoods from NYC Open Data and processed using these steps.
<!DOCTYPE html><html><head><metacharset="utf-8"/><metaname="viewport"content="width=device-width, initial-scale=1.0"><html><head><linkhref='http://api.tiles.mapbox.com/mapbox.js/v1.0.0/mapbox.css'rel='stylesheet'/><script src='http://api.tiles.mapbox.com/mapbox.js/v1.0.0/mapbox.js'></script><script src='http://bl.ocks.org/rsudekum/raw/5431771/nycneighborhoods.js'></script><style>html,body,#map{padding:0;margin:0;width:100%;height:100%;}.leaflet-top-pane{pointer-events:none;}</style></head>
4) Next we load the map, define the vector layer styles and then move it to the correct z-index
so it’s between the tile layers:
<body><divid="map"></div><script type="text/javascript">varmap=L.mapbox.map('map').setView([40.75,-73.94],15);// Set base style of vector datafunctionstyle(feature){return{weight:0,fillOpacity:0.5,fillColor:'#FFEDA0'};}// Set hover colorsfunctionhighlightFeature(e){varlayer=e.target;layer.setStyle({weight:10,opacity:1,color:'#09F',dashArray:'3',fillOpacity:0.7,fillColor:'#FEB24C'});}// A function to reset the colors when a neighborhood is not longer 'hovered'functionresetHighlight(e){geojson.resetStyle(e.target);}// Tell MapBox.js what functions to call when mousing over and out of a neighborhoodfunctiononEachFeature(feature,layer){layer.on({mouseover:highlightFeature,mouseout:resetHighlight});}// Add vector data to mapgeojson=L.geoJson(neighborhoods,{style:style,onEachFeature:onEachFeature}).addTo(map);// Here is where the magic happens: Manipulate the z-index of tile layers,// this makes sure our vector data shows up above the background map and// under roads and labels.vartopPane=map._createPane('leaflet-top-pane',map.getPanes().mapPane);vartopLayer=L.mapbox.tileLayer('bobbysud.map-3inxc2p4').addTo(map);topPane.appendChild(topLayer.getContainer());topLayer.setZIndex(7);</script></body></html>
5) Open the file in your browser
You should now see a map like the one below.
Notice how the neighborhood layer is below the tile layer, made possible with MapBox’s transparent tiles.
Again, hats off to the great team at Hipmunk for setting the bar on how to do this. Their service is awesome.
Get started building your own map
Get started creating your own neighborhood map by following this example or working from the full source code. Let us know how it goes on Twitter!