forked from mapbox/mapbox-gl-js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Proof of concept - vector source w/ dynamic property data
- Loading branch information
Anand Thakker
committed
Jul 14, 2016
1 parent
bd64c2a
commit ae67686
Showing
4 changed files
with
217 additions
and
42 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
'use strict'; | ||
|
||
var webworkify = require('webworkify'); | ||
var Bucket = require('../data/bucket'); | ||
var VectorTileSource = require('./vector_tile_source'); | ||
var vt = require('vector-tile'); | ||
var Protobuf = require('pbf'); | ||
var normalizeURL = require('../util/mapbox').normalizeTileURL; | ||
var util = require('../util/util'); | ||
|
||
module.exports = DynamicVectorSource; | ||
|
||
function DynamicVectorSource(id, options, dispatcher) { | ||
VectorTileSource.call(this, id, options, dispatcher); | ||
this.tileFeatures = {}; | ||
} | ||
|
||
DynamicVectorSource.workerSourceURL = URL.createObjectURL( | ||
webworkify(require('./dynamic_vector_worker'), { bare: true }) | ||
); | ||
|
||
DynamicVectorSource.prototype = util.inherit(VectorTileSource, { | ||
type: 'vector-dynamic', | ||
update: function(data) { | ||
this._dirty = true; | ||
console.info('Updating with random data; TODO: accept new data here and join against user-configured id property'); | ||
this.fire('change'); | ||
}, | ||
loadTile: function(tile, callback) { | ||
if (this._dirty && tile.loaded) { | ||
return this.updateTile(tile, callback); | ||
} | ||
|
||
var overscaling = tile.coord.z > this.maxzoom ? Math.pow(2, tile.coord.z - this.maxzoom) : 1; | ||
var params = { | ||
type: this.type, | ||
url: normalizeURL(tile.coord.url(this.tiles, this.maxzoom, this.scheme), this.url), | ||
uid: tile.uid, | ||
coord: tile.coord, | ||
zoom: tile.coord.z, | ||
tileSize: this.tileSize * overscaling, | ||
source: this.id, | ||
overscaling: overscaling, | ||
angle: this.map.transform.angle, | ||
pitch: this.map.transform.pitch, | ||
showCollisionBoxes: this.map.showCollisionBoxes | ||
}; | ||
|
||
if (tile.workerID) { | ||
params.rawTileData = tile.rawTileData; | ||
this.dispatcher.send('reload tile', params, done.bind(this), tile.workerID); | ||
} else { | ||
tile.workerID = this.dispatcher.send('load tile', params, done.bind(this)); | ||
} | ||
|
||
function done(err, data) { | ||
if (tile.aborted) | ||
return; | ||
|
||
if (err) { | ||
return callback(err); | ||
} | ||
|
||
tile.loadVectorData(data, this.map.style); | ||
|
||
// save serialized arrays even after creating the buckets | ||
// so we can transfer them back during updateTile | ||
for (var b = 0; b < data.buckets.length; b++) { | ||
var bucket = data.buckets[b]; | ||
tile.buckets[bucket.layerId].arrayGroups = bucket.arrays; | ||
} | ||
|
||
var layers = this.tileFeatures[tile.uid] = {}; | ||
this.vtLayers = new vt.VectorTile(new Protobuf(new Uint8Array(tile.rawTileData))).layers; | ||
for (var id in this.vtLayers) { | ||
var features = layers[id] = []; | ||
var layer = this.vtLayers[id]; | ||
for (var i = 0; i < layer.length; i++) { | ||
features.push(layer.feature(i)); | ||
} | ||
} | ||
|
||
if (tile.redoWhenDone) { | ||
tile.redoWhenDone = false; | ||
tile.redoPlacement(this); | ||
} | ||
|
||
callback(null); | ||
} | ||
}, | ||
|
||
getTilePropertyData: function (tile) { | ||
return this.tileFeatures[tile.uid]; | ||
}, | ||
|
||
updateTile: function(tile, callback) { | ||
var prevData = this.getTilePropertyData(tile); | ||
|
||
// dummy data; TODO: make it real | ||
var newData = {}; | ||
for (var layer in prevData) { | ||
newData[layer] = []; | ||
for (var i = 0; i < prevData[layer].length; i++) { | ||
newData[layer].push({ foo: Math.random() * 100 }); | ||
} | ||
} | ||
|
||
var params = { | ||
uid: tile.uid, | ||
source: this.id, | ||
data: newData, | ||
arrayGroups: util.mapObject(tile.buckets, function (b) { return b.arrayGroups; }) | ||
}; | ||
var transferables = []; | ||
if (tile.workerID) { | ||
var buckets = tile.buckets; | ||
for (var id in buckets) { | ||
if (!buckets[id].updateFeatureProperties) continue; | ||
buckets[id].getTransferables(transferables); | ||
} | ||
this.dispatcher.send(this.type + '.updateTile', params, done.bind(this), tile.workerID, transferables); | ||
} else { | ||
// load + update | ||
} | ||
|
||
function done (err, data) { | ||
tile.buckets = unserializeBuckets(data.buckets, this.map.style); | ||
|
||
// save serialized arrays even after creating the buckets | ||
// so we can transfer them back during updateTile | ||
for (var b = 0; b < data.buckets.length; b++) { | ||
var bucket = data.buckets[b]; | ||
tile.buckets[bucket.layerId].arrayGroups = bucket.arrays; | ||
} | ||
|
||
callback(err); | ||
} | ||
} | ||
}); | ||
|
||
function unserializeBuckets(input, style) { | ||
// Guard against the case where the map's style has been set to null while | ||
// this bucket has been parsing. | ||
if (!style) return; | ||
|
||
var output = {}; | ||
for (var i = 0; i < input.length; i++) { | ||
var layer = style.getLayer(input[i].layerId); | ||
if (!layer) continue; | ||
|
||
var bucket = Bucket.create(util.extend({ | ||
layer: layer, | ||
childLayers: input[i].childLayerIds | ||
.map(style.getLayer.bind(style)) | ||
.filter(function(layer) { return layer; }) | ||
}, input[i])); | ||
output[bucket.id] = bucket; | ||
} | ||
return output; | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
'use strict'; | ||
var VectorTileWorkerSource = require('./vector_tile_worker_source'); | ||
var util = require('../util/util'); | ||
|
||
module.exports = function (self) { | ||
self.registerWorkerSource('vector-dynamic', DynamicVectorWorker); | ||
}; | ||
|
||
function DynamicVectorWorker (actor, styleLayers, loadVectorData) { | ||
VectorTileWorkerSource.call(this, actor, styleLayers, loadVectorData); | ||
} | ||
|
||
DynamicVectorWorker.prototype = util.inherit(VectorTileWorkerSource, { | ||
updateTile: function (params, callback) { | ||
var source = params.source; | ||
var uid = params.uid; | ||
if (!this.loaded[source][uid]) { | ||
return callback(); | ||
} | ||
|
||
var layerFamilies = this.styleLayers.getLayerFamilies(); | ||
var tile = this.loaded[source][uid]; | ||
tile.updateProperties(params.data, layerFamilies, this.actor, params.arrayGroups, callback); | ||
} | ||
}); |
This file contains 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