diff --git a/qaup-collision/src/main/java/com/qaup/collision/websocket/broadcaster/WebSocketMessageBroadcaster.java b/qaup-collision/src/main/java/com/qaup/collision/websocket/broadcaster/WebSocketMessageBroadcaster.java index 80ec6ba..1f1c593 100644 --- a/qaup-collision/src/main/java/com/qaup/collision/websocket/broadcaster/WebSocketMessageBroadcaster.java +++ b/qaup-collision/src/main/java/com/qaup/collision/websocket/broadcaster/WebSocketMessageBroadcaster.java @@ -157,12 +157,19 @@ public class WebSocketMessageBroadcaster { public void handlePositionUpdate(PositionUpdateEvent event) { try { if (event == null || event.getPayload() == null) { + log.warn("[TMP-POS-DROP] reason=event_or_payload_null objectId= rawLatitude=null rawLongitude=null"); return; } if (!(event.getPayload() instanceof PositionUpdatePayload payload)) { + log.warn("[TMP-POS-DROP] reason=payload_not_position_update objectId= rawLatitude=null rawLongitude=null payloadType={}", + event.getPayload().getClass().getName()); return; } if (payload.getObjectId() == null || payload.getObjectId().isBlank()) { + Double rawLatitude = payload.getPosition() != null ? payload.getPosition().getLatitude() : null; + Double rawLongitude = payload.getPosition() != null ? payload.getPosition().getLongitude() : null; + log.warn("[TMP-POS-DROP] reason=blank_object_id objectId= rawLatitude={} rawLongitude={}", + rawLatitude, rawLongitude); return; } @@ -381,13 +388,27 @@ public class WebSocketMessageBroadcaster { if (payload.getPosition() == null || payload.getPosition().getLatitude() == null || payload.getPosition().getLongitude() == null) { + logDroppedPosition("missing_position_or_coordinate", payload, null, null, null); return null; } - double latitude = payload.getPosition().getLatitude(); - double longitude = payload.getPosition().getLongitude(); + double rawLatitude = payload.getPosition().getLatitude(); + double rawLongitude = payload.getPosition().getLongitude(); + double latitude = rawLatitude; + double longitude = rawLongitude; if (!isValidCoordinate(latitude, longitude)) { - return null; + // Optimization: tolerate upstream lat/lon swap and keep the track continuous. + if (isPotentiallySwappedCoordinate(latitude, longitude)) { + double swappedLatitude = longitude; + double swappedLongitude = latitude; + log.warn("[TMP-POS-FIX] reason=swap_lat_lon objectId={} rawLatitude={} rawLongitude={} fixedLatitude={} fixedLongitude={}", + safeObjectId(payload), rawLatitude, rawLongitude, swappedLatitude, swappedLongitude); + latitude = swappedLatitude; + longitude = swappedLongitude; + } else { + logDroppedPosition("invalid_coordinate_range", payload, rawLatitude, rawLongitude, null); + return null; + } } long payloadTimestamp = payload.getTimestamp() != null ? payload.getTimestamp() : System.currentTimeMillis(); @@ -425,6 +446,13 @@ public class WebSocketMessageBroadcaster { boolean isOutlierJump = rawDistance > maxAllowedJump; if (isOutlierJump && !aircraft && state.rejectedCount < REACQUIRE_AFTER_REJECTS - 1) { state.rejectedCount++; + logDroppedPosition( + "outlier_jump_rejected", + payload, + rawLatitude, + rawLongitude, + String.format("jumpMeter=%.3f,allowedMeter=%.3f,rejectedCount=%d", rawDistance, maxAllowedJump, state.rejectedCount) + ); log.debug("Drop outlier position update: objectId={}, jumpMeter={}, allowedMeter={}", payload.getObjectId(), rawDistance, maxAllowedJump); return null; @@ -514,6 +542,29 @@ public class WebSocketMessageBroadcaster { return latitude >= -90.0 && latitude <= 90.0 && longitude >= -180.0 && longitude <= 180.0; } + private boolean isPotentiallySwappedCoordinate(double latitude, double longitude) { + return latitude >= -180.0 && latitude <= 180.0 + && longitude >= -90.0 && longitude <= 90.0 + && !isValidCoordinate(latitude, longitude); + } + + private String safeObjectId(PositionUpdatePayload payload) { + if (payload == null || payload.getObjectId() == null || payload.getObjectId().isBlank()) { + return ""; + } + return payload.getObjectId(); + } + + private void logDroppedPosition(String reason, PositionUpdatePayload payload, Double rawLatitude, Double rawLongitude, String extra) { + if (extra == null || extra.isBlank()) { + log.warn("[TMP-POS-DROP] reason={} objectId={} rawLatitude={} rawLongitude={}", + reason, safeObjectId(payload), rawLatitude, rawLongitude); + } else { + log.warn("[TMP-POS-DROP] reason={} objectId={} rawLatitude={} rawLongitude={} {}", + reason, safeObjectId(payload), rawLatitude, rawLongitude, extra); + } + } + private double resolveMaxAllowedJumpMeters(double speedMps, double jumpMarginMeter, double dtSec) { double safeDtSec = Math.max(dtSec, MIN_DT_SECONDS); return speedMps * safeDtSec + Math.max(jumpMarginMeter, 0.0);