Created
May 26, 2015 23:54
-
-
Save mapsense-examples/be0ad69cbea40d842726 to your computer and use it in GitHub Desktop.
Leaflet tilelayer + mapsense vector tiles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content='initial-scale=1,maximum-scale=1,user-scalable=no' /> | |
<link rel="stylesheet" href="http://leafletjs.com/dist/leaflet.css" media="screen" type="text/css"> | |
<link rel="stylesheet" href="https://developer.mapsense.co/mapsense.css" media="screen" type="text/css"> | |
<script src='http://d3js.org/d3.v3.min.js' type="text/javascript"></script> | |
<script src='http://d3js.org/topojson.v1.min.js' type="text/javascript"></script> | |
<script src='http://leafletjs.com/dist/leaflet.js' type="text/javascript"></script> | |
<script src='L.TileLayer.d3_JSON_mapsense.js' type="text/javascript"></script> | |
<style> | |
html, body, #myMap { width: 100%; height: 100%; margin: 0; padding: 0;} | |
.leaflet-container { | |
background: transparent; | |
outline: 0; | |
} | |
.mapsense-light.tile-background { | |
fill: none; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="myMap"></div> | |
<script> | |
var map = L.map('myMap').setView([38, -122], 8); | |
new L.tileLayer("http://{s}.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg", { | |
attribution: '<a href="http://developer.mapquest.com/web/products/open/map</a>Mapquest</a>', | |
subdomains: ["otile1", "otile2", "otile3", "otile4"] | |
}).addTo(map); | |
// Hat Tip! http://bl.ocks.org/NelsonMinar/5624141 | |
// 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); | |
var mapsense_url = "https://{s}-api.mapsense.co/explore/api/universes/mapsense.earth/{z}/{x}/{y}.topojson?s=10&ringSpan=8&api-key=key-2d5eacd8b924489c8ed5e8418bd883bc"; | |
mapsense_url += "&where=layer=='roads'"; | |
new L.TileLayer.d3_JSON(mapsense_url, { | |
attribution: '<a target="_blank" href="https://developer.mapsense.co/tileViewer/?tileset=mapsense.earth">©Mapsense ©OpenStreetMap</a>', | |
// https://developer.mapsense.co/documentation/basemap | |
//mapsenseStyle: "vintage" // choose a basemap style, or style your own at styler.mapsense.co | |
}).addTo(map); | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
L.TileLayer.d3_JSON = L.TileLayer.extend({ | |
//extending L.TileLayer to support topoJSON and geoJSON vector sources | |
//rendering with d3, borrows from zjonsson & https://github.com/glenrobertson/leaflet-tilelayer-geojson/ | |
onAdd: function(map) { | |
var map_container_svg = d3.select(map._container).select("svg"); | |
L.TileLayer.prototype.onAdd.call(this, map); | |
this.mapsenseStyle = this.options.mapsenseStyle || 'light'; | |
this._path = d3.geo.path().projection({ | |
stream: function(stream) { | |
// no sampling along great arc | |
// just a pure projection, without the default d3 projection-stream pipeline | |
// so, long lines don't make curves, i.e. they obey the mercator projection | |
return { | |
point: function(x, y) { | |
var p = map.latLngToLayerPoint(new L.LatLng(y, x)); | |
stream.point(p.x, p.y); | |
}, | |
lineStart: stream.lineStart, | |
lineEnd: stream.lineEnd, | |
polygonStart: stream.polygonStart, | |
polygonEnd: stream.polygonEnd, | |
sphere: stream.sphere | |
}; | |
} | |
}); | |
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); | |
var mapsenseStyle = this.mapsenseStyle; | |
if (!tile.nodes && !tile.xhr) { | |
tile.xhr = d3.json(this.getTileUrl(tilePoint), function(data) { | |
var geoJson; | |
if (data === '') { | |
// Ignore empty submissions | |
} else { | |
geoJson = topo2Geo(data); | |
} | |
tile.xhr = null; | |
nwPoint = tilePoint.multiplyBy(256); | |
sePoint = nwPoint.add([256, 256]); | |
nw = map.unproject(nwPoint); | |
se = map.unproject(sePoint); | |
var point = map.latLngToLayerPoint(new L.LatLng(nw.lat, nw.lng)); | |
var tile_coords = "tile_" + point.x + "_" + point.y; | |
d3.select(map._container).select("svg") | |
.append("clipPath") | |
.attr("id", tile_coords) | |
.attr("style", "fill: none; stroke: pink; transform: translate(" + point.x + "px, " + point.y + "px); -webkit-transform: translate(" + point.x + "px, " + point.y + "px);") | |
.append("rect") | |
.attr("width", "256") | |
.attr("height", "256"); | |
d3.select(map._container).select("svg") | |
.append("rect") | |
.attr("style", "transform: translate(" + point.x + "px, " + point.y + "px); -webkit-transform: translate(" + point.x + "px, " + point.y + "px);") | |
.attr("width", "256") | |
.attr("height", "256") | |
.attr("class", "mapsense-"+self.mapsenseStyle +" tile-background"); | |
tile.nodes = d3.select(map._container).select("svg").append("g"); | |
// tile.nodes is now a bunch of appended g's | |
var grp = tile.nodes.selectAll("path") | |
.data(geoJson.features) | |
.enter() | |
.append("g") | |
.attr("class", "groupr"); | |
grp.append("path") | |
.attr("d", self._path) | |
.attr("clip-path", "url(#" + tile_coords + ")") | |
.attr("class", self.options.class) | |
.attr("class", function(d) { // this data is a bunch of features | |
var zoomClass = "_" + Math.floor(map.getZoom()); | |
var classes = ['mapsense-'+self.mapsenseStyle]; | |
if (d.properties) { | |
if (d.properties) { | |
if (d.properties.layer) | |
classes.push(d.properties.layer); | |
if (d.properties.natural) | |
classes.push(d.properties.natural); | |
if (d.properties.sub_layer) | |
classes.push(d.properties.sub_layer); | |
} else { | |
classes.push('unknown'); | |
} | |
classes = classes.join(' '); | |
return classes; | |
} else {} | |
}); | |
}); | |
} | |
} | |
}); | |
function topologyFeatures(topology) { | |
function convert(topology, object, layer, features) { | |
var featureOrCollection = topojson.feature(topology, object), | |
layerFeatures; | |
if (featureOrCollection.type === "FeatureCollection") { | |
layerFeatures = featureOrCollection.features; | |
} else { | |
layerFeatures = [featureOrCollection]; | |
} | |
layerFeatures.forEach(function(f) { | |
f.properties.layer = layer; | |
}); | |
features.push.apply(features, layerFeatures); | |
} | |
var features = []; | |
for (var o in topology.objects) { | |
convert(topology, topology.objects[o], o, features); | |
} | |
return features; | |
} | |
function topo2Geo(tj) { | |
var gj = { | |
type: "FeatureCollection", | |
features: topologyFeatures(tj) | |
}; | |
return gj; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment