From 122dfb293c951da073fcf6ff40c9a14988ce0ff5 Mon Sep 17 00:00:00 2001 From: Vladislav Chumak Date: Mon, 9 Jul 2018 19:27:48 +0200 Subject: [PATCH] Refactored estimation data serializers + added mark passings count --- .../GpsFixWithEstimationData.java | 20 +++ .../impl/GpsFixWithEstimationDataImpl.java | 48 ++++++ ...CompetitorTrackElementsJsonSerializer.java | 20 +++ ...TrackWithEstimationDataJsonSerializer.java | 137 ++++++++++++++++++ ...urvesWithEstimationDataJsonSerializer.java | 114 ++------------- ...FixesWithEstimationDataJsonSerializer.java | 131 +++++------------ .../gateway/jaxrs/api/RegattasResource.java | 37 +++-- 7 files changed, 297 insertions(+), 210 deletions(-) create mode 100644 java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/GpsFixWithEstimationData.java create mode 100644 java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/GpsFixWithEstimationDataImpl.java create mode 100644 java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CompetitorTrackElementsJsonSerializer.java create mode 100644 java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CompetitorTrackWithEstimationDataJsonSerializer.java diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/GpsFixWithEstimationData.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/GpsFixWithEstimationData.java new file mode 100644 index 00000000000..e0126209f4a --- /dev/null +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/GpsFixWithEstimationData.java @@ -0,0 +1,20 @@ +package com.sap.sailing.domain.maneuverdetection; + +import com.sap.sailing.domain.common.Wind; +import com.sap.sailing.domain.common.tracking.GPSFixMoving; +import com.sap.sse.common.Bearing; +import com.sap.sse.common.Distance; + +/** + * + * @author Vladislav Chumak (D069712) + * + */ +public interface GpsFixWithEstimationData extends GPSFixMoving { + + Wind getWind(); + + Bearing getRelativeBearingToNextMarkAfterManeuver(); + + Distance getDistanceToClosestMark(); +} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/GpsFixWithEstimationDataImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/GpsFixWithEstimationDataImpl.java new file mode 100644 index 00000000000..a9566317518 --- /dev/null +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/GpsFixWithEstimationDataImpl.java @@ -0,0 +1,48 @@ +package com.sap.sailing.domain.maneuverdetection.impl; + +import com.sap.sailing.domain.common.Position; +import com.sap.sailing.domain.common.SpeedWithBearing; +import com.sap.sailing.domain.common.Wind; +import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl; +import com.sap.sailing.domain.maneuverdetection.GpsFixWithEstimationData; +import com.sap.sse.common.Bearing; +import com.sap.sse.common.Distance; +import com.sap.sse.common.TimePoint; + +/** + * + * @author Vladislav Chumak (D069712) + * + */ +public class GpsFixWithEstimationDataImpl extends GPSFixMovingImpl implements GpsFixWithEstimationData { + + private static final long serialVersionUID = -6952863819352430365L; + + private Wind wind; + private Bearing relativeBearingToNextMarkAfterManeuver; + private Distance distanceToClosestMark; + + public GpsFixWithEstimationDataImpl(Position position, TimePoint timePoint, SpeedWithBearing speedWithBearing, + Wind wind, Bearing relativeBearingToNextMarkAfterManeuver, Distance distanceToClosestMark) { + super(position, timePoint, speedWithBearing); + this.wind = wind; + this.relativeBearingToNextMarkAfterManeuver = relativeBearingToNextMarkAfterManeuver; + this.distanceToClosestMark = distanceToClosestMark; + } + + @Override + public Wind getWind() { + return wind; + } + + @Override + public Bearing getRelativeBearingToNextMarkAfterManeuver() { + return relativeBearingToNextMarkAfterManeuver; + } + + @Override + public Distance getDistanceToClosestMark() { + return distanceToClosestMark; + } + +} diff --git a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CompetitorTrackElementsJsonSerializer.java b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CompetitorTrackElementsJsonSerializer.java new file mode 100644 index 00000000000..a1f57a3e224 --- /dev/null +++ b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CompetitorTrackElementsJsonSerializer.java @@ -0,0 +1,20 @@ +package com.sap.sailing.server.gateway.serialization.impl; + +import org.json.simple.JSONArray; + +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.maneuverdetection.impl.TrackTimeInfo; +import com.sap.sailing.domain.tracking.TrackedRace; +import com.sap.sse.common.TimePoint; + +/** + * + * @author Vladislav Chumak (D069712) + * @see CompetitorTrackWithEstimationDataJsonSerializer + */ +public interface CompetitorTrackElementsJsonSerializer { + + JSONArray serialize(TrackedRace trackedRace, Competitor competitor, TimePoint from, TimePoint to, + TrackTimeInfo trackTimeInfo); + +} diff --git a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CompetitorTrackWithEstimationDataJsonSerializer.java b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CompetitorTrackWithEstimationDataJsonSerializer.java new file mode 100644 index 00000000000..ddaa977ff8f --- /dev/null +++ b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CompetitorTrackWithEstimationDataJsonSerializer.java @@ -0,0 +1,137 @@ +package com.sap.sailing.server.gateway.serialization.impl; + +import java.util.NavigableSet; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import com.sap.sailing.domain.base.BoatClass; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.common.tracking.GPSFixMoving; +import com.sap.sailing.domain.maneuverdetection.impl.ManeuverDetectorImpl; +import com.sap.sailing.domain.maneuverdetection.impl.TrackTimeInfo; +import com.sap.sailing.domain.polars.PolarDataService; +import com.sap.sailing.domain.tracking.GPSFixTrack; +import com.sap.sailing.domain.tracking.MarkPassing; +import com.sap.sailing.domain.tracking.TrackedRace; +import com.sap.sse.common.Duration; +import com.sap.sse.common.TimePoint; +import com.sap.sse.common.Util; +import com.sap.sse.common.impl.MillisecondsDurationImpl; + +/** + * + * @author Vladislav Chumak (D069712) + * + */ +public class CompetitorTrackWithEstimationDataJsonSerializer extends AbstractTrackedRaceDataJsonSerializer { + public static final String elements = "elements"; + public static final String BOAT_CLASS = "boatClass"; + public static final String COMPETITOR_NAME = "competitorName"; + public static final String AVG_INTERVAL_BETWEEN_FIXES_IN_SECONDS = "avgIntervalBetweenFixesInSeconds"; + public static final String DISTANCE_TRAVELLED_IN_METERS = "distanceTravelledInMeters"; + public static final String START_TIME_POINT = "startUnixTime"; + public static final String END_TIME_POINT = "endUnixTime"; + public static final String FIXES_COUNT_FOR_POLARS = "fixesCountForPolars"; + public static final String MARK_PASSINGS_COUNT = "markPassingsCount"; + + private final BoatClassJsonSerializer boatClassJsonSerializer; + private final CompetitorTrackElementsJsonSerializer elementsJsonSerializer; + private final PolarDataService polarDataService; + private final Integer startBeforeStartLineInSeconds; + private final Integer endBeforeStartLineInSeconds; + private final Integer startAfterFinishLineInSeconds; + private final Integer endAfterFinishLineInSeconds; + + public CompetitorTrackWithEstimationDataJsonSerializer(PolarDataService polarDataService, + BoatClassJsonSerializer boatClassJsonSerializer, + CompetitorTrackElementsJsonSerializer elementsJsonSerializer, Integer startBeforeStartLineInSeconds, + Integer endBeforeStartLineInSeconds, Integer startAfterFinishLineInSeconds, + Integer endAfterFinishLineInSeconds) { + this.polarDataService = polarDataService; + this.boatClassJsonSerializer = boatClassJsonSerializer; + this.elementsJsonSerializer = elementsJsonSerializer; + this.startBeforeStartLineInSeconds = startBeforeStartLineInSeconds; + this.endBeforeStartLineInSeconds = endBeforeStartLineInSeconds; + this.startAfterFinishLineInSeconds = startAfterFinishLineInSeconds; + this.endAfterFinishLineInSeconds = endAfterFinishLineInSeconds; + } + + @Override + public JSONObject serialize(TrackedRace trackedRace) { + final JSONObject result = new JSONObject(); + JSONArray byCompetitorJson = new JSONArray(); + result.put(BYCOMPETITOR, byCompetitorJson); + for (Competitor competitor : trackedRace.getRace().getCompetitors()) { + ManeuverDetectorImpl maneuverDetector = new ManeuverDetectorImpl(trackedRace, competitor); + TrackTimeInfo trackTimeInfo = maneuverDetector.getTrackTimeInfo(); + TimePoint from = null; + TimePoint to = null; + if (startBeforeStartLineInSeconds != null) { + from = trackTimeInfo.getTrackStartTimePoint() + .minus(new MillisecondsDurationImpl(startBeforeStartLineInSeconds * 1000L)); + } else if (startAfterFinishLineInSeconds != null) { + from = trackTimeInfo.getTrackEndTimePoint() + .plus(new MillisecondsDurationImpl(startAfterFinishLineInSeconds * 1000L)); + } else { + from = trackTimeInfo.getTrackStartTimePoint(); + } + if (endAfterFinishLineInSeconds != null) { + to = trackTimeInfo.getTrackEndTimePoint() + .plus(new MillisecondsDurationImpl(endAfterFinishLineInSeconds * 1000L)); + } else if (endBeforeStartLineInSeconds != null) { + to = trackTimeInfo.getTrackStartTimePoint() + .minus(new MillisecondsDurationImpl(endBeforeStartLineInSeconds * 1000L)); + } else { + to = trackTimeInfo.getTrackEndTimePoint(); + } + if (trackTimeInfo != null) { + final JSONObject forCompetitorJson = new JSONObject(); + byCompetitorJson.add(forCompetitorJson); + forCompetitorJson.put(COMPETITOR_NAME, competitor.getName()); + forCompetitorJson.put(BOAT_CLASS, boatClassJsonSerializer + .serialize(trackedRace.getRace().getBoatOfCompetitor(competitor).getBoatClass())); + forCompetitorJson.put(FIXES_COUNT_FOR_POLARS, getFixesCountForPolars(trackedRace, competitor)); + Duration averageIntervalBetweenFixes = trackedRace.getTrack(competitor) + .getAverageIntervalBetweenFixes(); + forCompetitorJson.put(AVG_INTERVAL_BETWEEN_FIXES_IN_SECONDS, + averageIntervalBetweenFixes == null ? 0 : averageIntervalBetweenFixes.asSeconds()); + GPSFixTrack track = trackedRace.getTrack(competitor); + Double distanceTravelledInMeters = null; + if (trackTimeInfo.getTrackStartTimePoint() != null && trackTimeInfo.getTrackEndTimePoint() != null) { + distanceTravelledInMeters = track.getDistanceTraveled(trackTimeInfo.getTrackStartTimePoint(), + trackTimeInfo.getTrackEndTimePoint()).getMeters(); + } + forCompetitorJson.put(DISTANCE_TRAVELLED_IN_METERS, distanceTravelledInMeters); + forCompetitorJson.put(START_TIME_POINT, trackTimeInfo.getTrackStartTimePoint() == null ? null + : trackTimeInfo.getTrackStartTimePoint().asMillis()); + forCompetitorJson.put(END_TIME_POINT, trackTimeInfo.getTrackEndTimePoint() == null ? null + : trackTimeInfo.getTrackEndTimePoint().asMillis()); + int markPassingsCount = getMarkPassingsCount(trackedRace, competitor); + forCompetitorJson.put(MARK_PASSINGS_COUNT, markPassingsCount); + forCompetitorJson.put(elements, + elementsJsonSerializer.serialize(trackedRace, competitor, from, to, trackTimeInfo)); + } + } + return result; + } + + private int getMarkPassingsCount(TrackedRace trackedRace, Competitor competitor) { + int markPassingsCount = 0; + NavigableSet markPassings = trackedRace.getMarkPassings(competitor, false); + trackedRace.lockForRead(markPassings); + try { + markPassingsCount = Util.size(markPassings); + } finally { + trackedRace.unlockAfterRead(markPassings); + } + return markPassingsCount; + } + + private long getFixesCountForPolars(TrackedRace trackedRace, Competitor competitor) { + BoatClass boatClass = trackedRace.getRace().getBoatOfCompetitor(competitor).getBoatClass(); + Long fixesCountForBoatPolars = polarDataService.getFixCountPerBoatClass().get(boatClass); + return fixesCountForBoatPolars == null ? 0L : fixesCountForBoatPolars; + } + +} diff --git a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CompleteManeuverCurvesWithEstimationDataJsonSerializer.java b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CompleteManeuverCurvesWithEstimationDataJsonSerializer.java index 357d034b0d4..01b1e4ac610 100644 --- a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CompleteManeuverCurvesWithEstimationDataJsonSerializer.java +++ b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CompleteManeuverCurvesWithEstimationDataJsonSerializer.java @@ -4,11 +4,8 @@ import java.util.List; import java.util.stream.Collectors; import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.base.Competitor; -import com.sap.sailing.domain.common.tracking.GPSFixMoving; import com.sap.sailing.domain.maneuverdetection.CompleteManeuverCurveWithEstimationData; import com.sap.sailing.domain.maneuverdetection.ManeuverDetectorWithEstimationDataSupport; import com.sap.sailing.domain.maneuverdetection.impl.ManeuverDetectorImpl; @@ -17,116 +14,37 @@ import com.sap.sailing.domain.maneuverdetection.impl.ManeuverSpot; import com.sap.sailing.domain.maneuverdetection.impl.TrackTimeInfo; import com.sap.sailing.domain.polars.PolarDataService; import com.sap.sailing.domain.tracking.CompleteManeuverCurve; -import com.sap.sailing.domain.tracking.GPSFixTrack; import com.sap.sailing.domain.tracking.Maneuver; import com.sap.sailing.domain.tracking.TrackedRace; -import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; -import com.sap.sse.common.impl.MillisecondsDurationImpl; /** * * @author Vladislav Chumak (D069712) * */ -public class CompleteManeuverCurvesWithEstimationDataJsonSerializer extends AbstractTrackedRaceDataJsonSerializer { - public static final String MANEUVER_CURVES = "maneuverCurves"; - public static final String BOAT_CLASS = "boatClass"; - public static final String COMPETITOR_NAME = "competitorName"; - public static final String AVG_INTERVAL_BETWEEN_FIXES_IN_SECONDS = "avgIntervalBetweenFixesInSeconds"; - public static final String DISTANCE_TRAVELLED_IN_METERS = "distanceTravelledInMeters"; - public static final String START_TIME_POINT = "startUnixTime"; - public static final String END_TIME_POINT = "endUnixTime"; - public static final String FIXES_COUNT_FOR_POLARS = "fixesCountForPolars"; - - private final BoatClassJsonSerializer boatClassJsonSerializer; - private final CompleteManeuverCurveWithEstimationDataJsonSerializer maneuverWithEstimationDataJsonSerializer; +public class CompleteManeuverCurvesWithEstimationDataJsonSerializer implements CompetitorTrackElementsJsonSerializer { private final PolarDataService polarDataService; - private final Integer startBeforeStartLineInSeconds; - private final Integer endBeforeStartLineInSeconds; - private final Integer startAfterFinishLineInSeconds; - private final Integer endAfterFinishLineInSeconds; + private final CompleteManeuverCurveWithEstimationDataJsonSerializer maneuverWithEstimationDataJsonSerializer; public CompleteManeuverCurvesWithEstimationDataJsonSerializer(PolarDataService polarDataService, - BoatClassJsonSerializer boatClassJsonSerializer, - CompleteManeuverCurveWithEstimationDataJsonSerializer maneuverWithEstimationDataJsonSerializer, - Integer startBeforeStartLineInSeconds, Integer endBeforeStartLineInSeconds, - Integer startAfterFinishLineInSeconds, Integer endAfterFinishLineInSeconds) { + CompleteManeuverCurveWithEstimationDataJsonSerializer maneuverWithEstimationDataJsonSerializer) { this.polarDataService = polarDataService; - this.boatClassJsonSerializer = boatClassJsonSerializer; this.maneuverWithEstimationDataJsonSerializer = maneuverWithEstimationDataJsonSerializer; - this.startBeforeStartLineInSeconds = startBeforeStartLineInSeconds; - this.endBeforeStartLineInSeconds = endBeforeStartLineInSeconds; - this.startAfterFinishLineInSeconds = startAfterFinishLineInSeconds; - this.endAfterFinishLineInSeconds = endAfterFinishLineInSeconds; } @Override - public JSONObject serialize(TrackedRace trackedRace) { - final JSONObject result = new JSONObject(); - JSONArray byCompetitorJson = new JSONArray(); - result.put(BYCOMPETITOR, byCompetitorJson); - for (Competitor competitor : trackedRace.getRace().getCompetitors()) { - ManeuverDetectorImpl maneuverDetector = new ManeuverDetectorImpl(trackedRace, competitor); - TrackTimeInfo trackTimeInfo = maneuverDetector.getTrackTimeInfo(); - TimePoint from = null; - TimePoint to = null; - if (startBeforeStartLineInSeconds != Integer.MIN_VALUE) { - from = trackTimeInfo.getTrackStartTimePoint() - .minus(new MillisecondsDurationImpl(startBeforeStartLineInSeconds * 1000L)); - } else if (startAfterFinishLineInSeconds != Integer.MIN_VALUE) { - from = trackTimeInfo.getTrackEndTimePoint() - .plus(new MillisecondsDurationImpl(startAfterFinishLineInSeconds * 1000L)); - } - if (endAfterFinishLineInSeconds != Integer.MIN_VALUE) { - to = trackTimeInfo.getTrackEndTimePoint() - .plus(new MillisecondsDurationImpl(endAfterFinishLineInSeconds * 1000L)); - } else if (endBeforeStartLineInSeconds != Integer.MIN_VALUE) { - to = trackTimeInfo.getTrackStartTimePoint() - .minus(new MillisecondsDurationImpl(endBeforeStartLineInSeconds * 1000L)); - } - if (trackTimeInfo != null) { - if (from != null ^ to != null) { - if (from == null) { - from = trackTimeInfo.getTrackStartTimePoint(); - } - if (to == null) { - to = trackTimeInfo.getTrackEndTimePoint(); - } - } - final JSONObject forCompetitorJson = new JSONObject(); - byCompetitorJson.add(forCompetitorJson); - forCompetitorJson.put(COMPETITOR_NAME, competitor.getName()); - forCompetitorJson.put(BOAT_CLASS, boatClassJsonSerializer - .serialize(trackedRace.getRace().getBoatOfCompetitor(competitor).getBoatClass())); - final JSONArray completeManeuverCurvesWithEstimationData = new JSONArray(); - Iterable completeManeuvers = from != null - ? getCompleteManeuverCurvesWithEstimationData(trackedRace, competitor, from, to) - : getCompleteManeuverCurvesWithEstimationData(trackedRace, competitor); - for (CompleteManeuverCurveWithEstimationData maneuver : completeManeuvers) { - completeManeuverCurvesWithEstimationData - .add(maneuverWithEstimationDataJsonSerializer.serialize(maneuver)); - } - forCompetitorJson.put(FIXES_COUNT_FOR_POLARS, getFixesCountForPolars(trackedRace, competitor)); - forCompetitorJson.put(MANEUVER_CURVES, completeManeuverCurvesWithEstimationData); - Duration averageIntervalBetweenFixes = trackedRace.getTrack(competitor) - .getAverageIntervalBetweenFixes(); - forCompetitorJson.put(AVG_INTERVAL_BETWEEN_FIXES_IN_SECONDS, - averageIntervalBetweenFixes == null ? 0 : averageIntervalBetweenFixes.asSeconds()); - GPSFixTrack track = trackedRace.getTrack(competitor); - Double distanceTravelledInMeters = null; - if (trackTimeInfo.getTrackStartTimePoint() != null && trackTimeInfo.getTrackEndTimePoint() != null) { - distanceTravelledInMeters = track.getDistanceTraveled(trackTimeInfo.getTrackStartTimePoint(), - trackTimeInfo.getTrackEndTimePoint()).getMeters(); - } - forCompetitorJson.put(DISTANCE_TRAVELLED_IN_METERS, distanceTravelledInMeters); - forCompetitorJson.put(START_TIME_POINT, trackTimeInfo.getTrackStartTimePoint() == null ? null - : trackTimeInfo.getTrackStartTimePoint().asMillis()); - forCompetitorJson.put(END_TIME_POINT, trackTimeInfo.getTrackEndTimePoint() == null ? null - : trackTimeInfo.getTrackEndTimePoint().asMillis()); - } + public JSONArray serialize(TrackedRace trackedRace, Competitor competitor, TimePoint from, TimePoint to, + TrackTimeInfo trackTimeInfo) { + final JSONArray completeManeuverCurvesWithEstimationData = new JSONArray(); + Iterable completeManeuvers = trackTimeInfo.getTrackStartTimePoint() + .equals(from) && trackTimeInfo.getTrackEndTimePoint().equals(to) + ? getCompleteManeuverCurvesWithEstimationData(trackedRace, competitor) + : getCompleteManeuverCurvesWithEstimationData(trackedRace, competitor, from, to); + for (CompleteManeuverCurveWithEstimationData maneuver : completeManeuvers) { + completeManeuverCurvesWithEstimationData.add(maneuverWithEstimationDataJsonSerializer.serialize(maneuver)); } - return result; + return completeManeuverCurvesWithEstimationData; } private Iterable getCompleteManeuverCurvesWithEstimationData( @@ -155,10 +73,4 @@ public class CompleteManeuverCurvesWithEstimationDataJsonSerializer extends Abst return maneuversWithEstimationData; } - private long getFixesCountForPolars(TrackedRace trackedRace, Competitor competitor) { - BoatClass boatClass = trackedRace.getRace().getBoatOfCompetitor(competitor).getBoatClass(); - Long fixesCountForBoatPolars = polarDataService.getFixCountPerBoatClass().get(boatClass); - return fixesCountForBoatPolars == null ? 0L : fixesCountForBoatPolars; - } - } diff --git a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/GpsFixesWithEstimationDataJsonSerializer.java b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/GpsFixesWithEstimationDataJsonSerializer.java index 06cddcbfdd3..a2148acf2fe 100644 --- a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/GpsFixesWithEstimationDataJsonSerializer.java +++ b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/GpsFixesWithEstimationDataJsonSerializer.java @@ -14,16 +14,14 @@ import com.sap.sailing.domain.tracking.GPSFixTrack; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sse.common.Bearing; import com.sap.sse.common.Distance; -import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; -import com.sap.sse.common.impl.MillisecondsDurationImpl; /** * * @author Vladislav Chumak (D069712) * */ -public class GpsFixesWithEstimationDataJsonSerializer extends AbstractTrackedRaceDataJsonSerializer { +public class GpsFixesWithEstimationDataJsonSerializer implements CompetitorTrackElementsJsonSerializer { public static final String GPS_FIXES = "gpsFixes"; public static final String BOAT_CLASS = "boatClass"; public static final String COMPETITOR_NAME = "competitorName"; @@ -35,117 +33,58 @@ public class GpsFixesWithEstimationDataJsonSerializer extends AbstractTrackedRac public static final String RELATIVE_BEARING_TO_NEXT_MARK = "relativeBearingToNextMark"; public static final String CLOSEST_DISTANCE_TO_MARK = "closestDistanceToMarkInMeters"; - private final BoatClassJsonSerializer boatClassJsonSerializer; private final GPSFixMovingJsonSerializer gpsFixMovingJsonSerializer; private final boolean addWind; private final boolean addNextWaypoint; private final ManeuverWindJsonSerializer windJsonSerializer; private final Boolean smoothFixes; - private Integer startBeforeStartLineInSeconds; - private Integer endBeforeStartLineInSeconds; - private Integer startAfterFinishLineInSeconds; - private Integer endAfterFinishLineInSeconds; - public GpsFixesWithEstimationDataJsonSerializer(BoatClassJsonSerializer boatClassJsonSerializer, - GPSFixMovingJsonSerializer gpsFixMovingJsonSerializer, ManeuverWindJsonSerializer windJsonSerializer, - boolean addWind, boolean addNextWaypoint, Boolean smoothFixes, Integer startBeforeStartLineInSeconds, - Integer endBeforeStartLineInSeconds, Integer startAfterFinishLineInSeconds, - Integer endAfterFinishLineInSeconds) { - this.boatClassJsonSerializer = boatClassJsonSerializer; + public GpsFixesWithEstimationDataJsonSerializer(GPSFixMovingJsonSerializer gpsFixMovingJsonSerializer, + ManeuverWindJsonSerializer windJsonSerializer, boolean addWind, boolean addNextWaypoint, + Boolean smoothFixes) { this.gpsFixMovingJsonSerializer = gpsFixMovingJsonSerializer; this.windJsonSerializer = windJsonSerializer; this.addWind = addWind; this.addNextWaypoint = addNextWaypoint; this.smoothFixes = smoothFixes; - this.startBeforeStartLineInSeconds = startBeforeStartLineInSeconds; - this.endBeforeStartLineInSeconds = endBeforeStartLineInSeconds; - this.startAfterFinishLineInSeconds = startAfterFinishLineInSeconds; - this.endAfterFinishLineInSeconds = endAfterFinishLineInSeconds; } @Override - public JSONObject serialize(TrackedRace trackedRace) { - final JSONObject result = new JSONObject(); - JSONArray byCompetitorJson = new JSONArray(); - result.put(BYCOMPETITOR, byCompetitorJson); - for (Competitor competitor : trackedRace.getRace().getCompetitors()) { - ManeuverDetectorImpl maneuverDetector = new ManeuverDetectorImpl(trackedRace, competitor); - ManeuverDetectorWithEstimationDataSupportDecoratorImpl estimationDataSupportDecoratorImpl = new ManeuverDetectorWithEstimationDataSupportDecoratorImpl( - maneuverDetector, null); - TrackTimeInfo trackTimeInfo = maneuverDetector.getTrackTimeInfo(); - TimePoint from = null; - TimePoint to = null; - if (startBeforeStartLineInSeconds != Integer.MIN_VALUE) { - from = trackTimeInfo.getTrackStartTimePoint() - .minus(new MillisecondsDurationImpl(startBeforeStartLineInSeconds * 1000L)); - } else if (startAfterFinishLineInSeconds != Integer.MIN_VALUE) { - from = trackTimeInfo.getTrackEndTimePoint() - .plus(new MillisecondsDurationImpl(startAfterFinishLineInSeconds * 1000L)); - } else { - from = trackTimeInfo.getTrackStartTimePoint(); - } - if (endAfterFinishLineInSeconds != Integer.MIN_VALUE) { - to = trackTimeInfo.getTrackEndTimePoint() - .plus(new MillisecondsDurationImpl(endAfterFinishLineInSeconds * 1000L)); - } else if (endBeforeStartLineInSeconds != Integer.MIN_VALUE) { - to = trackTimeInfo.getTrackStartTimePoint() - .minus(new MillisecondsDurationImpl(endBeforeStartLineInSeconds * 1000L)); - } else { - to = trackTimeInfo.getTrackEndTimePoint(); - } - if (trackTimeInfo != null) { - final JSONObject forCompetitorJson = new JSONObject(); - byCompetitorJson.add(forCompetitorJson); - forCompetitorJson.put(COMPETITOR_NAME, competitor.getName()); - forCompetitorJson.put(BOAT_CLASS, boatClassJsonSerializer - .serialize(trackedRace.getRace().getBoatOfCompetitor(competitor).getBoatClass())); - final JSONArray gpsFixesWithEstimationData = new JSONArray(); - GPSFixTrack track = trackedRace.getTrack(competitor); - track.lockForRead(); - try { - for (GPSFixMoving gpsFix : track.getFixes(from, true, to, true)) { - JSONObject serializedGpsFix = gpsFixMovingJsonSerializer.serialize(gpsFix); - if (addWind) { - Wind wind = trackedRace.getWind(gpsFix.getPosition(), gpsFix.getTimePoint()); - JSONObject serializedWind = wind == null ? null : windJsonSerializer.serialize(wind); - serializedGpsFix.put(WIND, serializedWind); - } - if (addNextWaypoint) { - Distance closestDistanceToMark = estimationDataSupportDecoratorImpl - .getClosestDistanceToMark(gpsFix.getTimePoint()); - SpeedWithBearing speedWithBearing = smoothFixes - ? track.getEstimatedSpeed(gpsFix.getTimePoint()) : gpsFix.getSpeed(); - Bearing relativeBearingToNextMark = speedWithBearing == null ? null - : estimationDataSupportDecoratorImpl.getRelativeBearingToNextMark( - gpsFix.getTimePoint(), speedWithBearing.getBearing()); - serializedGpsFix.put(CLOSEST_DISTANCE_TO_MARK, - closestDistanceToMark == null ? null : closestDistanceToMark.getMeters()); - serializedGpsFix.put(RELATIVE_BEARING_TO_NEXT_MARK, - relativeBearingToNextMark == null ? null : relativeBearingToNextMark.getDegrees()); - } - gpsFixesWithEstimationData.add(serializedGpsFix); - } - } finally { - track.unlockAfterRead(); + public JSONArray serialize(TrackedRace trackedRace, Competitor competitor, TimePoint from, TimePoint to, + TrackTimeInfo trackTimeInfo) { + final JSONArray gpsFixesWithEstimationData = new JSONArray(); + ManeuverDetectorImpl maneuverDetector = new ManeuverDetectorImpl(trackedRace, competitor); + ManeuverDetectorWithEstimationDataSupportDecoratorImpl estimationDataSupportDecoratorImpl = new ManeuverDetectorWithEstimationDataSupportDecoratorImpl( + maneuverDetector, null); + GPSFixTrack track = trackedRace.getTrack(competitor); + track.lockForRead(); + try { + for (GPSFixMoving gpsFix : track.getFixes(from, true, to, true)) { + JSONObject serializedGpsFix = gpsFixMovingJsonSerializer.serialize(gpsFix); + if (addWind) { + Wind wind = trackedRace.getWind(gpsFix.getPosition(), gpsFix.getTimePoint()); + JSONObject serializedWind = wind == null ? null : windJsonSerializer.serialize(wind); + serializedGpsFix.put(WIND, serializedWind); } - forCompetitorJson.put(GPS_FIXES, gpsFixesWithEstimationData); - Duration averageIntervalBetweenFixes = trackedRace.getTrack(competitor) - .getAverageIntervalBetweenFixes(); - forCompetitorJson.put(AVG_INTERVAL_BETWEEN_FIXES_IN_SECONDS, - averageIntervalBetweenFixes == null ? 0 : averageIntervalBetweenFixes.asSeconds()); - Double distanceTravelledInMeters = null; - if (trackTimeInfo.getTrackStartTimePoint() != null && trackTimeInfo.getTrackEndTimePoint() != null) { - distanceTravelledInMeters = track.getDistanceTraveled(trackTimeInfo.getTrackStartTimePoint(), - trackTimeInfo.getTrackEndTimePoint()).getMeters(); + if (addNextWaypoint) { + Distance closestDistanceToMark = estimationDataSupportDecoratorImpl + .getClosestDistanceToMark(gpsFix.getTimePoint()); + SpeedWithBearing speedWithBearing = smoothFixes ? track.getEstimatedSpeed(gpsFix.getTimePoint()) + : gpsFix.getSpeed(); + Bearing relativeBearingToNextMark = speedWithBearing == null ? null + : estimationDataSupportDecoratorImpl.getRelativeBearingToNextMark(gpsFix.getTimePoint(), + speedWithBearing.getBearing()); + serializedGpsFix.put(CLOSEST_DISTANCE_TO_MARK, + closestDistanceToMark == null ? null : closestDistanceToMark.getMeters()); + serializedGpsFix.put(RELATIVE_BEARING_TO_NEXT_MARK, + relativeBearingToNextMark == null ? null : relativeBearingToNextMark.getDegrees()); } - forCompetitorJson.put(DISTANCE_TRAVELLED_IN_METERS, distanceTravelledInMeters); - forCompetitorJson.put(START_TIME_POINT, trackTimeInfo.getTrackStartTimePoint() == null ? null - : trackTimeInfo.getTrackStartTimePoint().asMillis()); - forCompetitorJson.put(END_TIME_POINT, trackTimeInfo.getTrackEndTimePoint() == null ? null - : trackTimeInfo.getTrackEndTimePoint().asMillis()); + gpsFixesWithEstimationData.add(serializedGpsFix); } + } finally { + track.unlockAfterRead(); } - return result; + return gpsFixesWithEstimationData; } } diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/RegattasResource.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/RegattasResource.java index 8215e8819d9..4b0f9768345 100644 --- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/RegattasResource.java +++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/RegattasResource.java @@ -78,6 +78,7 @@ import com.sap.sailing.server.gateway.serialization.impl.BoatJsonSerializer; import com.sap.sailing.server.gateway.serialization.impl.ColorJsonSerializer; import com.sap.sailing.server.gateway.serialization.impl.CompetitorAndBoatJsonSerializer; import com.sap.sailing.server.gateway.serialization.impl.CompetitorJsonSerializer; +import com.sap.sailing.server.gateway.serialization.impl.CompetitorTrackWithEstimationDataJsonSerializer; import com.sap.sailing.server.gateway.serialization.impl.CompleteManeuverCurveWithEstimationDataJsonSerializer; import com.sap.sailing.server.gateway.serialization.impl.CompleteManeuverCurvesWithEstimationDataJsonSerializer; import com.sap.sailing.server.gateway.serialization.impl.DefaultWindTrackJsonSerializer; @@ -1053,14 +1054,17 @@ public class RegattasResource extends AbstractSailingServerResource { .type(MediaType.TEXT_PLAIN).build(); } else { TrackedRace trackedRace = findTrackedRace(regattaName, raceName); - CompleteManeuverCurvesWithEstimationDataJsonSerializer serializer = new CompleteManeuverCurvesWithEstimationDataJsonSerializer( + CompetitorTrackWithEstimationDataJsonSerializer serializer = new CompetitorTrackWithEstimationDataJsonSerializer( getService().getPolarDataService(), new DetailedBoatClassJsonSerializer(), - new CompleteManeuverCurveWithEstimationDataJsonSerializer( - new ManeuverMainCurveWithEstimationDataJsonSerializer(), - new ManeuverCurveWithUnstableCourseAndSpeedWithEstimationDataJsonSerializer(), - new ManeuverWindJsonSerializer(), new PositionJsonSerializer()), - startBeforeStartLineInSeconds, endBeforeStartLineInSeconds, startAfterFinishLineInSeconds, - endAfterFinishLineInSeconds); + new CompleteManeuverCurvesWithEstimationDataJsonSerializer(getService().getPolarDataService(), + new CompleteManeuverCurveWithEstimationDataJsonSerializer( + new ManeuverMainCurveWithEstimationDataJsonSerializer(), + new ManeuverCurveWithUnstableCourseAndSpeedWithEstimationDataJsonSerializer(), + new ManeuverWindJsonSerializer(), new PositionJsonSerializer())), + getNullableValueFromDefault(startBeforeStartLineInSeconds), + getNullableValueFromDefault(endBeforeStartLineInSeconds), + getNullableValueFromDefault(startAfterFinishLineInSeconds), + getNullableValueFromDefault(endAfterFinishLineInSeconds)); JSONObject jsonMarkPassings = serializer.serialize(trackedRace); String json = jsonMarkPassings.toJSONString(); return Response.ok(json).header("Content-Type", MediaType.APPLICATION_JSON + ";charset=UTF-8").build(); @@ -1068,7 +1072,7 @@ public class RegattasResource extends AbstractSailingServerResource { } return response; } - + @GET @Produces("application/json;charset=UTF-8") @Path("{regattaname}/races/{racename}/gpsFixesWithEstimationData") @@ -1098,11 +1102,14 @@ public class RegattasResource extends AbstractSailingServerResource { .type(MediaType.TEXT_PLAIN).build(); } else { TrackedRace trackedRace = findTrackedRace(regattaName, raceName); - GpsFixesWithEstimationDataJsonSerializer serializer = new GpsFixesWithEstimationDataJsonSerializer( - new DetailedBoatClassJsonSerializer(), new GPSFixMovingJsonSerializer(), - new ManeuverWindJsonSerializer(), addWind, addNextWaypoint, smoothFixes, - startBeforeStartLineInSeconds, endBeforeStartLineInSeconds, startAfterFinishLineInSeconds, - endAfterFinishLineInSeconds); + CompetitorTrackWithEstimationDataJsonSerializer serializer = new CompetitorTrackWithEstimationDataJsonSerializer( + getService().getPolarDataService(), new DetailedBoatClassJsonSerializer(), + new GpsFixesWithEstimationDataJsonSerializer(new GPSFixMovingJsonSerializer(), + new ManeuverWindJsonSerializer(), addWind, addNextWaypoint, smoothFixes), + getNullableValueFromDefault(startBeforeStartLineInSeconds), + getNullableValueFromDefault(endBeforeStartLineInSeconds), + getNullableValueFromDefault(startAfterFinishLineInSeconds), + getNullableValueFromDefault(endAfterFinishLineInSeconds)); JSONObject jsonMarkPassings = serializer.serialize(trackedRace); String json = jsonMarkPassings.toJSONString(); return Response.ok(json).header("Content-Type", MediaType.APPLICATION_JSON + ";charset=UTF-8").build(); @@ -1111,6 +1118,10 @@ public class RegattasResource extends AbstractSailingServerResource { return response; } + private Integer getNullableValueFromDefault(Integer value) { + return Integer.MIN_VALUE == value ? null : value; + } + @GET @Produces("application/json;charset=UTF-8") @Path("{regattaname}/races")