UNPKG

mapbox-gl

Version:
162 lines (126 loc) 5.07 kB
'use strict'; var Actor = require('../util/actor'); var WorkerTile = require('./worker_tile'); var util = require('../util/util'); var ajax = require('../util/ajax'); var vt = require('vector-tile'); var Protobuf = require('pbf'); var supercluster = require('supercluster'); var geojsonvt = require('geojson-vt'); var GeoJSONWrapper = require('./geojson_wrapper'); module.exports = function(self) { return new Worker(self); }; function Worker(self) { this.self = self; this.actor = new Actor(self, this); this.loading = {}; this.loaded = {}; this.layers = []; this.geoJSONIndexes = {}; } util.extend(Worker.prototype, { 'set layers': function(layers) { this.layers = layers; }, 'load tile': function(params, callback) { var source = params.source, uid = params.uid; if (!this.loading[source]) this.loading[source] = {}; var tile = this.loading[source][uid] = new WorkerTile(params); tile.xhr = ajax.getArrayBuffer(params.url, done.bind(this)); function done(err, data) { delete this.loading[source][uid]; if (err) return callback(err); tile.data = new vt.VectorTile(new Protobuf(new Uint8Array(data))); tile.parse(tile.data, this.layers, this.actor, callback); this.loaded[source] = this.loaded[source] || {}; this.loaded[source][uid] = tile; } }, 'reload tile': function(params, callback) { var loaded = this.loaded[params.source], uid = params.uid; if (loaded && loaded[uid]) { var tile = loaded[uid]; tile.parse(tile.data, this.layers, this.actor, callback); } }, 'abort tile': function(params) { var loading = this.loading[params.source], uid = params.uid; if (loading && loading[uid]) { loading[uid].xhr.abort(); delete loading[uid]; } }, 'remove tile': function(params) { var loaded = this.loaded[params.source], uid = params.uid; if (loaded && loaded[uid]) { delete loaded[uid]; } }, 'redo placement': function(params, callback) { var loaded = this.loaded[params.source], loading = this.loading[params.source], uid = params.uid; if (loaded && loaded[uid]) { var tile = loaded[uid]; var result = tile.redoPlacement(params.angle, params.pitch, params.collisionDebug); if (result.result) { callback(null, result.result, result.transferables); } } else if (loading && loading[uid]) { loading[uid].angle = params.angle; } }, 'parse geojson': function(params, callback) { var indexData = function(err, data) { if (err) return callback(err); if (typeof data != 'object') { return callback(new Error("Input data is not a valid GeoJSON object.")); } try { this.geoJSONIndexes[params.source] = params.cluster ? supercluster(params.superclusterOptions).load(data.features) : geojsonvt(data, params.geojsonVtOptions); } catch (err) { return callback(err); } callback(null); }.bind(this); // TODO accept params.url for urls instead // Not, because of same origin issues, urls must either include an // explicit origin or absolute path. // ie: /foo/bar.json or http://example.com/bar.json // but not ../foo/bar.json if (typeof params.data === 'string') { ajax.getJSON(params.data, indexData); } else indexData(null, params.data); }, 'load geojson tile': function(params, callback) { var source = params.source, coord = params.coord; if (!this.geoJSONIndexes[source]) return callback(null, null); // we couldn't load the file // console.time('tile ' + coord.z + ' ' + coord.x + ' ' + coord.y); var geoJSONTile = this.geoJSONIndexes[source].getTile(Math.min(coord.z, params.maxZoom), coord.x, coord.y); // console.timeEnd('tile ' + coord.z + ' ' + coord.x + ' ' + coord.y); // if (!geoJSONTile) console.log('not found', this.geoJSONIndexes[source], coord); if (!geoJSONTile) return callback(null, null); // nothing in the given tile var tile = new WorkerTile(params); tile.parse(new GeoJSONWrapper(geoJSONTile.features), this.layers, this.actor, callback); this.loaded[source] = this.loaded[source] || {}; this.loaded[source][params.uid] = tile; }, 'query features': function(params, callback) { var tile = this.loaded[params.source] && this.loaded[params.source][params.uid]; if (tile) { tile.featureTree.query(params, callback); } else { callback(null, []); } } });