mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
feat(mapillary): street-level layer core — coverage, sequences, viewer bridge, query engine
Camera-driven Mapillary coverage (z0–5 overview points from orbit, z11–14 ground-clamped sequence lines below 60 km), per-sequence image cones, an embedded MapillaryJS viewer bridge with a camera-follow mode, sprite icons for map features, and a query engine that turns a plan into a streamed z14 tile fan-out. Registers an on-globe CC BY-SA 4.0 credit while enabled. Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
1 parent
0d41b6be54
commit
fa5710bcf2
46 files changed
+9935
-32
No files matched your search
@@ -0,0 +1,58 @@
|
||||
import { PbfReader, PbfWriter } from 'pbf';
|
||||
|
||||
/** Field number of `layers` in a Mapbox Vector Tile, and of `name` in a layer. */
|
||||
const TILE_LAYER_FIELD = 3;
|
||||
const LAYER_NAME_FIELD = 1;
|
||||
|
||||
/** Read a layer's name without touching its features. */
|
||||
function layerName(layerBytes) {
|
||||
const pbf = new PbfReader(layerBytes);
|
||||
let name = '';
|
||||
pbf.readFields((tag, _result, reader) => {
|
||||
if (tag !== LAYER_NAME_FIELD) return;
|
||||
name = reader.readString();
|
||||
reader.pos = reader.length; // the name is all we need
|
||||
}, null);
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop whole layers from a vector tile at the protobuf level. Nothing inside
|
||||
* a kept layer is decoded or re-encoded, so a 12 MB tile whose bulk is an
|
||||
* unused layer trims in a few milliseconds. Returns the input when nothing
|
||||
* was dropped.
|
||||
* @param {Buffer|Uint8Array} bytes
|
||||
* @param {Iterable<string>} dropNames
|
||||
*/
|
||||
export function stripTileLayers(bytes, dropNames) {
|
||||
const drop = new Set(dropNames || []);
|
||||
if (!bytes?.length || !drop.size) return bytes;
|
||||
const reader = new PbfReader(bytes);
|
||||
const writer = new PbfWriter();
|
||||
let dropped = false;
|
||||
reader.readFields((tag, _result, pbf) => {
|
||||
if (tag !== TILE_LAYER_FIELD) return; // pbf skips what we leave alone
|
||||
const end = pbf.readVarint() + pbf.pos;
|
||||
const layerBytes = bytes.subarray(pbf.pos, end);
|
||||
pbf.pos = end;
|
||||
if (drop.has(layerName(layerBytes))) {
|
||||
dropped = true;
|
||||
return;
|
||||
}
|
||||
writer.writeBytesField(TILE_LAYER_FIELD, layerBytes);
|
||||
}, null);
|
||||
return dropped ? Buffer.from(writer.finish()) : bytes;
|
||||
}
|
||||
|
||||
/** Names of the layers inside a vector tile, in order. */
|
||||
export function listTileLayers(bytes) {
|
||||
const names = [];
|
||||
if (!bytes?.length) return names;
|
||||
new PbfReader(bytes).readFields((tag, _result, pbf) => {
|
||||
if (tag !== TILE_LAYER_FIELD) return;
|
||||
const end = pbf.readVarint() + pbf.pos;
|
||||
names.push(layerName(bytes.subarray(pbf.pos, end)));
|
||||
pbf.pos = end;
|
||||
}, null);
|
||||
return names;
|
||||
}
|
||||
Reference in new issue
Block a user