Skip to content

Instantly share code, notes, and snippets.

@wboykinm
Created November 10, 2013 04:09
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save wboykinm/7393674 to your computer and use it in GitHub Desktop.
Leaflet + D3 + Vector Tiles (via Nelson Minar)
<!DOCTYPE html>
<meta charset="utf-8">
<title>D3 GeoJSON in Leaflet</title>
<link href='http://api.tiles.mapbox.com/mapbox.js/v1.4.0/mapbox.css' rel='stylesheet' />
<!--[if lte IE 8]>
<link href='http://api.tiles.mapbox.com/mapbox.js/v1.4.0/mapbox.ie.css' rel='stylesheet'>
<![endif]--><style>
html, body, #map { height: 100%;width:100%; background:#020B26;position:absolute;}
body { padding: 0; margin: 0; }
path { stroke-linejoin; round; stroke-linecap: round; fill: none}
path.road { stroke : #3C80A9; fill : none ;}
path.water { stroke:none; fill:#031536; }
img { -webkit-filter: grayscale(100%) brightness(40%) contrast(150%);}
</style>
<body>
<div id="map" class="dark"></div>
<svg>
<defs>
<linearGradient id='grad1'>
<stop offset='0%' stop-color='#E8DDC9'/>
<stop offset='100%' stop-color='#E8DDC9' stop-opacity='0' />
</linearGradient>
<linearGradient id='grad2'>
<stop offset='0%' stop-color='#CCB479'/>
<stop offset='100%' stop-color='#CCB479' stop-opacity='0' />
</linearGradient>
<linearGradient id='grad3'>
<stop offset='0%' stop-color='#3C80A9'/>
<stop offset='100%' stop-color='#3C80A9' stop-opacity='0' />
</linearGradient>
<linearGradient id='grad4'>
<stop offset='0%' stop-color='#7de'/>
<stop offset='100%' stop-color='#7de' stop-opacity='0' />
</linearGradient>
<linearGradient id='grad5'>
<stop offset='0%' stop-color='#74DC9B'/>
<stop offset='100%' stop-color='#74DC9B' stop-opacity='0' />
</linearGradient>
</defs>
</svg>
<script src="http://api.tiles.mapbox.com/mapbox.js/v1.4.0/mapbox.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script>
/* Experimental vector tile layer for Leaflet
* Uses D3 to render TopoJSON. Derived from a GeoJSON thing that was
* Originally by Ziggy Jonsson: http://bl.ocks.org/ZJONSSON/5602552
* Reworked by Nelson Minar: http://bl.ocks.org/NelsonMinar/5624141
*/
L.TileLayer.d3_topoJSON = L.TileLayer.extend({
onAdd : function(map) {
L.TileLayer.prototype.onAdd.call(this,map);
this._path = d3.geo.path().projection(function(d) {
var point = map.latLngToLayerPoint(new L.LatLng(d[1],d[0]));
return [point.x,point.y];
});
this.on("tileunload",function(d) {
if (d.tile.xhr) d.tile.xhr.abort();
if (d.tile.nodes) d.tile.nodes.remove();
d.tile.nodes = null;
d.tile.xhr = null;
});
},
_loadTile : function(tile,tilePoint) {
var self = this;
this._adjustTilePoint(tilePoint);
if (!tile.nodes && !tile.xhr) {
tile.xhr = d3.json(this.getTileUrl(tilePoint),function(error, tjData) {
if (error) {
console.log(error);
} else {
var geoJson = topojson.feature(tjData, tjData.objects[self.options.layerName]);
tile.xhr = null;
tile.nodes = d3.select(map._container).select("svg").append("g");
tile.nodes.selectAll("path")
.data(geoJson.features).enter()
.append("path")
.attr("d", self._path)
.attr("class", self.options.class)
.attr("style", self.options.style);
}
});
}
}
});
map = L.map(map).setView([47.6062095, -122.332070], 12);
map._initPathRoot();
// Add a fake GeoJSON line to coerce Leaflet into creating the <svg> tag that d3_geoJson needs
new L.geoJson({"type": "LineString","coordinates":[[0,0],[0,0]]}).addTo(map);
// Water Areas from OpenStreetMap
new L.TileLayer.d3_topoJSON("http://tile.openstreetmap.us/vectiles-water-areas/{z}/{x}/{y}.topojson", {
class: "water",
layerName: "vectile",
style: ""
}).addTo(map);
// Highways from OpenStreetMap
var roadSizes = {
"highway": "4px",
"major_road": "1.8px",
"minor_road": "1.2px",
"rail": "0.8px",
"path": "0.5px"
};
var roadColors = {
"highway": "url(#grad1)",
"major_road": "url(#grad2)",
"minor_road": "url(#grad3)",
"rail": "url(#grad4)",
"path": "url(#grad5)"
};
new L.TileLayer.d3_topoJSON("http://tile.openstreetmap.us/vectiles-highroad/{z}/{x}/{y}.topojson", {
class: "road",
layerName: "vectile",
style: function(d) { return "stroke-width: " + roadSizes[d.properties.kind] + "; stroke: " + roadColors[d.properties.kind]; }
}).addTo(map);
var topPane = map._createPane('leaflet-top-pane', map.getPanes().mapPane);
var topLayer = new L.tileLayer('http://{s}.tile.stamen.com/toner-labels/{z}/{x}/{y}.png', {
maxZoom: 17
}).addTo(map);
topPane.appendChild(topLayer.getContainer());
topLayer.setZIndex(7);
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment