- 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>
123 lines
4.5 KiB
SQL
123 lines
4.5 KiB
SQL
-- Invalid geometry 수정 스크립트
|
|
-- "Too few points" 에러를 해결하기 위해 단일 포인트를 2번 반복
|
|
|
|
-- ========================================
|
|
-- 1. 백업 (선택사항)
|
|
-- ========================================
|
|
-- CREATE TABLE signal.t_vessel_tracks_5min_backup_20251107 AS
|
|
-- SELECT * FROM signal.t_vessel_tracks_5min
|
|
-- WHERE track_geom IS NOT NULL AND NOT public.ST_IsValid(track_geom);
|
|
|
|
-- ========================================
|
|
-- 2. Invalid geometry 수정 (DRY RUN - 먼저 확인)
|
|
-- ========================================
|
|
SELECT
|
|
'DRY RUN - Will fix these records' as action,
|
|
sig_src_cd,
|
|
target_id,
|
|
time_bucket,
|
|
public.ST_NPoints(track_geom) as current_points,
|
|
public.ST_AsText(track_geom) as current_wkt,
|
|
-- 수정 후 WKT 미리보기
|
|
CASE
|
|
WHEN public.ST_NPoints(track_geom) = 1 THEN
|
|
'LINESTRING M(' ||
|
|
public.ST_X(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_Y(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_M(public.ST_PointN(track_geom, 1)) || ',' ||
|
|
public.ST_X(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_Y(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_M(public.ST_PointN(track_geom, 1)) || ')'
|
|
ELSE 'NO FIX NEEDED'
|
|
END as new_wkt
|
|
FROM signal.t_vessel_tracks_5min
|
|
WHERE track_geom IS NOT NULL
|
|
AND public.ST_IsValidReason(track_geom) LIKE '%Too few points%'
|
|
LIMIT 10;
|
|
|
|
-- ========================================
|
|
-- 3. 실제 수정 (확인 후 실행)
|
|
-- ========================================
|
|
-- 주의: 이 쿼리는 실제 데이터를 변경합니다!
|
|
-- DRY RUN 결과를 확인한 후 주석을 해제하고 실행하세요.
|
|
|
|
/*
|
|
UPDATE signal.t_vessel_tracks_5min
|
|
SET track_geom = public.ST_GeomFromText(
|
|
'LINESTRING M(' ||
|
|
public.ST_X(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_Y(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_M(public.ST_PointN(track_geom, 1)) || ',' ||
|
|
public.ST_X(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_Y(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_M(public.ST_PointN(track_geom, 1)) || ')',
|
|
4326
|
|
)
|
|
WHERE track_geom IS NOT NULL
|
|
AND public.ST_NPoints(track_geom) = 1
|
|
AND public.ST_IsValidReason(track_geom) LIKE '%Too few points%';
|
|
*/
|
|
|
|
-- ========================================
|
|
-- 4. 수정 결과 확인
|
|
-- ========================================
|
|
SELECT
|
|
'AFTER FIX' as status,
|
|
COUNT(*) as total_records,
|
|
COUNT(CASE WHEN public.ST_IsValid(track_geom) THEN 1 END) as valid_count,
|
|
COUNT(CASE WHEN NOT public.ST_IsValid(track_geom) THEN 1 END) as invalid_count
|
|
FROM signal.t_vessel_tracks_5min
|
|
WHERE track_geom IS NOT NULL;
|
|
|
|
-- ========================================
|
|
-- 5. 여전히 Invalid한 geometry 확인
|
|
-- ========================================
|
|
SELECT
|
|
'REMAINING INVALID' as status,
|
|
public.ST_IsValidReason(track_geom) as reason,
|
|
COUNT(*) as count
|
|
FROM signal.t_vessel_tracks_5min
|
|
WHERE track_geom IS NOT NULL
|
|
AND NOT public.ST_IsValid(track_geom)
|
|
GROUP BY public.ST_IsValidReason(track_geom);
|
|
|
|
-- ========================================
|
|
-- 6. Hourly 테이블도 동일하게 수정 (필요시)
|
|
-- ========================================
|
|
/*
|
|
UPDATE signal.t_vessel_tracks_hourly
|
|
SET track_geom = public.ST_GeomFromText(
|
|
'LINESTRING M(' ||
|
|
public.ST_X(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_Y(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_M(public.ST_PointN(track_geom, 1)) || ',' ||
|
|
public.ST_X(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_Y(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_M(public.ST_PointN(track_geom, 1)) || ')',
|
|
4326
|
|
)
|
|
WHERE track_geom IS NOT NULL
|
|
AND public.ST_NPoints(track_geom) = 1
|
|
AND public.ST_IsValidReason(track_geom) LIKE '%Too few points%';
|
|
*/
|
|
|
|
-- ========================================
|
|
-- 7. Daily 테이블도 동일하게 수정 (필요시)
|
|
-- ========================================
|
|
/*
|
|
UPDATE signal.t_vessel_tracks_daily
|
|
SET track_geom = public.ST_GeomFromText(
|
|
'LINESTRING M(' ||
|
|
public.ST_X(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_Y(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_M(public.ST_PointN(track_geom, 1)) || ',' ||
|
|
public.ST_X(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_Y(public.ST_PointN(track_geom, 1)) || ' ' ||
|
|
public.ST_M(public.ST_PointN(track_geom, 1)) || ')',
|
|
4326
|
|
)
|
|
WHERE track_geom IS NOT NULL
|
|
AND public.ST_NPoints(track_geom) = 1
|
|
AND public.ST_IsValidReason(track_geom) LIKE '%Too few points%';
|
|
*/
|