release: 2026-03-31 (39건 커밋) #210
@ -412,7 +412,7 @@ export function useGearReplayLayers(
|
||||
}
|
||||
}
|
||||
|
||||
// 8. Operational polygons (per model — union of member positions + high-score correlation vessels)
|
||||
// 8. Operational polygons (멤버 위치 + enabledVessels ON인 연관 선박으로 폴리곤 생성)
|
||||
for (const [mn, items] of correlationByModel) {
|
||||
if (!enabledModels.has(mn)) continue;
|
||||
const color = MODEL_COLORS[mn] ?? '#94a3b8';
|
||||
@ -420,13 +420,15 @@ export function useGearReplayLayers(
|
||||
|
||||
const extraPts: [number, number][] = [];
|
||||
for (const c of items as GearCorrelationItem[]) {
|
||||
if (c.score < 0.7) continue;
|
||||
// enabledVessels로 개별 on/off 제어 (토글 대응)
|
||||
if (!enabledVessels.has(c.targetMmsi)) continue;
|
||||
const cp = corrPositions.find(p => p.mmsi === c.targetMmsi);
|
||||
if (cp) extraPts.push([cp.lon, cp.lat]);
|
||||
}
|
||||
if (extraPts.length === 0) continue;
|
||||
|
||||
const opPolygon = buildInterpPolygon([...memberPts, ...extraPts]);
|
||||
const basePts = enabledModels.has('identity') ? memberPts : [];
|
||||
const opPolygon = buildInterpPolygon([...basePts, ...extraPts]);
|
||||
if (!opPolygon) continue;
|
||||
|
||||
layers.push(new PolygonLayer({
|
||||
|
||||
@ -144,8 +144,9 @@ export interface CorrelationTrackPoint {
|
||||
export interface CorrelationVesselTrack {
|
||||
mmsi: string;
|
||||
name: string;
|
||||
type: string; // 'VESSEL' | 'GEAR'
|
||||
score: number;
|
||||
modelName: string;
|
||||
models: Record<string, number>; // { modelName: score }
|
||||
track: CorrelationTrackPoint[];
|
||||
}
|
||||
|
||||
|
||||
@ -78,8 +78,9 @@ def get_correlation_tracks(
|
||||
):
|
||||
"""Return correlated vessels with their track history for map rendering.
|
||||
|
||||
Queries gear_correlation_scores (default model) and enriches with
|
||||
Queries gear_correlation_scores (ALL active models) and enriches with
|
||||
24h track data from in-memory vessel_store.
|
||||
Each vessel includes which models detected it.
|
||||
"""
|
||||
from cache.vessel_store import vessel_store
|
||||
|
||||
@ -87,7 +88,7 @@ def get_correlation_tracks(
|
||||
conn = kcgdb.get_conn()
|
||||
cur = conn.cursor()
|
||||
|
||||
# Get correlated vessels from default model
|
||||
# Get correlated vessels from ALL active models
|
||||
cur.execute("""
|
||||
SELECT s.target_mmsi, s.target_type, s.target_name,
|
||||
s.current_score, m.name AS model_name
|
||||
@ -95,7 +96,6 @@ def get_correlation_tracks(
|
||||
JOIN kcg.correlation_param_models m ON s.model_id = m.id
|
||||
WHERE s.group_key = %s
|
||||
AND s.current_score >= %s
|
||||
AND m.is_default = TRUE
|
||||
AND m.is_active = TRUE
|
||||
ORDER BY s.current_score DESC
|
||||
""", (group_key, min_score))
|
||||
@ -107,31 +107,41 @@ def get_correlation_tracks(
|
||||
if not rows:
|
||||
return {'groupKey': group_key, 'vessels': []}
|
||||
|
||||
# Collect target MMSIs
|
||||
vessel_info = []
|
||||
mmsis = []
|
||||
# Group by MMSI: collect all models per vessel, keep highest score
|
||||
vessel_map: dict[str, dict] = {}
|
||||
for row in rows:
|
||||
vessel_info.append({
|
||||
'mmsi': row[0],
|
||||
'type': row[1],
|
||||
'name': row[2] or '',
|
||||
'score': float(row[3]),
|
||||
'modelName': row[4],
|
||||
})
|
||||
mmsis.append(row[0])
|
||||
mmsi = row[0]
|
||||
model_name = row[4]
|
||||
score = float(row[3])
|
||||
if mmsi not in vessel_map:
|
||||
vessel_map[mmsi] = {
|
||||
'mmsi': mmsi,
|
||||
'type': row[1],
|
||||
'name': row[2] or '',
|
||||
'score': score,
|
||||
'models': {model_name: score},
|
||||
}
|
||||
else:
|
||||
entry = vessel_map[mmsi]
|
||||
entry['models'][model_name] = score
|
||||
if score > entry['score']:
|
||||
entry['score'] = score
|
||||
|
||||
mmsis = list(vessel_map.keys())
|
||||
|
||||
# Get tracks from vessel_store
|
||||
tracks = vessel_store.get_vessel_tracks(mmsis, hours)
|
||||
|
||||
# Build response
|
||||
vessels = []
|
||||
for info in vessel_info:
|
||||
for info in vessel_map.values():
|
||||
track = tracks.get(info['mmsi'], [])
|
||||
vessels.append({
|
||||
'mmsi': info['mmsi'],
|
||||
'name': info['name'],
|
||||
'type': info['type'],
|
||||
'score': info['score'],
|
||||
'modelName': info['modelName'],
|
||||
'models': info['models'], # {modelName: score, ...}
|
||||
'track': track,
|
||||
})
|
||||
|
||||
|
||||
불러오는 중...
Reference in New Issue
Block a user