Skip to content

Instantly share code, notes, and snippets.

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='' rel='stylesheet' />
<!--[if lte IE 8]>
<link href='' rel='stylesheet'>
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%);}
<div id="map" class="dark"></div>
<linearGradient id='grad1'>
<stop offset='0%' stop-color='#E8DDC9'/>
<stop offset='100%' stop-color='#E8DDC9' stop-opacity='0' />
<linearGradient id='grad2'>
<stop offset='0%' stop-color='#CCB479'/>
<stop offset='100%' stop-color='#CCB479' stop-opacity='0' />
<linearGradient id='grad3'>
<stop offset='0%' stop-color='#3C80A9'/>
<stop offset='100%' stop-color='#3C80A9' stop-opacity='0' />
<linearGradient id='grad4'>
<stop offset='0%' stop-color='#7de'/>
<stop offset='100%' stop-color='#7de' stop-opacity='0' />
<linearGradient id='grad5'>
<stop offset='0%' stop-color='#74DC9B'/>
<stop offset='100%' stop-color='#74DC9B' stop-opacity='0' />
<script src=""></script>
<script src="" charset="utf-8"></script>
<script src=""></script>
/* Experimental vector tile layer for Leaflet
* Uses D3 to render TopoJSON. Derived from a GeoJSON thing that was
* Originally by Ziggy Jonsson:
* Reworked by Nelson Minar:
L.TileLayer.d3_topoJSON = L.TileLayer.extend({
onAdd : function(map) {,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;
if (!tile.nodes && !tile.xhr) {
tile.xhr = d3.json(this.getTileUrl(tilePoint),function(error, tjData) {
if (error) {
} else {
var geoJson = topojson.feature(tjData, tjData.objects[self.options.layerName]);
tile.xhr = null;
tile.nodes ="svg").append("g");
.attr("d", self._path)
.attr("class", self.options.class)
map =[47.6062095, -122.332070], 12);
// 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("{z}/{x}/{y}.topojson", {
class: "water",
layerName: "vectile",
style: ""
// 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("{z}/{x}/{y}.topojson", {
class: "road",
layerName: "vectile",
style: function(d) { return "stroke-width: " + roadSizes[] + "; stroke: " + roadColors[]; }
var topPane = map._createPane('leaflet-top-pane', map.getPanes().mapPane);
var topLayer = new L.tileLayer('http://{s}{z}/{x}/{y}.png', {
maxZoom: 17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment