fix(map): apply vessel data filters to the carrier layer

Carrier icons and labels are built on the main thread from the raw ship
array, separately from the worker that draws every other vessel, so the
Data Filters vessel name / type selection never reached them. Filtering
to yachts left the aircraft carriers on the map.

Move the ship filter predicate into a shared helper used by both the
worker and the carrier builder so all ship sources honour the same
selection.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
C3B2W23
2026-09-11 16:02:31 -07:00
co-authored by Claude Fable 5.1
parent 46f6b7891f
commit 9df81bf636
4 changed files with 70 additions and 14 deletions
@@ -3,6 +3,7 @@
import { classifyAircraft } from '@/utils/aircraftClassification';
import type { Flight, Ship, SigintSignal } from '@/types/dashboard';
import type { FlightLayerConfig } from '@/components/map/geoJSONBuilders';
import { filterShipsByActiveFilters } from '@/components/map/shipFilters';
type BoundsTuple = [number, number, number, number];
type FC = GeoJSON.FeatureCollection | null;
@@ -523,16 +524,7 @@ function applyFilters(activeFilters: Record<string, string[]> | undefined) {
}
// ── Ships ──
let ships = dynamicData.ships;
if (ships && (has('ship_name') || has('ship_type'))) {
const nameSet = has('ship_name') ? set('ship_name') : null;
const typeSet = has('ship_type') ? set('ship_type') : null;
ships = ships.filter((s: any) => {
if (nameSet && !nameSet.has(s.name)) return false;
if (typeSet && !typeSet.has(s.type)) return false;
return true;
});
}
const ships = dynamicData.ships ? filterShipsByActiveFilters(dynamicData.ships, f) : dynamicData.ships;
return { commercial, private_, jets, military, tracked, ships };
}
@@ -0,0 +1,21 @@
import type { Ship } from '@/types/dashboard';
/**
* Operator vessel filters from the Data Filters panel. Shared by the worker
* (regular ship icons) and the main thread (carrier icons and labels) so every
* ship source honours the same name / type selection.
*/
export function filterShipsByActiveFilters<T extends Pick<Ship, 'name' | 'type'>>(
ships: T[] | undefined,
activeFilters: Record<string, string[]> | undefined,
): T[] {
if (!ships) return [];
const nameSet = activeFilters?.ship_name?.length ? new Set(activeFilters.ship_name) : null;
const typeSet = activeFilters?.ship_type?.length ? new Set(activeFilters.ship_type) : null;
if (!nameSet && !typeSet) return ships;
return ships.filter((s) => {
if (nameSet && !nameSet.has(s.name)) return false;
if (typeSet && !typeSet.has(s.type)) return false;
return true;
});
}