Merge branch 'master' into bug4454

This commit is contained in:
Steffen Schaefer committed 2018-04-18 08:58:32 +02:00
commit 0fb416a032
17 files changed
+155 -45

No files matched your search

@@ -32,6 +32,7 @@ import com.sap.sailing.domain.swisstimingadapter.Mark;
import com.sap.sailing.domain.swisstimingadapter.MessageType;
import com.sap.sailing.domain.swisstimingadapter.Race;
import com.sap.sailing.domain.swisstimingadapter.RaceStatus;
import com.sap.sailing.domain.swisstimingadapter.RacingStatus;
import com.sap.sailing.domain.swisstimingadapter.SailMasterConnector;
import com.sap.sailing.domain.swisstimingadapter.SailMasterListener;
import com.sap.sailing.domain.swisstimingadapter.SailMasterMessage;
@@ -114,11 +115,11 @@ public class SailMasterConnectivityTest {
@Override
public void receivedWindData(String raceID, int zeroBasedMarkIndex, double windDirectionTrueDegrees, double windSpeedInKnots) {}
@Override
public void receivedRacePositionData(String raceID, RaceStatus status, TimePoint timePoint, TimePoint startTime,
Long millisecondsSinceRaceStart, Integer nextMarkIndexForLeader, Distance distanceToNextMarkForLeaderInMeters,
Collection<Fix> fixes) {
public void receivedRacePositionData(String raceID, RaceStatus raceStatus, RacingStatus racingStatus, TimePoint timePoint,
TimePoint startTime, Long millisecondsSinceRaceStart, Integer nextMarkIndexForLeader,
Distance distanceToNextMarkForLeaderInMeters, Collection<Fix> fixes) {
raceIDResult[0] = raceID;
raceStatusResult[0] = status;
raceStatusResult[0] = raceStatus;
fixesResult.addAll(fixes);
synchronized (SailMasterConnectivityTest.this) {
SailMasterConnectivityTest.this.notifyAll();
@@ -134,6 +135,50 @@ public class SailMasterConnectivityTest {
assertEquals(59, fixesResult.size());
}
@Test
public void testRPDWithRacingStatus() throws IOException, InterruptedException {
final String[] raceIDResult = new String[1];
final RaceStatus[] raceStatusResult = new RaceStatus[1];
final RacingStatus[] racingStatusResult = new RacingStatus[1];
final Collection<Fix> fixesResult = new ArrayList<Fix>();
connector4702.addSailMasterListener(new SailMasterListener() {
@Override
public void receivedTimingData(String raceID, String boatID, List<com.sap.sse.common.Util.Triple<Integer, Integer, Long>> markIndicesRanksAndTimesSinceStartInMilliseconds) {}
@Override
public void receivedStartList(String raceID, StartList startList) {}
@Override
public void receivedCourseConfiguration(String raceID, Course course) {}
@Override
public void receivedClockAtMark(String raceID, List<com.sap.sse.common.Util.Triple<Integer, TimePoint, String>> markIndicesTimePointsAndBoatIDs) {}
@Override
public void receivedAvailableRaces(Iterable<Race> races) {}
@Override
public void storedDataProgress(String raceID, double progress) {}
@Override
public void receivedWindData(String raceID, int zeroBasedMarkIndex, double windDirectionTrueDegrees, double windSpeedInKnots) {}
@Override
public void receivedRacePositionData(String raceID, RaceStatus raceStatus, RacingStatus racingStatus, TimePoint timePoint,
TimePoint startTime, Long millisecondsSinceRaceStart, Integer nextMarkIndexForLeader,
Distance distanceToNextMarkForLeaderInMeters, Collection<Fix> fixes) {
raceIDResult[0] = raceID;
raceStatusResult[0] = raceStatus;
racingStatusResult[0] = racingStatus;
fixesResult.addAll(fixes);
synchronized (SailMasterConnectivityTest.this) {
SailMasterConnectivityTest.this.notifyAll();
}
}
});
synchronized (this) {
sailMaster.sendEvent("RPD|W4702|0,3|2011-06-06T18:16:40+02:00|||||61|SB;2;0;50.621906;-2.366133;0.2;;;90;;;;|MB4;4;0;50.604516;-2.373371;2.1;;;108;;;;|MB3;4;0;50.607238;-2.388115;5.4;;;218;;;;|MB2;4;0;50.618063;-2.352200;3.5;;;150;;;;|MB1;4;0;50.620284;-2.366468;0.6;;;0;;;;|M7;5;0;50.621875;-2.366162;0.0;;;90;;;;|M6;5;0;50.607593;-2.387875;0.6;;;0;;;;|M5;5;0;50.605033;-2.373561;0.8;;;90;;;;|M4;5;0;50.617114;-2.352124;0.4;;;90;;;;|M3;5;0;50.620244;-2.366878;0.0;;;180;;;;|M2;5;0;50.619857;-2.366341;1.0;;;90;;;;|M1;5;0;50.617371;-2.352767;1.4;;;90;;;;|FP;4;0;50.619979;-2.354295;1.2;;;90;;;;|FB;4;0;50.619997;-2.354945;0.0;;;90;;;;|SP;4;0;50.610540;-2.347954;4.3;;;276;;;;|ARG_8;1;0;50.609389;-2.378625;4.3;;;70;;;;|AUS_7;1;0;50.607808;-2.377885;5.1;;;79;;;;|AUT_431;1;0;50.609798;-2.375270;5.6;;;60;;;;|BRA_177;1;0;50.611476;-2.379518;5.8;;;63;;;;|BRA_1187;1;0;50.611936;-2.379847;6.0;;;71;;;;|CAN_11;1;0;50.608996;-2.378944;4.3;;;63;;;;|CAN_610;1;0;50.609465;-2.380589;5.8;;;78;;;;|CHN_1211;1;0;50.609146;-2.379306;5.8;;;55;;;;|CHN_1261;1;27;50.609774;-2.381628;5.4;;;44;;;;|CHN_221;1;0;50.611029;-2.376609;5.4;;;82;;;;|CHN_616;1;0;50.611100;-2.375881;5.1;;;73;;;;|CRO_111;1;0;50.610189;-2.376963;5.1;;;72;;;;|DEN_143;1;0;50.609804;-2.375818;4.9;;;49;;;;|ESP_133;1;0;50.609543;-2.380252;6.0;;;54;;;;|ESP_696;1;0;50.609737;-2.375615;4.3;;;54;;;;|EST_20;1;0;50.609752;-2.378286;4.7;;;25;;;;|FRA_12;1;0;50.612187;-2.381923;5.4;;;32;;;;|FRA_4;1;0;50.609405;-2.378963;5.8;;;81;;;;|FRA_9;1;0;50.608222;-2.377562;5.1;;;59;;;;|GBR_812;1;0;50.608942;-2.378740;5.8;;;81;;;;|GBR_831;1;;;;;;;;;;;|GBR_841;1;0;50.610339;-2.378788;4.1;;;84;;;;|GBR_847;1;0;50.609013;-2.378316;4.9;;;61;;;;|GBR_850;1;0;50.609983;-2.376479;5.2;;;66;;;;|GBR_855;1;0;50.610087;-2.377418;4.9;;;61;;;;|GER_12;1;0;50.608424;-2.378020;5.1;;;90;;;;|GER_21;1;0;50.608690;-2.379355;5.2;;;75;;;;|GER_61;1;0;50.612197;-2.380552;5.1;;;72;;;;|GER_66;1;0;50.610299;-2.379494;5.6;;;56;;;;|GER_72;1;0;50.611263;-2.382863;4.9;;;41;;;;|ISR_311;1;0;50.611931;-2.378758;5.2;;;48;;;;|ITA_23;1;0;50.611871;-2.376589;5.1;;;10;;;;|JPN_4151;1;0;50.610487;-2.376647;5.1;;;17;;;;|JPN_4321;1;0;50.609067;-2.378408;5.8;;;63;;;;|NED_11;1;0;50.609497;-2.374946;5.4;;;94;;;;|NED_24;1;;;;;;;;;;;|NZL_75;1;0;50.609794;-2.376366;5.6;;;51;;;;|RUS_12;1;0;50.609904;-2.380138;5.1;;;56;;;;|RUS_700;1;0;50.609864;-2.381247;4.7;;;29;;;;|SLO_64;1;0;50.611275;-2.380638;5.2;;;53;;;;|SUI_14;1;0;50.611303;-2.382679;7.6;;;32;;;;|SWE_342;1;0;50.608294;-2.377717;4.7;;;96;;;;|SWE_344;1;0;50.609573;-2.375109;6.0;;;77;;;;|USA_1712;1;0;50.609414;-2.379397;5.8;;;85;;;;|USA_1736;1;0;50.611837;-2.380319;5.4;;;72;;;;|USA_1757;1;0;50.610240;-2.376824;5.8;;;9;;;;");
this.wait();
}
assertEquals("W4702", raceIDResult[0]);
assertEquals(RaceStatus.READY, raceStatusResult[0]);
assertEquals(RacingStatus.FINISHED, racingStatusResult[0]);
assertEquals(59, fixesResult.size());
}
@Test
public void testRAC() throws UnknownHostException, IOException, InterruptedException {
// TODO this test probably doesn't make sense anymore because request/response is no longer supported
@@ -26,6 +26,7 @@ import com.sap.sailing.domain.swisstimingadapter.Fix;
import com.sap.sailing.domain.swisstimingadapter.Mark;
import com.sap.sailing.domain.swisstimingadapter.Race;
import com.sap.sailing.domain.swisstimingadapter.RaceStatus;
import com.sap.sailing.domain.swisstimingadapter.RacingStatus;
import com.sap.sailing.domain.swisstimingadapter.SailMasterConnector;
import com.sap.sailing.domain.swisstimingadapter.SailMasterListener;
import com.sap.sailing.domain.swisstimingadapter.StartList;
@@ -164,9 +165,9 @@ public class SwissTimingSailMasterLiveTest implements SailMasterListener {
}
@Override
public void receivedRacePositionData(String raceID, RaceStatus status, TimePoint timePoint, TimePoint startTime,
Long millisecondsSinceRaceStart, Integer nextMarkIndexForLeader, Distance distanceToNextMarkForLeader,
Collection<Fix> fixes) {
public void receivedRacePositionData(String raceID, RaceStatus raceStatus, RacingStatus racingStatus, TimePoint timePoint,
TimePoint startTime, Long millisecondsSinceRaceStart, Integer nextMarkIndexForLeader,
Distance distanceToNextMarkForLeader, Collection<Fix> fixes) {
System.out.print(".");
rpdCounter++;
}
@@ -0,0 +1,5 @@
package com.sap.sailing.domain.swisstimingadapter;
public enum RacingStatus {
NONE, ABANDONED, COMPLETED, FINISHED, GENERALRECALL, NORACINGTODAY, POSTPONED, RACING, RACINGIR, RUNAFTER, STARTSEQUENCE
}
@@ -10,9 +10,9 @@ import com.sap.sse.common.Util;
public abstract class SailMasterAdapter implements SailMasterListener {
@Override
public void receivedRacePositionData(String raceID, RaceStatus status, TimePoint timePoint, TimePoint startTime,
Long millisecondsSinceRaceStart, Integer nextMarkIndexForLeader, Distance distanceToNextMarkForLeader,
Collection<Fix> fixes) {
public void receivedRacePositionData(String raceID, RaceStatus raceStatus, RacingStatus racingStatus, TimePoint timePoint,
TimePoint startTime, Long millisecondsSinceRaceStart, Integer nextMarkIndexForLeader,
Distance distanceToNextMarkForLeader, Collection<Fix> fixes) {
}
@Override
@@ -54,7 +54,7 @@ public interface SailMasterConnector {
/**
* Enables receiving RPD (Race Position Data) events to be emitted by the server. If such events are received, they
* are forwarded to {@link #addSailMasterListener(SailMasterListener) registered} listeners by calling their
* {@link SailMasterListener#receivedRacePositionData(String, RaceStatus, TimePoint, TimePoint, Long, Integer, com.sap.sailing.domain.common.Distance, java.util.Collection)}
* {@link SailMasterListener#receivedRacePositionData(String, RaceStatus, RacingStatus, TimePoint, TimePoint, Long, Integer, com.sap.sailing.domain.common.Distance, java.util.Collection)}
* method.
*/
void enableRacePositionData() throws UnknownHostException, IOException, InterruptedException;
@@ -8,9 +8,9 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
public interface SailMasterListener {
void receivedRacePositionData(String raceID, RaceStatus status, TimePoint timePoint, TimePoint startTime,
Long millisecondsSinceRaceStart, Integer nextMarkIndexForLeader, Distance distanceToNextMarkForLeader,
Collection<Fix> fixes);
void receivedRacePositionData(String raceID, RaceStatus raceStatus, RacingStatus racingStatus, TimePoint timePoint,
TimePoint startTime, Long millisecondsSinceRaceStart, Integer nextMarkIndexForLeader,
Distance distanceToNextMarkForLeader, Collection<Fix> fixes);
void receivedTimingData(String raceID, String boatID, List<Util.Triple<Integer, Integer, Long>> markIndicesRanksAndTimesSinceStartInMilliseconds);
@@ -46,6 +46,7 @@ import com.sap.sailing.domain.swisstimingadapter.Mark.MarkType;
import com.sap.sailing.domain.swisstimingadapter.MessageType;
import com.sap.sailing.domain.swisstimingadapter.Race;
import com.sap.sailing.domain.swisstimingadapter.RaceStatus;
import com.sap.sailing.domain.swisstimingadapter.RacingStatus;
import com.sap.sailing.domain.swisstimingadapter.SailMasterConnector;
import com.sap.sailing.domain.swisstimingadapter.SailMasterListener;
import com.sap.sailing.domain.swisstimingadapter.SailMasterMessage;
@@ -248,7 +249,7 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
}
} catch (Exception e) {
// broken messages are ignored
logger.warning("Exception caught during parsing of message '" + message.getMessage() + "' : " + e.getMessage());
logger.log(Level.WARNING, "Exception caught during parsing of message '" + message.getMessage() + "' : " + e.getMessage(), e);
}
}
@@ -356,7 +357,16 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
assert message.getType() == MessageType.RPD;
String[] sections = message.getSections();
String raceID = sections[1];
RaceStatus status = RaceStatus.values()[Integer.valueOf(sections[2])];
final RaceStatus raceStatus;
final RacingStatus racingStatus;
if (sections[2].contains(",")) {
final String[] raceStatusIntAndRacingStatusInt = sections[2].split(",");
raceStatus = RaceStatus.values()[Integer.valueOf(raceStatusIntAndRacingStatusInt[0])];
racingStatus = RacingStatus.values()[Integer.valueOf(raceStatusIntAndRacingStatusInt[1])];
} else {
raceStatus = RaceStatus.values()[Integer.valueOf(sections[2])];
racingStatus = null;
}
TimePoint timePoint = new MillisecondsTimePoint(parseTimeAndDateISO(sections[3], raceID));
lastRPDMessageTimePoint = timePoint;
String dateISO = sections[3].substring(0, sections[3].indexOf('T'));
@@ -420,8 +430,8 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
Set<SailMasterListener> allListeners = getListeners();
for (SailMasterListener listener : allListeners) {
try {
listener.receivedRacePositionData(raceID, status, timePoint, startTimeEstimatedStartTime, millisecondsSinceRaceStart,
nextMarkIndexForLeader, distanceToNextMarkForLeader, fixes);
listener.receivedRacePositionData(raceID, raceStatus, racingStatus, timePoint, startTimeEstimatedStartTime,
millisecondsSinceRaceStart, nextMarkIndexForLeader, distanceToNextMarkForLeader, fixes);
} catch (Exception e) {
logger.info("Exception occurred trying to notify listener "+listener+" about "+message+": "+e.getMessage());
logger.throwing(SailMasterConnectorImpl.class.getName(), "notifyListenersRPD", e);
@@ -531,6 +541,9 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
logger.info("Requesting messages starting from sequence number " + (maxSequenceNumber + 1)+" in "+this);
// already received a numbered message; ask only for newer messages with greater sequence number
lsnArgs.add(new Long(maxSequenceNumber + 1).toString());
} else {
logger.info("Requesting messages starting from the beginning in "+this);
lsnArgs.add("1");
}
final SailMasterMessage lsnRequest = createSailMasterMessage(MessageType.LSN,
lsnArgs.toArray(new String[0]));
@@ -43,6 +43,7 @@ import com.sap.sailing.domain.swisstimingadapter.Fix;
import com.sap.sailing.domain.swisstimingadapter.Race;
import com.sap.sailing.domain.swisstimingadapter.RaceStatus;
import com.sap.sailing.domain.swisstimingadapter.RaceType;
import com.sap.sailing.domain.swisstimingadapter.RacingStatus;
import com.sap.sailing.domain.swisstimingadapter.SailMasterConnector;
import com.sap.sailing.domain.swisstimingadapter.SailMasterListener;
import com.sap.sailing.domain.swisstimingadapter.StartList;
@@ -257,9 +258,9 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl
}
@Override
public void receivedRacePositionData(String raceID, RaceStatus status, TimePoint timePoint, TimePoint startTime,
Long millisecondsSinceRaceStart, Integer nextMarkIndexForLeader, Distance distanceToNextMarkForLeader,
Collection<Fix> fixes) {
public void receivedRacePositionData(String raceID, RaceStatus raceStatus, RacingStatus racingStatus, TimePoint timePoint,
TimePoint startTime, Long millisecondsSinceRaceStart, Integer nextMarkIndexForLeader,
Distance distanceToNextMarkForLeader, Collection<Fix> fixes) {
assert this.raceID.equals(raceID);
if (isTrackedRaceStillReachable()) {
if (this.raceID.equals(raceID)) {
@@ -2,8 +2,11 @@ package com.sap.sailing.domain.maneuverdetection;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.ManeuverType;
import com.sap.sailing.domain.common.Positioned;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.tracking.CompleteManeuverCurve;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Timed;
import com.sap.sse.datamining.annotations.Connector;
import com.sap.sse.datamining.annotations.Dimension;
@@ -15,7 +18,7 @@ import com.sap.sse.datamining.annotations.Dimension;
* @see CompleteManeuverCurve
*
*/
public interface CompleteManeuverCurveWithEstimationData {
public interface CompleteManeuverCurveWithEstimationData extends Timed, Positioned {
@Dimension(messageKey = "ManeuverType")
default ManeuverType getManeuverTypeForCompleteManeuverCurve() {
@@ -33,6 +36,11 @@ public interface CompleteManeuverCurveWithEstimationData {
}
return isManeuverStartsByRunningAwayFromWind() ? ManeuverType.BEAR_AWAY : ManeuverType.HEAD_UP;
}
@Override
default TimePoint getTimePoint() {
return getMainCurve().getTimePointOfMaxTurningRate();
}
/**
* Gets the information of the main curve of maneuver including its boundaries, course change, and other data
@@ -1,6 +1,7 @@
package com.sap.sailing.domain.maneuverdetection.impl;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.maneuverdetection.CompleteManeuverCurveWithEstimationData;
import com.sap.sailing.domain.maneuverdetection.ManeuverCurveWithUnstableCourseAndSpeedWithEstimationData;
@@ -13,6 +14,7 @@ import com.sap.sailing.domain.maneuverdetection.ManeuverMainCurveWithEstimationD
*/
public class CompleteManeuverCurveWithEstimationDataImpl implements CompleteManeuverCurveWithEstimationData {
private static final long serialVersionUID = 8858661029172491784L;
private final ManeuverMainCurveWithEstimationData mainCurve;
private final ManeuverCurveWithUnstableCourseAndSpeedWithEstimationData curveWithUnstableCourseAndSpeed;
private final Wind wind;
@@ -22,12 +24,14 @@ public class CompleteManeuverCurveWithEstimationDataImpl implements CompleteMane
private final Bearing relativeBearingToNextMarkBeforeManeuver;
private final Bearing relativeBearingToNextMarkAfterManeuver;
private final boolean markPassing;
private Position position;
public CompleteManeuverCurveWithEstimationDataImpl(ManeuverMainCurveWithEstimationData mainCurve,
public CompleteManeuverCurveWithEstimationDataImpl(Position position, ManeuverMainCurveWithEstimationData mainCurve,
ManeuverCurveWithUnstableCourseAndSpeedWithEstimationData curveWithUnstableCourseAndSpeed, Wind wind,
int tackingCount, int jibingCount, boolean maneuverStartsByRunningAwayFromWind,
Bearing relativeBearingToNextMarkBeforeManeuver,
Bearing relativeBearingToNextMarkAfterManeuver, boolean markPassing) {
Bearing relativeBearingToNextMarkBeforeManeuver, Bearing relativeBearingToNextMarkAfterManeuver,
boolean markPassing) {
this.position = position;
this.mainCurve = mainCurve;
this.curveWithUnstableCourseAndSpeed = curveWithUnstableCourseAndSpeed;
this.wind = wind;
@@ -84,4 +88,9 @@ public class CompleteManeuverCurveWithEstimationDataImpl implements CompleteMane
return markPassing;
}
@Override
public Position getPosition() {
return position;
}
}
@@ -379,10 +379,10 @@ public class ManeuverDetectorImpl implements ManeuverDetector {
Bearing relativeBearingToNextMarkPassingAfterManeuver = getRelativeBearingToNextMark(
maneuverCurve.getManeuverCurveWithStableSpeedAndCourseBoundaries().getTimePointAfter(), maneuverCurve
.getManeuverCurveWithStableSpeedAndCourseBoundaries().getSpeedWithBearingAfter().getBearing());
return new CompleteManeuverCurveWithEstimationDataImpl(mainCurve, curveWithUnstableCourseAndSpeed, wind,
numberOfTacks, numberOfJibes, maneuverStartsByRunningAwayFromWind,
relativeBearingToNextMarkPassingBeforeManeuver, relativeBearingToNextMarkPassingAfterManeuver,
maneuverCurve.isMarkPassing());
return new CompleteManeuverCurveWithEstimationDataImpl(maneuverPosition, mainCurve,
curveWithUnstableCourseAndSpeed, wind, numberOfTacks, numberOfJibes,
maneuverStartsByRunningAwayFromWind, relativeBearingToNextMarkPassingBeforeManeuver,
relativeBearingToNextMarkPassingAfterManeuver, maneuverCurve.isMarkPassing());
}
/**
@@ -38,6 +38,7 @@ public class SwissTimingRaceRecordDTO extends AbstractRaceRecordDTO {
public String toString() {
return "SwissTimingRaceRecordDTO [raceId=" + raceId + ", raceName=" + getName() + ", raceStartTime="
+ raceStartTime + ", regattaName=" + regattaName + ", seriesName=" + seriesName + ", fleetName="
+ fleetName + ", raceStatus=" + raceStatus + ", boatClass=" + boatClass + ", gender=" + gender + "]";
+ fleetName + ", raceStatus=" + raceStatus + ", boatClass=" + boatClass + ", gender=" + gender +
", xrrEntriesUrl=" + xrrEntriesUrl + "]";
}
}
@@ -119,6 +119,7 @@ public class EstimationDataSerializationDeserializationTest {
DegreePosition windPosition = new DegreePosition(54.325246, 10.148556);
Wind wind = new WindImpl(windPosition, windTimePoint, windSpeedWithBearing);
DegreePosition maneuverPosition = new DegreePosition(50.325246, 11.148556);
int jibingCount = 203;
int tackingCount = 12345;
boolean maneuverStartsByRunningAwayFromWind = true;
@@ -126,20 +127,22 @@ public class EstimationDataSerializationDeserializationTest {
Bearing relativeBearingToNextMarkAfterManeuver = new DegreeBearingImpl(10.01);
boolean markPassing = true;
CompleteManeuverCurveWithEstimationData toSerialize = new CompleteManeuverCurveWithEstimationDataImpl(mainCurve,
curve, wind, tackingCount, jibingCount, maneuverStartsByRunningAwayFromWind,
relativeBearingToNextMarkBeforeManeuver, relativeBearingToNextMarkAfterManeuver, markPassing);
CompleteManeuverCurveWithEstimationData toSerialize = new CompleteManeuverCurveWithEstimationDataImpl(
maneuverPosition, mainCurve, curve, wind, tackingCount, jibingCount,
maneuverStartsByRunningAwayFromWind, relativeBearingToNextMarkBeforeManeuver,
relativeBearingToNextMarkAfterManeuver, markPassing);
CompleteManeuverCurveWithEstimationDataJsonSerializer serializer = new CompleteManeuverCurveWithEstimationDataJsonSerializer(
new ManeuverMainCurveWithEstimationDataJsonSerializer(),
new ManeuverCurveWithUnstableCourseAndSpeedWithEstimationDataJsonSerializer(),
new WindJsonSerializer(new PositionJsonSerializer()));
new WindJsonSerializer(new PositionJsonSerializer()), new PositionJsonSerializer());
JSONObject json = serializer.serialize(toSerialize);
CompleteManeuverCurveWithEstimationDataJsonDeserializer deserializer = new CompleteManeuverCurveWithEstimationDataJsonDeserializer(
new ManeuverMainCurveWithEstimationDataJsonDeserializer(),
new ManeuverCurveWithUnstableCourseAndSpeedWithEstimationDataJsonDeserializer(),
new WindJsonDeserializer(new PositionJsonDeserializer()));
new WindJsonDeserializer(new PositionJsonDeserializer()), new PositionJsonDeserializer());
CompleteManeuverCurveWithEstimationData deserialized = deserializer.deserialize(json);
assertEquals(maneuverPosition, deserialized.getPosition());
assertEquals(tackingCount, deserialized.getTackingCount());
assertEquals(jibingCount, deserialized.getJibingCount());
assertEquals(maneuverStartsByRunningAwayFromWind, deserialized.isManeuverStartsByRunningAwayFromWind());
@@ -279,21 +282,24 @@ public class EstimationDataSerializationDeserializationTest {
Bearing relativeBearingToNextMarkBeforeManeuver = null;
Bearing relativeBearingToNextMarkAfterManeuver = null;
boolean markPassing = false;
DegreePosition maneuverPosition = new DegreePosition(50.325246, 11.148556);
CompleteManeuverCurveWithEstimationData toSerialize = new CompleteManeuverCurveWithEstimationDataImpl(mainCurve,
curve, wind, tackingCount, jibingCount, maneuverStartsByRunningAwayFromWind,
relativeBearingToNextMarkBeforeManeuver, relativeBearingToNextMarkAfterManeuver, markPassing);
CompleteManeuverCurveWithEstimationData toSerialize = new CompleteManeuverCurveWithEstimationDataImpl(
maneuverPosition, mainCurve, curve, wind, tackingCount, jibingCount,
maneuverStartsByRunningAwayFromWind, relativeBearingToNextMarkBeforeManeuver,
relativeBearingToNextMarkAfterManeuver, markPassing);
CompleteManeuverCurveWithEstimationDataJsonSerializer serializer = new CompleteManeuverCurveWithEstimationDataJsonSerializer(
new ManeuverMainCurveWithEstimationDataJsonSerializer(),
new ManeuverCurveWithUnstableCourseAndSpeedWithEstimationDataJsonSerializer(),
new WindJsonSerializer(new PositionJsonSerializer()));
new WindJsonSerializer(new PositionJsonSerializer()), new PositionJsonSerializer());
JSONObject json = serializer.serialize(toSerialize);
CompleteManeuverCurveWithEstimationDataJsonDeserializer deserializer = new CompleteManeuverCurveWithEstimationDataJsonDeserializer(
new ManeuverMainCurveWithEstimationDataJsonDeserializer(),
new ManeuverCurveWithUnstableCourseAndSpeedWithEstimationDataJsonDeserializer(),
new WindJsonDeserializer(new PositionJsonDeserializer()));
new WindJsonDeserializer(new PositionJsonDeserializer()), new PositionJsonDeserializer());
CompleteManeuverCurveWithEstimationData deserialized = deserializer.deserialize(json);
assertEquals(maneuverPosition, deserialized.getPosition());
assertEquals(tackingCount, deserialized.getTackingCount());
assertEquals(jibingCount, deserialized.getJibingCount());
assertEquals(maneuverStartsByRunningAwayFromWind, deserialized.isManeuverStartsByRunningAwayFromWind());
@@ -3,6 +3,7 @@ package com.sap.sailing.server.gateway.deserialization.impl;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
import com.sap.sailing.domain.maneuverdetection.CompleteManeuverCurveWithEstimationData;
@@ -24,18 +25,22 @@ public class CompleteManeuverCurveWithEstimationDataJsonDeserializer
private final ManeuverMainCurveWithEstimationDataJsonDeserializer mainCurveDeserializer;
private final ManeuverCurveWithUnstableCourseAndSpeedWithEstimationDataJsonDeserializer curveWithUnstableCourseAndSpeedDeserializer;
private final WindJsonDeserializer windDeserializer;
private final PositionJsonDeserializer positionDeserializer;
public CompleteManeuverCurveWithEstimationDataJsonDeserializer(
ManeuverMainCurveWithEstimationDataJsonDeserializer mainCurveDeserializer,
ManeuverCurveWithUnstableCourseAndSpeedWithEstimationDataJsonDeserializer curveWithUnstableCourseAndSpeedDeserializer,
WindJsonDeserializer windDeserializer) {
WindJsonDeserializer windDeserializer, PositionJsonDeserializer positionDeserializer) {
this.mainCurveDeserializer = mainCurveDeserializer;
this.curveWithUnstableCourseAndSpeedDeserializer = curveWithUnstableCourseAndSpeedDeserializer;
this.windDeserializer = windDeserializer;
this.positionDeserializer = positionDeserializer;
}
@Override
public CompleteManeuverCurveWithEstimationData deserialize(JSONObject object) throws JsonDeserializationException {
Position position = positionDeserializer
.deserialize((JSONObject) object.get(CompleteManeuverCurveWithEstimationDataJsonSerializer.POSITION));
boolean markPassing = (Boolean) object.get(CompleteManeuverCurveWithEstimationDataJsonSerializer.MARK_PASSING);
ManeuverMainCurveWithEstimationData mainCurve = mainCurveDeserializer
.deserialize((JSONObject) object.get(CompleteManeuverCurveWithEstimationDataJsonSerializer.MAIN_CURVE));
@@ -54,8 +59,8 @@ public class CompleteManeuverCurveWithEstimationDataJsonDeserializer
CompleteManeuverCurveWithEstimationDataJsonSerializer.RELATIVE_BEARING_TO_NEXT_MARK_BEFORE_MANEUVER);
Double relativeBearingToNextMarkAfterManeuver = (Double) object.get(
CompleteManeuverCurveWithEstimationDataJsonSerializer.RELATIVE_BEARING_TO_NEXT_MARK_AFTER_MANEUVER);
return new CompleteManeuverCurveWithEstimationDataImpl(mainCurve, curveWithUnstableCourseAndSpeed, wind,
tackingCount, jibingCount, maneuverStartsByRunningAwayFromWind,
return new CompleteManeuverCurveWithEstimationDataImpl(position, mainCurve, curveWithUnstableCourseAndSpeed,
wind, tackingCount, jibingCount, maneuverStartsByRunningAwayFromWind,
convertBearing(relativeBearingToNextMarkBeforeManeuver),
convertBearing(relativeBearingToNextMarkAfterManeuver), markPassing);
}
@@ -13,6 +13,7 @@ import com.sap.sailing.server.gateway.serialization.JsonSerializer;
public class CompleteManeuverCurveWithEstimationDataJsonSerializer
implements JsonSerializer<CompleteManeuverCurveWithEstimationData> {
public static final String POSITION = "position";
public static final String MARK_PASSING = "markPassing";
public static final String MAIN_CURVE = "mainCurve";
public static final String CURVE_WITH_UNSTABLE_COURSE_AND_SPEED = "curveWithUnstableCourseAndSpeed";
@@ -26,19 +27,22 @@ public class CompleteManeuverCurveWithEstimationDataJsonSerializer
private final ManeuverCurveBoundariesJsonSerializer mainCurveSerializer;
private final ManeuverCurveBoundariesJsonSerializer curveWithUnstableCourseAndSpeedSerializer;
private final WindJsonSerializer windSerializer;
private final PositionJsonSerializer positionSerializer;
public CompleteManeuverCurveWithEstimationDataJsonSerializer(
ManeuverCurveBoundariesJsonSerializer mainCurveSerializer,
ManeuverCurveBoundariesJsonSerializer curveWithUnstableCourseAndSpeedSerializer,
WindJsonSerializer windSerializer) {
WindJsonSerializer windSerializer, PositionJsonSerializer positionSerializer) {
this.mainCurveSerializer = mainCurveSerializer;
this.curveWithUnstableCourseAndSpeedSerializer = curveWithUnstableCourseAndSpeedSerializer;
this.windSerializer = windSerializer;
this.positionSerializer = positionSerializer;
}
@Override
public JSONObject serialize(CompleteManeuverCurveWithEstimationData maneuverWithEstimationData) {
final JSONObject result = new JSONObject();
result.put(POSITION, positionSerializer.serialize(maneuverWithEstimationData.getPosition()));
result.put(MARK_PASSING, maneuverWithEstimationData.isMarkPassing());
result.put(MAIN_CURVE, mainCurveSerializer.serialize(maneuverWithEstimationData.getMainCurve()));
result.put(CURVE_WITH_UNSTABLE_COURSE_AND_SPEED, curveWithUnstableCourseAndSpeedSerializer
@@ -1047,7 +1047,7 @@ public class RegattasResource extends AbstractSailingServerResource {
new CompleteManeuverCurveWithEstimationDataJsonSerializer(
new ManeuverMainCurveWithEstimationDataJsonSerializer(),
new ManeuverCurveWithUnstableCourseAndSpeedWithEstimationDataJsonSerializer(),
new WindJsonSerializer(new PositionJsonSerializer())));
new WindJsonSerializer(new PositionJsonSerializer()), new PositionJsonSerializer()));
JSONObject jsonMarkPassings = serializer.serialize(trackedRace);
String json = jsonMarkPassings.toJSONString();
return Response.ok(json).header("Content-Type", MediaType.APPLICATION_JSON + ";charset=UTF-8").build();
@@ -22,6 +22,17 @@
<h2 class="releaseHeadline">Release Notes - Administration Console</h2>
<div class="innerContent">
<h2 class="articleSubheadline">April 2018</h2>
<ul class="bulletList">
<li>The import of additional expedition data was extended to read many additional measures.
These can be visualized in the leaderboard as well as the competitor charts in <tt>RaceBoard.html</tt>.
In addition, the leaderboard has been extended to provide bravo and expedition related measures consistently on race and leg level.
The respective settings dialogs were changed as well to only show specific options, if bravo or expedition tracks are available.
Any previously imported expedition tracks may be dropped and reimported to gain access to the newly introduced measures.</li>
<li>The settings dialog of the competitor charts in <tt>RaceBoard.html</tt> now provides the measures in alphabetical order (based on the current locale).
Expedition specific measures - if available - are shown at the end of the list.</li>
</ul>
<h2 class="articleSubheadline">March 2018</h2>
<ul class="bulletList">
<li>Boats are now separate entities. See the "Tracked Races / Boats" tab in the admin console.
@@ -51,6 +62,7 @@
</li>
</ul>
<h2 class="articleSubheadline">February 2018</h2>
<ul class="bulletList">
<li>Further improvements of maneuver detection algorithm were introduced. Mark Passing is no longer regarded as a separate maneuver type. Instead, it is regarded as a supplementary information which gets appended to a maneuver instance. Therefore, a new filtering dimension was added for maneuver data mining, which is boolean and is named as "Mark Passing".</li>
<li>Added leaderboard group name as a dimension to a leaderboard's context</li>