mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
Port ALPR camera visuals into the shared layer
Add camera badges, gradient direction wedges and animated tactical selection cards while preserving bounded loading and layer lifecycle. Align the ALPR data-layer header and retain native pick ownership for overlay badges. Co-authored-by: manjunath22466 <[email protected]>
This commit is contained in:
1 parent
687edc4da7
commit
87629ac175
21 files changed
+951
-97
No files matched your search
@@ -462,29 +462,25 @@ test('all manufacturers share one ALPR title and color; only supplied metadata a
|
||||
assert.equal(alprCamerasLayer.name, 'ALPR Cameras');
|
||||
assert.deepEqual(
|
||||
entities.map((entity) => entity.gevLabelModel.title),
|
||||
Array(3).fill('ALPR CAMERA'),
|
||||
['ALPR-0042', 'ALPR-0043', 'ALPR-0044'],
|
||||
);
|
||||
assert.equal(
|
||||
new Set(
|
||||
entities.map((entity) =>
|
||||
entity.point.color.getValue().toCssColorString(),
|
||||
),
|
||||
).size,
|
||||
new Set(entities.map((entity) => entity.billboard.image.getValue())).size,
|
||||
1,
|
||||
);
|
||||
assert.deepEqual(entities[0].gevLabelModel.details, [
|
||||
'Manufacturer: Flock Safety',
|
||||
'Operator: City Police',
|
||||
'Type: fixed',
|
||||
'Source: OpenStreetMap',
|
||||
'OSM MAPPED',
|
||||
'FLOCK SAFETY · CITY POLICE · FIXED',
|
||||
'PUBLIC MAP DATA',
|
||||
]);
|
||||
assert.deepEqual(entities[1].gevLabelModel.details, [
|
||||
'Manufacturer: Motorola Solutions',
|
||||
'Source: OpenStreetMap',
|
||||
'OSM MAPPED',
|
||||
'MOTOROLA SOLUTIONS',
|
||||
'PUBLIC MAP DATA',
|
||||
]);
|
||||
assert.deepEqual(
|
||||
entities[2].gevLabelModel.details,
|
||||
['Source: OpenStreetMap'],
|
||||
['OSM MAPPED', 'PUBLIC MAP DATA'],
|
||||
'unknown metadata is not guessed, but the source is always named',
|
||||
);
|
||||
for (const entity of entities) {
|
||||
@@ -523,8 +519,8 @@ test('clicking the selected camera or empty map deselects, including after refre
|
||||
await alprCamerasLayer.update();
|
||||
assert.equal(getSelectedEntityContext(), null);
|
||||
assert.equal(
|
||||
h.source.entities.getById('alpr:42').point.pixelSize.getValue(),
|
||||
8,
|
||||
h.source.entities.getById('alpr:42').billboard.width.getValue(),
|
||||
38,
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
@@ -582,8 +578,8 @@ test('disable removes contexts and highlight; cache reuse after re-enable does n
|
||||
await alprCamerasLayer.update();
|
||||
assert.equal(getSelectedEntityContext(), null);
|
||||
assert.equal(
|
||||
h.source.entities.getById('alpr:42').point.pixelSize.getValue(),
|
||||
8,
|
||||
h.source.entities.getById('alpr:42').billboard.width.getValue(),
|
||||
38,
|
||||
);
|
||||
} finally {
|
||||
h.restore();
|
||||
@@ -1100,7 +1096,7 @@ test('nearby count and discovery control frame a real loaded camera without fetc
|
||||
await alprCamerasLayer.update();
|
||||
assert.equal(alprCamerasLayer.getStats().countLabel, '1 nearby');
|
||||
const controls = alprCamerasLayer.getRowControls();
|
||||
assert.equal(controls.legend[0].label, 'Purple dots');
|
||||
assert.equal(controls.legend[0].label, 'Camera badges');
|
||||
assert.equal(controls.chips[0].onClick(), true);
|
||||
assert.equal(flights.length, 1);
|
||||
assert.equal(getSelectedEntityContext().id, 'alpr:42');
|
||||
|
||||
@@ -142,8 +142,16 @@ export function createTrackedOverlayEntry(entity) {
|
||||
title,
|
||||
details: Array.isArray(model.details) ? model.details.map((line) => String(line)) : [],
|
||||
accent: model.accent || WORLD_OVERLAY_STYLE.accent,
|
||||
anchorRadiusPx: 10,
|
||||
anchorRadiusScale: TRACKED_BILLBOARD_SCALE,
|
||||
cardStyle: model.cardStyle,
|
||||
selected: model.selected === true,
|
||||
leaderStyle: model.leaderStyle,
|
||||
leaderAnimationMs: model.leaderAnimationMs,
|
||||
leaderAnimationStartedAt: model.leaderAnimationStartedAt,
|
||||
leaderDrawRatio: model.leaderDrawRatio,
|
||||
anchorRadiusPx: Number.isFinite(Number(model.anchorRadiusPx))
|
||||
? Math.max(0, Number(model.anchorRadiusPx)) : 10,
|
||||
anchorRadiusScale: Object.prototype.hasOwnProperty.call(model, 'anchorRadiusScale')
|
||||
? model.anchorRadiusScale : TRACKED_BILLBOARD_SCALE,
|
||||
minAnchorGapPx: 16,
|
||||
anchorGapPaddingPx: 10,
|
||||
verticalOnly: true,
|
||||
|
||||
@@ -121,6 +121,26 @@ test('tracked entry factory pins the production protected-lane policy', () => {
|
||||
assert.equal(entry.edgeFade, 'keyhole');
|
||||
});
|
||||
|
||||
test('selected camera readout carries tactical animation and fixed badge clearance', () => {
|
||||
const entry = createTrackedOverlayEntry({
|
||||
id: 'alpr:42', gevDisplayPosition: () => ({ x: 1, y: 2, z: 3 }),
|
||||
gevLabelModel: {
|
||||
title: 'ALPR-0042', details: ['OSM MAPPED'], accent: '#ff6474',
|
||||
cardStyle: 'tactical', selected: true, leaderStyle: 'elbow',
|
||||
leaderAnimationMs: 440, leaderAnimationStartedAt: 100, leaderDrawRatio: 0.68,
|
||||
anchorRadiusPx: 30, anchorRadiusScale: null,
|
||||
},
|
||||
});
|
||||
assert.equal(entry.cardStyle, 'tactical');
|
||||
assert.equal(entry.selected, true);
|
||||
assert.equal(entry.leaderStyle, 'elbow');
|
||||
assert.equal(entry.leaderAnimationMs, 440);
|
||||
assert.equal(entry.leaderAnimationStartedAt, 100);
|
||||
assert.equal(entry.leaderDrawRatio, 0.68);
|
||||
assert.equal(entry.anchorRadiusPx, 30);
|
||||
assert.equal(entry.anchorRadiusScale, null);
|
||||
});
|
||||
|
||||
test('tracked entity publishes a protected host entry backed by the frame cache', () => {
|
||||
const originalWindow = globalThis.window;
|
||||
const fakeWindow = new EventTarget();
|
||||
|
||||
Reference in new issue
Block a user