- CollectDB 다중 신호 수집 → S&P Global AIS API 단일 수집으로 전환 - sig_src_cd + target_id 이중 식별자 → mmsi(VARCHAR) 단일 식별자 - t_vessel_latest_position → t_ais_position 테이블 전환 - 레거시 배치/유틸 ~30개 클래스 삭제 (VesselAggregationJobConfig, ShipKindCodeConverter 등) - AisTargetCacheManager 기반 캐시 이중 구조 (최신위치 + 트랙 버퍼) - CacheBasedVesselTrackDataReader + CacheBasedTrackJobListener 신규 추가 - VesselStaticStepConfig: 정적정보 CDC 변경 검출 + hourly job 편승 - SignalKindCode enum: vesselType/extraInfo 기반 선종 자동 분류 - WebSocket/STOMP 전체 mmsi 전환 (StompTrackStreamingService ~40곳) - 모니터링/성능 최적화 코드 mmsi 기반 전환 - DataSource 설정 통합 (snpdb 단일 DB) - AreaBoundaryCache Polygon→Geometry 캐스트 수정 (MULTIPOLYGON 지원) - ConcurrentHashMap 적용 (VesselTrackStepConfig 동시성 버그 수정) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
136 lines
5.1 KiB
SQL
136 lines
5.1 KiB
SQL
-- t_abnormal_tracks 테스트용 INSERT 쿼리
|
|
-- PostGIS ST_GeomFromText 함수 테스트
|
|
|
|
-- 1. 기본 테스트 (track_geom 컬럼 사용)
|
|
INSERT INTO signal.t_abnormal_tracks (
|
|
sig_src_cd,
|
|
target_id,
|
|
time_bucket,
|
|
track_geom,
|
|
abnormal_type,
|
|
abnormal_reason,
|
|
distance_nm,
|
|
avg_speed,
|
|
max_speed,
|
|
point_count,
|
|
source_table
|
|
) VALUES (
|
|
'AIS', -- sig_src_cd
|
|
'TEST_VESSEL_001', -- target_id
|
|
'2025-10-10 12:00:00'::timestamp, -- time_bucket
|
|
ST_GeomFromText('LINESTRING M(126.0 37.0 1728547200, 126.1 37.1 1728547260)', 4326), -- track_geom (LineString M 타입)
|
|
'EXCESSIVE_SPEED', -- abnormal_type
|
|
'{"reason": "Speed exceeds 200 knots", "detected_speed": 250.5}'::jsonb, -- abnormal_reason
|
|
15.5, -- distance_nm
|
|
180.3, -- avg_speed
|
|
250.5, -- max_speed
|
|
10, -- point_count
|
|
'hourly' -- source_table
|
|
)
|
|
ON CONFLICT (sig_src_cd, target_id, time_bucket, source_table)
|
|
DO UPDATE SET
|
|
track_geom = EXCLUDED.track_geom,
|
|
abnormal_type = EXCLUDED.abnormal_type,
|
|
abnormal_reason = EXCLUDED.abnormal_reason,
|
|
distance_nm = EXCLUDED.distance_nm,
|
|
avg_speed = EXCLUDED.avg_speed,
|
|
max_speed = EXCLUDED.max_speed,
|
|
point_count = EXCLUDED.point_count,
|
|
detected_at = NOW();
|
|
|
|
-- 2. track_geom_v2 컬럼을 사용하는 경우
|
|
INSERT INTO signal.t_abnormal_tracks (
|
|
sig_src_cd,
|
|
target_id,
|
|
time_bucket,
|
|
track_geom_v2,
|
|
abnormal_type,
|
|
abnormal_reason,
|
|
distance_nm,
|
|
avg_speed,
|
|
max_speed,
|
|
point_count,
|
|
source_table
|
|
) VALUES (
|
|
'LRIT', -- sig_src_cd
|
|
'TEST_VESSEL_002', -- target_id
|
|
'2025-10-10 13:00:00'::timestamp, -- time_bucket
|
|
ST_GeomFromText('LINESTRING M(127.0 38.0 1728550800, 127.2 38.2 1728550860, 127.4 38.4 1728550920)', 4326), -- track_geom_v2
|
|
'UNREALISTIC_DISTANCE', -- abnormal_type
|
|
'{"reason": "Distance too large for time interval", "distance_nm": 120.0, "time_interval_minutes": 5}'::jsonb, -- abnormal_reason
|
|
120.0, -- distance_nm
|
|
1440.0, -- avg_speed (120nm / 5min = 1440 knots)
|
|
1500.0, -- max_speed
|
|
3, -- point_count
|
|
'5min' -- source_table
|
|
)
|
|
ON CONFLICT (sig_src_cd, target_id, time_bucket, source_table)
|
|
DO UPDATE SET
|
|
track_geom_v2 = EXCLUDED.track_geom_v2,
|
|
abnormal_type = EXCLUDED.abnormal_type,
|
|
abnormal_reason = EXCLUDED.abnormal_reason,
|
|
distance_nm = EXCLUDED.distance_nm,
|
|
avg_speed = EXCLUDED.avg_speed,
|
|
max_speed = EXCLUDED.max_speed,
|
|
point_count = EXCLUDED.point_count,
|
|
detected_at = NOW();
|
|
|
|
-- 3. public 스키마를 명시적으로 지정한 버전
|
|
INSERT INTO signal.t_abnormal_tracks (
|
|
sig_src_cd,
|
|
target_id,
|
|
time_bucket,
|
|
track_geom,
|
|
abnormal_type,
|
|
abnormal_reason,
|
|
distance_nm,
|
|
avg_speed,
|
|
max_speed,
|
|
point_count,
|
|
source_table
|
|
) VALUES (
|
|
'VPASS', -- sig_src_cd
|
|
'TEST_VESSEL_003', -- target_id
|
|
'2025-10-10 14:00:00'::timestamp, -- time_bucket
|
|
public.ST_GeomFromText('LINESTRING M(128.0 36.0 1728554400, 128.1 36.1 1728554460)', 4326), -- public 스키마 명시
|
|
'SUDDEN_DIRECTION_CHANGE', -- abnormal_type
|
|
'{"reason": "Unrealistic turn angle", "angle_degrees": 175}'::jsonb, -- abnormal_reason
|
|
8.5, -- distance_nm
|
|
102.0, -- avg_speed
|
|
120.0, -- max_speed
|
|
2, -- point_count
|
|
'hourly' -- source_table
|
|
)
|
|
ON CONFLICT (sig_src_cd, target_id, time_bucket, source_table)
|
|
DO UPDATE SET
|
|
track_geom = EXCLUDED.track_geom,
|
|
abnormal_type = EXCLUDED.abnormal_type,
|
|
abnormal_reason = EXCLUDED.abnormal_reason,
|
|
distance_nm = EXCLUDED.distance_nm,
|
|
avg_speed = EXCLUDED.avg_speed,
|
|
max_speed = EXCLUDED.max_speed,
|
|
point_count = EXCLUDED.point_count,
|
|
detected_at = NOW();
|
|
|
|
-- 4. 검증 쿼리
|
|
SELECT
|
|
sig_src_cd,
|
|
target_id,
|
|
time_bucket,
|
|
abnormal_type,
|
|
abnormal_reason,
|
|
distance_nm,
|
|
avg_speed,
|
|
max_speed,
|
|
point_count,
|
|
source_table,
|
|
ST_AsText(track_geom) as track_geom_wkt,
|
|
ST_AsText(track_geom_v2) as track_geom_v2_wkt,
|
|
detected_at
|
|
FROM signal.t_abnormal_tracks
|
|
WHERE target_id LIKE 'TEST_VESSEL_%'
|
|
ORDER BY time_bucket DESC;
|
|
|
|
-- 5. 정리 (테스트 데이터 삭제)
|
|
-- DELETE FROM signal.t_abnormal_tracks WHERE target_id LIKE 'TEST_VESSEL_%';
|