mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
Separate vessel records and acquisition from scene resources
This commit is contained in:
1 parent
852008df4d
commit
bdc026e50a
26 files changed
+877
-508
No files matched your search
@@ -27,8 +27,8 @@ export function createQueries({
|
||||
function aisRetryInSec() {
|
||||
// A rejected key is terminal until someone changes it; an hour-long
|
||||
// countdown would imply waiting is the fix.
|
||||
if (state.transportStatus === 'auth-failed') return 0;
|
||||
const at = Number(state.nextAttemptAt);
|
||||
if (state.feed.transportStatus === 'auth-failed') return 0;
|
||||
const at = Number(state.feed.nextAttemptAt);
|
||||
if (!Number.isFinite(at) || at <= 0) return 0;
|
||||
return Math.max(0, Math.ceil((at - vesselState._aisRuntime.now()) / 1000));
|
||||
}
|
||||
@@ -142,7 +142,7 @@ export function createQueries({
|
||||
* fields are null, never NaN/undefined. navStatus is always null: the
|
||||
* /api/ais-live proxy does not surface AIS NavigationalStatus, so it
|
||||
* cannot be derived client-side.
|
||||
* @param {Object|null|undefined} record - `state.vesselMap`/`state.vesselRecords` entry.
|
||||
* @param {Object|null|undefined} record - `state.records.byMmsi`/`state.records.all` entry.
|
||||
* @returns {{id: string|null, mmsi: string|null, name: string|null,
|
||||
* lat: number|null, lon: number|null, speedKts: number|null,
|
||||
* courseDeg: number|null, shipType: string|null, destination: string|null,
|
||||
@@ -248,14 +248,14 @@ export function createQueries({
|
||||
*/
|
||||
findByQuery(query) {
|
||||
if (query === null || query === undefined) return null;
|
||||
const records = state.vesselRecords;
|
||||
const records = state.records.all;
|
||||
if (!Array.isArray(records) || !records.length) return null;
|
||||
const q = String(query).trim();
|
||||
if (!q) return null;
|
||||
|
||||
let record = null;
|
||||
if (/^\d+$/.test(q)) {
|
||||
record = state.vesselMap.get(q) || null;
|
||||
record = state.records.byMmsi.get(q) || null;
|
||||
}
|
||||
if (!record) {
|
||||
const lower = q.toLowerCase();
|
||||
@@ -268,7 +268,9 @@ export function createQueries({
|
||||
}
|
||||
if (!record) return null;
|
||||
|
||||
const position = record.billboard?.position || record.position;
|
||||
const position =
|
||||
components.rendering.getVisual(record).billboard?.position ||
|
||||
components.rendering.getVisual(record).position;
|
||||
if (!position) return null;
|
||||
return {
|
||||
mmsi: record.mmsi,
|
||||
@@ -290,7 +292,7 @@ export function createQueries({
|
||||
* @returns {Array<{ mmsi: string, name: string, position: Cesium.Cartesian3, distanceM: number }>}
|
||||
*/
|
||||
getNearby(centerCartesian, rangeM, maxCount = 25) {
|
||||
const records = state.vesselRecords;
|
||||
const records = state.records.all;
|
||||
if (!centerCartesian || !Array.isArray(records) || !records.length)
|
||||
return [];
|
||||
const range = Number.isFinite(rangeM) && rangeM > 0 ? rangeM : Infinity;
|
||||
@@ -299,9 +301,10 @@ export function createQueries({
|
||||
|
||||
const entries = [];
|
||||
for (const record of records) {
|
||||
const visual = components.rendering.getVisual(record);
|
||||
if (!Number.isFinite(record.lat) || !Number.isFinite(record.lon))
|
||||
continue;
|
||||
const position = record.billboard?.position || record.position;
|
||||
const position = visual.billboard?.position || visual.position;
|
||||
if (!position) continue;
|
||||
const distanceM = Cesium.Cartesian3.distance(centerCartesian, position);
|
||||
if (!Number.isFinite(distanceM) || distanceM > range) continue;
|
||||
@@ -333,22 +336,27 @@ export function createQueries({
|
||||
* holds no data and therefore cannot answer.
|
||||
*/
|
||||
hasContact(mmsi) {
|
||||
if (!state.enabled || !state.vesselMap || state.vesselMap.size === 0)
|
||||
if (
|
||||
!state.feed.enabled ||
|
||||
!state.records.byMmsi ||
|
||||
state.records.byMmsi.size === 0
|
||||
)
|
||||
return null;
|
||||
if (!mmsi) return false;
|
||||
return state.vesselMap.has(String(mmsi).trim());
|
||||
return state.records.byMmsi.has(String(mmsi).trim());
|
||||
},
|
||||
|
||||
getAllPositions(maxCount = 800) {
|
||||
const result = [];
|
||||
const records = state.vesselRecords;
|
||||
const records = state.records.all;
|
||||
if (!Array.isArray(records)) return result;
|
||||
const cap =
|
||||
Number.isFinite(maxCount) && maxCount > 0 ? Math.floor(maxCount) : 800;
|
||||
|
||||
for (const record of records) {
|
||||
const visual = components.rendering.getVisual(record);
|
||||
if (result.length >= cap) break;
|
||||
const position = record.billboard?.position || record.position;
|
||||
const position = visual.billboard?.position || visual.position;
|
||||
if (!position) continue;
|
||||
result.push({
|
||||
id: record.mmsi,
|
||||
@@ -370,8 +378,8 @@ export function createQueries({
|
||||
* @returns {Array<Object>} See mapAnalystRecord for the record shape.
|
||||
*/
|
||||
getAnalystRecords(maxCount = 2000) {
|
||||
if (!state.enabled) return [];
|
||||
const records = state.vesselRecords;
|
||||
if (!state.feed.enabled) return [];
|
||||
const records = state.records.all;
|
||||
if (!Array.isArray(records) || !records.length) return [];
|
||||
const limit = Number.isFinite(maxCount)
|
||||
? Math.max(1, Math.floor(maxCount))
|
||||
@@ -394,7 +402,7 @@ export function createQueries({
|
||||
if (mmsi === null || mmsi === undefined) return false;
|
||||
const target = String(mmsi).trim();
|
||||
if (!target) return false;
|
||||
const record = state.vesselMap.get(target);
|
||||
const record = state.records.byMmsi.get(target);
|
||||
if (!record) return false;
|
||||
components.selection.selectVessel(record);
|
||||
return true;
|
||||
@@ -438,12 +446,12 @@ export function createQueries({
|
||||
*/
|
||||
getDetectableObjects(options = {}) {
|
||||
if (
|
||||
!state.enabled ||
|
||||
!state.feed.enabled ||
|
||||
!state.billboardCollection ||
|
||||
!state.billboardCollection.show
|
||||
)
|
||||
return [];
|
||||
const records = state.vesselRecords;
|
||||
const records = state.records.all;
|
||||
if (!Array.isArray(records) || !records.length) return [];
|
||||
|
||||
const maxCount = Number.isFinite(options.maxCount)
|
||||
@@ -459,8 +467,9 @@ export function createQueries({
|
||||
for (let idx = 0; idx < records.length; idx += 1) {
|
||||
if ((idx - start) % stride !== 0) continue;
|
||||
const record = records[idx];
|
||||
if (record.billboard && !record.billboard.show) continue;
|
||||
const position = record.billboard?.position || record.position;
|
||||
const visual = components.rendering.getVisual(record);
|
||||
if (visual.billboard && !visual.billboard.show) continue;
|
||||
const position = visual.billboard?.position || visual.position;
|
||||
if (!position) continue;
|
||||
result.push({
|
||||
position,
|
||||
@@ -488,22 +497,25 @@ export function createQueries({
|
||||
: {}),
|
||||
|
||||
getStats() {
|
||||
const waitingForFirstPosition = state.firstConnectPhase === 'loading';
|
||||
const waitingForFirstPosition =
|
||||
state.feed.firstConnectPhase === 'loading';
|
||||
return {
|
||||
count: state.count,
|
||||
lastUpdate: state.lastUpdate,
|
||||
loading: state.loading || waitingForFirstPosition,
|
||||
count: state.feed.count,
|
||||
lastUpdate: state.feed.lastUpdate,
|
||||
loading: state.feed.loading || waitingForFirstPosition,
|
||||
loadingLabel: waitingForFirstPosition
|
||||
? AIS_FIRST_CONNECT_LABEL
|
||||
: state.loadingLabel,
|
||||
error: state.error,
|
||||
stale: state.stale,
|
||||
: state.feed.loadingLabel,
|
||||
error: state.feed.error,
|
||||
stale: state.feed.stale,
|
||||
status:
|
||||
state.firstConnectPhase === 'unavailable' ? 'unavailable' : undefined,
|
||||
transportStatus: state.transportStatus,
|
||||
lastMessageAt: state.lastMessageAt,
|
||||
rawRowCount: state.rawRowCount,
|
||||
acceptedRowCount: state.acceptedRowCount,
|
||||
state.feed.firstConnectPhase === 'unavailable'
|
||||
? 'unavailable'
|
||||
: undefined,
|
||||
transportStatus: state.feed.transportStatus,
|
||||
lastMessageAt: state.feed.lastMessageAt,
|
||||
rawRowCount: state.feed.rawRowCount,
|
||||
acceptedRowCount: state.feed.acceptedRowCount,
|
||||
// Same chip affordance the flights layer uses: when the server is
|
||||
// backing off, say how long until the next attempt instead of leaving
|
||||
// the user to guess whether anything is still happening.
|
||||
|
||||
Reference in new issue
Block a user