Skip to content

Instantly share code, notes, and snippets.

@bsudekum
Last active December 17, 2015 10:59
Show Gist options
  • Save bsudekum/5598998 to your computer and use it in GitHub Desktop.
Save bsudekum/5598998 to your computer and use it in GitHub Desktop.
Rendering OSM Vector tiles with MapBox.js. This needs to be improved, big time.
<!DOCTYPE html>
<html lang="en"><head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0"/>
<script src='http://api.tiles.mapbox.com/mapbox.js/v1.0.2/mapbox.js'></script>
<link href='http://api.tiles.mapbox.com/mapbox.js/v1.0.2/mapbox.css' rel='stylesheet' />
<!--[if lte IE 8]>
<link href='http://api.tiles.mapbox.com/mapbox.js/v1.0.2/mapbox.ie.css' rel='stylesheet' >
<![endif]-->
<script src="tilejson.js"></script>
<style type="text/css">
html,
body {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#map {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
var map = L.map('map').setView([37.7946, -122.4113], 16);
L_PREFER_CANVAS = true;
var geojsonURL = "http://a.tile.openstreetmap.us/vectiles-highroad/{z}/{x}/{y}.json";
var geojsonTileLayer = new L.TileLayer.GeoJSON(geojsonURL);
map.addLayer(geojsonTileLayer);
map.attributionControl.addAttribution("OSM");
</script>
</body>
</html>
var totalData = 0
// Load data tiles using the JQuery ajax function
L.TileLayer.Ajax = L.TileLayer.extend({
_requests: [],
_data: [],
data: function () {
for (var t in this._tiles) {
var tile = this._tiles[t];
if (!tile.processed) {
this._data = this._data.concat(tile.datum);
tile.processed = true;
}
}
return this._data;
},
_addTile: function(tilePoint, container) {
var tile = { datum: null, processed: false };
this._tiles[tilePoint.x + ':' + tilePoint.y] = tile;
this._loadTile(tile, tilePoint);
},
// XMLHttpRequest handler; closure over the XHR object, the layer, and the tile
_xhrHandler: function (req, layer, tile) {
return function() {
if (req.readyState != 4) {
return;
}
var s = req.status;
if ((s >= 200 && s < 300) || s == 304) {
totalData += req.responseText.length;
console.log(Math.round(window.performance.now() - req._startTime) + "ms",
Math.round(req.responseText.length / 1024) + "k total: " + Math.round(totalData / 1024) + "k " +
req._url);
tile.datum = JSON.parse(req.responseText);
layer._tileLoaded();
} else {
layer._tileLoaded();
}
}
},
// Load the requested tile via AJAX
_loadTile: function (tile, tilePoint) {
this._adjustTilePoint(tilePoint);
var layer = this;
var req = new XMLHttpRequest();
req._startTime = window.performance.now()
req._url = this.getTileUrl(tilePoint);
this._requests.push(req);
req.onreadystatechange = this._xhrHandler(req, layer, tile);
req.open('GET', this.getTileUrl(tilePoint), true);
req.send();
},
_resetCallback: function() {
this._data = [];
L.TileLayer.prototype._resetCallback.apply(this, arguments);
for (var i in this._requests) {
this._requests[i].abort();
}
this._requests = [];
},
_update: function() {
if (this._map._panTransition && this._map._panTransition._inProgress) { return; }
if (this._tilesToLoad < 0) this._tilesToLoad = 0;
L.TileLayer.prototype._update.apply(this, arguments);
}
});
L.TileLayer.GeoJSON = L.TileLayer.Ajax.extend({
_geojson: {"type":"FeatureCollection","features":[]},
initialize: function (url, options, geojsonOptions) {
L.TileLayer.Ajax.prototype.initialize.call(this, url, options);
this.geojsonLayer = new L.GeoJSON(this._geojson, geojsonOptions);
this.geojsonOptions = geojsonOptions;
},
onAdd: function (map) {
this._map = map;
L.TileLayer.Ajax.prototype.onAdd.call(this, map);
this.on('load', this._tilesLoaded);
map.addLayer(this.geojsonLayer);
},
onRemove: function (map) {
map.removeLayer(this.geojsonLayer);
this.off('load', this._tilesLoaded);
L.TileLayer.Ajax.prototype.onRemove.call(this, map);
},
data: function () {
this._geojson.features = [];
if (this.options.unique) {
this._uniqueKeys = {};
}
var tileData = L.TileLayer.Ajax.prototype.data.call(this);
for (var t in tileData) {
var tileDatum = tileData[t];
if (tileDatum && tileDatum.features) {
// deduplicate features by using the string result of the unique function
if (this.options.unique) {
for (var f in tileDatum.features) {
var featureKey = this.options.unique(tileDatum.features[f]);
if (this._uniqueKeys.hasOwnProperty(featureKey)) {
delete tileDatum.features[f];
}
else {
this._uniqueKeys[featureKey] = featureKey;
}
}
}
this._geojson.features =
this._geojson.features.concat(tileDatum.features);
}
}
return this._geojson;
},
_resetCallback: function () {
this._geojson.features = [];
L.TileLayer.Ajax.prototype._resetCallback.apply(this, arguments);
},
_tilesLoaded: function (evt) {
this.geojsonLayer.clearLayers().addData(this.data());
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment