vector-tile-esm
Version:
Parses vector tiles
126 lines (100 loc) • 2.66 kB
JavaScript
import { types, toGeoJSON } from "./geojson.js";
export function VectorTileFeature(pbf, end, extent, keys, values) {
// Public
this.properties = {};
this.extent = extent;
this.type = 0;
// Private
this._pbf = pbf;
this._geometry = -1;
this._keys = keys;
this._values = values;
pbf.readFields(readFeature, this, end);
}
function readFeature(tag, feature, pbf) {
if (tag == 1) feature.id = pbf.readVarint();
else if (tag == 2) readTag(pbf, feature);
else if (tag == 3) feature.type = pbf.readVarint();
else if (tag == 4) feature._geometry = pbf.pos;
}
function readTag(pbf, feature) {
const end = pbf.readVarint() + pbf.pos;
const { _keys, _values } = feature;
while (pbf.pos < end) {
const key = _keys[pbf.readVarint()];
const value = _values[pbf.readVarint()];
feature.properties[key] = value;
}
}
VectorTileFeature.prototype.loadGeometry = function() {
const pbf = this._pbf;
pbf.pos = this._geometry;
const end = pbf.readVarint() + pbf.pos;
let cmd = 1;
let length = 0;
let x = 0;
let y = 0;
const lines = [];
let line;
while (pbf.pos < end) {
if (length <= 0) {
const cmdLen = pbf.readVarint();
cmd = cmdLen & 0x7;
length = cmdLen >> 3;
}
length--;
if (cmd === 1 || cmd === 2) {
x += pbf.readSVarint();
y += pbf.readSVarint();
if (cmd === 1) { // moveTo
if (line) lines.push(line);
line = [];
}
line.push({ x, y });
} else if (cmd === 7) {
// Workaround for https://github.com/mapbox/mapnik-vector-tile/issues/90
if (line) line.push({ // closePolygon
x: line[0].x,
y: line[0].y
});
} else {
throw Error("unknown command " + cmd);
}
}
if (line) lines.push(line);
return lines;
};
VectorTileFeature.prototype.bbox = function() {
const pbf = this._pbf;
pbf.pos = this._geometry;
const end = pbf.readVarint() + pbf.pos;
let cmd = 1;
let length = 0;
let x = 0;
let y = 0;
let x1 = Infinity;
let x2 = -Infinity;
let y1 = Infinity;
let y2 = -Infinity;
while (pbf.pos < end) {
if (length <= 0) {
const cmdLen = pbf.readVarint();
cmd = cmdLen & 0x7;
length = cmdLen >> 3;
}
length--;
if (cmd === 1 || cmd === 2) {
x += pbf.readSVarint();
y += pbf.readSVarint();
if (x < x1) x1 = x;
if (x > x2) x2 = x;
if (y < y1) y1 = y;
if (y > y2) y2 = y;
} else if (cmd !== 7) {
throw Error("unknown command " + cmd);
}
}
return [x1, y1, x2, y2];
};
VectorTileFeature.types = types;
VectorTileFeature.prototype.toGeoJSON = toGeoJSON;