mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-13 06:42:23 +00:00
fix(cockpit): the bridge radar matches the view out of the window
The radar centred on the ship's last AIS fix while the camera rode that fix dead-reckoned up to 180 s ahead: at 20 kn about a nautical mile apart, so a ship already passed still showed ahead. Own ship now sits where the camera rides and each contact is dead-reckoned to the same moment; the query reaches past the range for ships that have since moved into it. Ships with no MMSI each get a key of their own instead of all sharing an empty one on the scope.
This commit is contained in:
1 parent
18c15d0352
commit
052731202d
9 files changed
+154
-29
No files matched your search
@@ -360,8 +360,12 @@ export function createQueries({
|
||||
* @param {number} [maxCount=60] Maximum entries to return.
|
||||
* @returns {Array<{ id: string, name: string, latitude: number,
|
||||
* longitude: number, course: number|null, heading: number|null,
|
||||
* type: string, color: string, stale: boolean }>} Empty while the
|
||||
* layer is off.
|
||||
* type: string, color: string, stale: boolean,
|
||||
* motionCourse: number|null, velocityMps: number|null,
|
||||
* fixEpochMs: number|null, receivedAtMs: number|null,
|
||||
* feedEpochMs: number|null }>} Empty while the layer is off. The
|
||||
* motion fields are `vesselCockpitInfo`'s, for dead reckoning; a
|
||||
* ship with no MMSI has no motion fields and an `unkeyed:` id.
|
||||
*/
|
||||
getRadarContacts(lat, lon, rangeM, maxCount = 60) {
|
||||
const records = state.records.all;
|
||||
@@ -379,27 +383,36 @@ export function createQueries({
|
||||
};
|
||||
|
||||
const entries = [];
|
||||
for (const record of records) {
|
||||
if (subject && String(record.mmsi) === subject) continue;
|
||||
records.forEach((record, index) => {
|
||||
if (subject && String(record.mmsi) === subject) return;
|
||||
const distanceM = greatCircleMeters(center, {
|
||||
lat: record.lat,
|
||||
lon: record.lon,
|
||||
});
|
||||
if (!(distanceM <= rangeM)) continue;
|
||||
entries.push({ record, distanceM });
|
||||
}
|
||||
if (!(distanceM <= rangeM)) return;
|
||||
entries.push({ record, index, distanceM });
|
||||
});
|
||||
entries.sort((a, b) => a.distanceM - b.distanceM);
|
||||
return entries.slice(0, cap).map(({ record }) => ({
|
||||
id: String(record.mmsi),
|
||||
name: String(record.name || record.mmsi),
|
||||
latitude: record.lat,
|
||||
longitude: record.lon,
|
||||
course: finite(record.course),
|
||||
heading: finite(record.heading),
|
||||
type: String(record.type || ''),
|
||||
color: vesselTypeCss(record.type),
|
||||
stale: (record.missedRefreshes || 0) > 0,
|
||||
}));
|
||||
return entries.slice(0, cap).map(({ record, index }) => {
|
||||
const motion = vesselCockpitInfo(record);
|
||||
return {
|
||||
// A ship with no MMSI still needs a key of its own on the scope.
|
||||
id: record.mmsi ? String(record.mmsi) : `unkeyed:${index}`,
|
||||
name: String(record.name || record.mmsi || ''),
|
||||
latitude: record.lat,
|
||||
longitude: record.lon,
|
||||
course: finite(record.course),
|
||||
heading: finite(record.heading),
|
||||
type: String(record.type || ''),
|
||||
color: vesselTypeCss(record.type),
|
||||
stale: (record.missedRefreshes || 0) > 0,
|
||||
motionCourse: motion?.motionCourse ?? null,
|
||||
velocityMps: motion?.velocityMps ?? null,
|
||||
fixEpochMs: motion?.fixEpochMs ?? null,
|
||||
receivedAtMs: motion?.receivedAtMs ?? null,
|
||||
feedEpochMs: motion?.feedEpochMs ?? null,
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user