mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-12 06:12:18 +00:00
feat(alpr): render camera markers on Navara
Separate native scene ownership from shared ALPR source and selection state, and add bounded Navara sprites with the existing direction/card overlay. Preserve marker artwork, picking, floor retries and source attribution. Fix lost post-render wakeups and redundant mobile rail mutations, and keep HUD typewriter dimensions stable so static views settle without extra frames. Add parser-fed dev/preview and legacy evidence, including retained failures. Common W2 terrain and combined performance gates remain open.
This commit is contained in:
1 parent
9d587c1d37
commit
46b3aceafc
23 files changed
+2081
-181
No files matched your search
@@ -0,0 +1,132 @@
|
||||
import { PbfWriter } from 'pbf';
|
||||
|
||||
// Recorded journeys cover both a dense neighbourhood and the wider Austin view.
|
||||
export const cameras = [
|
||||
...Array.from({ length: 225 }, (_, i) => ({
|
||||
latitude: 30.262 + (Math.floor(i / 15) - 7) * 0.003,
|
||||
longitude: -97.7431 + ((i % 15) - 7) * 0.003,
|
||||
})),
|
||||
...Array.from({ length: 100 }, (_, i) => ({
|
||||
latitude: 30.308 + (Math.floor(i / 10) - 4.5) * 0.001,
|
||||
longitude: -97.77 + ((i % 10) - 4.5) * 0.001,
|
||||
})),
|
||||
].map((position, i) => ({
|
||||
...position,
|
||||
osmId: 9000000 + i,
|
||||
operator: i % 3 ? 'W2 fixture' : 'Cámara pública',
|
||||
brand: 'Fixture camera',
|
||||
cameraType: 'fixed',
|
||||
direction: i % 5 ? String((i * 37) % 360) : '',
|
||||
}));
|
||||
|
||||
export function cameraTile(z, x, y, records = cameras) {
|
||||
const extent = 4096;
|
||||
const scale = 2 ** z;
|
||||
const rows = records.flatMap((record) => {
|
||||
const latitude = (record.latitude * Math.PI) / 180;
|
||||
const tx = ((record.longitude + 180) / 360) * scale;
|
||||
const ty = ((1 - Math.asinh(Math.tan(latitude)) / Math.PI) / 2) * scale;
|
||||
if (Math.floor(tx) !== x || Math.floor(ty) !== y) return [];
|
||||
return [
|
||||
{
|
||||
record,
|
||||
x: Math.round((tx - x) * extent),
|
||||
y: Math.round((ty - y) * extent),
|
||||
},
|
||||
];
|
||||
});
|
||||
const keys = [
|
||||
'osmType',
|
||||
'osmId',
|
||||
'operator',
|
||||
'brand',
|
||||
'cameraType',
|
||||
'direction',
|
||||
];
|
||||
const writer = new PbfWriter();
|
||||
writer.writeMessage(
|
||||
3,
|
||||
(_, layer) => {
|
||||
layer.writeVarintField(15, 2);
|
||||
layer.writeStringField(1, 'cameras');
|
||||
layer.writeVarintField(5, extent);
|
||||
for (const key of keys) layer.writeStringField(3, key);
|
||||
rows.forEach(({ record, x, y }, index) => {
|
||||
for (const key of keys)
|
||||
layer.writeMessage(
|
||||
4,
|
||||
(_, value) =>
|
||||
value.writeStringField(
|
||||
1,
|
||||
key === 'osmType' ? 'node' : String(record[key]),
|
||||
),
|
||||
null,
|
||||
);
|
||||
layer.writeMessage(
|
||||
2,
|
||||
(_, feature) => {
|
||||
feature.writeVarintField(1, record.osmId);
|
||||
feature.writePackedVarint(
|
||||
2,
|
||||
keys.flatMap((_, i) => [i, index * keys.length + i]),
|
||||
);
|
||||
feature.writeVarintField(3, 1);
|
||||
feature.writePackedVarint(4, [9, x * 2, y * 2]);
|
||||
},
|
||||
null,
|
||||
);
|
||||
});
|
||||
},
|
||||
null,
|
||||
);
|
||||
return Buffer.from(writer.finish());
|
||||
}
|
||||
|
||||
/** Real TileJSON/MVT transport; no replacement of the layer or source parser. */
|
||||
export async function installAlprFixture(page) {
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', (request) => {
|
||||
if (request.isInterceptResolutionHandled()) return;
|
||||
const url = new URL(request.url());
|
||||
// The journey also asks for nearby-place labels while moving. Pin that
|
||||
// auxiliary service; these runs do not test Google Places availability.
|
||||
if (
|
||||
['localhost', '127.0.0.1'].includes(url.hostname) &&
|
||||
url.pathname === '/api/google/nearby-places'
|
||||
) {
|
||||
void request.respond({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({ places: [] }),
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (url.hostname !== 'tiles.dontgetflocked.com') {
|
||||
void request.continue();
|
||||
return;
|
||||
}
|
||||
const headers = { 'access-control-allow-origin': '*' };
|
||||
if (url.pathname.endsWith('.json')) {
|
||||
const country = url.pathname.includes('-ca-') ? 'ca' : 'us';
|
||||
void request.respond({
|
||||
status: 200,
|
||||
headers,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({
|
||||
tiles: [
|
||||
`https://tiles.dontgetflocked.com/cameras-${country}-hourly/{z}/{x}/{y}.mvt`,
|
||||
],
|
||||
bounds: country === 'ca' ? [-124, 42, -63, 54] : [-160, 17, -64, 59],
|
||||
}),
|
||||
});
|
||||
return;
|
||||
}
|
||||
const match = url.pathname.match(/\/(\d+)\/(\d+)\/(\d+)\.mvt$/);
|
||||
void request.respond({
|
||||
status: match ? 200 : 404,
|
||||
headers,
|
||||
contentType: 'application/x-protobuf',
|
||||
body: match ? cameraTile(...match.slice(1).map(Number)) : '',
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user