test(cctv): verify Bosch MIC aliases and preserve estimated optics

This commit is contained in:
Said Turksever committed 2026-10-22 23:46:12 +01:00
1 parent 72d1b0f055
commit dec6cb937e
4 files changed
+62 -13

No files matched your search

+6 -4
View File
@@ -236,13 +236,15 @@ fixtures retain their provenance in `src/data/fixtures/README.md`.
### CCTV Camera Database (`src/layers/cctv/modelSpecs.js`)
The CCTV layer's hardware-model specs are a small verbatim extract (v2.26.0, plus the Bosch MIC
The CCTV layer's hardware-model specs are a small extract (v2.26.0, plus the Bosch MIC
records from v2.29.0) of the
[CCTV Camera Database](https://github.com/ch-bas/cctv-camera-database), an open dataset of
camera models transcribed from manufacturer datasheets, dedicated to the public domain under
**CC0-1.0**. Only the records for hardware that the integrated public catalogs name (King
County, Sarasota County, Sioux Falls and the City of Amsterdam register) are bundled, compiled into the module. Nothing is
fetched at runtime. The records describe camera products (optics, resolution, night vision)
**CC0-1.0**. Only the records for hardware named by the integrated public catalogs (King
County, Sarasota County and Sioux Falls), plus the City of Amsterdam register proposed
in [#251](https://github.com/bilawalsidhu/gods-eye-view/pull/251), are bundled, compiled into the module. Nothing is
fetched at runtime. The MIC specification fields are unchanged; product titles are shortened
to model codes and colour aliases are added locally. The records describe camera products (optics, resolution, night vision)
only, never endpoints, stream paths or access data. CC0 requires no attribution; the CCTV HUD
credits it anyway as `SPECS: CCTV-DATABASE.COM` beside any spec line it renders.
+4
View File
@@ -4585,6 +4585,10 @@ silently demoting every later lookup for the session.
multi-sensor datasheets publish a capability range, not the lens's current zoom, so those
cameras keep their estimate and show `SPEC FOV min–max° (CAPABILITY)` beside it. Public
camera state carries `fovSource`, `specFovMinDeg`, `specFovMaxDeg` and `spec` (#452).
The table also includes Bosch MIC-7130, MIC-7502 and MIC-7522 records for the Amsterdam
register proposed in #251, including its `x` colour aliases (#1319). Their axis-less
datasheet FOV does not supply a horizontal capability range or replace the estimated
FOV. Adding these records does not enable the proposed source pack.
- **FIRMS**: no ground clamping (zero 3D-tiles height sampling), ≤18 screen-decluttered ambient labels, click-to-inspect detail card, 2.5k/3k sprite budgets viewport-clipped by FRP.
- **CCTV v2 foundation:** a pitched
frustum wireframe (4 corner rays + far-cap rectangle) with a monitor plane at the frustum's
+11 -9
View File
@@ -12,24 +12,26 @@
* Cameras without an identified model are untouched — unknown never implies
* anything.
*
* Spec records are vendored verbatim from the CCTV Camera Database
* Specification fields are vendored from the CCTV Camera Database
* (https://github.com/ch-bas/cctv-camera-database, CC0-1.0) — an open dataset
* of 29,000+ camera models transcribed from manufacturer datasheets (76% with
* FOV, as of v2.29.0). This module vendors the records that the currently integrated public
* FOV, as of v2.29.0). This module vendors records that the integrated public
* catalogs publish hardware for — King County WA (Cohu, Bosch AUTODOME, Axis
* Q6135-LE), plus the Bosch AUTODOME and Axis PTZ/multisensor models that
* appear in Sarasota County FL and Sioux Falls SD open data, and the Bosch MIC
* PTZs in the City of Amsterdam camera register; packs that publish other
* hardware models can grow it, or vendor the full extract.
* appear in Sarasota County FL and Sioux Falls SD open data, plus the Bosch MIC
* PTZs for the City of Amsterdam camera register proposed in #251; packs that
* publish other hardware models can grow it, or vendor the full extract.
*
* Scope guardrail: records describe camera PRODUCTS (optics, resolution,
* night vision) — never endpoints, stream paths, or access/config data.
*/
/**
* Verbatim records from the dataset's model-enrichment extract (v2.26.0; the
* Bosch MIC records from v2.29.0). Bosch MIC order codes end in a colour
* letter (B black, G grey, W white) on one shared datasheet; those siblings,
* Records from the dataset's model-enrichment extract (v2.26.0; the Bosch MIC
* records from v2.29.0). MIC specification fields are unchanged; product
* titles are shortened to model codes and colour aliases are added locally.
* Bosch MIC order codes end in a colour letter (B black, G grey, W white)
* on one shared datasheet; those siblings,
* and the `x` wildcard registries write for the colour letter, are listed as
* aliases of the one vendored record.
*/
@@ -488,7 +490,7 @@ const NAME_INDEX = RECORDS.flatMap((record) => {
* guesses).
* @param {string} model - Hardware model as named by a source pack or seed.
* @param {string} [manufacturer] - The source's manufacturer, when published.
* @returns {Object|null} The verbatim spec record, or null when unknown.
* @returns {Object|null} The matched spec record, or null when unknown.
*/
export function lookupModelSpec(model, manufacturer) {
const query = words(model).map(stripVariantSuffix);
+41
View File
@@ -273,6 +273,47 @@ test('Amsterdam camera register model strings resolve', () => {
assert.equal(horizontalFovRangeDeg(lookupModelSpec('MIC-7522-Z30B')), null);
});
test('Bosch MIC colour aliases resolve without accepting unknown variants', () => {
for (const [pattern, id] of [
['MIC-7130-P?4', 'bosch-mic-7130-pb4'],
['MIC-7502-Z30?', 'bosch-mic-7502-z30b'],
['MIC-7522-Z30?', 'bosch-mic-7522-z30b'],
]) {
for (const colour of ['B', 'G', 'W', 'x']) {
const model = pattern.replace('?', colour);
assert.equal(lookupModelSpec(model)?.id, id, model);
assert.equal(lookupModelSpec(`bosch ${model.toLowerCase()}`)?.id, id);
assert.equal(lookupModelSpec(model, 'Bosch')?.id, id);
assert.equal(lookupModelSpec(model, 'Axis'), null);
assert.equal(lookupModelSpec(`${model}-UNKNOWN`), null);
}
assert.equal(lookupModelSpec(pattern.replace('?', 'R')), null);
}
});
test('Bosch MIC catalog enrichment preserves estimated and explicit optics', () => {
for (const model of [
'Bosch MIC-7130-Px4',
'Bosch MIC-7502-Z30x',
'Bosch MIC-7522-Z30x',
]) {
for (const pose of [{}, { fovDeg: 44 }, { poseSource: 'curated' }]) {
const [camera] = browserCatalog().buildCatalogFromSources([
{ id: 'amsterdam-mic', lat: 52.37, lon: 4.9, model, ...pose },
]);
assert.ok(camera.spec, model);
assert.equal(camera.fovDeg, pose.fovDeg ?? 74, model);
assert.equal(camera.fovSource, undefined);
assert.equal(camera.specFovMinDeg, undefined);
assert.equal(camera.specFovMaxDeg, undefined);
assert.equal(horizontalFovRangeDeg(camera.spec), null);
assert.equal(fixedHorizontalFovDeg(camera.spec), null);
assert.equal(specFovCapabilityToken(camera), null);
assert.match(specSummary(camera.spec), /^Bosch MIC-.* · PTZ$/);
}
}
});
test('catalog never overwrites an explicit FOV or a curated pose', () => {
const [explicit, curated, cohu, pelco] =
browserCatalog().buildCatalogFromSources([