mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-28 14:57:12 +00:00
Merge remote-tracking branch 'origin/master' into design2015
Conflicts: java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java
This commit is contained in:
commit
89fd4e4471
171 files changed
+6404
-1625
No files matched your search
+3
-3
@@ -136,10 +136,10 @@ public class StartlineAnalysisCard extends Composite implements HasWidgets, Star
|
|||||||
com.sap.sse.gwt.client.player.Timer timer = new com.sap.sse.gwt.client.player.Timer(PlayModes.Live, 1000l);
|
com.sap.sse.gwt.client.player.Timer timer = new com.sap.sse.gwt.client.player.Timer(PlayModes.Live, 1000l);
|
||||||
timer.pause();
|
timer.pause();
|
||||||
ArrayList<ZoomTypes> zoomTypes = new ArrayList<ZoomTypes>();
|
ArrayList<ZoomTypes> zoomTypes = new ArrayList<ZoomTypes>();
|
||||||
if(startAnalysisDTO.racingProcedureType.equals(RacingProcedureType.GateStart)){
|
if (startAnalysisDTO.racingProcedureType.equals(RacingProcedureType.GateStart)) {
|
||||||
timer.setTime(startAnalysisDTO.timeOfStartInMilliSeconds+startAnalysisDTO.tailLenghtInMilliseconds);
|
timer.setTime(startAnalysisDTO.timeOfStartInMilliSeconds + startAnalysisDTO.tailLenghtInMilliseconds);
|
||||||
zoomTypes.add(ZoomTypes.BUOYS);
|
zoomTypes.add(ZoomTypes.BUOYS);
|
||||||
}else{
|
} else {
|
||||||
timer.setTime(startAnalysisDTO.timeOfStartInMilliSeconds);
|
timer.setTime(startAnalysisDTO.timeOfStartInMilliSeconds);
|
||||||
zoomTypes.add(ZoomTypes.TAILS);
|
zoomTypes.add(ZoomTypes.TAILS);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
package com.sap.sailing.datamining.data;
|
package com.sap.sailing.datamining.data;
|
||||||
|
|
||||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
|
|
||||||
public interface HasLeaderboardContext {
|
public interface HasLeaderboardContext {
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
package com.sap.sailing.datamining.data;
|
package com.sap.sailing.datamining.data;
|
||||||
|
|
||||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
|
|
||||||
public interface HasLeaderboardGroupContext {
|
public interface HasLeaderboardGroupContext {
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ import java.util.concurrent.ExecutorService;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.sap.sailing.datamining.impl.data.LeaderboardGroupWithContext;
|
import com.sap.sailing.datamining.impl.data.LeaderboardGroupWithContext;
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.server.RacingEventService;
|
import com.sap.sailing.server.RacingEventService;
|
||||||
import com.sap.sse.datamining.components.Processor;
|
import com.sap.sse.datamining.components.Processor;
|
||||||
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
|
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ package com.sap.sailing.datamining.impl.data;
|
|||||||
|
|
||||||
import com.sap.sailing.datamining.data.HasLeaderboardGroupContext;
|
import com.sap.sailing.datamining.data.HasLeaderboardGroupContext;
|
||||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
|
|
||||||
public class LeaderboardGroupWithContext implements HasLeaderboardGroupContext {
|
public class LeaderboardGroupWithContext implements HasLeaderboardGroupContext {
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ package com.sap.sailing.datamining.impl.data;
|
|||||||
|
|
||||||
import com.sap.sailing.datamining.data.HasLeaderboardContext;
|
import com.sap.sailing.datamining.data.HasLeaderboardContext;
|
||||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
|
|
||||||
public class LeaderboardWithContext implements HasLeaderboardContext {
|
public class LeaderboardWithContext implements HasLeaderboardContext {
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -20,11 +20,11 @@ import com.sap.sailing.domain.common.Tack;
|
|||||||
import com.sap.sailing.domain.common.scalablevalue.impl.ScalableSpeed;
|
import com.sap.sailing.domain.common.scalablevalue.impl.ScalableSpeed;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||||
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
|
||||||
import com.sap.sse.common.Duration;
|
import com.sap.sse.common.Duration;
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
import com.sap.sse.common.Util;
|
import com.sap.sse.common.Util;
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package com.sap.sailing.domain.common;
|
||||||
|
|
||||||
|
public interface LegIdentifier extends RegattaAndRaceIdentifier {
|
||||||
|
RaceIdentifier getRaceIdentifier();
|
||||||
|
String getLegName();
|
||||||
|
int getLegNumber();
|
||||||
|
}
|
||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
package com.sap.sailing.domain.common;
|
||||||
|
|
||||||
|
public class LegIdentifierImpl extends RegattaNameAndRaceName implements LegIdentifier {
|
||||||
|
private static final long serialVersionUID = 3599904513673776450L;
|
||||||
|
private RaceIdentifier raceIdentifier = null;
|
||||||
|
private String legName;
|
||||||
|
|
||||||
|
LegIdentifierImpl() {}
|
||||||
|
|
||||||
|
public LegIdentifierImpl(RegattaAndRaceIdentifier raceIdentifier, String legName) {
|
||||||
|
super(raceIdentifier.getRegattaName(), raceIdentifier.getRaceName());
|
||||||
|
this.raceIdentifier = raceIdentifier;
|
||||||
|
this.legName = legName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RaceIdentifier getRaceIdentifier() {
|
||||||
|
return this.raceIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLegName() {
|
||||||
|
return legName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLegNumber() {
|
||||||
|
return Integer.parseInt(legName)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getRegattaName() + "/" + getRaceName() + "/" + getLegName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = prime * result + ((legName == null) ? 0 : legName.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (!super.equals(obj))
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
LegIdentifierImpl other = (LegIdentifierImpl) obj;
|
||||||
|
if (legName == null) {
|
||||||
|
if (other.legName != null)
|
||||||
|
return false;
|
||||||
|
} else if (!legName.equals(other.legName))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+2
-1
@@ -13,7 +13,8 @@ public enum RacingProcedureType {
|
|||||||
RRS26("Fix Line Start (RRS26)"),
|
RRS26("Fix Line Start (RRS26)"),
|
||||||
GateStart("Gate Start"),
|
GateStart("Gate Start"),
|
||||||
ESS("\"Extreme Sailing Series\"-Start"),
|
ESS("\"Extreme Sailing Series\"-Start"),
|
||||||
BASIC("Basic Countdown Start");
|
BASIC("Basic Countdown Start"),
|
||||||
|
LEAGUE("League Start");
|
||||||
|
|
||||||
private String displayName;
|
private String displayName;
|
||||||
|
|
||||||
|
|||||||
+3
@@ -11,6 +11,7 @@ import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.ReadonlyRac
|
|||||||
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.basic.impl.BasicRacingProcedureImpl;
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.basic.impl.BasicRacingProcedureImpl;
|
||||||
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.ess.impl.ESSRacingProcedureImpl;
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.ess.impl.ESSRacingProcedureImpl;
|
||||||
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.gate.impl.GateStartRacingProcedureImpl;
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.gate.impl.GateStartRacingProcedureImpl;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.impl.LeagueRacingProcedureImpl;
|
||||||
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.rrs26.impl.RRS26RacingProcedureImpl;
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.rrs26.impl.RRS26RacingProcedureImpl;
|
||||||
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
|
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
|
||||||
import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
|
import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
|
||||||
@@ -48,6 +49,8 @@ public class ReadonlyRacingProcedureFactory implements RacingProcedureFactory {
|
|||||||
return new RRS26RacingProcedureImpl(raceLog, author, factory, loadedConfiguration.getRRS26Configuration());
|
return new RRS26RacingProcedureImpl(raceLog, author, factory, loadedConfiguration.getRRS26Configuration());
|
||||||
case BASIC:
|
case BASIC:
|
||||||
return new BasicRacingProcedureImpl(raceLog, author, factory, loadedConfiguration.getBasicConfiguration());
|
return new BasicRacingProcedureImpl(raceLog, author, factory, loadedConfiguration.getBasicConfiguration());
|
||||||
|
case LEAGUE:
|
||||||
|
return new LeagueRacingProcedureImpl(raceLog, author, factory, loadedConfiguration.getLeagueConfiguration());
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unknown racing procedure " + type.toString());
|
throw new UnsupportedOperationException("Unknown racing procedure " + type.toString());
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure;
|
||||||
|
|
||||||
|
public interface LeagueRacingProcedure extends RacingProcedure {
|
||||||
|
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedureChangedListener;
|
||||||
|
|
||||||
|
public interface LeagueRacingProcedureChangedListener extends RacingProcedureChangedListener {
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.impl;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedurePrerequisite;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.BaseRacingProcedurePrerequisite;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.LeagueRacingProcedure;
|
||||||
|
import com.sap.sse.common.TimePoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Easy access to the {@link LeagueRacingProcedure}.
|
||||||
|
*/
|
||||||
|
public abstract class LeaguePrerequisite extends BaseRacingProcedurePrerequisite implements RacingProcedurePrerequisite {
|
||||||
|
|
||||||
|
public LeaguePrerequisite(FulfillmentFunction function, LeagueRacingProcedure procedure, TimePoint originalNow,
|
||||||
|
TimePoint originalStartTime) {
|
||||||
|
super(function, procedure, originalNow, originalStartTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected LeagueRacingProcedure getProcedure() {
|
||||||
|
return (LeagueRacingProcedure) procedure;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.impl;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.RacingProcedureChangedListeners;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.LeagueRacingProcedureChangedListener;
|
||||||
|
|
||||||
|
public class LeagueRacingProcedureChangedListeners extends RacingProcedureChangedListeners<LeagueRacingProcedureChangedListener> implements
|
||||||
|
LeagueRacingProcedureChangedListener {
|
||||||
|
}
|
||||||
+141
@@ -0,0 +1,141 @@
|
|||||||
|
package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.impl;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.RaceLogEventFactory;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.RaceStateEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateEventImpl;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateEvents;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.FlagPoleState;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedureChangedListener;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedurePrerequisite;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedurePrerequisite.FulfillmentFunction;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.BaseRacingProcedure;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.NoMorePrerequisite;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.RacingProcedureChangedListeners;
|
||||||
|
import com.sap.sailing.domain.base.configuration.procedures.LeagueConfiguration;
|
||||||
|
import com.sap.sailing.domain.common.racelog.FlagPole;
|
||||||
|
import com.sap.sailing.domain.common.racelog.Flags;
|
||||||
|
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
||||||
|
import com.sap.sse.common.TimePoint;
|
||||||
|
|
||||||
|
// TODO consider subclassing RRS26RacingProcedureImpl instead of this copy&paste orgy...
|
||||||
|
public class LeagueRacingProcedureImpl extends BaseRacingProcedure {
|
||||||
|
private final static long startPhaseClassUpInterval = 3 * 60 * 1000; // minutes * seconds * milliseconds
|
||||||
|
private final static long startPhaseStartModeUpInterval = 2 * 60 * 1000; // minutes * seconds * milliseconds
|
||||||
|
private final static long startPhaseStartModeDownInterval = 1 * 60 * 1000; // minutes * seconds * milliseconds
|
||||||
|
|
||||||
|
private final static Flags startmodeFlag = Flags.PAPA;
|
||||||
|
|
||||||
|
public LeagueRacingProcedureImpl(RaceLog raceLog, AbstractLogEventAuthor author,
|
||||||
|
RaceLogEventFactory factory, LeagueConfiguration configuration) {
|
||||||
|
super(raceLog, author, factory, configuration);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RacingProcedureType getType() {
|
||||||
|
return RacingProcedureType.LEAGUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasIndividualRecall() {
|
||||||
|
boolean hasRecall = super.hasIndividualRecall();
|
||||||
|
if (!hasRecall) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return hasRecall;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean hasIndividualRecallByDefault() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RacingProcedurePrerequisite checkPrerequisitesForStart(TimePoint now, TimePoint startTime,
|
||||||
|
FulfillmentFunction function) {
|
||||||
|
return new NoMorePrerequisite(function);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStartphaseActive(TimePoint startTime, TimePoint now) {
|
||||||
|
if (now.before(startTime)) {
|
||||||
|
long timeTillStart = startTime.minus(now.asMillis()).asMillis();
|
||||||
|
return timeTillStart < startPhaseClassUpInterval;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Collection<RaceStateEvent> createStartStateEvents(TimePoint startTime) {
|
||||||
|
// Remark: We are reusing here CLASS_UP, STARTMODE_UP and STARTMODE_DOWN from the RRS26 procedure
|
||||||
|
// The question is why there are no generic CLASS_UP, STARTMODE_UP and STARTMODE_DOWN events
|
||||||
|
return Arrays.<RaceStateEvent> asList(
|
||||||
|
new RaceStateEventImpl(startTime.minus(startPhaseClassUpInterval), RaceStateEvents.RRS26_CLASS_UP),
|
||||||
|
new RaceStateEventImpl(startTime.minus(startPhaseStartModeUpInterval), RaceStateEvents.RRS26_STARTMODE_UP),
|
||||||
|
new RaceStateEventImpl(startTime.minus(startPhaseStartModeDownInterval), RaceStateEvents.RRS26_STARTMODE_DOWN),
|
||||||
|
new RaceStateEventImpl(startTime, RaceStateEvents.START));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FlagPoleState getActiveFlags(TimePoint startTime, TimePoint now) {
|
||||||
|
Flags classFlag = getConfiguration().getClassFlag() != null ?
|
||||||
|
getConfiguration().getClassFlag() : Flags.CLASS;
|
||||||
|
if (now.before(startTime.minus(startPhaseClassUpInterval))) {
|
||||||
|
return new FlagPoleState(
|
||||||
|
Arrays.asList(new FlagPole(classFlag, false), new FlagPole(startmodeFlag, false)),
|
||||||
|
null,
|
||||||
|
Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, false)),
|
||||||
|
startTime.minus(startPhaseClassUpInterval));
|
||||||
|
} else if (now.before(startTime.minus(startPhaseStartModeUpInterval))) {
|
||||||
|
return new FlagPoleState(
|
||||||
|
Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, false)),
|
||||||
|
startTime.minus(startPhaseClassUpInterval),
|
||||||
|
Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, true)),
|
||||||
|
startTime.minus(startPhaseStartModeUpInterval));
|
||||||
|
} else if (now.before(startTime.minus(startPhaseStartModeDownInterval))) {
|
||||||
|
return new FlagPoleState(
|
||||||
|
Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, true)),
|
||||||
|
startTime.minus(startPhaseStartModeUpInterval),
|
||||||
|
Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, false)),
|
||||||
|
startTime.minus(startPhaseStartModeDownInterval));
|
||||||
|
} else if (now.before(startTime)) {
|
||||||
|
return new FlagPoleState(
|
||||||
|
Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, false)),
|
||||||
|
startTime.minus(startPhaseStartModeDownInterval),
|
||||||
|
Arrays.asList(new FlagPole(classFlag, false), new FlagPole(startmodeFlag, false)),
|
||||||
|
startTime);
|
||||||
|
} else {
|
||||||
|
if (isIndividualRecallDisplayed(now)) {
|
||||||
|
return new FlagPoleState(
|
||||||
|
Arrays.asList(new FlagPole(Flags.XRAY, true)),
|
||||||
|
getIndividualRecallDisplayedTime(),
|
||||||
|
Arrays.asList(new FlagPole(Flags.XRAY, false)),
|
||||||
|
getIndividualRecallRemovalTime());
|
||||||
|
} else if (isFinished(now)) {
|
||||||
|
return new FlagPoleState(
|
||||||
|
Arrays.asList(new FlagPole(Flags.BLUE, false)), getFinishedTime());
|
||||||
|
} else if (isInFinishingPhase(now)) {
|
||||||
|
return new FlagPoleState(
|
||||||
|
Arrays.asList(new FlagPole(Flags.BLUE, true)),
|
||||||
|
getFinishingTime(),
|
||||||
|
Arrays.asList(new FlagPole(Flags.BLUE, false)),
|
||||||
|
null);
|
||||||
|
} else {
|
||||||
|
TimePoint recallRemoved = getIndividualRecallRemovalTime();
|
||||||
|
return new FlagPoleState(Collections.<FlagPole>emptyList(), recallRemoved == null ? startTime : recallRemoved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RacingProcedureChangedListeners<? extends RacingProcedureChangedListener> createChangedListenerContainer() {
|
||||||
|
return new LeagueRacingProcedureChangedListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-1
@@ -5,6 +5,7 @@ import java.io.Serializable;
|
|||||||
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure;
|
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure;
|
||||||
import com.sap.sailing.domain.base.configuration.procedures.ESSConfiguration;
|
import com.sap.sailing.domain.base.configuration.procedures.ESSConfiguration;
|
||||||
import com.sap.sailing.domain.base.configuration.procedures.GateStartConfiguration;
|
import com.sap.sailing.domain.base.configuration.procedures.GateStartConfiguration;
|
||||||
|
import com.sap.sailing.domain.base.configuration.procedures.LeagueConfiguration;
|
||||||
import com.sap.sailing.domain.base.configuration.procedures.RRS26Configuration;
|
import com.sap.sailing.domain.base.configuration.procedures.RRS26Configuration;
|
||||||
import com.sap.sailing.domain.common.CourseDesignerMode;
|
import com.sap.sailing.domain.common.CourseDesignerMode;
|
||||||
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
||||||
@@ -42,7 +43,13 @@ public interface RegattaConfiguration extends Serializable, Cloneable {
|
|||||||
* @return <code>null</code> if there is no configuration.
|
* @return <code>null</code> if there is no configuration.
|
||||||
*/
|
*/
|
||||||
ESSConfiguration getESSConfiguration();
|
ESSConfiguration getESSConfiguration();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the configuration for league races.
|
||||||
|
* @return <code>null</code> if there is no configuration.
|
||||||
|
*/
|
||||||
|
LeagueConfiguration getLeagueConfiguration();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the configuration for Basic races.
|
* Gets the configuration for Basic races.
|
||||||
* @return <code>null</code> if there is no configuration.
|
* @return <code>null</code> if there is no configuration.
|
||||||
|
|||||||
+1
@@ -21,6 +21,7 @@ public class EmptyRegattaConfiguration extends RegattaConfigurationImpl implemen
|
|||||||
setGateStartConfiguration(new GateStartConfigurationImpl());
|
setGateStartConfiguration(new GateStartConfigurationImpl());
|
||||||
setESSConfiguration(new ESSConfigurationImpl());
|
setESSConfiguration(new ESSConfigurationImpl());
|
||||||
setBasicConfiguration(new RacingProcedureConfigurationImpl());
|
setBasicConfiguration(new RacingProcedureConfigurationImpl());
|
||||||
|
setLeagueConfiguration(new LeagueConfigurationImpl());
|
||||||
return clone();
|
return clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
package com.sap.sailing.domain.base.configuration.impl;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration;
|
||||||
|
import com.sap.sailing.domain.base.configuration.procedures.LeagueConfiguration;
|
||||||
|
|
||||||
|
public class LeagueConfigurationImpl extends RacingProcedureConfigurationImpl implements LeagueConfiguration {
|
||||||
|
private static final long serialVersionUID = 3625803505541394766L;
|
||||||
|
|
||||||
|
protected LeagueConfigurationImpl copy() {
|
||||||
|
LeagueConfigurationImpl copy = (LeagueConfigurationImpl) super.copy(new LeagueConfigurationImpl());
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RacingProcedureConfiguration merge(RacingProcedureConfiguration update) {
|
||||||
|
LeagueConfigurationImpl target = (LeagueConfigurationImpl) super.merge(update);
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+16
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration;
|
|||||||
import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
|
import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
|
||||||
import com.sap.sailing.domain.base.configuration.procedures.ESSConfiguration;
|
import com.sap.sailing.domain.base.configuration.procedures.ESSConfiguration;
|
||||||
import com.sap.sailing.domain.base.configuration.procedures.GateStartConfiguration;
|
import com.sap.sailing.domain.base.configuration.procedures.GateStartConfiguration;
|
||||||
|
import com.sap.sailing.domain.base.configuration.procedures.LeagueConfiguration;
|
||||||
import com.sap.sailing.domain.base.configuration.procedures.RRS26Configuration;
|
import com.sap.sailing.domain.base.configuration.procedures.RRS26Configuration;
|
||||||
import com.sap.sailing.domain.common.CourseDesignerMode;
|
import com.sap.sailing.domain.common.CourseDesignerMode;
|
||||||
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
||||||
@@ -18,6 +19,7 @@ public class RegattaConfigurationImpl implements RegattaConfiguration {
|
|||||||
private RRS26Configuration rrs26Configuration;
|
private RRS26Configuration rrs26Configuration;
|
||||||
private GateStartConfiguration gateStartConfiguration;
|
private GateStartConfiguration gateStartConfiguration;
|
||||||
private ESSConfiguration essConfiguration;
|
private ESSConfiguration essConfiguration;
|
||||||
|
private LeagueConfiguration leagueConfiguration;
|
||||||
private RacingProcedureConfiguration basicConfiguration;
|
private RacingProcedureConfiguration basicConfiguration;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -65,6 +67,15 @@ public class RegattaConfigurationImpl implements RegattaConfiguration {
|
|||||||
this.essConfiguration = essConfiguration;
|
this.essConfiguration = essConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LeagueConfiguration getLeagueConfiguration() {
|
||||||
|
return leagueConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeagueConfiguration(LeagueConfiguration leagueConfiguration) {
|
||||||
|
this.leagueConfiguration = leagueConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RacingProcedureConfiguration getBasicConfiguration() {
|
public RacingProcedureConfiguration getBasicConfiguration() {
|
||||||
return basicConfiguration;
|
return basicConfiguration;
|
||||||
@@ -83,6 +94,7 @@ public class RegattaConfigurationImpl implements RegattaConfiguration {
|
|||||||
copy.setGateStartConfiguration(gateStartConfiguration);
|
copy.setGateStartConfiguration(gateStartConfiguration);
|
||||||
copy.setESSConfiguration(essConfiguration);
|
copy.setESSConfiguration(essConfiguration);
|
||||||
copy.setBasicConfiguration(basicConfiguration);
|
copy.setBasicConfiguration(basicConfiguration);
|
||||||
|
copy.setLeagueConfiguration(leagueConfiguration);
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,6 +124,10 @@ public class RegattaConfigurationImpl implements RegattaConfiguration {
|
|||||||
target.setBasicConfiguration(
|
target.setBasicConfiguration(
|
||||||
(RacingProcedureConfiguration) target.getBasicConfiguration().merge(update.getBasicConfiguration()));
|
(RacingProcedureConfiguration) target.getBasicConfiguration().merge(update.getBasicConfiguration()));
|
||||||
}
|
}
|
||||||
|
if (update.getLeagueConfiguration() != null) {
|
||||||
|
target.setLeagueConfiguration(
|
||||||
|
(LeagueConfiguration) target.getLeagueConfiguration().merge(update.getLeagueConfiguration()));
|
||||||
|
}
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package com.sap.sailing.domain.base.configuration.procedures;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration;
|
||||||
|
|
||||||
|
public interface LeagueConfiguration extends RacingProcedureConfiguration {
|
||||||
|
|
||||||
|
}
|
||||||
+3
-1
@@ -149,7 +149,9 @@ public class WindEstimationOnConstructedTracksTest extends StoredTrackBasedTest
|
|||||||
Wind combinedWindDirection = combinedTrack.getAveragedWind(/* position */ null, now);
|
Wind combinedWindDirection = combinedTrack.getAveragedWind(/* position */ null, now);
|
||||||
// The course layout makes a wind estimation around 7deg. The confidence of the cluster based wind estimation is a lot
|
// The course layout makes a wind estimation around 7deg. The confidence of the cluster based wind estimation is a lot
|
||||||
// higher that that of the course layout wind (currently at approximately 10E-13), we will end up quite near 180 deg.
|
// higher that that of the course layout wind (currently at approximately 10E-13), we will end up quite near 180 deg.
|
||||||
assertEquals(180.0, combinedWindDirection.getBearing().getDegrees(), 0.2);
|
// Update 04/24/15: Since polar data service is not available here, the confidence will not be as good as it once was.
|
||||||
|
// So we have quite a big delta in the assert
|
||||||
|
assertEquals(180.0, combinedWindDirection.getBearing().getDegrees(), 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+5
@@ -40,6 +40,7 @@ import com.sap.sailing.domain.common.racelog.Flags;
|
|||||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||||
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||||
import com.sap.sailing.domain.regattalike.RegattaLikeIdentifier;
|
import com.sap.sailing.domain.regattalike.RegattaLikeIdentifier;
|
||||||
import com.sap.sailing.domain.regattalike.RegattaLikeListener;
|
import com.sap.sailing.domain.regattalike.RegattaLikeListener;
|
||||||
@@ -904,4 +905,8 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
|||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPolarDataService(PolarDataService polarDataService) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+8
-3
@@ -29,6 +29,7 @@ import com.sap.sailing.domain.common.Tack;
|
|||||||
import com.sap.sailing.domain.common.Wind;
|
import com.sap.sailing.domain.common.Wind;
|
||||||
import com.sap.sailing.domain.common.WindSource;
|
import com.sap.sailing.domain.common.WindSource;
|
||||||
import com.sap.sailing.domain.common.WindSourceType;
|
import com.sap.sailing.domain.common.WindSourceType;
|
||||||
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||||
@@ -591,12 +592,12 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
|
|||||||
public GPSFixTrack<Mark, GPSFix> getTrack(Mark mark) {
|
public GPSFixTrack<Mark, GPSFix> getTrack(Mark mark) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getGateStartGolfDownTime() {
|
public long getGateStartGolfDownTime() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isUsingMarkPassingCalculator() {
|
public boolean isUsingMarkPassingCalculator() {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
@@ -608,5 +609,9 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
|
|||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPolarDataService(PolarDataService polarDataService) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,7 @@ Export-Package: com.sap.sailing.domain.base,
|
|||||||
com.sap.sailing.domain.markpassingcalculation.impl,
|
com.sap.sailing.domain.markpassingcalculation.impl,
|
||||||
com.sap.sailing.domain.markpassingcalculation.splining,
|
com.sap.sailing.domain.markpassingcalculation.splining,
|
||||||
com.sap.sailing.domain.masterdataimport,
|
com.sap.sailing.domain.masterdataimport,
|
||||||
|
com.sap.sailing.domain.polars,
|
||||||
com.sap.sailing.domain.racelog,
|
com.sap.sailing.domain.racelog,
|
||||||
com.sap.sailing.domain.racelog.impl,
|
com.sap.sailing.domain.racelog.impl,
|
||||||
com.sap.sailing.domain.racelog.tracking,
|
com.sap.sailing.domain.racelog.tracking,
|
||||||
@@ -38,4 +39,5 @@ Require-Bundle: com.googlecode.java-diff-utils;bundle-version="1.3.0",
|
|||||||
com.sap.sse.datamining.shared,
|
com.sap.sse.datamining.shared,
|
||||||
com.sap.sse.common,
|
com.sap.sse.common,
|
||||||
com.sap.sse,
|
com.sap.sse,
|
||||||
com.sap.sse.shared.android
|
com.sap.sse.shared.android,
|
||||||
|
org.apache.commons.math
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package com.sap.sailing.polars;
|
package com.sap.sailing.domain.polars;
|
||||||
|
|
||||||
import com.sap.sailing.domain.base.BoatClass;
|
import com.sap.sailing.domain.base.BoatClass;
|
||||||
import com.sap.sailing.domain.common.Bearing;
|
import com.sap.sailing.domain.common.Bearing;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package com.sap.sailing.polars.regression;
|
package com.sap.sailing.domain.polars;
|
||||||
|
|
||||||
|
|
||||||
public class NotEnoughDataHasBeenAddedException extends Exception {
|
public class NotEnoughDataHasBeenAddedException extends Exception {
|
||||||
Executable → Regular
+23
-3
@@ -1,4 +1,4 @@
|
|||||||
package com.sap.sailing.polars;
|
package com.sap.sailing.domain.polars;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
@@ -17,10 +17,9 @@ import com.sap.sailing.domain.common.PolarSheetGenerationSettings;
|
|||||||
import com.sap.sailing.domain.common.PolarSheetsData;
|
import com.sap.sailing.domain.common.PolarSheetsData;
|
||||||
import com.sap.sailing.domain.common.Speed;
|
import com.sap.sailing.domain.common.Speed;
|
||||||
import com.sap.sailing.domain.common.Tack;
|
import com.sap.sailing.domain.common.Tack;
|
||||||
|
import com.sap.sailing.domain.common.confidence.BearingWithConfidence;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
import com.sap.sailing.polars.mining.MovingAverageProcessor;
|
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
|
||||||
import com.sap.sse.common.Util.Pair;
|
import com.sap.sse.common.Util.Pair;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -206,7 +205,28 @@ public interface PolarDataService {
|
|||||||
*/
|
*/
|
||||||
PolynomialFunction getSpeedRegressionFunction(BoatClass boatClass, double trueWindAngle) throws NotEnoughDataHasBeenAddedException;
|
PolynomialFunction getSpeedRegressionFunction(BoatClass boatClass, double trueWindAngle) throws NotEnoughDataHasBeenAddedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For Upwind and Downwind returns the typical angle needed for a maneuver.
|
||||||
|
*
|
||||||
|
* @param boatClass
|
||||||
|
* @param maneuverType
|
||||||
|
* needs to be Tack or Jibe
|
||||||
|
* @param windSpeed
|
||||||
|
* Since the maneuver angle is windSpeed depended, supply it here
|
||||||
|
* @return angle with confidence as supplied by polars. Angle is always >= 0
|
||||||
|
* @throws NotEnoughDataHasBeenAddedException
|
||||||
|
*/
|
||||||
|
BearingWithConfidence<Void> getManeuverAngle(BoatClass boatClass, ManeuverType maneuverType, Speed windSpeed)
|
||||||
|
throws NotEnoughDataHasBeenAddedException;
|
||||||
|
|
||||||
void raceFinishedLoading(TrackedRace race);
|
void raceFinishedLoading(TrackedRace race);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See {@link #getAverageSpeedWithBearing(BoatClass, Speed, LegType, Tack, boolean)}
|
||||||
|
* Always use regression
|
||||||
|
*/
|
||||||
|
SpeedWithBearingWithConfidence<Void> getAverageSpeedWithBearing(BoatClass boatClass, Speed windSpeed,
|
||||||
|
LegType legType, Tack tack) throws NotEnoughDataHasBeenAddedException;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -35,6 +35,7 @@ import com.sap.sailing.domain.common.WindSourceType;
|
|||||||
import com.sap.sailing.domain.common.dto.TrackedRaceDTO;
|
import com.sap.sailing.domain.common.dto.TrackedRaceDTO;
|
||||||
import com.sap.sailing.domain.common.racelog.Flags;
|
import com.sap.sailing.domain.common.racelog.Flags;
|
||||||
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
||||||
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||||
@@ -770,4 +771,6 @@ public interface TrackedRace extends Serializable {
|
|||||||
|
|
||||||
boolean isUsingMarkPassingCalculator();
|
boolean isUsingMarkPassingCalculator();
|
||||||
|
|
||||||
|
void setPolarDataService(PolarDataService polarDataService);
|
||||||
|
|
||||||
}
|
}
|
||||||
+99
-36
@@ -101,6 +101,8 @@ import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
|||||||
import com.sap.sailing.domain.confidence.ConfidenceBasedWindAverager;
|
import com.sap.sailing.domain.confidence.ConfidenceBasedWindAverager;
|
||||||
import com.sap.sailing.domain.confidence.ConfidenceFactory;
|
import com.sap.sailing.domain.confidence.ConfidenceFactory;
|
||||||
import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator;
|
import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator;
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
||||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||||
@@ -317,6 +319,8 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
|||||||
*/
|
*/
|
||||||
private transient ShortTimeWindCache shortTimeWindCache;
|
private transient ShortTimeWindCache shortTimeWindCache;
|
||||||
|
|
||||||
|
private transient PolarDataService polarDataService;
|
||||||
|
|
||||||
public TrackedRaceImpl(final TrackedRegatta trackedRegatta, RaceDefinition race,
|
public TrackedRaceImpl(final TrackedRegatta trackedRegatta, RaceDefinition race,
|
||||||
final Iterable<Sideline> sidelines, final WindStore windStore, final GPSFixStore gpsFixStore,
|
final Iterable<Sideline> sidelines, final WindStore windStore, final GPSFixStore gpsFixStore,
|
||||||
long delayToLiveInMillis, final long millisecondsOverWhichToAverageWind,
|
long delayToLiveInMillis, final long millisecondsOverWhichToAverageWind,
|
||||||
@@ -407,7 +411,6 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
|||||||
windTracks.putAll(loadedWindTracks);
|
windTracks.putAll(loadedWindTracks);
|
||||||
updateEventTimePoints(loadedWindTracks.values());
|
updateEventTimePoints(loadedWindTracks.values());
|
||||||
logger.info("Finished loading wind tracks for " + getRace().getName() + ". Found " + windTracks.size() + " wind tracks for this race.");
|
logger.info("Finished loading wind tracks for " + getRace().getName() + ". Found " + windTracks.size() + " wind tracks for this race.");
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
synchronized (TrackedRaceImpl.this) {
|
synchronized (TrackedRaceImpl.this) {
|
||||||
loadingFromWindStoreState = LoadingFromStoresState.FINISHED;
|
loadingFromWindStoreState = LoadingFromStoresState.FINISHED;
|
||||||
@@ -1861,40 +1864,66 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
|||||||
BearingWithConfidence<TimePoint> resultBearing = null;
|
BearingWithConfidence<TimePoint> resultBearing = null;
|
||||||
ScalablePosition scaledPosition = null;
|
ScalablePosition scaledPosition = null;
|
||||||
int numberOfFixesConsideredForScaledPosition = 0;
|
int numberOfFixesConsideredForScaledPosition = 0;
|
||||||
|
Set<WindSource> estimationExcluded = new HashSet<>();
|
||||||
|
estimationExcluded.addAll(getWindSources(WindSourceType.TRACK_BASED_ESTIMATION));
|
||||||
|
estimationExcluded.addAll(getWindSources(WindSourceType.COURSE_BASED));
|
||||||
if (bearings != null) {
|
if (bearings != null) {
|
||||||
BearingWithConfidenceCluster<TimePoint>[] bearingClustersUpwind = bearings.get(LegType.UPWIND).getA().splitInTwo(
|
int numberOfFixesUpwind = bearings.get(LegType.UPWIND).getA().size();
|
||||||
getMinimumAngleBetweenDifferentTacksUpwind(), timePoint);
|
if (numberOfFixesUpwind > 0) {
|
||||||
if (!bearingClustersUpwind[0].isEmpty() && !bearingClustersUpwind[1].isEmpty()) {
|
ScalablePosition upwindPosition = bearings.get(LegType.UPWIND).getB();
|
||||||
BearingWithConfidence<TimePoint> average0 = bearingClustersUpwind[0].getAverage(timePoint);
|
Pair<Double, Double> minimumAngleBetweenDifferentTacksUpwindWithConfidence = getMinimumAngleBetweenDifferentTacksUpwind(getWind(
|
||||||
BearingWithConfidence<TimePoint> average1 = bearingClustersUpwind[1].getAverage(timePoint);
|
upwindPosition.divide(numberOfFixesUpwind), timePoint, estimationExcluded));
|
||||||
upwindNumberOfRelevantBoats = Math
|
BearingWithConfidenceCluster<TimePoint>[] bearingClustersUpwind = bearings
|
||||||
.min(bearingClustersUpwind[0].size(), bearingClustersUpwind[1].size());
|
.get(LegType.UPWIND)
|
||||||
confidence = Math.min(average0.getConfidence(), average1.getConfidence())
|
.getA()
|
||||||
* getRace().getBoatClass().getUpwindWindEstimationConfidence(upwindNumberOfRelevantBoats);
|
.splitInTwo(
|
||||||
reversedUpwindAverage = new BearingWithConfidenceImpl<TimePoint>(average0.getObject()
|
minimumAngleBetweenDifferentTacksUpwindWithConfidence.getA(),
|
||||||
.middle(average1.getObject()).reverse(), confidence, timePoint);
|
timePoint);
|
||||||
scaledPosition = bearings.get(LegType.UPWIND).getB();
|
if (!bearingClustersUpwind[0].isEmpty() && !bearingClustersUpwind[1].isEmpty()) {
|
||||||
numberOfFixesConsideredForScaledPosition += bearings.get(LegType.UPWIND).getA().size();
|
BearingWithConfidence<TimePoint> average0 = bearingClustersUpwind[0].getAverage(timePoint);
|
||||||
|
BearingWithConfidence<TimePoint> average1 = bearingClustersUpwind[1].getAverage(timePoint);
|
||||||
|
upwindNumberOfRelevantBoats = Math.min(bearingClustersUpwind[0].size(),
|
||||||
|
bearingClustersUpwind[1].size());
|
||||||
|
confidence = Math.min(average0.getConfidence(), average1.getConfidence())
|
||||||
|
* getRace().getBoatClass().getUpwindWindEstimationConfidence(upwindNumberOfRelevantBoats)
|
||||||
|
* minimumAngleBetweenDifferentTacksUpwindWithConfidence.getB();
|
||||||
|
reversedUpwindAverage = new BearingWithConfidenceImpl<TimePoint>(average0.getObject()
|
||||||
|
.middle(average1.getObject()).reverse(), confidence, timePoint);
|
||||||
|
scaledPosition = upwindPosition;
|
||||||
|
numberOfFixesConsideredForScaledPosition += bearings.get(LegType.UPWIND).getA().size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
BearingWithConfidenceImpl<TimePoint> downwindAverage = null;
|
BearingWithConfidenceImpl<TimePoint> downwindAverage = null;
|
||||||
int downwindNumberOfRelevantBoats = 0;
|
int downwindNumberOfRelevantBoats = 0;
|
||||||
BearingWithConfidenceCluster<TimePoint>[] bearingClustersDownwind = bearings.get(LegType.DOWNWIND).getA()
|
int numberOfFixesDownwind = bearings.get(LegType.DOWNWIND).getA().size();
|
||||||
.splitInTwo(getMinimumAngleBetweenDifferentTacksDownwind(), timePoint);
|
if (numberOfFixesDownwind > 0) {
|
||||||
if (!bearingClustersDownwind[0].isEmpty() && !bearingClustersDownwind[1].isEmpty()) {
|
ScalablePosition downwindPosition = bearings.get(LegType.DOWNWIND).getB();
|
||||||
BearingWithConfidence<TimePoint> average0 = bearingClustersDownwind[0].getAverage(timePoint);
|
Pair<Double, Double> minimumAngleBetweenDifferentTacksDownwindWithConfidence = getMinimumAngleBetweenDifferentTacksDownwind(getWind(
|
||||||
BearingWithConfidence<TimePoint> average1 = bearingClustersDownwind[1].getAverage(timePoint);
|
downwindPosition.divide(numberOfFixesDownwind), timePoint, estimationExcluded));
|
||||||
downwindNumberOfRelevantBoats = Math.min(bearingClustersDownwind[0].size(),
|
BearingWithConfidenceCluster<TimePoint>[] bearingClustersDownwind = bearings
|
||||||
bearingClustersDownwind[1].size());
|
.get(LegType.DOWNWIND)
|
||||||
confidence = Math.min(average0.getConfidence(), average1.getConfidence())
|
.getA()
|
||||||
* getRace().getBoatClass().getDownwindWindEstimationConfidence(downwindNumberOfRelevantBoats);
|
.splitInTwo(
|
||||||
downwindAverage = new BearingWithConfidenceImpl<TimePoint>(average0.getObject().middle(
|
minimumAngleBetweenDifferentTacksDownwindWithConfidence.getA(),
|
||||||
average1.getObject()), confidence, timePoint);
|
timePoint);
|
||||||
if (scaledPosition == null) {
|
if (!bearingClustersDownwind[0].isEmpty() && !bearingClustersDownwind[1].isEmpty()) {
|
||||||
scaledPosition = bearings.get(LegType.DOWNWIND).getB();
|
BearingWithConfidence<TimePoint> average0 = bearingClustersDownwind[0].getAverage(timePoint);
|
||||||
} else {
|
BearingWithConfidence<TimePoint> average1 = bearingClustersDownwind[1].getAverage(timePoint);
|
||||||
scaledPosition.add(bearings.get(LegType.DOWNWIND).getB());
|
downwindNumberOfRelevantBoats = Math.min(bearingClustersDownwind[0].size(),
|
||||||
|
bearingClustersDownwind[1].size());
|
||||||
|
confidence = Math.min(average0.getConfidence(), average1.getConfidence())
|
||||||
|
* getRace().getBoatClass().getDownwindWindEstimationConfidence(
|
||||||
|
downwindNumberOfRelevantBoats)
|
||||||
|
* minimumAngleBetweenDifferentTacksDownwindWithConfidence.getB();
|
||||||
|
downwindAverage = new BearingWithConfidenceImpl<TimePoint>(average0.getObject().middle(
|
||||||
|
average1.getObject()), confidence, timePoint);
|
||||||
|
if (scaledPosition == null) {
|
||||||
|
scaledPosition = downwindPosition;
|
||||||
|
} else {
|
||||||
|
scaledPosition.add(downwindPosition);
|
||||||
|
}
|
||||||
|
numberOfFixesConsideredForScaledPosition += bearings.get(LegType.DOWNWIND).getA().size();
|
||||||
}
|
}
|
||||||
numberOfFixesConsideredForScaledPosition += bearings.get(LegType.DOWNWIND).getA().size();
|
|
||||||
}
|
}
|
||||||
BearingWithConfidenceCluster<TimePoint> resultCluster = new BearingWithConfidenceCluster<TimePoint>(weigher);
|
BearingWithConfidenceCluster<TimePoint> resultCluster = new BearingWithConfidenceCluster<TimePoint>(weigher);
|
||||||
assert upwindNumberOfRelevantBoats == 0 || reversedUpwindAverage != null;
|
assert upwindNumberOfRelevantBoats == 0 || reversedUpwindAverage != null;
|
||||||
@@ -2716,12 +2745,41 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
|||||||
return getRace().getBoatClass().getManeuverDegreeAngleThreshold();
|
return getRace().getBoatClass().getManeuverDegreeAngleThreshold();
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getMinimumAngleBetweenDifferentTacksDownwind() {
|
private Pair<Double, Double> getMinimumAngleBetweenDifferentTacksDownwind(Wind wind) {
|
||||||
return getRace().getBoatClass().getMinimumAngleBetweenDifferentTacksDownwind();
|
Pair<Double, Double> result;
|
||||||
|
double defaultAngle = getRace().getBoatClass().getMinimumAngleBetweenDifferentTacksDownwind();
|
||||||
|
double threshold = 20;
|
||||||
|
result = usePolarsIfPossible(wind, defaultAngle, LegType.DOWNWIND, threshold);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pair<Double, Double> getMinimumAngleBetweenDifferentTacksUpwind(Wind wind) {
|
||||||
|
Pair<Double, Double> result;
|
||||||
|
double defaultAngle = getRace().getBoatClass().getMinimumAngleBetweenDifferentTacksUpwind();
|
||||||
|
double threshold = 10;
|
||||||
|
result = usePolarsIfPossible(wind, defaultAngle, LegType.UPWIND, threshold);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getMinimumAngleBetweenDifferentTacksUpwind() {
|
private Pair<Double, Double> usePolarsIfPossible(Wind wind, double defaultAngle, LegType legType, double threshold) {
|
||||||
return getRace().getBoatClass().getMinimumAngleBetweenDifferentTacksUpwind();
|
Pair<Double, Double> result;
|
||||||
|
if (polarDataService != null) {
|
||||||
|
try {
|
||||||
|
BearingWithConfidence<Void> average = polarDataService.getManeuverAngle(getRace().getBoatClass(),
|
||||||
|
legType == LegType.DOWNWIND ? ManeuverType.JIBE : ManeuverType.TACK, wind);
|
||||||
|
double averageAngleInDegMinusThreshold = average.getObject().getDegrees() - threshold;
|
||||||
|
if (averageAngleInDegMinusThreshold < defaultAngle) {
|
||||||
|
result = new Pair<Double, Double>(defaultAngle, 0.1);
|
||||||
|
} else {
|
||||||
|
result = new Pair<Double, Double>(averageAngleInDegMinusThreshold, average.getConfidence());
|
||||||
|
}
|
||||||
|
} catch (NotEnoughDataHasBeenAddedException e) {
|
||||||
|
result = new Pair<Double, Double>(defaultAngle, 0.1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = new Pair<Double, Double>(defaultAngle, 0.1);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getApproximateManeuverDurationInMilliseconds() {
|
private long getApproximateManeuverDurationInMilliseconds() {
|
||||||
@@ -2880,7 +2938,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
|||||||
(DynamicGPSFixTrack<Competitor, GPSFixMoving>) tracks.get(competitor), log,
|
(DynamicGPSFixTrack<Competitor, GPSFixMoving>) tracks.get(competitor), log,
|
||||||
competitor);
|
competitor);
|
||||||
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
||||||
logger.log(Level.WARNING, "Could not load track for " + competitor);
|
logger.log(Level.WARNING, "Could not load track for " + competitor, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.info("Finished loading competitor tracks for " + getRace().getName());
|
logger.info("Finished loading competitor tracks for " + getRace().getName());
|
||||||
@@ -2890,7 +2948,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
|||||||
gpsFixStore.loadMarkTrack((DynamicGPSFixTrack<Mark, GPSFix>) markTracks.get(mark), log,
|
gpsFixStore.loadMarkTrack((DynamicGPSFixTrack<Mark, GPSFix>) markTracks.get(mark), log,
|
||||||
mark);
|
mark);
|
||||||
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
||||||
logger.log(Level.WARNING, "Could not load track for " + mark);
|
logger.log(Level.WARNING, "Could not load track for " + mark, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.info("Finished loading mark tracks for " + getRace().getName());
|
logger.info("Finished loading mark tracks for " + getRace().getName());
|
||||||
@@ -3456,5 +3514,10 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPolarDataService(PolarDataService polarDataService) {
|
||||||
|
this.polarDataService = polarDataService;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -444,4 +444,11 @@ Computes leaderboard information for sailing races and offers RESTful APIs to al
|
|||||||
version="0.0.0"
|
version="0.0.0"
|
||||||
unpack="false"/>
|
unpack="false"/>
|
||||||
|
|
||||||
|
<plugin
|
||||||
|
id="com.sap.sailing.polars"
|
||||||
|
download-size="0"
|
||||||
|
install-size="0"
|
||||||
|
version="0.0.0"
|
||||||
|
unpack="false"/>
|
||||||
|
|
||||||
</feature>
|
</feature>
|
||||||
+5
@@ -38,6 +38,7 @@ import com.sap.sailing.domain.common.racelog.Flags;
|
|||||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||||
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||||
import com.sap.sailing.domain.regattalike.RegattaLikeIdentifier;
|
import com.sap.sailing.domain.regattalike.RegattaLikeIdentifier;
|
||||||
import com.sap.sailing.domain.regattalike.RegattaLikeListener;
|
import com.sap.sailing.domain.regattalike.RegattaLikeListener;
|
||||||
@@ -902,4 +903,8 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
|||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPolarDataService(PolarDataService polarDataService) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -50,10 +50,7 @@ Require-Bundle: com.sap.sailing.domain,
|
|||||||
com.sap.sse.gwt.theme
|
com.sap.sse.gwt.theme
|
||||||
Bundle-Activator: com.sap.sailing.gwt.ui.server.Activator
|
Bundle-Activator: com.sap.sailing.gwt.ui.server.Activator
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
Import-Package: com.sap.sailing.polars,
|
Import-Package: javax.jms;version="1.1.0",
|
||||||
com.sap.sailing.polars.factory,
|
|
||||||
com.sap.sailing.polars.regression,
|
|
||||||
javax.jms;version="1.1.0",
|
|
||||||
javax.servlet;version="3.1.0",
|
javax.servlet;version="3.1.0",
|
||||||
javax.servlet.descriptor;version="3.1.0",
|
javax.servlet.descriptor;version="3.1.0",
|
||||||
javax.servlet.http;version="3.1.0",
|
javax.servlet.http;version="3.1.0",
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 281 KiB After Width: | Height: | Size: 286 KiB |
+1
@@ -44,6 +44,7 @@ public interface TextMessages extends Messages {
|
|||||||
String overview();
|
String overview();
|
||||||
String sapSailing();
|
String sapSailing();
|
||||||
String search();
|
String search();
|
||||||
|
String startSimulator();
|
||||||
|
|
||||||
String countdownDays();
|
String countdownDays();
|
||||||
String countdownHours();
|
String countdownHours();
|
||||||
|
|||||||
+1
@@ -33,6 +33,7 @@ whatsNew=What''s new
|
|||||||
overview=Overview
|
overview=Overview
|
||||||
sapSailing=SAP Sailing
|
sapSailing=SAP Sailing
|
||||||
search=Search
|
search=Search
|
||||||
|
startSimulator=Start Simulator
|
||||||
|
|
||||||
countdownDays=Days
|
countdownDays=Days
|
||||||
countdownHours=Hrs
|
countdownHours=Hrs
|
||||||
|
|||||||
+1
@@ -33,6 +33,7 @@ whatsNew=Neuigkeiten
|
|||||||
overview=Übersicht
|
overview=Übersicht
|
||||||
sapSailing=SAP Sailing
|
sapSailing=SAP Sailing
|
||||||
search=Suche
|
search=Suche
|
||||||
|
startSimulator=Simulator starten
|
||||||
|
|
||||||
countdownDays=Tage
|
countdownDays=Tage
|
||||||
countdownHours=Std.
|
countdownHours=Std.
|
||||||
|
|||||||
+9
@@ -1,5 +1,8 @@
|
|||||||
package com.sap.sailing.gwt.home.client.app;
|
package com.sap.sailing.gwt.home.client.app;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import com.google.gwt.place.shared.PlaceController;
|
import com.google.gwt.place.shared.PlaceController;
|
||||||
import com.sap.sailing.gwt.home.client.place.aboutus.AboutUsPlace;
|
import com.sap.sailing.gwt.home.client.place.aboutus.AboutUsPlace;
|
||||||
import com.sap.sailing.gwt.home.client.place.contact.ContactPlace;
|
import com.sap.sailing.gwt.home.client.place.contact.ContactPlace;
|
||||||
@@ -19,6 +22,7 @@ import com.sap.sailing.gwt.home.client.place.sponsoring.SponsoringPlace;
|
|||||||
import com.sap.sailing.gwt.home.client.place.start.StartPlace;
|
import com.sap.sailing.gwt.home.client.place.start.StartPlace;
|
||||||
import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewPlace;
|
import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewPlace;
|
||||||
import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewPlace.WhatsNewNavigationTabs;
|
import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewPlace.WhatsNewNavigationTabs;
|
||||||
|
import com.sap.sailing.gwt.ui.client.EntryPointLinkFactory;
|
||||||
|
|
||||||
public class HomePlacesNavigator extends AbstractPlaceNavigator {
|
public class HomePlacesNavigator extends AbstractPlaceNavigator {
|
||||||
|
|
||||||
@@ -42,6 +46,11 @@ public class HomePlacesNavigator extends AbstractPlaceNavigator {
|
|||||||
return createLocalPlaceNavigation(new WhatsNewPlace(navigationTab));
|
return createLocalPlaceNavigation(new WhatsNewPlace(navigationTab));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSimulatorURL() {
|
||||||
|
Map<String, String> parameters = new HashMap<String, String>();
|
||||||
|
return EntryPointLinkFactory.createSimulatorLink(parameters);
|
||||||
|
}
|
||||||
|
|
||||||
public PlaceNavigation<SponsoringPlace> getSponsoringNavigation() {
|
public PlaceNavigation<SponsoringPlace> getSponsoringNavigation() {
|
||||||
return createGlobalPlaceNavigation(new SponsoringPlace());
|
return createGlobalPlaceNavigation(new SponsoringPlace());
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-11
@@ -28,15 +28,15 @@ public class TabletAndDesktopWhatsNewView extends Composite implements WhatsNewV
|
|||||||
private static final HyperlinkImpl HYPERLINK_IMPL = GWT.create(HyperlinkImpl.class);
|
private static final HyperlinkImpl HYPERLINK_IMPL = GWT.create(HyperlinkImpl.class);
|
||||||
|
|
||||||
@UiField HTML sailingAnalyticsNotes;
|
@UiField HTML sailingAnalyticsNotes;
|
||||||
// @UiField HTML sailingSimulatorNotes;
|
@UiField HTML sailingSimulatorNotes;
|
||||||
@UiField HTML raceCommitteeAppNotes;
|
@UiField HTML raceCommitteeAppNotes;
|
||||||
|
|
||||||
@UiField Anchor sailingAnalyticsNotesAnchor;
|
@UiField Anchor sailingAnalyticsNotesAnchor;
|
||||||
// @UiField Anchor sailingSimulatorNotesAnchor;
|
@UiField Anchor sailingSimulatorNotesAnchor;
|
||||||
@UiField Anchor raceCommitteeAppNotesAnchor;
|
@UiField Anchor raceCommitteeAppNotesAnchor;
|
||||||
|
|
||||||
private final PlaceNavigation<WhatsNewPlace> sailingAnalyticNotesNavigation;
|
private final PlaceNavigation<WhatsNewPlace> sailingAnalyticNotesNavigation;
|
||||||
// private final PlaceNavigation<WhatsNewPlace> sailingSimulatorNoteNavigation;
|
private final PlaceNavigation<WhatsNewPlace> sailingSimulatorNoteNavigation;
|
||||||
private final PlaceNavigation<WhatsNewPlace> raceCommitteeAppNotesNavigation;
|
private final PlaceNavigation<WhatsNewPlace> raceCommitteeAppNotesNavigation;
|
||||||
|
|
||||||
private final List<Anchor> links;
|
private final List<Anchor> links;
|
||||||
@@ -49,19 +49,19 @@ public class TabletAndDesktopWhatsNewView extends Composite implements WhatsNewV
|
|||||||
initWidget(uiBinder.createAndBindUi(this));
|
initWidget(uiBinder.createAndBindUi(this));
|
||||||
|
|
||||||
sailingAnalyticsNotes.setHTML(WhatsNewResources.INSTANCE.getSailingAnalyticsNotesHtml().getText());
|
sailingAnalyticsNotes.setHTML(WhatsNewResources.INSTANCE.getSailingAnalyticsNotesHtml().getText());
|
||||||
// sailingSimulatorNotes.setHTML(WhatsNewResources.INSTANCE.getSailingSimulatorNotesHtml().getText());
|
sailingSimulatorNotes.setHTML(WhatsNewResources.INSTANCE.getSailingSimulatorNotesHtml().getText());
|
||||||
raceCommitteeAppNotes.setHTML(WhatsNewResources.INSTANCE.getRaceCommitteeAppNotesHtml().getText());
|
raceCommitteeAppNotes.setHTML(WhatsNewResources.INSTANCE.getRaceCommitteeAppNotesHtml().getText());
|
||||||
|
|
||||||
sailingAnalyticNotesNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingAnalytics);
|
sailingAnalyticNotesNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingAnalytics);
|
||||||
// sailingSimulatorNoteNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingSimulator);
|
sailingSimulatorNoteNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingSimulator);
|
||||||
raceCommitteeAppNotesNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.RaceCommiteeApp);
|
raceCommitteeAppNotesNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.RaceCommiteeApp);
|
||||||
|
|
||||||
sailingAnalyticsNotesAnchor.setHref(sailingAnalyticNotesNavigation.getTargetUrl());
|
sailingAnalyticsNotesAnchor.setHref(sailingAnalyticNotesNavigation.getTargetUrl());
|
||||||
// sailingSimulatorNotesAnchor.setHref(sailingSimulatorNoteNavigation.getTargetUrl());
|
sailingSimulatorNotesAnchor.setHref(sailingSimulatorNoteNavigation.getTargetUrl());
|
||||||
raceCommitteeAppNotesAnchor.setHref(raceCommitteeAppNotesNavigation.getTargetUrl());
|
raceCommitteeAppNotesAnchor.setHref(raceCommitteeAppNotesNavigation.getTargetUrl());
|
||||||
|
|
||||||
links = Arrays.asList(new Anchor[] { sailingAnalyticsNotesAnchor, /*sailingSimulatorNotesAnchor,*/ raceCommitteeAppNotesAnchor });
|
links = Arrays.asList(new Anchor[] { sailingAnalyticsNotesAnchor, sailingSimulatorNotesAnchor, raceCommitteeAppNotesAnchor });
|
||||||
contentWidgets = Arrays.asList(new HTML[] { sailingAnalyticsNotes, /*sailingSimulatorNotes,*/ raceCommitteeAppNotes });
|
contentWidgets = Arrays.asList(new HTML[] { sailingAnalyticsNotes, sailingSimulatorNotes, raceCommitteeAppNotes });
|
||||||
|
|
||||||
switch(navigationTab) {
|
switch(navigationTab) {
|
||||||
case PostRaceAnalytics:
|
case PostRaceAnalytics:
|
||||||
@@ -73,7 +73,7 @@ public class TabletAndDesktopWhatsNewView extends Composite implements WhatsNewV
|
|||||||
setActiveContent(sailingAnalyticsNotes, sailingAnalyticsNotesAnchor);
|
setActiveContent(sailingAnalyticsNotes, sailingAnalyticsNotesAnchor);
|
||||||
break;
|
break;
|
||||||
case SailingSimulator:
|
case SailingSimulator:
|
||||||
// setActiveContent(sailingSimulatorNotes, sailingSimulatorNotesAnchor);
|
setActiveContent(sailingSimulatorNotes, sailingSimulatorNotesAnchor);
|
||||||
break;
|
break;
|
||||||
case TrainingDiary:
|
case TrainingDiary:
|
||||||
break;
|
break;
|
||||||
@@ -85,13 +85,13 @@ public class TabletAndDesktopWhatsNewView extends Composite implements WhatsNewV
|
|||||||
setActiveContent(sailingAnalyticsNotes, sailingAnalyticsNotesAnchor);
|
setActiveContent(sailingAnalyticsNotes, sailingAnalyticsNotesAnchor);
|
||||||
handleClickEventWithLocalNavigation(event, sailingAnalyticNotesNavigation);
|
handleClickEventWithLocalNavigation(event, sailingAnalyticNotesNavigation);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
@UiHandler("sailingSimulatorNotesAnchor")
|
@UiHandler("sailingSimulatorNotesAnchor")
|
||||||
void featuresClicked(ClickEvent event) {
|
void featuresClicked(ClickEvent event) {
|
||||||
setActiveContent(sailingSimulatorNotes, sailingSimulatorNotesAnchor);
|
setActiveContent(sailingSimulatorNotes, sailingSimulatorNotesAnchor);
|
||||||
handleClickEventWithLocalNavigation(event, sailingSimulatorNoteNavigation);
|
handleClickEventWithLocalNavigation(event, sailingSimulatorNoteNavigation);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
@UiHandler("raceCommitteeAppNotesAnchor")
|
@UiHandler("raceCommitteeAppNotesAnchor")
|
||||||
void releaseNotesClicked(ClickEvent event) {
|
void releaseNotesClicked(ClickEvent event) {
|
||||||
setActiveContent(raceCommitteeAppNotes, raceCommitteeAppNotesAnchor);
|
setActiveContent(raceCommitteeAppNotes, raceCommitteeAppNotesAnchor);
|
||||||
|
|||||||
+1
-5
@@ -10,9 +10,7 @@
|
|||||||
<div class="{res.mediaCss.grid}">
|
<div class="{res.mediaCss.grid}">
|
||||||
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
|
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
|
||||||
<g:Anchor ui:field="sailingAnalyticsNotesAnchor" href="javascript:;" styleName="{local_res.css.whatsnew_nav_link}"><ui:text from='{i18n.solutionsSAPHeadline}'/></g:Anchor>
|
<g:Anchor ui:field="sailingAnalyticsNotesAnchor" href="javascript:;" styleName="{local_res.css.whatsnew_nav_link}"><ui:text from='{i18n.solutionsSAPHeadline}'/></g:Anchor>
|
||||||
<!--
|
<g:Anchor ui:field="sailingSimulatorNotesAnchor" href="javascript:;" styleName="{local_res.css.whatsnew_nav_link}"><ui:text from='{i18n.solutionsSimulatorHeadline}'/></g:Anchor>
|
||||||
<g:Anchor ui:field="sailingSimulatorNotesAnchor" href="javascript:;" styleName="{local_res.css.whatsnew_nav_link}"><ui:text from='{i18n.solutionsSimulatorHeadline}'/></g:Anchor>
|
|
||||||
-->
|
|
||||||
<g:Anchor ui:field="raceCommitteeAppNotesAnchor" href="javascript:;" styleName="{local_res.css.whatsnew_nav_link}"><ui:text from='{i18n.solutionsRaceHeadline}'/></g:Anchor>
|
<g:Anchor ui:field="raceCommitteeAppNotesAnchor" href="javascript:;" styleName="{local_res.css.whatsnew_nav_link}"><ui:text from='{i18n.solutionsRaceHeadline}'/></g:Anchor>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -20,9 +18,7 @@
|
|||||||
<div class="{res.mediaCss.grid}">
|
<div class="{res.mediaCss.grid}">
|
||||||
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
|
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
|
||||||
<g:HTML ui:field="sailingAnalyticsNotes" />
|
<g:HTML ui:field="sailingAnalyticsNotes" />
|
||||||
<!--
|
|
||||||
<g:HTML ui:field="sailingSimulatorNotes" />
|
<g:HTML ui:field="sailingSimulatorNotes" />
|
||||||
-->
|
|
||||||
<g:HTML ui:field="raceCommitteeAppNotes" />
|
<g:HTML ui:field="raceCommitteeAppNotes" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+12
-1
@@ -44,6 +44,8 @@ public class Solutions extends Composite {
|
|||||||
|
|
||||||
@UiField Anchor sailingAnalyticsDetailsAnchor;
|
@UiField Anchor sailingAnalyticsDetailsAnchor;
|
||||||
@UiField Anchor raceCommitteeAppDetailsAnchor;
|
@UiField Anchor raceCommitteeAppDetailsAnchor;
|
||||||
|
@UiField Anchor simulatorStartAnchor;
|
||||||
|
@UiField Anchor simulatorAppDetailsAnchor;
|
||||||
|
|
||||||
private final PlaceNavigation<SolutionsPlace> sailingAnalyticsNavigation;
|
private final PlaceNavigation<SolutionsPlace> sailingAnalyticsNavigation;
|
||||||
private final PlaceNavigation<SolutionsPlace> raceCommitteeAppNavigation;
|
private final PlaceNavigation<SolutionsPlace> raceCommitteeAppNavigation;
|
||||||
@@ -55,6 +57,7 @@ public class Solutions extends Composite {
|
|||||||
|
|
||||||
private final PlaceNavigation<WhatsNewPlace> sailingAnalyticsDetailsNavigation;
|
private final PlaceNavigation<WhatsNewPlace> sailingAnalyticsDetailsNavigation;
|
||||||
private final PlaceNavigation<WhatsNewPlace> raceCommitteeAppDetailsNavigation;
|
private final PlaceNavigation<WhatsNewPlace> raceCommitteeAppDetailsNavigation;
|
||||||
|
private final PlaceNavigation<WhatsNewPlace> simulatorAppDetailsNavigation;
|
||||||
private final HomePlacesNavigator placesNavigator;
|
private final HomePlacesNavigator placesNavigator;
|
||||||
|
|
||||||
public Solutions(SolutionsNavigationTabs navigationTab, HomePlacesNavigator placesNavigator) {
|
public Solutions(SolutionsNavigationTabs navigationTab, HomePlacesNavigator placesNavigator) {
|
||||||
@@ -67,9 +70,12 @@ public class Solutions extends Composite {
|
|||||||
|
|
||||||
sailingAnalyticsDetailsNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingAnalytics);
|
sailingAnalyticsDetailsNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingAnalytics);
|
||||||
raceCommitteeAppDetailsNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.RaceCommiteeApp);
|
raceCommitteeAppDetailsNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.RaceCommiteeApp);
|
||||||
|
simulatorAppDetailsNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingSimulator);
|
||||||
|
|
||||||
sailingAnalyticsDetailsAnchor.setHref(sailingAnalyticsDetailsNavigation.getTargetUrl());
|
sailingAnalyticsDetailsAnchor.setHref(sailingAnalyticsDetailsNavigation.getTargetUrl());
|
||||||
raceCommitteeAppDetailsAnchor.setHref(raceCommitteeAppDetailsNavigation.getTargetUrl());
|
raceCommitteeAppDetailsAnchor.setHref(raceCommitteeAppDetailsNavigation.getTargetUrl());
|
||||||
|
simulatorAppDetailsAnchor.setHref(simulatorAppDetailsNavigation.getTargetUrl());
|
||||||
|
simulatorStartAnchor.setHref(placesNavigator.getSimulatorURL());
|
||||||
|
|
||||||
sailingAnalyticsNavigation = placesNavigator.getSolutionsNavigation(SolutionsNavigationTabs.SailingAnalytics);
|
sailingAnalyticsNavigation = placesNavigator.getSolutionsNavigation(SolutionsNavigationTabs.SailingAnalytics);
|
||||||
raceCommitteeAppNavigation = placesNavigator.getSolutionsNavigation(SolutionsNavigationTabs.RaceCommiteeApp);
|
raceCommitteeAppNavigation = placesNavigator.getSolutionsNavigation(SolutionsNavigationTabs.RaceCommiteeApp);
|
||||||
@@ -127,7 +133,12 @@ public class Solutions extends Composite {
|
|||||||
public void sailingAnalyticsDetailsClicked(ClickEvent e) {
|
public void sailingAnalyticsDetailsClicked(ClickEvent e) {
|
||||||
handleClickEventWithPlaceController(e, sailingAnalyticsDetailsNavigation);
|
handleClickEventWithPlaceController(e, sailingAnalyticsDetailsNavigation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UiHandler("simulatorAppDetailsAnchor")
|
||||||
|
public void simulatorAppDetailsAnchorClicked(ClickEvent e) {
|
||||||
|
handleClickEventWithPlaceController(e, simulatorAppDetailsNavigation);
|
||||||
|
}
|
||||||
|
|
||||||
private void scrollToView(SolutionsNavigationTabs navigationTab) {
|
private void scrollToView(SolutionsNavigationTabs navigationTab) {
|
||||||
switch (navigationTab) {
|
switch (navigationTab) {
|
||||||
case SailingAnalytics:
|
case SailingAnalytics:
|
||||||
|
|||||||
+3
-1
@@ -67,7 +67,9 @@
|
|||||||
<div class="{res.mediaCss.small5} {res.mediaCss.smalloffset7} {res.mediaCss.columns}">
|
<div class="{res.mediaCss.small5} {res.mediaCss.smalloffset7} {res.mediaCss.columns}">
|
||||||
<h2><ui:text from='{i18n.solutionsSimulatorHeadline}'/></h2>
|
<h2><ui:text from='{i18n.solutionsSimulatorHeadline}'/></h2>
|
||||||
<p><ui:text from='{i18n.solutionsSimulatorText}'/></p>
|
<p><ui:text from='{i18n.solutionsSimulatorText}'/></p>
|
||||||
<!-- <a href="#" class="{res.mainCss.button}">Learn More</a> -->
|
<g:Anchor ui:field="simulatorAppDetailsAnchor" styleName="{res.mainCss.button}"><ui:text from='{i18n.whatsNew}'/></g:Anchor>
|
||||||
|
<span> </span>
|
||||||
|
<g:Anchor ui:field="simulatorStartAnchor" target="_blank" styleName="{res.mainCss.button}"><ui:text from='{i18n.startSimulator}'/></g:Anchor>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+6
-3
@@ -5,6 +5,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
|
import com.sap.sailing.domain.common.LegIdentifier;
|
||||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||||
@@ -20,10 +21,11 @@ public class GetRaceMapDataAction implements AsyncAction<RaceMapDataDTO> {
|
|||||||
private final Map<CompetitorDTO, Date> to;
|
private final Map<CompetitorDTO, Date> to;
|
||||||
private final boolean extrapolate;
|
private final boolean extrapolate;
|
||||||
private final Date date;
|
private final Date date;
|
||||||
|
private final LegIdentifier simulationLegIdentifier;
|
||||||
|
|
||||||
public GetRaceMapDataAction(SailingServiceAsync sailingService, Iterable<CompetitorDTO> allCompetitors,
|
public GetRaceMapDataAction(SailingServiceAsync sailingService, Iterable<CompetitorDTO> allCompetitors,
|
||||||
RegattaAndRaceIdentifier raceIdentifier, Date date, Map<CompetitorDTO, Date> from,
|
RegattaAndRaceIdentifier raceIdentifier, Date date, Map<CompetitorDTO, Date> from,
|
||||||
Map<CompetitorDTO, Date> to, boolean extrapolate) {
|
Map<CompetitorDTO, Date> to, boolean extrapolate, LegIdentifier simulationLegIdentifier) {
|
||||||
this.allCompetitors = allCompetitors;
|
this.allCompetitors = allCompetitors;
|
||||||
this.sailingService = sailingService;
|
this.sailingService = sailingService;
|
||||||
this.raceIdentifier = raceIdentifier;
|
this.raceIdentifier = raceIdentifier;
|
||||||
@@ -31,6 +33,7 @@ public class GetRaceMapDataAction implements AsyncAction<RaceMapDataDTO> {
|
|||||||
this.from = from;
|
this.from = from;
|
||||||
this.to = to;
|
this.to = to;
|
||||||
this.extrapolate = extrapolate;
|
this.extrapolate = extrapolate;
|
||||||
|
this.simulationLegIdentifier = simulationLegIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -46,7 +49,7 @@ public class GetRaceMapDataAction implements AsyncAction<RaceMapDataDTO> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sailingService.getRaceMapData(raceIdentifier, date, fromByCompetitorIdAsString, toByCompetitorIdAsString,
|
sailingService.getRaceMapData(raceIdentifier, date, fromByCompetitorIdAsString, toByCompetitorIdAsString,
|
||||||
extrapolate, new AsyncCallback<CompactRaceMapDataDTO>() {
|
extrapolate, simulationLegIdentifier, new AsyncCallback<CompactRaceMapDataDTO>() {
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable caught) {
|
public void onFailure(Throwable caught) {
|
||||||
callback.onFailure(caught);
|
callback.onFailure(caught);
|
||||||
|
|||||||
+6
-11
@@ -1,12 +1,11 @@
|
|||||||
package com.sap.sailing.gwt.ui.actions;
|
package com.sap.sailing.gwt.ui.actions;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
import com.sap.sailing.domain.common.LegIdentifier;
|
||||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMap;
|
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMap;
|
||||||
import com.sap.sailing.gwt.ui.shared.SimulatorResultsDTO;
|
import com.sap.sailing.gwt.ui.shared.SimulatorResultsDTO;
|
||||||
|
import com.sap.sailing.gwt.ui.shared.racemap.RaceSimulationOverlay;
|
||||||
import com.sap.sse.gwt.client.async.AsyncAction;
|
import com.sap.sse.gwt.client.async.AsyncAction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,19 +17,15 @@ import com.sap.sse.gwt.client.async.AsyncAction;
|
|||||||
*/
|
*/
|
||||||
public class GetSimulationAction implements AsyncAction<SimulatorResultsDTO> {
|
public class GetSimulationAction implements AsyncAction<SimulatorResultsDTO> {
|
||||||
private final SailingServiceAsync sailingService;
|
private final SailingServiceAsync sailingService;
|
||||||
private final RegattaAndRaceIdentifier raceIdentifier;
|
private final LegIdentifier legIdentifier;
|
||||||
private final Date from;
|
|
||||||
private final Date prevStartTime;
|
|
||||||
|
|
||||||
public GetSimulationAction(SailingServiceAsync sailingService, RegattaAndRaceIdentifier raceIdentifier, Date from, Date prevStartTime) {
|
public GetSimulationAction(SailingServiceAsync sailingService, LegIdentifier legIdentifier) {
|
||||||
this.sailingService = sailingService;
|
this.sailingService = sailingService;
|
||||||
this.raceIdentifier = raceIdentifier;
|
this.legIdentifier = legIdentifier;
|
||||||
this.from = from;
|
|
||||||
this.prevStartTime = prevStartTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(AsyncCallback<SimulatorResultsDTO> callback) {
|
public void execute(AsyncCallback<SimulatorResultsDTO> callback) {
|
||||||
sailingService.getSimulatorResults(raceIdentifier, from, prevStartTime, callback);
|
sailingService.getSimulatorResults(legIdentifier, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
-6
@@ -41,7 +41,7 @@ public class CompetitorEditDialog extends DataEntryDialog<CompetitorDTO> {
|
|||||||
private final TextBox sailId;
|
private final TextBox sailId;
|
||||||
private final TextBox email;
|
private final TextBox email;
|
||||||
private final StringMessages stringMessages;
|
private final StringMessages stringMessages;
|
||||||
private final TextBox flagImageURL;
|
private final URLFieldWithFileUpload flagImageURL;
|
||||||
private final URLFieldWithFileUpload imageUrlAndUploadComposite;
|
private final URLFieldWithFileUpload imageUrlAndUploadComposite;
|
||||||
|
|
||||||
public CompetitorEditDialog(final StringMessages stringMessages, CompetitorDTO competitorToEdit,
|
public CompetitorEditDialog(final StringMessages stringMessages, CompetitorDTO competitorToEdit,
|
||||||
@@ -123,12 +123,12 @@ public class CompetitorEditDialog extends DataEntryDialog<CompetitorDTO> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.sailId = createTextBox(competitorToEdit.getSailID());
|
this.sailId = createTextBox(competitorToEdit.getSailID());
|
||||||
this.flagImageURL = createTextBox(competitorToEdit.getFlagImageURL(), 100);
|
this.flagImageURL = new URLFieldWithFileUpload(stringMessages);
|
||||||
imageUrlAndUploadComposite = new URLFieldWithFileUpload(stringMessages);
|
this.flagImageURL.setURL(competitorToEdit.getFlagImageURL());
|
||||||
imageUrlAndUploadComposite.setURL(competitorToEdit.getImageURL());
|
this.imageUrlAndUploadComposite = new URLFieldWithFileUpload(stringMessages);
|
||||||
|
this.imageUrlAndUploadComposite.setURL(competitorToEdit.getImageURL());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void show() {
|
public void show() {
|
||||||
super.show();
|
super.show();
|
||||||
@@ -182,7 +182,7 @@ public class CompetitorEditDialog extends DataEntryDialog<CompetitorDTO> {
|
|||||||
/* twoLetterIsoCountryCode */ null,
|
/* twoLetterIsoCountryCode */ null,
|
||||||
threeLetterIocCountryCode.getValue(threeLetterIocCountryCode.getSelectedIndex()),
|
threeLetterIocCountryCode.getValue(threeLetterIocCountryCode.getSelectedIndex()),
|
||||||
/* countryName */ null, sailId.getText(), competitorToEdit.getIdAsString(),
|
/* countryName */ null, sailId.getText(), competitorToEdit.getIdAsString(),
|
||||||
imageUrlAndUploadComposite.getURL(), flagImageURL.getText(), boatClass);
|
imageUrlAndUploadComposite.getURL(), flagImageURL.getURL(), boatClass);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+44
-13
@@ -60,6 +60,11 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
|||||||
private ListBox basicClassFlagListBox;
|
private ListBox basicClassFlagListBox;
|
||||||
private CheckBox basicRecallBox;
|
private CheckBox basicRecallBox;
|
||||||
|
|
||||||
|
private DisclosurePanel leagueDisclosurePanel;
|
||||||
|
private CheckBox leagueEnabledBox;
|
||||||
|
private ListBox leagueClassFlagListBox;
|
||||||
|
private CheckBox leagueRecallBox;
|
||||||
|
|
||||||
public RegattaConfigurationDialog(DeviceConfigurationDTO.RegattaConfigurationDTO regattaConfiguration,
|
public RegattaConfigurationDialog(DeviceConfigurationDTO.RegattaConfigurationDTO regattaConfiguration,
|
||||||
StringMessages messages, DataEntryDialog.DialogCallback<RegattaConfigurationDTO> callback) {
|
StringMessages messages, DataEntryDialog.DialogCallback<RegattaConfigurationDTO> callback) {
|
||||||
super(messages.racingProcedureConfiguration(), "", messages.save(), messages.cancel(), /* validator */ null, callback);
|
super(messages.racingProcedureConfiguration(), "", messages.save(), messages.cancel(), /* validator */ null, callback);
|
||||||
@@ -75,6 +80,7 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
|||||||
setupGateStart();
|
setupGateStart();
|
||||||
setupESS();
|
setupESS();
|
||||||
setupBasic();
|
setupBasic();
|
||||||
|
setupLeague();
|
||||||
|
|
||||||
if (rrs26EnabledBox.getValue()) {
|
if (rrs26EnabledBox.getValue()) {
|
||||||
rrs26DisclosurePanel.setOpen(true);
|
rrs26DisclosurePanel.setOpen(true);
|
||||||
@@ -88,6 +94,9 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
|||||||
if (basicEnabledBox.getValue()) {
|
if (basicEnabledBox.getValue()) {
|
||||||
basicDisclosurePanel.setOpen(true);
|
basicDisclosurePanel.setOpen(true);
|
||||||
}
|
}
|
||||||
|
if (leagueEnabledBox.getValue()) {
|
||||||
|
leagueDisclosurePanel.setOpen(true);
|
||||||
|
}
|
||||||
|
|
||||||
return contentPanel;
|
return contentPanel;
|
||||||
}
|
}
|
||||||
@@ -109,7 +118,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
|||||||
racingProcedureListBox.addChangeHandler(new ChangeHandler() {
|
racingProcedureListBox.addChangeHandler(new ChangeHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void onChange(ChangeEvent event) {
|
public void onChange(ChangeEvent event) {
|
||||||
markAsDrity(true);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
grid.setWidget(gridRow, 0, new Label(stringMessages.racingProcedure()));
|
grid.setWidget(gridRow, 0, new Label(stringMessages.racingProcedure()));
|
||||||
@@ -126,7 +134,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
|||||||
designerModeEntryListBox.addChangeHandler(new ChangeHandler() {
|
designerModeEntryListBox.addChangeHandler(new ChangeHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void onChange(ChangeEvent event) {
|
public void onChange(ChangeEvent event) {
|
||||||
markAsDrity(true);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
grid.setWidget(gridRow, 0, new Label(stringMessages.courseDesignerMode()));
|
grid.setWidget(gridRow, 0, new Label(stringMessages.courseDesignerMode()));
|
||||||
@@ -143,7 +150,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
|||||||
box.addChangeHandler(new ChangeHandler() {
|
box.addChangeHandler(new ChangeHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void onChange(ChangeEvent event) {
|
public void onChange(ChangeEvent event) {
|
||||||
markAsDrity(true);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return box;
|
return box;
|
||||||
@@ -155,7 +161,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
||||||
markAsDrity(true);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return box;
|
return box;
|
||||||
@@ -170,7 +175,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
|||||||
rrs26EnabledBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
rrs26EnabledBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
||||||
markAsDrity(true);
|
|
||||||
boolean isActive = event.getValue();
|
boolean isActive = event.getValue();
|
||||||
rrs26ClassFlagListBox.setEnabled(isActive);
|
rrs26ClassFlagListBox.setEnabled(isActive);
|
||||||
rrs26RecallBox.setEnabled(isActive);
|
rrs26RecallBox.setEnabled(isActive);
|
||||||
@@ -215,7 +219,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
|||||||
rrs26StartModeFlagsBox.addChangeHandler(new ChangeHandler() {
|
rrs26StartModeFlagsBox.addChangeHandler(new ChangeHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void onChange(ChangeEvent event) {
|
public void onChange(ChangeEvent event) {
|
||||||
markAsDrity(true);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -229,7 +232,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
|||||||
gateStartEnabledBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
gateStartEnabledBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
||||||
markAsDrity(true);
|
|
||||||
gateStartClassFlagListBox.setEnabled(event.getValue());
|
gateStartClassFlagListBox.setEnabled(event.getValue());
|
||||||
gateStartRecallBox.setEnabled(event.getValue());
|
gateStartRecallBox.setEnabled(event.getValue());
|
||||||
gateStartPathfinderBox.setEnabled(event.getValue());
|
gateStartPathfinderBox.setEnabled(event.getValue());
|
||||||
@@ -244,14 +246,12 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
|||||||
gateStartPathfinderBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
gateStartPathfinderBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
||||||
markAsDrity(true);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
gateStartGolfDownBox = createCheckbox(stringMessages.hasAdditionalGolfDownTime());
|
gateStartGolfDownBox = createCheckbox(stringMessages.hasAdditionalGolfDownTime());
|
||||||
gateStartGolfDownBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
gateStartGolfDownBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
||||||
markAsDrity(true);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -284,7 +284,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
|||||||
essEnabledBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
essEnabledBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
||||||
markAsDrity(true);
|
|
||||||
essClassFlagListBox.setEnabled(event.getValue());
|
essClassFlagListBox.setEnabled(event.getValue());
|
||||||
essRecallBox.setEnabled(event.getValue());
|
essRecallBox.setEnabled(event.getValue());
|
||||||
}
|
}
|
||||||
@@ -318,7 +317,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
|||||||
basicEnabledBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
basicEnabledBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
||||||
markAsDrity(true);
|
|
||||||
basicClassFlagListBox.setEnabled(event.getValue());
|
basicClassFlagListBox.setEnabled(event.getValue());
|
||||||
basicRecallBox.setEnabled(event.getValue());
|
basicRecallBox.setEnabled(event.getValue());
|
||||||
}
|
}
|
||||||
@@ -343,8 +341,37 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
|||||||
contentPanel.add(basicDisclosurePanel);
|
contentPanel.add(basicDisclosurePanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markAsDrity(boolean b) {
|
private void setupLeague() {
|
||||||
// hmnn do we need to this?
|
leagueDisclosurePanel = new DisclosurePanel(stringMessages.leagueStart());
|
||||||
|
VerticalPanel panel = new VerticalPanel();
|
||||||
|
|
||||||
|
Grid grid = new Grid(2, 3);
|
||||||
|
leagueEnabledBox = new CheckBox(stringMessages.setConfiguration());
|
||||||
|
leagueEnabledBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public void onValueChange(ValueChangeEvent<Boolean> event) {
|
||||||
|
leagueClassFlagListBox.setEnabled(event.getValue());
|
||||||
|
leagueRecallBox.setEnabled(event.getValue());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
leagueClassFlagListBox = setupClassFlagListBox(originalConfiguration == null ? null
|
||||||
|
: originalConfiguration.leagueConfiguration);
|
||||||
|
leagueClassFlagListBox.setWidth("100%");
|
||||||
|
leagueRecallBox = setupRecallBox();
|
||||||
|
|
||||||
|
grid.setWidget(0, 0, new Label(stringMessages.classFlag() + ":"));
|
||||||
|
grid.setWidget(0, 1, leagueClassFlagListBox);
|
||||||
|
grid.setWidget(0, 2, createHelpImage(stringMessages.classFlagHelpText("league start")));
|
||||||
|
grid.setWidget(1, 0, leagueRecallBox);
|
||||||
|
grid.setWidget(1, 2, createHelpImage(stringMessages.individualRecallHelpText()));
|
||||||
|
|
||||||
|
leagueEnabledBox.setValue(originalConfiguration != null && originalConfiguration.leagueConfiguration != null);
|
||||||
|
ValueChangeEvent.fire(leagueEnabledBox, leagueEnabledBox.getValue());
|
||||||
|
|
||||||
|
panel.add(leagueEnabledBox);
|
||||||
|
panel.add(grid);
|
||||||
|
leagueDisclosurePanel.add(panel);
|
||||||
|
contentPanel.add(leagueDisclosurePanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Widget createHelpImage(String tooltip) {
|
private Widget createHelpImage(String tooltip) {
|
||||||
@@ -399,6 +426,10 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
|
|||||||
result.basicConfiguration = new DeviceConfigurationDTO.RegattaConfigurationDTO.RacingProcedureConfigurationDTO();
|
result.basicConfiguration = new DeviceConfigurationDTO.RegattaConfigurationDTO.RacingProcedureConfigurationDTO();
|
||||||
getRacingProcedureConfigurationResults(result.basicConfiguration, basicClassFlagListBox, basicRecallBox);
|
getRacingProcedureConfigurationResults(result.basicConfiguration, basicClassFlagListBox, basicRecallBox);
|
||||||
}
|
}
|
||||||
|
if (leagueEnabledBox.getValue()) {
|
||||||
|
result.leagueConfiguration = new DeviceConfigurationDTO.RegattaConfigurationDTO.LeagueConfigurationDTO();
|
||||||
|
getRacingProcedureConfigurationResults(result.leagueConfiguration, leagueClassFlagListBox, leagueRecallBox);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
@@ -9,6 +9,10 @@ public class EntryPointLinkFactory extends AbstractEntryPointLinkFactory {
|
|||||||
return createEntryPointLink("/gwt/RaceBoard.html", parameters);
|
return createEntryPointLink("/gwt/RaceBoard.html", parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String createSimulatorLink(Map<String, String> parameters) {
|
||||||
|
return createEntryPointLink("/gwt/Simulator.html", parameters);
|
||||||
|
}
|
||||||
|
|
||||||
public static String createLeaderboardLink(Map<String, String> parameters) {
|
public static String createLeaderboardLink(Map<String, String> parameters) {
|
||||||
return createEntryPointLink("/gwt/Leaderboard.html", parameters);
|
return createEntryPointLink("/gwt/Leaderboard.html", parameters);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.base.RemoteSailingServerReference;
|
|||||||
import com.sap.sailing.domain.common.DataImportProgress;
|
import com.sap.sailing.domain.common.DataImportProgress;
|
||||||
import com.sap.sailing.domain.common.DetailType;
|
import com.sap.sailing.domain.common.DetailType;
|
||||||
import com.sap.sailing.domain.common.LeaderboardType;
|
import com.sap.sailing.domain.common.LeaderboardType;
|
||||||
|
import com.sap.sailing.domain.common.LegIdentifier;
|
||||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||||
import com.sap.sailing.domain.common.NoWindException;
|
import com.sap.sailing.domain.common.NoWindException;
|
||||||
import com.sap.sailing.domain.common.PassingInstruction;
|
import com.sap.sailing.domain.common.PassingInstruction;
|
||||||
@@ -144,10 +145,10 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
|
|||||||
|
|
||||||
boolean getPolarResults(RegattaAndRaceIdentifier raceIdentifier);
|
boolean getPolarResults(RegattaAndRaceIdentifier raceIdentifier);
|
||||||
|
|
||||||
SimulatorResultsDTO getSimulatorResults(RegattaAndRaceIdentifier raceIdentifier, Date from, Date prevStartTime);
|
SimulatorResultsDTO getSimulatorResults(LegIdentifier legIdentifier);
|
||||||
|
|
||||||
CompactRaceMapDataDTO getRaceMapData(RegattaAndRaceIdentifier raceIdentifier, Date date, Map<String, Date> fromPerCompetitorIdAsString,
|
CompactRaceMapDataDTO getRaceMapData(RegattaAndRaceIdentifier raceIdentifier, Date date, Map<String, Date> fromPerCompetitorIdAsString,
|
||||||
Map<String, Date> toPerCompetitorIdAsString, boolean extrapolate) throws NoWindException;
|
Map<String, Date> toPerCompetitorIdAsString, boolean extrapolate, LegIdentifier simulationLegIdentifier) throws NoWindException;
|
||||||
|
|
||||||
RaceTimesInfoDTO getRaceTimesInfo(RegattaAndRaceIdentifier raceIdentifier);
|
RaceTimesInfoDTO getRaceTimesInfo(RegattaAndRaceIdentifier raceIdentifier);
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -13,6 +13,7 @@ import com.sap.sailing.domain.base.RemoteSailingServerReference;
|
|||||||
import com.sap.sailing.domain.common.DataImportProgress;
|
import com.sap.sailing.domain.common.DataImportProgress;
|
||||||
import com.sap.sailing.domain.common.DetailType;
|
import com.sap.sailing.domain.common.DetailType;
|
||||||
import com.sap.sailing.domain.common.LeaderboardType;
|
import com.sap.sailing.domain.common.LeaderboardType;
|
||||||
|
import com.sap.sailing.domain.common.LegIdentifier;
|
||||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||||
import com.sap.sailing.domain.common.PassingInstruction;
|
import com.sap.sailing.domain.common.PassingInstruction;
|
||||||
import com.sap.sailing.domain.common.PolarSheetGenerationResponse;
|
import com.sap.sailing.domain.common.PolarSheetGenerationResponse;
|
||||||
@@ -191,7 +192,7 @@ public interface SailingServiceAsync extends BuildVersionRetriever, FileStorageM
|
|||||||
|
|
||||||
void getPolarResults(RegattaAndRaceIdentifier raceIdentifier, AsyncCallback<Boolean> callback);
|
void getPolarResults(RegattaAndRaceIdentifier raceIdentifier, AsyncCallback<Boolean> callback);
|
||||||
|
|
||||||
void getSimulatorResults(RegattaAndRaceIdentifier raceIdentifier, Date from, Date prevStartTime, AsyncCallback<SimulatorResultsDTO> callback);
|
void getSimulatorResults(LegIdentifier legIdentifier, AsyncCallback<SimulatorResultsDTO> callback);
|
||||||
|
|
||||||
void setWind(RegattaAndRaceIdentifier raceIdentifier, WindDTO wind, AsyncCallback<Void> callback);
|
void setWind(RegattaAndRaceIdentifier raceIdentifier, WindDTO wind, AsyncCallback<Void> callback);
|
||||||
|
|
||||||
@@ -336,7 +337,7 @@ public interface SailingServiceAsync extends BuildVersionRetriever, FileStorageM
|
|||||||
* identified by <code>raceIdentifier</code> will be used, considering that race's delay.
|
* identified by <code>raceIdentifier</code> will be used, considering that race's delay.
|
||||||
*/
|
*/
|
||||||
void getRaceMapData(RegattaAndRaceIdentifier raceIdentifier, Date date, Map<String, Date> fromPerCompetitorIdAsString,
|
void getRaceMapData(RegattaAndRaceIdentifier raceIdentifier, Date date, Map<String, Date> fromPerCompetitorIdAsString,
|
||||||
Map<String, Date> toPerCompetitorIdAsString, boolean extrapolate, AsyncCallback<CompactRaceMapDataDTO> callback);
|
Map<String, Date> toPerCompetitorIdAsString, boolean extrapolate, LegIdentifier simulationLegIdentifier, AsyncCallback<CompactRaceMapDataDTO> callback);
|
||||||
|
|
||||||
void getReplicaInfo(AsyncCallback<ReplicationStateDTO> callback);
|
void getReplicaInfo(AsyncCallback<ReplicationStateDTO> callback);
|
||||||
|
|
||||||
|
|||||||
+18
-1
@@ -19,6 +19,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
|||||||
String wind();
|
String wind();
|
||||||
String windPanelLabel();
|
String windPanelLabel();
|
||||||
String refresh();
|
String refresh();
|
||||||
|
@Override
|
||||||
String remove();
|
String remove();
|
||||||
String windSource();
|
String windSource();
|
||||||
String dampeningInterval();
|
String dampeningInterval();
|
||||||
@@ -53,6 +54,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
|||||||
String linkToColumn();
|
String linkToColumn();
|
||||||
String unlink();
|
String unlink();
|
||||||
String leaderboardName();
|
String leaderboardName();
|
||||||
|
@Override
|
||||||
String cancel();
|
String cancel();
|
||||||
String pleaseEnterAName();
|
String pleaseEnterAName();
|
||||||
String pleaseEnterABoatClass();
|
String pleaseEnterABoatClass();
|
||||||
@@ -65,6 +67,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
|||||||
String renameLeaderboard();
|
String renameLeaderboard();
|
||||||
String addColumnToLeaderboard();
|
String addColumnToLeaderboard();
|
||||||
String pleaseEnterNameForNewRaceColumn();
|
String pleaseEnterNameForNewRaceColumn();
|
||||||
|
@Override
|
||||||
String ok();
|
String ok();
|
||||||
String medalRace();
|
String medalRace();
|
||||||
String renameRace();
|
String renameRace();
|
||||||
@@ -81,6 +84,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
|||||||
String leaderboard();
|
String leaderboard();
|
||||||
String leaderboards();
|
String leaderboards();
|
||||||
String leaderboardSettings();
|
String leaderboardSettings();
|
||||||
|
@Override
|
||||||
String settings();
|
String settings();
|
||||||
String linkedRaces();
|
String linkedRaces();
|
||||||
String selectAtLeastOneLegDetail();
|
String selectAtLeastOneLegDetail();
|
||||||
@@ -154,6 +158,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
|||||||
String penaltyCircles();
|
String penaltyCircles();
|
||||||
String medalRaceIsNull();
|
String medalRaceIsNull();
|
||||||
String maneuverTypes();
|
String maneuverTypes();
|
||||||
|
@Override
|
||||||
String configuration();
|
String configuration();
|
||||||
String chooseChart();
|
String chooseChart();
|
||||||
String distanceTraveled();
|
String distanceTraveled();
|
||||||
@@ -166,12 +171,14 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
|||||||
String in();
|
String in();
|
||||||
String secondsUnit();
|
String secondsUnit();
|
||||||
String metersUnit();
|
String metersUnit();
|
||||||
|
@Override
|
||||||
String close();
|
String close();
|
||||||
String compareCompetitors();
|
String compareCompetitors();
|
||||||
String description();
|
String description();
|
||||||
String sailNumber();
|
String sailNumber();
|
||||||
String country();
|
String country();
|
||||||
String no3LetterCodes();
|
String no3LetterCodes();
|
||||||
|
@Override
|
||||||
String add();
|
String add();
|
||||||
String delete();
|
String delete();
|
||||||
String showCharts();
|
String showCharts();
|
||||||
@@ -944,6 +951,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
|||||||
String pathfinderHelpText();
|
String pathfinderHelpText();
|
||||||
String essStart();
|
String essStart();
|
||||||
String basicStart();
|
String basicStart();
|
||||||
|
String leagueStart();
|
||||||
String configured();
|
String configured();
|
||||||
String overwriteRacingProceduresConfiguration();
|
String overwriteRacingProceduresConfiguration();
|
||||||
String overwriteRacingProceduresConfigurationHelpText();
|
String overwriteRacingProceduresConfigurationHelpText();
|
||||||
@@ -1141,9 +1149,13 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
|||||||
String enterRaceName();
|
String enterRaceName();
|
||||||
String enterCourseName();
|
String enterCourseName();
|
||||||
String scoringSchemeHighPointFirstGetsTenOrEightDescription();
|
String scoringSchemeHighPointFirstGetsTenOrEightDescription();
|
||||||
|
@Override
|
||||||
String serverError();
|
String serverError();
|
||||||
|
@Override
|
||||||
String remoteProcedureCall();
|
String remoteProcedureCall();
|
||||||
|
@Override
|
||||||
String serverReplies();
|
String serverReplies();
|
||||||
|
@Override
|
||||||
String errorCommunicatingWithServer();
|
String errorCommunicatingWithServer();
|
||||||
String userManagement();
|
String userManagement();
|
||||||
String structureImportUrls();
|
String structureImportUrls();
|
||||||
@@ -1191,10 +1203,15 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
|||||||
String sendingMailsSuccessful();
|
String sendingMailsSuccessful();
|
||||||
String selectEventForInvitation();
|
String selectEventForInvitation();
|
||||||
String imageURL();
|
String imageURL();
|
||||||
|
@Override
|
||||||
String upload();
|
String upload();
|
||||||
String removeResult(JSONValue status, JSONValue message);
|
String removeResult(JSONValue status, JSONValue message);
|
||||||
|
@Override
|
||||||
String uploadSuccessful();
|
String uploadSuccessful();
|
||||||
String fileUploadResult(JSONValue status, JSONValue message);
|
@Override
|
||||||
|
String fileUploadResult(String status, String message);
|
||||||
|
@Override
|
||||||
|
String removeUploadedImage();
|
||||||
String showCompetitorSailIdColumn();
|
String showCompetitorSailIdColumn();
|
||||||
String showCompetitorFullNameColumn();
|
String showCompetitorFullNameColumn();
|
||||||
String loadingDimensionValues();
|
String loadingDimensionValues();
|
||||||
|
|||||||
+2
@@ -924,6 +924,7 @@ activatePathfinder=Activate Pathfinder
|
|||||||
pathfinderHelpText=When activated the Race Officer is able to set the Pathfinder boat.
|
pathfinderHelpText=When activated the Race Officer is able to set the Pathfinder boat.
|
||||||
essStart=ESS Start
|
essStart=ESS Start
|
||||||
basicStart=Basic Start
|
basicStart=Basic Start
|
||||||
|
leagueStart=League Start
|
||||||
configured=Configured
|
configured=Configured
|
||||||
overwriteRacingProceduresConfiguration=Activate regatta configuration
|
overwriteRacingProceduresConfiguration=Activate regatta configuration
|
||||||
overwriteRacingProceduresConfigurationHelpText=Enabling this option will provide a base regatta configuration for all options unconfigured in the regatta-specific configuration.
|
overwriteRacingProceduresConfigurationHelpText=Enabling this option will provide a base regatta configuration for all options unconfigured in the regatta-specific configuration.
|
||||||
@@ -1176,6 +1177,7 @@ upload=Upload
|
|||||||
removeResult=Remove operation: {0} {1}
|
removeResult=Remove operation: {0} {1}
|
||||||
uploadSuccessful=Upload successful
|
uploadSuccessful=Upload successful
|
||||||
fileUploadResult=File upload: {0} {1}.\nIn case of error please check that your File Storage service is properly configured.
|
fileUploadResult=File upload: {0} {1}.\nIn case of error please check that your File Storage service is properly configured.
|
||||||
|
removeUploadedImage=Remove uploaded image
|
||||||
showCompetitorSailIdColumn=Show Competitor Sail Id
|
showCompetitorSailIdColumn=Show Competitor Sail Id
|
||||||
showCompetitorFullNameColumn=Show Competitor Full Name
|
showCompetitorFullNameColumn=Show Competitor Full Name
|
||||||
loadingDimensionValues=Loading dimension values
|
loadingDimensionValues=Loading dimension values
|
||||||
|
|||||||
+1194
File diff suppressed because it is too large.
Load diff
+2
@@ -920,6 +920,7 @@ activatePathfinder=Aktiviere Pathfinder
|
|||||||
pathfinderHelpText=Wenn aktiviert, ermöglicht dem Race Officer einen Pathfinder auszuwählen.
|
pathfinderHelpText=Wenn aktiviert, ermöglicht dem Race Officer einen Pathfinder auszuwählen.
|
||||||
essStart=ESS Start
|
essStart=ESS Start
|
||||||
basicStart=Basic Start
|
basicStart=Basic Start
|
||||||
|
leagueStart=Liga Start
|
||||||
configured=Konfiguriert
|
configured=Konfiguriert
|
||||||
overwriteRacingProceduresConfiguration=Aktivere Regattakonfiguration
|
overwriteRacingProceduresConfiguration=Aktivere Regattakonfiguration
|
||||||
overwriteRacingProceduresConfigurationHelpText=Wenn aktiviert überschreibt jegliche Konfiguration der Rennarten durch eine Regatta.
|
overwriteRacingProceduresConfigurationHelpText=Wenn aktiviert überschreibt jegliche Konfiguration der Rennarten durch eine Regatta.
|
||||||
@@ -1166,6 +1167,7 @@ upload=Hochladen
|
|||||||
removeResult=Löschergebnis: {0} {1}
|
removeResult=Löschergebnis: {0} {1}
|
||||||
uploadSuccessful=Hochladen erfolgreich
|
uploadSuccessful=Hochladen erfolgreich
|
||||||
fileUploadResult=Ergebnis des Hochladens: {0} {1}\nIm Fehlerfall bitte die Konfiguration für "Datei Speicherung" prüfen.
|
fileUploadResult=Ergebnis des Hochladens: {0} {1}\nIm Fehlerfall bitte die Konfiguration für "Datei Speicherung" prüfen.
|
||||||
|
removeUploadedImage=Hochgeladenes Bild löschen
|
||||||
showCompetitorSailIdColumn=Sail Id anzeigen
|
showCompetitorSailIdColumn=Sail Id anzeigen
|
||||||
showCompetitorFullNameColumn=Vollen Namen anzeigen
|
showCompetitorFullNameColumn=Vollen Namen anzeigen
|
||||||
loadingDimensionValues=Lade Dimensionswerte
|
loadingDimensionValues=Lade Dimensionswerte
|
||||||
|
|||||||
+3
-1
@@ -913,7 +913,8 @@ gateStart=Ворота старта
|
|||||||
activatePathfinder=Активировать «Следопыт»
|
activatePathfinder=Активировать «Следопыт»
|
||||||
pathfinderHelpText=После активации официальное лицо гонки может настроить судно «Следопыт».
|
pathfinderHelpText=После активации официальное лицо гонки может настроить судно «Следопыт».
|
||||||
essStart=Старт ESS
|
essStart=Старт ESS
|
||||||
basicStart=Основной старт
|
basicStart=Основной старт
|
||||||
|
leagueStart=League Start
|
||||||
configured=Настроенный
|
configured=Настроенный
|
||||||
overwriteRacingProceduresConfiguration=Активировать конфигурацию регаты
|
overwriteRacingProceduresConfiguration=Активировать конфигурацию регаты
|
||||||
overwriteRacingProceduresConfigurationHelpText=Включение этой опции предоставляет базовую конфигурацию регаты для всех опций, не настроенных в специальной конфигурации регаты.
|
overwriteRacingProceduresConfigurationHelpText=Включение этой опции предоставляет базовую конфигурацию регаты для всех опций, не настроенных в специальной конфигурации регаты.
|
||||||
@@ -1115,6 +1116,7 @@ upload=Upload
|
|||||||
removeResult=Remove operation: {0} {1}
|
removeResult=Remove operation: {0} {1}
|
||||||
uploadSuccessful=Upload successful
|
uploadSuccessful=Upload successful
|
||||||
fileUploadResult=File upload: {0} {1}.\nIn case of error please check that your File Storage service is properly configured.
|
fileUploadResult=File upload: {0} {1}.\nIn case of error please check that your File Storage service is properly configured.
|
||||||
|
removeUploadedImage=Remove uploaded image
|
||||||
showCompetitorSailIdColumn=Show Competitor Sail Id
|
showCompetitorSailIdColumn=Show Competitor Sail Id
|
||||||
showCompetitorFullNameColumn=Show Competitor Full Name
|
showCompetitorFullNameColumn=Show Competitor Full Name
|
||||||
loadingDimensionValues=Loading dimension values
|
loadingDimensionValues=Loading dimension values
|
||||||
|
|||||||
+9
-14
@@ -307,6 +307,8 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
|||||||
private boolean isMapInitialized;
|
private boolean isMapInitialized;
|
||||||
|
|
||||||
private Date lastTimeChangeBeforeInitialization;
|
private Date lastTimeChangeBeforeInitialization;
|
||||||
|
|
||||||
|
private int lastLegNumber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The last quick ranks received from a call to {@link SailingServiceAsync#getQuickRanks(RaceIdentifier, Date, AsyncCallback)} upon
|
* The last quick ranks received from a call to {@link SailingServiceAsync#getQuickRanks(RaceIdentifier, Date, AsyncCallback)} upon
|
||||||
@@ -739,7 +741,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
|||||||
// next, do the full thing; being the later call, if request throttling kicks in, the later call
|
// next, do the full thing; being the later call, if request throttling kicks in, the later call
|
||||||
// supersedes the earlier call which may get dropped then
|
// supersedes the earlier call which may get dropped then
|
||||||
GetRaceMapDataAction getRaceMapDataAction = new GetRaceMapDataAction(sailingService, competitorSelection.getAllCompetitors(), race,
|
GetRaceMapDataAction getRaceMapDataAction = new GetRaceMapDataAction(sailingService, competitorSelection.getAllCompetitors(), race,
|
||||||
useNullAsTimePoint() ? null : newTime, fromAndToAndOverlap.getA(), fromAndToAndOverlap.getB(), /* extrapolate */ true);
|
useNullAsTimePoint() ? null : newTime, fromAndToAndOverlap.getA(), fromAndToAndOverlap.getB(), /* extrapolate */ true, (settings.isShowSimulationOverlay() ? simulationOverlay.getLegIdentifier() : null));
|
||||||
asyncActionsExecutor.execute(getRaceMapDataAction, GET_RACE_MAP_DATA_CATEGORY,
|
asyncActionsExecutor.execute(getRaceMapDataAction, GET_RACE_MAP_DATA_CATEGORY,
|
||||||
getRaceMapDataCallback(oldTime, newTime, fromAndToAndOverlap.getC(), competitorsToShow, requestID));
|
getRaceMapDataCallback(oldTime, newTime, fromAndToAndOverlap.getC(), competitorsToShow, requestID));
|
||||||
|
|
||||||
@@ -820,7 +822,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
|||||||
final GetRaceMapDataAction result;
|
final GetRaceMapDataAction result;
|
||||||
if (!fromTimes.isEmpty()) {
|
if (!fromTimes.isEmpty()) {
|
||||||
result = new GetRaceMapDataAction(sailingService, competitorSelection.getAllCompetitors(),
|
result = new GetRaceMapDataAction(sailingService, competitorSelection.getAllCompetitors(),
|
||||||
race, useNullAsTimePoint() ? null : newTime, fromTimes, toTimes, /* extrapolate */true);
|
race, useNullAsTimePoint() ? null : newTime, fromTimes, toTimes, /* extrapolate */true, (settings.isShowSimulationOverlay() ? simulationOverlay.getLegIdentifier() : null));
|
||||||
} else {
|
} else {
|
||||||
result = null;
|
result = null;
|
||||||
}
|
}
|
||||||
@@ -843,7 +845,8 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
|||||||
if (map != null && raceMapDataDTO != null) {
|
if (map != null && raceMapDataDTO != null) {
|
||||||
quickRanks = raceMapDataDTO.quickRanks;
|
quickRanks = raceMapDataDTO.quickRanks;
|
||||||
if (showViewSimulation && settings.isShowSimulationOverlay()) {
|
if (showViewSimulation && settings.isShowSimulationOverlay()) {
|
||||||
simulationOverlay.updateLeg(getCurrentLeg(), newTime, /* clearCanvas */ false);
|
lastLegNumber = raceMapDataDTO.coursePositions.currentLegNumber;
|
||||||
|
simulationOverlay.updateLeg(Math.max(lastLegNumber,1), /* clearCanvas */ false, raceMapDataDTO.simulationResultVersion);
|
||||||
}
|
}
|
||||||
// process response only if not received out of order
|
// process response only if not received out of order
|
||||||
if (startedProcessingRequestID < requestID) {
|
if (startedProcessingRequestID < requestID) {
|
||||||
@@ -2228,7 +2231,9 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
|||||||
if (newSettings.isShowSimulationOverlay() != settings.isShowSimulationOverlay()) {
|
if (newSettings.isShowSimulationOverlay() != settings.isShowSimulationOverlay()) {
|
||||||
settings.setShowSimulationOverlay(newSettings.isShowSimulationOverlay());
|
settings.setShowSimulationOverlay(newSettings.isShowSimulationOverlay());
|
||||||
simulationOverlay.setVisible(newSettings.isShowSimulationOverlay());
|
simulationOverlay.setVisible(newSettings.isShowSimulationOverlay());
|
||||||
simulationOverlay.updateLeg(getCurrentLeg(), timer.getTime(), true);
|
if (newSettings.isShowSimulationOverlay()) {
|
||||||
|
simulationOverlay.updateLeg(Math.max(lastLegNumber,1), true, -1 /* ensure ui-update */);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (newSettings.isWindUp() != settings.isWindUp()) {
|
if (newSettings.isWindUp() != settings.isWindUp()) {
|
||||||
settings.setWindUp(newSettings.isWindUp());
|
settings.setWindUp(newSettings.isWindUp());
|
||||||
@@ -2437,16 +2442,6 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCurrentLeg() {
|
|
||||||
com.sap.sse.common.Util.Pair<Integer, CompetitorDTO> leaderWithLeg = this
|
|
||||||
.getLeadingVisibleCompetitorWithOneBasedLegNumber(getCompetitorsToShow());
|
|
||||||
if (leaderWithLeg == null) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return leaderWithLeg.getA();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Image createSAPLogo() {
|
private Image createSAPLogo() {
|
||||||
ImageResource sapLogoResource = resources.sapLogoOverlay();
|
ImageResource sapLogoResource = resources.sapLogoOverlay();
|
||||||
Image sapLogo = new Image(sapLogoResource);
|
Image sapLogo = new Image(sapLogoResource);
|
||||||
|
|||||||
Regular → Executable
+58
-95
@@ -117,6 +117,7 @@ import com.sap.sailing.domain.base.configuration.impl.DeviceConfigurationMatcher
|
|||||||
import com.sap.sailing.domain.base.configuration.impl.DeviceConfigurationMatcherSingle;
|
import com.sap.sailing.domain.base.configuration.impl.DeviceConfigurationMatcherSingle;
|
||||||
import com.sap.sailing.domain.base.configuration.impl.ESSConfigurationImpl;
|
import com.sap.sailing.domain.base.configuration.impl.ESSConfigurationImpl;
|
||||||
import com.sap.sailing.domain.base.configuration.impl.GateStartConfigurationImpl;
|
import com.sap.sailing.domain.base.configuration.impl.GateStartConfigurationImpl;
|
||||||
|
import com.sap.sailing.domain.base.configuration.impl.LeagueConfigurationImpl;
|
||||||
import com.sap.sailing.domain.base.configuration.impl.RRS26ConfigurationImpl;
|
import com.sap.sailing.domain.base.configuration.impl.RRS26ConfigurationImpl;
|
||||||
import com.sap.sailing.domain.base.configuration.impl.RacingProcedureConfigurationImpl;
|
import com.sap.sailing.domain.base.configuration.impl.RacingProcedureConfigurationImpl;
|
||||||
import com.sap.sailing.domain.base.configuration.impl.RegattaConfigurationImpl;
|
import com.sap.sailing.domain.base.configuration.impl.RegattaConfigurationImpl;
|
||||||
@@ -137,6 +138,7 @@ import com.sap.sailing.domain.common.DetailType;
|
|||||||
import com.sap.sailing.domain.common.Distance;
|
import com.sap.sailing.domain.common.Distance;
|
||||||
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
||||||
import com.sap.sailing.domain.common.LeaderboardType;
|
import com.sap.sailing.domain.common.LeaderboardType;
|
||||||
|
import com.sap.sailing.domain.common.LegIdentifier;
|
||||||
import com.sap.sailing.domain.common.LegType;
|
import com.sap.sailing.domain.common.LegType;
|
||||||
import com.sap.sailing.domain.common.ManeuverType;
|
import com.sap.sailing.domain.common.ManeuverType;
|
||||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||||
@@ -221,6 +223,8 @@ import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
|||||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||||
import com.sap.sailing.domain.persistence.MongoRaceLogStoreFactory;
|
import com.sap.sailing.domain.persistence.MongoRaceLogStoreFactory;
|
||||||
import com.sap.sailing.domain.persistence.MongoRegattaLogStoreFactory;
|
import com.sap.sailing.domain.persistence.MongoRegattaLogStoreFactory;
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.RaceStateOfSameDayHelper;
|
import com.sap.sailing.domain.racelog.RaceStateOfSameDayHelper;
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
@@ -340,8 +344,6 @@ import com.sap.sailing.manage2sail.EventResultDescriptor;
|
|||||||
import com.sap.sailing.manage2sail.Manage2SailEventResultsParserImpl;
|
import com.sap.sailing.manage2sail.Manage2SailEventResultsParserImpl;
|
||||||
import com.sap.sailing.manage2sail.RaceResultDescriptor;
|
import com.sap.sailing.manage2sail.RaceResultDescriptor;
|
||||||
import com.sap.sailing.manage2sail.RegattaResultDescriptor;
|
import com.sap.sailing.manage2sail.RegattaResultDescriptor;
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
|
||||||
import com.sap.sailing.resultimport.ResultUrlProvider;
|
import com.sap.sailing.resultimport.ResultUrlProvider;
|
||||||
import com.sap.sailing.resultimport.ResultUrlRegistry;
|
import com.sap.sailing.resultimport.ResultUrlRegistry;
|
||||||
import com.sap.sailing.server.RacingEventService;
|
import com.sap.sailing.server.RacingEventService;
|
||||||
@@ -395,24 +397,20 @@ import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardScoreCo
|
|||||||
import com.sap.sailing.server.operationaltransformation.UpdateRaceDelayToLive;
|
import com.sap.sailing.server.operationaltransformation.UpdateRaceDelayToLive;
|
||||||
import com.sap.sailing.server.operationaltransformation.UpdateSeries;
|
import com.sap.sailing.server.operationaltransformation.UpdateSeries;
|
||||||
import com.sap.sailing.server.operationaltransformation.UpdateSpecificRegatta;
|
import com.sap.sailing.server.operationaltransformation.UpdateSpecificRegatta;
|
||||||
|
import com.sap.sailing.server.simulation.SimulationService;
|
||||||
import com.sap.sailing.simulator.Path;
|
import com.sap.sailing.simulator.Path;
|
||||||
|
import com.sap.sailing.simulator.PathType;
|
||||||
import com.sap.sailing.simulator.PolarDiagram;
|
import com.sap.sailing.simulator.PolarDiagram;
|
||||||
import com.sap.sailing.simulator.SailingSimulator;
|
import com.sap.sailing.simulator.SimulationResults;
|
||||||
import com.sap.sailing.simulator.SimulationParameters;
|
|
||||||
import com.sap.sailing.simulator.TimedPositionWithSpeed;
|
import com.sap.sailing.simulator.TimedPositionWithSpeed;
|
||||||
import com.sap.sailing.simulator.impl.PolarDiagramGPS;
|
import com.sap.sailing.simulator.impl.PolarDiagramGPS;
|
||||||
import com.sap.sailing.simulator.impl.SailingSimulatorImpl;
|
import com.sap.sailing.simulator.impl.SparseSimulationDataException;
|
||||||
import com.sap.sailing.simulator.impl.SimulationParametersImpl;
|
|
||||||
import com.sap.sailing.simulator.util.SailingSimulatorConstants;
|
|
||||||
import com.sap.sailing.simulator.windfield.WindFieldGenerator;
|
|
||||||
import com.sap.sailing.simulator.windfield.impl.WindFieldTrackedRaceImpl;
|
|
||||||
import com.sap.sailing.xrr.schema.RegattaResults;
|
import com.sap.sailing.xrr.schema.RegattaResults;
|
||||||
import com.sap.sailing.xrr.structureimport.SeriesParameters;
|
import com.sap.sailing.xrr.structureimport.SeriesParameters;
|
||||||
import com.sap.sailing.xrr.structureimport.StructureImporter;
|
import com.sap.sailing.xrr.structureimport.StructureImporter;
|
||||||
import com.sap.sailing.xrr.structureimport.buildstructure.SetRacenumberFromSeries;
|
import com.sap.sailing.xrr.structureimport.buildstructure.SetRacenumberFromSeries;
|
||||||
import com.sap.sse.BuildVersion;
|
import com.sap.sse.BuildVersion;
|
||||||
import com.sap.sse.common.CountryCode;
|
import com.sap.sse.common.CountryCode;
|
||||||
import com.sap.sse.common.Duration;
|
|
||||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
import com.sap.sse.common.TimeRange;
|
import com.sap.sse.common.TimeRange;
|
||||||
@@ -421,7 +419,6 @@ import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
|||||||
import com.sap.sse.common.Util;
|
import com.sap.sse.common.Util;
|
||||||
import com.sap.sse.common.Util.Pair;
|
import com.sap.sse.common.Util.Pair;
|
||||||
import com.sap.sse.common.Util.Triple;
|
import com.sap.sse.common.Util.Triple;
|
||||||
import com.sap.sse.common.impl.MillisecondsDurationImpl;
|
|
||||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||||
import com.sap.sse.common.mail.MailException;
|
import com.sap.sse.common.mail.MailException;
|
||||||
@@ -1436,107 +1433,55 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
|||||||
} else {
|
} else {
|
||||||
BoatClass boatClass = trackedRace.getRace().getBoatClass();
|
BoatClass boatClass = trackedRace.getRace().getBoatClass();
|
||||||
PolarDataService polarData = getService().getPolarDataService();
|
PolarDataService polarData = getService().getPolarDataService();
|
||||||
PolarDiagram polarDiagram = new PolarDiagramGPS(boatClass, polarData);
|
PolarDiagram polarDiagram;
|
||||||
|
try {
|
||||||
|
polarDiagram = new PolarDiagramGPS(boatClass, polarData);
|
||||||
|
} catch (SparseSimulationDataException e) {
|
||||||
|
polarDiagram = null;
|
||||||
|
// TODO: raise a UI message, to inform user about missing polar data resulting in unability to simulate
|
||||||
|
}
|
||||||
result = polarDiagram != null;
|
result = polarDiagram != null;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SimulatorResultsDTO getSimulatorResults(RegattaAndRaceIdentifier raceIdentifier, Date from, Date prevStartTime) {
|
public SimulatorResultsDTO getSimulatorResults(LegIdentifier legIdentifier) {
|
||||||
TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier);
|
// get simulation-results from smart-future-cached simulation-service
|
||||||
SimulatorResultsDTO result = null;
|
SimulatorResultsDTO result = null;
|
||||||
|
SimulationService simulationService = getService().getSimulationService();
|
||||||
if (trackedRace != null) {
|
if (simulationService == null)
|
||||||
TimePoint fromTimePoint = from == null ? new MillisecondsTimePoint(trackedRace.getStartOfRace().asMillis() + 10000) : new MillisecondsTimePoint(from);
|
return result;
|
||||||
|
SimulationResults simulationResults = simulationService.getSimulationResults(legIdentifier);
|
||||||
// get previous mark or start line as start-position
|
if (simulationResults == null)
|
||||||
TrackedLeg trackedLeg = trackedRace.getCurrentLeg(fromTimePoint);
|
return result;
|
||||||
if (trackedLeg == null) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
Waypoint fromWaypoint = trackedLeg.getLeg().getFrom();
|
|
||||||
|
|
||||||
// get next mark as end-position
|
|
||||||
Waypoint toWaypoint = trackedLeg.getLeg().getTo();
|
|
||||||
|
|
||||||
TimePoint startTimePoint = null;
|
|
||||||
TimePoint endTimePoint = null;
|
|
||||||
Iterable<Util.Pair<Waypoint, Util.Pair<TimePoint, TimePoint>>> markPassings = trackedRace.getMarkPassingsTimes();
|
|
||||||
long legDuration = 0;
|
|
||||||
synchronized(markPassings) {
|
|
||||||
for(Pair<Waypoint, Pair<TimePoint, TimePoint>> markPassing : markPassings) {
|
|
||||||
if (markPassing.getA().equals(fromWaypoint)) {
|
|
||||||
startTimePoint = markPassing.getB().getA();
|
|
||||||
}
|
|
||||||
if (markPassing.getA().equals(toWaypoint)) {
|
|
||||||
endTimePoint = markPassing.getB().getA();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
legDuration = endTimePoint.asMillis() - startTimePoint.asMillis();
|
|
||||||
Position startPosition = trackedRace.getApproximatePosition(fromWaypoint, startTimePoint);
|
|
||||||
Position endPosition = trackedRace.getApproximatePosition(toWaypoint, endTimePoint);
|
|
||||||
|
|
||||||
if (startTimePoint.asDate().equals(prevStartTime)) {
|
|
||||||
return new SimulatorResultsDTO(startTimePoint.asDate(), 0, 0, null, null, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine legtype upwind/downwind/reaching
|
|
||||||
LegType legType = null;
|
|
||||||
try {
|
|
||||||
legType = trackedLeg.getLegType(fromTimePoint);
|
|
||||||
} catch (NoWindException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get windfield
|
|
||||||
WindFieldGenerator windField = new WindFieldTrackedRaceImpl(trackedRace);
|
|
||||||
Duration timeStep = new MillisecondsDurationImpl(15 * 1000);
|
|
||||||
windField.generate(startTimePoint, null, timeStep);
|
|
||||||
|
|
||||||
// prepare simulation-parameters
|
|
||||||
List<Position> course = new ArrayList<>();
|
|
||||||
course.add(startPosition);
|
|
||||||
course.add(endPosition);
|
|
||||||
BoatClass boatClass = trackedRace.getRace().getBoatClass();
|
|
||||||
PolarDataService polarData = getService().getPolarDataService();
|
|
||||||
PolarDiagram polarDiagram = new PolarDiagramGPS(boatClass, polarData);
|
|
||||||
SimulationParameters simulationPars = new SimulationParametersImpl(course, polarDiagram, windField, SailingSimulatorConstants.ModeEvent, true, true);
|
|
||||||
|
|
||||||
// for upwind/downwind, run simulation with start-time, start-position, end-position and windfield
|
|
||||||
SailingSimulator simulator = new SailingSimulatorImpl(simulationPars);
|
|
||||||
Map<String, Path> pathsAndNames = null;
|
|
||||||
if (legType != LegType.REACHING) {
|
|
||||||
pathsAndNames = simulator.getAllPathsEvenTimed(timeStep.asMillis(), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare simulator-results-dto
|
// prepare simulator-results-dto
|
||||||
if (pathsAndNames != null) {
|
Map<PathType, Path> paths = simulationResults.getPaths();
|
||||||
int noOfPaths = pathsAndNames.size();
|
if (paths != null) {
|
||||||
|
int noOfPaths = paths.size();
|
||||||
PathDTO[] pathDTOs = new PathDTO[noOfPaths];
|
PathDTO[] pathDTOs = new PathDTO[noOfPaths];
|
||||||
int index = noOfPaths - 1;
|
int index = noOfPaths - 1;
|
||||||
for (Entry<String, Path> entry : pathsAndNames.entrySet()) {
|
for (Entry<PathType, Path> entry : paths.entrySet()) {
|
||||||
pathDTOs[index] = new PathDTO(entry.getKey());
|
pathDTOs[index] = new PathDTO(entry.getKey().getTxtId());
|
||||||
// fill pathDTO with path points where speed is true wind speed
|
// fill pathDTO with path points where speed is true wind speed
|
||||||
List<SimulatorWindDTO> wList = new ArrayList<SimulatorWindDTO>();
|
List<SimulatorWindDTO> wList = new ArrayList<SimulatorWindDTO>();
|
||||||
for (TimedPositionWithSpeed p : entry.getValue().getPathPoints()) {
|
for (TimedPositionWithSpeed p : entry.getValue().getPathPoints()) {
|
||||||
wList.add(createSimulatorWindDTO(p));
|
wList.add(createSimulatorWindDTO(p));
|
||||||
}
|
}
|
||||||
pathDTOs[index].setPoints(wList);
|
pathDTOs[index].setPoints(wList);
|
||||||
|
pathDTOs[index].setAlgorithmTimedOut(entry.getValue().getAlgorithmTimedOut());
|
||||||
|
pathDTOs[index].setMixedLeg(entry.getValue().getMixedLeg());
|
||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
RaceMapDataDTO rcDTO;
|
RaceMapDataDTO rcDTO;
|
||||||
rcDTO = new RaceMapDataDTO();
|
rcDTO = new RaceMapDataDTO();
|
||||||
rcDTO.coursePositions = new CoursePositionsDTO();
|
rcDTO.coursePositions = new CoursePositionsDTO();
|
||||||
rcDTO.coursePositions.waypointPositions = new ArrayList<>();
|
rcDTO.coursePositions.waypointPositions = new ArrayList<Position>();
|
||||||
rcDTO.coursePositions.waypointPositions.add(startPosition);
|
rcDTO.coursePositions.waypointPositions.add(simulationResults.getStartPosition());
|
||||||
rcDTO.coursePositions.waypointPositions.add(endPosition);
|
rcDTO.coursePositions.waypointPositions.add(simulationResults.getEndPosition());
|
||||||
result = new SimulatorResultsDTO(startTimePoint.asDate(), timeStep.asMillis(), legDuration, rcDTO, pathDTOs, null, null);
|
result = new SimulatorResultsDTO(simulationResults.hashCode(), simulationResults.getStartTime(), simulationResults.getTimeStep(),
|
||||||
|
simulationResults.getLegDuration(), rcDTO, pathDTOs, null, null);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1612,13 +1557,18 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
|||||||
@Override
|
@Override
|
||||||
public CompactRaceMapDataDTO getRaceMapData(RegattaAndRaceIdentifier raceIdentifier, Date date,
|
public CompactRaceMapDataDTO getRaceMapData(RegattaAndRaceIdentifier raceIdentifier, Date date,
|
||||||
Map<String, Date> fromPerCompetitorIdAsString, Map<String, Date> toPerCompetitorIdAsString,
|
Map<String, Date> fromPerCompetitorIdAsString, Map<String, Date> toPerCompetitorIdAsString,
|
||||||
boolean extrapolate) throws NoWindException {
|
boolean extrapolate, LegIdentifier simulationLegIdentifier) throws NoWindException {
|
||||||
final Map<CompetitorDTO, List<GPSFixDTO>> boatPositions = getBoatPositions(raceIdentifier,
|
final Map<CompetitorDTO, List<GPSFixDTO>> boatPositions = getBoatPositions(raceIdentifier,
|
||||||
fromPerCompetitorIdAsString, toPerCompetitorIdAsString, extrapolate);
|
fromPerCompetitorIdAsString, toPerCompetitorIdAsString, extrapolate);
|
||||||
final CoursePositionsDTO coursePositions = getCoursePositions(raceIdentifier, date);
|
final CoursePositionsDTO coursePositions = getCoursePositions(raceIdentifier, date);
|
||||||
final List<SidelineDTO> courseSidelines = getCourseSidelines(raceIdentifier, date);
|
final List<SidelineDTO> courseSidelines = getCourseSidelines(raceIdentifier, date);
|
||||||
final List<QuickRankDTO> quickRanks = getQuickRanks(raceIdentifier, date);
|
final List<QuickRankDTO> quickRanks = getQuickRanks(raceIdentifier, date);
|
||||||
return new CompactRaceMapDataDTO(boatPositions, coursePositions, courseSidelines, quickRanks);
|
int simulationResultVersion = 0;
|
||||||
|
if (simulationLegIdentifier != null) {
|
||||||
|
SimulationService simulationService = getService().getSimulationService();
|
||||||
|
simulationResultVersion = simulationService.getSimulationResultsVersion(simulationLegIdentifier);
|
||||||
|
}
|
||||||
|
return new CompactRaceMapDataDTO(boatPositions, coursePositions, courseSidelines, quickRanks, simulationResultVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1897,6 +1847,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
|||||||
} else {
|
} else {
|
||||||
dateAsTimePoint = new MillisecondsTimePoint(date);
|
dateAsTimePoint = new MillisecondsTimePoint(date);
|
||||||
}
|
}
|
||||||
|
result.totalLegsCount = trackedRace.getRace().getCourse().getLegs().size();
|
||||||
|
result.currentLegNumber = trackedRace.getLastLegStarted(dateAsTimePoint);
|
||||||
result.marks = new HashSet<MarkDTO>();
|
result.marks = new HashSet<MarkDTO>();
|
||||||
result.waypointPositions = new ArrayList<>();
|
result.waypointPositions = new ArrayList<>();
|
||||||
Set<Mark> marks = new HashSet<Mark>();
|
Set<Mark> marks = new HashSet<Mark>();
|
||||||
@@ -4527,8 +4479,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
|||||||
getService().apply(
|
getService().apply(
|
||||||
new UpdateCompetitor(competitor.getIdAsString(), competitor.getName(), competitor
|
new UpdateCompetitor(competitor.getIdAsString(), competitor.getName(), competitor
|
||||||
.getColor(), competitor.getEmail(), competitor.getSailID(), nationality,
|
.getColor(), competitor.getEmail(), competitor.getSailID(), nationality,
|
||||||
competitor.getFlagImageURL() == null ? null : new URI(competitor.getFlagImageURL()),
|
competitor.getImageURL() == null ? null : new URI(competitor.getImageURL()),
|
||||||
competitor.getImageURL() == null ? null : new URI(competitor.getImageURL()))));
|
competitor.getFlagImageURL() == null ? null : new URI(competitor.getFlagImageURL()))));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -4643,6 +4595,11 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
|||||||
dto.basicConfiguration.classFlag = configuration.getBasicConfiguration().getClassFlag();
|
dto.basicConfiguration.classFlag = configuration.getBasicConfiguration().getClassFlag();
|
||||||
dto.basicConfiguration.hasInidividualRecall = configuration.getBasicConfiguration().hasInidividualRecall();
|
dto.basicConfiguration.hasInidividualRecall = configuration.getBasicConfiguration().hasInidividualRecall();
|
||||||
}
|
}
|
||||||
|
if (configuration.getLeagueConfiguration() != null) {
|
||||||
|
dto.leagueConfiguration = new DeviceConfigurationDTO.RegattaConfigurationDTO.LeagueConfigurationDTO();
|
||||||
|
dto.leagueConfiguration.classFlag = configuration.getLeagueConfiguration().getClassFlag();
|
||||||
|
dto.leagueConfiguration.hasInidividualRecall = configuration.getLeagueConfiguration().hasInidividualRecall();
|
||||||
|
}
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4688,6 +4645,12 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
|||||||
config.setHasInidividualRecall(dto.basicConfiguration.hasInidividualRecall);
|
config.setHasInidividualRecall(dto.basicConfiguration.hasInidividualRecall);
|
||||||
configuration.setBasicConfiguration(config);
|
configuration.setBasicConfiguration(config);
|
||||||
}
|
}
|
||||||
|
if (dto.leagueConfiguration != null) {
|
||||||
|
LeagueConfigurationImpl config = new LeagueConfigurationImpl();
|
||||||
|
config.setClassFlag(dto.leagueConfiguration.classFlag);
|
||||||
|
config.setHasInidividualRecall(dto.leagueConfiguration.hasInidividualRecall);
|
||||||
|
configuration.setLeagueConfiguration(config);
|
||||||
|
}
|
||||||
return configuration;
|
return configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+176
-107
@@ -9,6 +9,11 @@ import java.util.Map;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.NavigableMap;
|
import java.util.NavigableMap;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
|
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
|
||||||
@@ -21,6 +26,7 @@ import com.sap.sailing.domain.common.Wind;
|
|||||||
import com.sap.sailing.domain.common.dto.BoatClassDTO;
|
import com.sap.sailing.domain.common.dto.BoatClassDTO;
|
||||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||||
|
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||||
import com.sap.sailing.domain.common.impl.NauticalMileDistance;
|
import com.sap.sailing.domain.common.impl.NauticalMileDistance;
|
||||||
import com.sap.sailing.gwt.ui.client.SimulatorService;
|
import com.sap.sailing.gwt.ui.client.SimulatorService;
|
||||||
import com.sap.sailing.gwt.ui.shared.BoatClassDTOsAndNotificationMessage;
|
import com.sap.sailing.gwt.ui.shared.BoatClassDTOsAndNotificationMessage;
|
||||||
@@ -50,11 +56,14 @@ import com.sap.sailing.gwt.ui.simulator.windpattern.WindPatternDisplay;
|
|||||||
import com.sap.sailing.gwt.ui.simulator.windpattern.WindPatternDisplayManager;
|
import com.sap.sailing.gwt.ui.simulator.windpattern.WindPatternDisplayManager;
|
||||||
import com.sap.sailing.gwt.ui.simulator.windpattern.WindPatternNotFoundException;
|
import com.sap.sailing.gwt.ui.simulator.windpattern.WindPatternNotFoundException;
|
||||||
import com.sap.sailing.gwt.ui.simulator.windpattern.WindPatternSetting;
|
import com.sap.sailing.gwt.ui.simulator.windpattern.WindPatternSetting;
|
||||||
|
import com.sap.sailing.server.simulation.SimulationService;
|
||||||
|
import com.sap.sailing.server.simulation.SimulationServiceFactory;
|
||||||
import com.sap.sailing.simulator.BoatClassProperties;
|
import com.sap.sailing.simulator.BoatClassProperties;
|
||||||
import com.sap.sailing.simulator.Grid;
|
import com.sap.sailing.simulator.Grid;
|
||||||
import com.sap.sailing.simulator.Path;
|
import com.sap.sailing.simulator.Path;
|
||||||
|
import com.sap.sailing.simulator.PathType;
|
||||||
import com.sap.sailing.simulator.PolarDiagram;
|
import com.sap.sailing.simulator.PolarDiagram;
|
||||||
import com.sap.sailing.simulator.SailingSimulator;
|
import com.sap.sailing.simulator.Simulator;
|
||||||
import com.sap.sailing.simulator.SimulationParameters;
|
import com.sap.sailing.simulator.SimulationParameters;
|
||||||
import com.sap.sailing.simulator.TimedPosition;
|
import com.sap.sailing.simulator.TimedPosition;
|
||||||
import com.sap.sailing.simulator.TimedPositionWithSpeed;
|
import com.sap.sailing.simulator.TimedPositionWithSpeed;
|
||||||
@@ -64,7 +73,7 @@ import com.sap.sailing.simulator.impl.PathGenerator1Turner;
|
|||||||
import com.sap.sailing.simulator.impl.PathImpl;
|
import com.sap.sailing.simulator.impl.PathImpl;
|
||||||
import com.sap.sailing.simulator.impl.PolarDiagramCSV;
|
import com.sap.sailing.simulator.impl.PolarDiagramCSV;
|
||||||
import com.sap.sailing.simulator.impl.ReadingConfigurationFileStatus;
|
import com.sap.sailing.simulator.impl.ReadingConfigurationFileStatus;
|
||||||
import com.sap.sailing.simulator.impl.SailingSimulatorImpl;
|
import com.sap.sailing.simulator.impl.SimulatorImpl;
|
||||||
import com.sap.sailing.simulator.impl.SimulationParametersImpl;
|
import com.sap.sailing.simulator.impl.SimulationParametersImpl;
|
||||||
import com.sap.sailing.simulator.impl.TimedPositionImpl;
|
import com.sap.sailing.simulator.impl.TimedPositionImpl;
|
||||||
import com.sap.sailing.simulator.impl.TimedPositionWithSpeedImpl;
|
import com.sap.sailing.simulator.impl.TimedPositionWithSpeedImpl;
|
||||||
@@ -77,6 +86,7 @@ import com.sap.sse.common.Duration;
|
|||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
import com.sap.sse.common.Util;
|
import com.sap.sse.common.Util;
|
||||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||||
|
|
||||||
public class SimulatorServiceImpl extends RemoteServiceServlet implements SimulatorService {
|
public class SimulatorServiceImpl extends RemoteServiceServlet implements SimulatorService {
|
||||||
|
|
||||||
private static final long serialVersionUID = 4445427185387524086L;
|
private static final long serialVersionUID = 4445427185387524086L;
|
||||||
@@ -89,11 +99,23 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
// private static final double TOTAL_TIME_SCALE_FACTOR = 0.9;
|
// private static final double TOTAL_TIME_SCALE_FACTOR = 0.9;
|
||||||
private static final int DEFAULT_STEP_MAX = 800;
|
private static final int DEFAULT_STEP_MAX = 800;
|
||||||
private static final long DEFAULT_TIMESTEP = 6666;
|
private static final long DEFAULT_TIMESTEP = 6666;
|
||||||
|
private final SimulationService simulationService;
|
||||||
|
|
||||||
private double stepSizeMeters = 0.0;
|
private double stepSizeMeters = 0.0;
|
||||||
private WindControlParameters controlParameters = new WindControlParameters(0, 0);
|
private WindControlParameters controlParameters = new WindControlParameters(0, 0);
|
||||||
private SpeedWithBearing averageWind = null;
|
private SpeedWithBearing averageWind = null;
|
||||||
|
|
||||||
|
public SimulatorServiceImpl() {
|
||||||
|
final int THREAD_POOL_SIZE = Math.max(Runtime.getRuntime().availableProcessors(), 3);
|
||||||
|
Executor simulatorExecutor = new ThreadPoolExecutor(/* corePoolSize */THREAD_POOL_SIZE,
|
||||||
|
/* maximumPoolSize */THREAD_POOL_SIZE,
|
||||||
|
/* keepAliveTime */60, TimeUnit.SECONDS,
|
||||||
|
/* workQueue */new LinkedBlockingQueue<Runnable>());
|
||||||
|
// TODO: initialize smart-future-cache for simulation-results and add to simulation-service
|
||||||
|
simulationService = SimulationServiceFactory.INSTANCE.getService(simulatorExecutor, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Position[] getRaceLocations() {
|
public Position[] getRaceLocations() {
|
||||||
Position lakeGarda = new DegreePosition(45.57055337226086, 10.693345069885254);
|
Position lakeGarda = new DegreePosition(45.57055337226086, 10.693345069885254);
|
||||||
@@ -185,7 +207,8 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
throw new WindPatternNotFoundException("Please select a valid wind pattern.");
|
throw new WindPatternNotFoundException("Please select a valid wind pattern.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Position[][] grid = bd.generatePositions(params.getxRes(), params.getyRes(), params.getBorderY(), params.getBorderX());
|
Position[][] grid = bd.generatePositions(params.getxRes(), params.getyRes(), params.getBorderY(),
|
||||||
|
params.getBorderX());
|
||||||
wf.setPositionGrid(grid);
|
wf.setPositionGrid(grid);
|
||||||
|
|
||||||
TimePoint startTime = new MillisecondsTimePoint(params.getStartTime().getTime());
|
TimePoint startTime = new MillisecondsTimePoint(params.getStartTime().getTime());
|
||||||
@@ -220,13 +243,13 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SimulatorResultsDTO getSimulatorResults(char mode, char rcDirection, WindFieldGenParamsDTO params, WindPatternDisplay pattern, boolean withWindField,
|
public SimulatorResultsDTO getSimulatorResults(char mode, char rcDirection, WindFieldGenParamsDTO params,
|
||||||
SimulatorUISelectionDTO selection) throws WindPatternNotFoundException,
|
WindPatternDisplay pattern, boolean withWindField, SimulatorUISelectionDTO selection)
|
||||||
ConfigurationException {
|
throws WindPatternNotFoundException, ConfigurationException {
|
||||||
WindFieldGenerator wf = null;
|
WindFieldGenerator wf = null;
|
||||||
List<Position> course = null;
|
List<Position> course = null;
|
||||||
TimePoint startTime = new MillisecondsTimePoint(params.getStartTime().getTime());
|
TimePoint startTime = new MillisecondsTimePoint(params.getStartTime().getTime());
|
||||||
@@ -235,7 +258,7 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
this.controlParameters.resetBlastRandomStream = params.isKeepState();
|
this.controlParameters.resetBlastRandomStream = params.isKeepState();
|
||||||
this.retreiveWindControlParameters(pattern);
|
this.retreiveWindControlParameters(pattern);
|
||||||
if (rcDirection == SailingSimulatorConstants.LegTypeDownwind) {
|
if (rcDirection == SailingSimulatorConstants.LegTypeDownwind) {
|
||||||
this.controlParameters.baseWindBearing += 180.0;
|
this.controlParameters.baseWindBearing += 180.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
wf = wfGenFactory.createWindFieldGenerator(pattern.getWindPatternName(), null, this.controlParameters);
|
wf = wfGenFactory.createWindFieldGenerator(pattern.getWindPatternName(), null, this.controlParameters);
|
||||||
@@ -259,13 +282,14 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
gridRes[0] = params.getxRes();
|
gridRes[0] = params.getxRes();
|
||||||
gridRes[1] = params.getyRes();
|
gridRes[1] = params.getyRes();
|
||||||
gridRes[2] = params.getBorderY();
|
gridRes[2] = params.getBorderY();
|
||||||
gridRes[3] = params.getBorderX();
|
gridRes[3] = params.getBorderX();
|
||||||
wf.setGridResolution(gridRes);
|
wf.setGridResolution(gridRes);
|
||||||
|
|
||||||
wf.generate(startTime, null, timeStep);
|
wf.generate(startTime, null, timeStep);
|
||||||
Long longestPathTime = 0L;
|
Long longestPathTime = 0L;
|
||||||
|
|
||||||
SimulatedPathsEvenTimedResultDTO simulatedPaths = this.getSimulatedPathsEvenTimed(course, wf, mode, selection, params.showOmniscient, params.showOpportunist);
|
SimulatedPathsEvenTimedResultDTO simulatedPaths = this.getSimulatedPathsEvenTimed(course, wf, mode, selection,
|
||||||
|
params.showOmniscient, params.showOpportunist);
|
||||||
PathDTO[] pathDTOs = simulatedPaths.pathDTOs;
|
PathDTO[] pathDTOs = simulatedPaths.pathDTOs;
|
||||||
RaceMapDataDTO rcDTO = simulatedPaths.raceMapDataDTO;
|
RaceMapDataDTO rcDTO = simulatedPaths.raceMapDataDTO;
|
||||||
|
|
||||||
@@ -283,10 +307,13 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
|
|
||||||
WindFieldDTO windFieldDTO = null;
|
WindFieldDTO windFieldDTO = null;
|
||||||
if (pattern != null) {
|
if (pattern != null) {
|
||||||
windFieldDTO = this.createWindFieldDTO(wf, startTime, endTime, timeStep, params); // params.isShowStreamlets2(), params.isShowLines(), params.getSeedLines());
|
windFieldDTO = this.createWindFieldDTO(wf, startTime, endTime, timeStep, params); // params.isShowStreamlets2(),
|
||||||
|
// params.isShowLines(),
|
||||||
|
// params.getSeedLines());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SimulatorResultsDTO(null, timeStep.asMillis(), 0, rcDTO, pathDTOs, windFieldDTO, simulatedPaths.notificationMessage);
|
return new SimulatorResultsDTO(0, null, timeStep.asMillis(), 0, rcDTO, pathDTOs, windFieldDTO,
|
||||||
|
simulatedPaths.notificationMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -349,20 +376,23 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
@Override
|
@Override
|
||||||
public ResponseTotalTimeDTO getTotalTime(RequestTotalTimeDTO requestData) throws ConfigurationException {
|
public ResponseTotalTimeDTO getTotalTime(RequestTotalTimeDTO requestData) throws ConfigurationException {
|
||||||
|
|
||||||
this.averageWind = requestData.useRealAverageWindSpeed ? SimulatorServiceUtils.getAverage(requestData.allPoints)
|
this.averageWind = requestData.useRealAverageWindSpeed ? SimulatorServiceUtils
|
||||||
: SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
.getAverage(requestData.allPoints) : SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
||||||
|
|
||||||
this.stepSizeMeters = SimulatorServiceUtils.knotsToMetersPerSecond(this.averageWind.getKnots()) * (requestData.stepDurationMilliseconds / 1000.);
|
this.stepSizeMeters = SimulatorServiceUtils.knotsToMetersPerSecond(this.averageWind.getKnots())
|
||||||
|
* (requestData.stepDurationMilliseconds / 1000.);
|
||||||
|
|
||||||
// List<Position> points = SimulatorServiceUtils.getIntermediatePoints2(requestData.turnPoints,
|
// List<Position> points = SimulatorServiceUtils.getIntermediatePoints2(requestData.turnPoints,
|
||||||
// this.stepSizeMeters);
|
// this.stepSizeMeters);
|
||||||
// int noOfPointsMinus1 = points.size() - 1;
|
// int noOfPointsMinus1 = points.size() - 1;
|
||||||
|
|
||||||
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this.getPolarDiagram(requestData.selection.boatClassIndex);
|
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this
|
||||||
|
.getPolarDiagram(requestData.selection.boatClassIndex);
|
||||||
PolarDiagram polarDiagram = polarDiagramAndNotificationMessage.getA();
|
PolarDiagram polarDiagram = polarDiagramAndNotificationMessage.getA();
|
||||||
String notificationMessage = polarDiagramAndNotificationMessage.getB();
|
String notificationMessage = polarDiagramAndNotificationMessage.getB();
|
||||||
|
|
||||||
SailingSimulator simulator = new SailingSimulatorImpl(new SimulationParametersImpl(null, polarDiagram, null, SailingSimulatorConstants.ModeMeasured, true, true));
|
Simulator simulator = new SimulatorImpl(new SimulationParametersImpl(null, polarDiagram, null,
|
||||||
|
null, SailingSimulatorConstants.ModeMeasured, true, true));
|
||||||
Path gpsTrack = simulator.getLegGPSTrack(SimulatorServiceUtils.toSimulatorUISelection(requestData.selection));
|
Path gpsTrack = simulator.getLegGPSTrack(SimulatorServiceUtils.toSimulatorUISelection(requestData.selection));
|
||||||
|
|
||||||
// Position startPoint = null;
|
// Position startPoint = null;
|
||||||
@@ -405,14 +435,12 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
//
|
//
|
||||||
// double totalTimeSeconds = (timepointAsMillis - courseStartPoint.timepoint) / 1000;
|
// double totalTimeSeconds = (timepointAsMillis - courseStartPoint.timepoint) / 1000;
|
||||||
//
|
//
|
||||||
double totalTimeGPSTrackSeconds = (gpsTrack.getPathPoints().get(gpsTrack.getPathPoints().size() - 1).getTimePoint().asMillis() - gpsTrack
|
double totalTimeGPSTrackSeconds = (gpsTrack.getPathPoints().get(gpsTrack.getPathPoints().size() - 1)
|
||||||
.getPathPoints().get(0).getTimePoint().asMillis()) / 1000;
|
.getTimePoint().asMillis() - gpsTrack.getPathPoints().get(0).getTimePoint().asMillis()) / 1000;
|
||||||
|
|
||||||
|
|
||||||
//while (totalTimeSeconds > totalTimeGPSTrackSeconds) {
|
|
||||||
// totalTimeSeconds *= TOTAL_TIME_SCALE_FACTOR;
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
// while (totalTimeSeconds > totalTimeGPSTrackSeconds) {
|
||||||
|
// totalTimeSeconds *= TOTAL_TIME_SCALE_FACTOR;
|
||||||
|
// }
|
||||||
|
|
||||||
long startTimePoint = requestData.allPoints.get(0).timepoint;
|
long startTimePoint = requestData.allPoints.get(0).timepoint;
|
||||||
long segmentTime = 0;
|
long segmentTime = 0;
|
||||||
@@ -425,8 +453,9 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
|
|
||||||
totalTime += segmentTime;
|
totalTime += segmentTime;
|
||||||
|
|
||||||
segmentTime = getTimeMillisecondsBetween(requestData.turnPoints.get(index), requestData.turnPoints.get(index + 1), this.stepSizeMeters,
|
segmentTime = getTimeMillisecondsBetween(requestData.turnPoints.get(index),
|
||||||
requestData.useRealAverageWindSpeed, gpsTrack, polarDiagram, startTimePoint + totalTime);
|
requestData.turnPoints.get(index + 1), this.stepSizeMeters, requestData.useRealAverageWindSpeed,
|
||||||
|
gpsTrack, polarDiagram, startTimePoint + totalTime);
|
||||||
|
|
||||||
System.out.println("Total time of segment " + segmentIndex + " = " + segmentTime + " milliseconds");
|
System.out.println("Total time of segment " + segmentIndex + " = " + segmentTime + " milliseconds");
|
||||||
}
|
}
|
||||||
@@ -437,25 +466,30 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
|
|
||||||
System.out.println("TotalTimeGPS: " + totalTimeGPSTrackSeconds + " TotalTimePoly: " + totalTimeSeconds);
|
System.out.println("TotalTimeGPS: " + totalTimeGPSTrackSeconds + " TotalTimePoly: " + totalTimeSeconds);
|
||||||
|
|
||||||
return new ResponseTotalTimeDTO(totalTimeSeconds, totalTimeSeconds/totalTimeGPSTrackSeconds, notificationMessage);
|
return new ResponseTotalTimeDTO(totalTimeSeconds, totalTimeSeconds / totalTimeGPSTrackSeconds,
|
||||||
|
notificationMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Override
|
// @Override
|
||||||
public ResponseTotalTimeDTO getTotalTimeOld(RequestTotalTimeDTO requestData) throws ConfigurationException {
|
public ResponseTotalTimeDTO getTotalTimeOld(RequestTotalTimeDTO requestData) throws ConfigurationException {
|
||||||
|
|
||||||
this.averageWind = requestData.useRealAverageWindSpeed ? SimulatorServiceUtils.getAverage(requestData.allPoints)
|
this.averageWind = requestData.useRealAverageWindSpeed ? SimulatorServiceUtils
|
||||||
: SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
.getAverage(requestData.allPoints) : SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
||||||
|
|
||||||
this.stepSizeMeters = SimulatorServiceUtils.knotsToMetersPerSecond(this.averageWind.getKnots()) * (requestData.stepDurationMilliseconds / 1000.);
|
this.stepSizeMeters = SimulatorServiceUtils.knotsToMetersPerSecond(this.averageWind.getKnots())
|
||||||
|
* (requestData.stepDurationMilliseconds / 1000.);
|
||||||
|
|
||||||
List<Position> points = SimulatorServiceUtils.getIntermediatePoints2(requestData.turnPoints, this.stepSizeMeters);
|
List<Position> points = SimulatorServiceUtils.getIntermediatePoints2(requestData.turnPoints,
|
||||||
|
this.stepSizeMeters);
|
||||||
int noOfPointsMinus1 = points.size() - 1;
|
int noOfPointsMinus1 = points.size() - 1;
|
||||||
|
|
||||||
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this.getPolarDiagram(requestData.selection.boatClassIndex);
|
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this
|
||||||
|
.getPolarDiagram(requestData.selection.boatClassIndex);
|
||||||
PolarDiagram polarDiagram = polarDiagramAndNotificationMessage.getA();
|
PolarDiagram polarDiagram = polarDiagramAndNotificationMessage.getA();
|
||||||
String notificationMessage = polarDiagramAndNotificationMessage.getB();
|
String notificationMessage = polarDiagramAndNotificationMessage.getB();
|
||||||
|
|
||||||
SailingSimulator simulator = new SailingSimulatorImpl(new SimulationParametersImpl(null, polarDiagram, null, SailingSimulatorConstants.ModeMeasured, true, true));
|
Simulator simulator = new SimulatorImpl(new SimulationParametersImpl(null, polarDiagram, null,
|
||||||
|
null, SailingSimulatorConstants.ModeMeasured, true, true));
|
||||||
Path gpsTrack = simulator.getLegGPSTrack(SimulatorServiceUtils.toSimulatorUISelection(requestData.selection));
|
Path gpsTrack = simulator.getLegGPSTrack(SimulatorServiceUtils.toSimulatorUISelection(requestData.selection));
|
||||||
|
|
||||||
Position startPoint = null;
|
Position startPoint = null;
|
||||||
@@ -476,17 +510,18 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
endPoint = points.get(index + 1);
|
endPoint = points.get(index + 1);
|
||||||
distanceMeters = startPoint.getDistance(endPoint).getMeters();
|
distanceMeters = startPoint.getDistance(endPoint).getMeters();
|
||||||
|
|
||||||
windAtTimePoint = requestData.useRealAverageWindSpeed ? SimulatorServiceUtils.getWindAtTimepoint(timepointAsMillis, gpsTrack)
|
windAtTimePoint = requestData.useRealAverageWindSpeed ? SimulatorServiceUtils.getWindAtTimepoint(
|
||||||
: SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
timepointAsMillis, gpsTrack) : SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
||||||
|
|
||||||
boatBearingDeg = SimulatorServiceUtils.getInitialBearing(startPoint, endPoint);
|
boatBearingDeg = SimulatorServiceUtils.getInitialBearing(startPoint, endPoint);
|
||||||
polarDiagram.setWind(windAtTimePoint);
|
polarDiagram.setWind(windAtTimePoint);
|
||||||
boatSpeedMetersPerSecond = polarDiagram.getSpeedAtBearing(new DegreeBearingImpl(boatBearingDeg)).getMetersPerSecond();
|
boatSpeedMetersPerSecond = polarDiagram.getSpeedAtBearing(new DegreeBearingImpl(boatBearingDeg))
|
||||||
|
.getMetersPerSecond();
|
||||||
stepTimeMilliseconds = (long) ((distanceMeters / boatSpeedMetersPerSecond) * 1000);
|
stepTimeMilliseconds = (long) ((distanceMeters / boatSpeedMetersPerSecond) * 1000);
|
||||||
//problem right here
|
// problem right here
|
||||||
//boatSpeed might be 0 for very small distances
|
// boatSpeed might be 0 for very small distances
|
||||||
//this is a rough fix
|
// this is a rough fix
|
||||||
if(boatSpeedMetersPerSecond == 0.0) {
|
if (boatSpeedMetersPerSecond == 0.0) {
|
||||||
stepTimeMilliseconds = 1000;
|
stepTimeMilliseconds = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,23 +531,23 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
|
|
||||||
double totalTimeSeconds = (timepointAsMillis - requestData.allPoints.get(0).timepoint) / 1000;
|
double totalTimeSeconds = (timepointAsMillis - requestData.allPoints.get(0).timepoint) / 1000;
|
||||||
|
|
||||||
double totalTimeGPSTrackSeconds = (gpsTrack.getPathPoints().get(gpsTrack.getPathPoints().size() - 1).getTimePoint().asMillis() - gpsTrack
|
double totalTimeGPSTrackSeconds = (gpsTrack.getPathPoints().get(gpsTrack.getPathPoints().size() - 1)
|
||||||
.getPathPoints().get(0).getTimePoint().asMillis()) / 1000;
|
.getTimePoint().asMillis() - gpsTrack.getPathPoints().get(0).getTimePoint().asMillis()) / 1000;
|
||||||
|
|
||||||
|
// while (totalTimeSeconds > totalTimeGPSTrackSeconds) {
|
||||||
|
// totalTimeSeconds *= TOTAL_TIME_SCALE_FACTOR;
|
||||||
|
// }
|
||||||
|
System.out.println("TotalTimeGPS: " + totalTimeGPSTrackSeconds + " TotalTimePoly: " + totalTimeSeconds);
|
||||||
|
|
||||||
//while (totalTimeSeconds > totalTimeGPSTrackSeconds) {
|
return new ResponseTotalTimeDTO((long) totalTimeSeconds, (double) totalTimeSeconds
|
||||||
// totalTimeSeconds *= TOTAL_TIME_SCALE_FACTOR;
|
/ (double) totalTimeGPSTrackSeconds, notificationMessage);
|
||||||
//}
|
|
||||||
System.out.println("TotalTimeGPS: "+totalTimeGPSTrackSeconds+" TotalTimePoly: "+totalTimeSeconds);
|
|
||||||
|
|
||||||
return new ResponseTotalTimeDTO((long) totalTimeSeconds, (double)totalTimeSeconds/(double)totalTimeGPSTrackSeconds, notificationMessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response1TurnerDTO get1Turner(Request1TurnerDTO requestData) throws ConfigurationException {
|
public Response1TurnerDTO get1Turner(Request1TurnerDTO requestData) throws ConfigurationException {
|
||||||
|
|
||||||
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this.getPolarDiagram(requestData.selection.boatClassIndex);
|
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this
|
||||||
|
.getPolarDiagram(requestData.selection.boatClassIndex);
|
||||||
PolarDiagram polarDiagram = polarDiagramAndNotificationMessage.getA();
|
PolarDiagram polarDiagram = polarDiagramAndNotificationMessage.getA();
|
||||||
String notificationMessage = polarDiagramAndNotificationMessage.getB();
|
String notificationMessage = polarDiagramAndNotificationMessage.getB();
|
||||||
|
|
||||||
@@ -522,16 +557,19 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
Position oldMovedPosition = requestData.oldMovedPoint;
|
Position oldMovedPosition = requestData.oldMovedPoint;
|
||||||
Position newMovedPosition = requestData.newMovedPoint;
|
Position newMovedPosition = requestData.newMovedPoint;
|
||||||
Bearing oldMovedToNewMovedBearing = oldMovedPosition.getBearingGreatCircle(newMovedPosition);
|
Bearing oldMovedToNewMovedBearing = oldMovedPosition.getBearingGreatCircle(newMovedPosition);
|
||||||
boolean areTowardsSameDirection = SimulatorServiceUtils.areTowardsSameDirection(oldMovedToNewMovedBearing, new DegreeBearingImpl(
|
boolean areTowardsSameDirection = SimulatorServiceUtils.areTowardsSameDirection(oldMovedToNewMovedBearing,
|
||||||
requestData.startToEndBearingDegrees));
|
new DegreeBearingImpl(requestData.startToEndBearingDegrees));
|
||||||
|
|
||||||
System.out.println("oldMovedToNewMovedBearing = " + oldMovedToNewMovedBearing.getDegrees() + " degrees");
|
System.out.println("oldMovedToNewMovedBearing = " + oldMovedToNewMovedBearing.getDegrees() + " degrees");
|
||||||
System.out.println("requestData.startToEndBearingDegrees = " + requestData.startToEndBearingDegrees + " degrees");
|
System.out.println("requestData.startToEndBearingDegrees = " + requestData.startToEndBearingDegrees
|
||||||
|
+ " degrees");
|
||||||
System.out.println("areTowardsSameDirection = " + areTowardsSameDirection);
|
System.out.println("areTowardsSameDirection = " + areTowardsSameDirection);
|
||||||
|
|
||||||
SimulationParameters simulationParameters = new SimulationParametersImpl(null, polarDiagram, null, SailingSimulatorConstants.ModeMeasured, true, true);
|
SimulationParameters simulationParameters = new SimulationParametersImpl(null, polarDiagram, null, null,
|
||||||
SailingSimulator sailingSimulator = new SailingSimulatorImpl(simulationParameters);
|
SailingSimulatorConstants.ModeMeasured, true, true);
|
||||||
Path gpsWind = sailingSimulator.getLegGPSTrack(SimulatorServiceUtils.toSimulatorUISelection(requestData.selection));
|
Simulator sailingSimulator = new SimulatorImpl(simulationParameters);
|
||||||
|
Path gpsWind = sailingSimulator.getLegGPSTrack(SimulatorServiceUtils
|
||||||
|
.toSimulatorUISelection(requestData.selection));
|
||||||
|
|
||||||
Grid grid = new CurvedGrid(oldMovedPosition, newMovedPosition);
|
Grid grid = new CurvedGrid(oldMovedPosition, newMovedPosition);
|
||||||
this.controlParameters.baseWindBearing += grid.getSouth().getDegrees();
|
this.controlParameters.baseWindBearing += grid.getSouth().getDegrees();
|
||||||
@@ -548,8 +586,10 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
Position realStart = areTowardsSameDirection ? oldMovedPosition : newMovedPosition;
|
Position realStart = areTowardsSameDirection ? oldMovedPosition : newMovedPosition;
|
||||||
Position realEnd = areTowardsSameDirection ? newMovedPosition : oldMovedPosition;
|
Position realEnd = areTowardsSameDirection ? newMovedPosition : oldMovedPosition;
|
||||||
|
|
||||||
leftSide1Turner = pathGenerator.get1Turner(windFieldGenerator, polarDiagram, realStart, realEnd, startTime, true, DEFAULT_STEP_MAX, DEFAULT_TIMESTEP);
|
leftSide1Turner = pathGenerator.get1Turner(windFieldGenerator, polarDiagram, realStart, realEnd, startTime,
|
||||||
rightSide1Turner = pathGenerator.get1Turner(windFieldGenerator, polarDiagram, realStart, realEnd, startTime, false, DEFAULT_STEP_MAX, DEFAULT_TIMESTEP);
|
true, DEFAULT_STEP_MAX, DEFAULT_TIMESTEP);
|
||||||
|
rightSide1Turner = pathGenerator.get1Turner(windFieldGenerator, polarDiagram, realStart, realEnd, startTime,
|
||||||
|
false, DEFAULT_STEP_MAX, DEFAULT_TIMESTEP);
|
||||||
|
|
||||||
boolean isLeftSide1TurnerOnTheInside = SimulatorServiceUtils.isPointInsideTriangle(leftSide1Turner.getPosition(),
|
boolean isLeftSide1TurnerOnTheInside = SimulatorServiceUtils.isPointInsideTriangle(leftSide1Turner.getPosition(),
|
||||||
requestData.beforeMovedPoint,
|
requestData.beforeMovedPoint,
|
||||||
@@ -579,8 +619,7 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
} else if (SimulatorServiceUtils.equals(rightSide1Turner.getPosition(), newMovedPosition, 0.0001)) {
|
} else if (SimulatorServiceUtils.equals(rightSide1Turner.getPosition(), newMovedPosition, 0.0001)) {
|
||||||
System.out.println("voi folosi endPosition = rightSide1Turner!");
|
System.out.println("voi folosi endPosition = rightSide1Turner!");
|
||||||
correct1Turner = rightSide1Turner;
|
correct1Turner = rightSide1Turner;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
System.out.println("nu ar trebui sa ajunga aici NICIODATA!");
|
System.out.println("nu ar trebui sa ajunga aici NICIODATA!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -588,11 +627,8 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
long timeStepMilliseconds = 2000;
|
long timeStepMilliseconds = 2000;
|
||||||
double minimumDistanceMeters = 4.0;
|
double minimumDistanceMeters = 4.0;
|
||||||
|
|
||||||
List<TimedPositionWithSpeed> path = pathGenerator.getIntersectionOptimalTowardWind(windFieldGenerator, polarDiagram, edgeStart, edgeEnd,
|
List<TimedPositionWithSpeed> path = pathGenerator.getIntersectionOptimalTowardWind(windFieldGenerator,
|
||||||
correct1Turner,
|
polarDiagram, edgeStart, edgeEnd, correct1Turner, true, timeStepMilliseconds, minimumDistanceMeters);
|
||||||
true,
|
|
||||||
timeStepMilliseconds, minimumDistanceMeters);
|
|
||||||
|
|
||||||
|
|
||||||
return new Response1TurnerDTO(SimulatorServiceUtils.toSimulatorWindDTOList(path), SimulatorServiceUtils.toSimulatorWindDTO(leftSide1Turner),
|
return new Response1TurnerDTO(SimulatorServiceUtils.toSimulatorWindDTOList(path), SimulatorServiceUtils.toSimulatorWindDTO(leftSide1Turner),
|
||||||
SimulatorServiceUtils.toSimulatorWindDTO(rightSide1Turner), oldMovedPosition,
|
SimulatorServiceUtils.toSimulatorWindDTO(rightSide1Turner), oldMovedPosition,
|
||||||
@@ -607,7 +643,8 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
selectedRaceIndex = 0;
|
selectedRaceIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SailingSimulator simulator = new SailingSimulatorImpl(new SimulationParametersImpl(null, null, null, SailingSimulatorConstants.ModeMeasured, true, true));
|
Simulator simulator = new SimulatorImpl(new SimulationParametersImpl(null, null, null, null,
|
||||||
|
SailingSimulatorConstants.ModeMeasured, true, true));
|
||||||
|
|
||||||
return simulator.getLegsNames(selectedRaceIndex);
|
return simulator.getLegsNames(selectedRaceIndex);
|
||||||
}
|
}
|
||||||
@@ -615,7 +652,8 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
@Override
|
@Override
|
||||||
public List<String> getRacesNames() {
|
public List<String> getRacesNames() {
|
||||||
|
|
||||||
SailingSimulator simulator = new SailingSimulatorImpl(new SimulationParametersImpl(null, null, null, SailingSimulatorConstants.ModeMeasured, true, true));
|
Simulator simulator = new SimulatorImpl(new SimulationParametersImpl(null, null, null, null,
|
||||||
|
SailingSimulatorConstants.ModeMeasured, true, true));
|
||||||
|
|
||||||
return simulator.getRacesNames();
|
return simulator.getRacesNames();
|
||||||
}
|
}
|
||||||
@@ -627,9 +665,10 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
selectedRaceIndex = 0;
|
selectedRaceIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SailingSimulator simulator = new SailingSimulatorImpl(new SimulationParametersImpl(null, null, null, SailingSimulatorConstants.ModeMeasured,true, true));
|
Simulator simulator = new SimulatorImpl(new SimulationParametersImpl(null, null, null, null,
|
||||||
|
SailingSimulatorConstants.ModeMeasured, true, true));
|
||||||
|
|
||||||
return simulator.getComeptitorsNames(selectedRaceIndex);
|
return simulator.getCompetitorsNames(selectedRaceIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void retreiveWindControlParameters(WindPatternDisplay pattern) {
|
private void retreiveWindControlParameters(WindPatternDisplay pattern) {
|
||||||
@@ -687,11 +726,11 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
|
|
||||||
SimulatorWindDTO result = new SimulatorWindDTO();
|
SimulatorWindDTO result = new SimulatorWindDTO();
|
||||||
if (speedWithBearing == null) {
|
if (speedWithBearing == null) {
|
||||||
result.trueWindBearingDeg = 0.0;
|
result.trueWindBearingDeg = 0.0;
|
||||||
result.trueWindSpeedInKnots = 0.0;
|
result.trueWindSpeedInKnots = 0.0;
|
||||||
} else {
|
} else {
|
||||||
result.trueWindBearingDeg = speedWithBearing.getBearing().getDegrees();
|
result.trueWindBearingDeg = speedWithBearing.getBearing().getDegrees();
|
||||||
result.trueWindSpeedInKnots = speedWithBearing.getKnots();
|
result.trueWindSpeedInKnots = speedWithBearing.getKnots();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (position != null) {
|
if (position != null) {
|
||||||
@@ -779,9 +818,9 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO: throws null pointer exception for when reading serialized paths.
|
// TODO: throws null pointer exception for when reading serialized paths.
|
||||||
//TODO: should windlines also be serialized?
|
// TODO: should windlines also be serialized?
|
||||||
//logger.info("Added : " + windFieldDTO.getWindLinesDTO().getWindLinesMap().size() + " wind lines");
|
// logger.info("Added : " + windFieldDTO.getWindLinesDTO().getWindLinesMap().size() + " wind lines");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getWindLinesFromEndLine(WindFieldGenerator wf, WindFieldDTO windFieldDTO, TimePoint startTime,
|
private void getWindLinesFromEndLine(WindFieldGenerator wf, WindFieldDTO windFieldDTO, TimePoint startTime,
|
||||||
@@ -850,22 +889,49 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SimulatedPathsEvenTimedResultDTO getSimulatedPathsEvenTimed(List<Position> course, WindFieldGenerator wf, char mode,
|
private SimulatedPathsEvenTimedResultDTO getSimulatedPathsEvenTimed(List<Position> course, WindFieldGenerator wf,
|
||||||
SimulatorUISelectionDTO selection, boolean showOmniscient, boolean showOpportunist) throws ConfigurationException {
|
char mode, SimulatorUISelectionDTO selection, boolean showOmniscient, boolean showOpportunist)
|
||||||
|
throws ConfigurationException {
|
||||||
LOGGER.info("Retrieving simulated paths");
|
LOGGER.info("Retrieving simulated paths");
|
||||||
|
|
||||||
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this.getPolarDiagram(selection.boatClassIndex);
|
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this.getPolarDiagram(selection.boatClassIndex);
|
||||||
PolarDiagram pd = polarDiagramAndNotificationMessage.getA();
|
PolarDiagram pd = polarDiagramAndNotificationMessage.getA();
|
||||||
|
int[] gridRes = wf.getGridResolution();
|
||||||
SimulationParameters sp = new SimulationParametersImpl(course, pd, wf, mode, showOmniscient, showOpportunist);
|
Position[] gridArea = wf.getGridAreaGps();
|
||||||
SailingSimulator simulator = new SailingSimulatorImpl(sp);
|
LOGGER.info("showOmniscient : "+showOmniscient);
|
||||||
|
LOGGER.info("showOpportunist: "+showOpportunist);
|
||||||
Map<String, Path> pathsAndNames = null;
|
if (gridArea != null) {
|
||||||
|
// initialize grid of supporting location for windfield
|
||||||
pathsAndNames = simulator.getAllPathsEvenTimed(wf.getTimeStep().asMillis(),
|
Grid bd = new CurvedGrid(gridArea[0], gridArea[1]);
|
||||||
(mode == SailingSimulatorConstants.ModeMeasured) ? SimulatorServiceUtils.toSimulatorUISelection(selection) : null);
|
// set base wind bearing
|
||||||
|
wf.getWindParameters().baseWindBearing += bd.getSouth().getDegrees();
|
||||||
|
LOGGER.info("base wind: " + pd.getWind().getKnots() + " kn, "
|
||||||
|
+ ((wf.getWindParameters().baseWindBearing) % 360.0) + "\u00B0");
|
||||||
|
// set water current
|
||||||
|
SpeedWithBearing current = new KnotSpeedWithBearingImpl(wf.getWindParameters().curSpeed, new DegreeBearingImpl(wf.getWindParameters().curBearing));
|
||||||
|
if (wf.getWindParameters().curSpeed > 0) {
|
||||||
|
pd.initializeSOGwithCurrent(); // polar-diagram is extended with data to support water currents
|
||||||
|
}
|
||||||
|
pd.setCurrent(current);
|
||||||
|
if (pd.getCurrent() != null) {
|
||||||
|
LOGGER.info("water current: " + pd.getCurrent().getKnots() + " kn, "
|
||||||
|
+ pd.getCurrent().getBearing().getDegrees() + "\u00B0");
|
||||||
|
}
|
||||||
|
wf.setBoundary(bd);
|
||||||
|
Position[][] positionGrid = bd.generatePositions(gridRes[0], gridRes[1], gridRes[2], gridRes[3]);
|
||||||
|
wf.setPositionGrid(positionGrid);
|
||||||
|
wf.generate(wf.getStartTime(), wf.getEndTime(), wf.getTimeStep());
|
||||||
|
}
|
||||||
|
SimulationParameters sp = new SimulationParametersImpl(course, pd, wf, null, mode, showOmniscient, showOpportunist);
|
||||||
|
Map<PathType, Path> pathsAndNames = null;
|
||||||
|
try {
|
||||||
|
pathsAndNames = simulationService.getAllPathsEvenTimed(sp, wf.getTimeStep().asMillis());
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
int noOfPaths = pathsAndNames.size();
|
int noOfPaths = pathsAndNames.size();
|
||||||
if (mode == SailingSimulatorConstants.ModeMeasured) {
|
if (mode == SailingSimulatorConstants.ModeMeasured) {
|
||||||
noOfPaths++; // the last path is the polyline
|
noOfPaths++; // the last path is the polyline
|
||||||
@@ -878,20 +944,21 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
pathDTOs[0] = this.getPolylinePathDTO(pathsAndNames.get("6#GPS Poly"), pathsAndNames.get("7#GPS Track"));
|
pathDTOs[0] = this.getPolylinePathDTO(pathsAndNames.get("6#GPS Poly"), pathsAndNames.get("7#GPS Track"));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Entry<String, Path> entry : pathsAndNames.entrySet()) {
|
for (Entry<PathType, Path> entry : pathsAndNames.entrySet()) {
|
||||||
LOGGER.info("Path " + entry.getKey());
|
LOGGER.info("Path " + entry.getKey().getTxtId());
|
||||||
|
|
||||||
// NOTE: pathName convention is: sort-digit + "#" + path-name
|
// NOTE: pathName convention is: sort-digit + "#" + path-name
|
||||||
// pathsAndNames is TreeMap which ensures sorting
|
// pathsAndNames is TreeMap which ensures sorting
|
||||||
pathDTOs[index] = new PathDTO(entry.getKey());
|
pathDTOs[index] = new PathDTO(entry.getKey().getTxtId());
|
||||||
|
|
||||||
// fill pathDTO with path points where speed is true wind speed
|
// fill pathDTO with path points where speed is true wind speed
|
||||||
List<SimulatorWindDTO> wList = new ArrayList<SimulatorWindDTO>();
|
List<SimulatorWindDTO> wList = new ArrayList<SimulatorWindDTO>();
|
||||||
for (TimedPositionWithSpeed p : entry.getValue().getPathPoints()) {
|
for (TimedPositionWithSpeed p : entry.getValue().getPathPoints()) {
|
||||||
wList.add(createSimulatorWindDTO(p));
|
wList.add(createSimulatorWindDTO(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
pathDTOs[index].setPoints(wList);
|
pathDTOs[index].setPoints(wList);
|
||||||
|
pathDTOs[index].setAlgorithmTimedOut(entry.getValue().getAlgorithmTimedOut());
|
||||||
|
pathDTOs[index].setMixedLeg(entry.getValue().getMixedLeg());
|
||||||
|
|
||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
@@ -901,9 +968,8 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
rcDTO = new RaceMapDataDTO();
|
rcDTO = new RaceMapDataDTO();
|
||||||
rcDTO.coursePositions = new CoursePositionsDTO();
|
rcDTO.coursePositions = new CoursePositionsDTO();
|
||||||
rcDTO.coursePositions.waypointPositions = new ArrayList<>();
|
rcDTO.coursePositions.waypointPositions = new ArrayList<>();
|
||||||
Path rc = simulator.getRaceCourse();
|
rcDTO.coursePositions.waypointPositions.add(course.get(0));
|
||||||
rcDTO.coursePositions.waypointPositions.add(rc.getPathPoints().get(0).getPosition());
|
rcDTO.coursePositions.waypointPositions.add(course.get(1));
|
||||||
rcDTO.coursePositions.waypointPositions.add(rc.getPathPoints().get(1).getPosition());
|
|
||||||
} else {
|
} else {
|
||||||
rcDTO = null;
|
rcDTO = null;
|
||||||
}
|
}
|
||||||
@@ -963,7 +1029,7 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
|
|
||||||
List<TimedPositionWithSpeed> polylinePoints = gpsTrackPoints.subList(startPointIndex, endPointIndex + 1);
|
List<TimedPositionWithSpeed> polylinePoints = gpsTrackPoints.subList(startPointIndex, endPointIndex + 1);
|
||||||
|
|
||||||
List<TimedPositionWithSpeed> turns = (new PathImpl(polylinePoints, null)).getTurns();
|
List<TimedPositionWithSpeed> turns = (new PathImpl(polylinePoints, null, false /* algorithmTimedOut */, false /* mixedLeg */)).getTurns();
|
||||||
// PathImpl.saveToGpxFile(new PathImpl(turns, null), "C:\\gps_path_turns_20deg_not_even_timed.gpx");
|
// PathImpl.saveToGpxFile(new PathImpl(turns, null), "C:\\gps_path_turns_20deg_not_even_timed.gpx");
|
||||||
|
|
||||||
List<SimulatorWindDTO> points = new ArrayList<SimulatorWindDTO>();
|
List<SimulatorWindDTO> points = new ArrayList<SimulatorWindDTO>();
|
||||||
@@ -977,8 +1043,10 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
isTurn = false;
|
isTurn = false;
|
||||||
|
|
||||||
for (TimedPositionWithSpeed turn : turns) {
|
for (TimedPositionWithSpeed turn : turns) {
|
||||||
if (turn.getPosition().getLatDeg() == point.getPosition().getLatDeg() && turn.getPosition().getLngDeg() == point.getPosition().getLngDeg()
|
if (turn.getPosition().getLatDeg() == point.getPosition().getLatDeg()
|
||||||
&& turn.getTimePoint().asMillis() == point.getTimePoint().asMillis() && turn.getSpeed().getKnots() == point.getSpeed().getKnots()
|
&& turn.getPosition().getLngDeg() == point.getPosition().getLngDeg()
|
||||||
|
&& turn.getTimePoint().asMillis() == point.getTimePoint().asMillis()
|
||||||
|
&& turn.getSpeed().getKnots() == point.getSpeed().getKnots()
|
||||||
&& turn.getSpeed().getBearing().getDegrees() == point.getSpeed().getBearing().getDegrees()) {
|
&& turn.getSpeed().getBearing().getDegrees() == point.getSpeed().getBearing().getDegrees()) {
|
||||||
isTurn = true;
|
isTurn = true;
|
||||||
break;
|
break;
|
||||||
@@ -989,12 +1057,12 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
position = point.getPosition();
|
position = point.getPosition();
|
||||||
|
|
||||||
points.add(new SimulatorWindDTO(position.getLatDeg(), position.getLngDeg(), speedWithBearing.getKnots(),
|
points.add(new SimulatorWindDTO(position.getLatDeg(), position.getLngDeg(), speedWithBearing.getKnots(),
|
||||||
speedWithBearing.getBearing()
|
speedWithBearing.getBearing().getDegrees(), point.getTimePoint().asMillis(), isTurn));
|
||||||
.getDegrees(), point.getTimePoint().asMillis(), isTurn));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PathDTO result = new PathDTO(POLYLINE_PATH_NAME);
|
PathDTO result = new PathDTO(POLYLINE_PATH_NAME);
|
||||||
result.setPoints(points);
|
result.setPoints(points);
|
||||||
|
result.setAlgorithmTimedOut(false);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1081,17 +1149,18 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
|||||||
endPoint = points.get(index + 1);
|
endPoint = points.get(index + 1);
|
||||||
distanceMeters = startPoint.getDistance(endPoint).getMeters();
|
distanceMeters = startPoint.getDistance(endPoint).getMeters();
|
||||||
|
|
||||||
windAtTimePoint = useRealAverageWindSpeed ? SimulatorServiceUtils.getWindAtTimepoint(timepointAsMillis, gpsTrack)
|
windAtTimePoint = useRealAverageWindSpeed ? SimulatorServiceUtils.getWindAtTimepoint(timepointAsMillis,
|
||||||
: SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
gpsTrack) : SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
||||||
|
|
||||||
boatBearingDeg = SimulatorServiceUtils.getInitialBearing(startPoint, endPoint);
|
boatBearingDeg = SimulatorServiceUtils.getInitialBearing(startPoint, endPoint);
|
||||||
polarDiagram.setWind(windAtTimePoint);
|
polarDiagram.setWind(windAtTimePoint);
|
||||||
boatSpeedMetersPerSecond = polarDiagram.getSpeedAtBearing(new DegreeBearingImpl(boatBearingDeg)).getMetersPerSecond();
|
boatSpeedMetersPerSecond = polarDiagram.getSpeedAtBearing(new DegreeBearingImpl(boatBearingDeg))
|
||||||
|
.getMetersPerSecond();
|
||||||
stepTimeMilliseconds = (long) ((distanceMeters / boatSpeedMetersPerSecond) * 1000);
|
stepTimeMilliseconds = (long) ((distanceMeters / boatSpeedMetersPerSecond) * 1000);
|
||||||
|
|
||||||
// problem right here: boatSpeed might be 0 for very small distances
|
// problem right here: boatSpeed might be 0 for very small distances
|
||||||
// this is a rough fix
|
// this is a rough fix
|
||||||
if(boatSpeedMetersPerSecond == 0.0) {
|
if (boatSpeedMetersPerSecond == 0.0) {
|
||||||
stepTimeMilliseconds = 1000;
|
stepTimeMilliseconds = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -25,11 +25,12 @@ public class CompactRaceMapDataDTO implements IsSerializable {
|
|||||||
private CoursePositionsDTO coursePositions;
|
private CoursePositionsDTO coursePositions;
|
||||||
private List<SidelineDTO> courseSidelines;
|
private List<SidelineDTO> courseSidelines;
|
||||||
private List<CompactQuickRankDTO> quickRanks;
|
private List<CompactQuickRankDTO> quickRanks;
|
||||||
|
private int simulationResultVersion;
|
||||||
|
|
||||||
CompactRaceMapDataDTO() {}
|
CompactRaceMapDataDTO() {}
|
||||||
|
|
||||||
public CompactRaceMapDataDTO(Map<CompetitorDTO, List<GPSFixDTO>> boatPositions, CoursePositionsDTO coursePositions,
|
public CompactRaceMapDataDTO(Map<CompetitorDTO, List<GPSFixDTO>> boatPositions, CoursePositionsDTO coursePositions,
|
||||||
List<SidelineDTO> courseSidelines, List<QuickRankDTO> quickRanks) {
|
List<SidelineDTO> courseSidelines, List<QuickRankDTO> quickRanks, int simulationResultVersion) {
|
||||||
this.boatPositionsByCompetitorIdAsString = new HashMap<String, List<GPSFixDTO>>();
|
this.boatPositionsByCompetitorIdAsString = new HashMap<String, List<GPSFixDTO>>();
|
||||||
for (Map.Entry<CompetitorDTO, List<GPSFixDTO>> e : boatPositions.entrySet()) {
|
for (Map.Entry<CompetitorDTO, List<GPSFixDTO>> e : boatPositions.entrySet()) {
|
||||||
this.boatPositionsByCompetitorIdAsString.put(e.getKey().getIdAsString(), e.getValue());
|
this.boatPositionsByCompetitorIdAsString.put(e.getKey().getIdAsString(), e.getValue());
|
||||||
@@ -43,6 +44,7 @@ public class CompactRaceMapDataDTO implements IsSerializable {
|
|||||||
}
|
}
|
||||||
this.courseSidelines = courseSidelines;
|
this.courseSidelines = courseSidelines;
|
||||||
this.coursePositions = coursePositions;
|
this.coursePositions = coursePositions;
|
||||||
|
this.simulationResultVersion = simulationResultVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RaceMapDataDTO getRaceMapDataDTO(Iterable<CompetitorDTO> competitors) {
|
public RaceMapDataDTO getRaceMapDataDTO(Iterable<CompetitorDTO> competitors) {
|
||||||
@@ -68,6 +70,7 @@ public class CompactRaceMapDataDTO implements IsSerializable {
|
|||||||
result.boatPositions.put(competitor, e.getValue());
|
result.boatPositions.put(competitor, e.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
result.simulationResultVersion = simulationResultVersion;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
@@ -13,6 +13,9 @@ public class CoursePositionsDTO implements IsSerializable {
|
|||||||
public List<Position> finishMarkPositions;
|
public List<Position> finishMarkPositions;
|
||||||
public Set<MarkDTO> marks;
|
public Set<MarkDTO> marks;
|
||||||
|
|
||||||
|
public int totalLegsCount;
|
||||||
|
public int currentLegNumber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>null</code> if the start waypoint does not have exactly two marks with valid positions; in this case,
|
* <code>null</code> if the start waypoint does not have exactly two marks with valid positions; in this case,
|
||||||
* {@link #startLineAdvantageousSide}, {@link #startLineAdvantageInMeters} and {@link #startLineLengthInMeters} are
|
* {@link #startLineAdvantageousSide}, {@link #startLineAdvantageInMeters} and {@link #startLineLengthInMeters} are
|
||||||
|
|||||||
+6
-1
@@ -22,7 +22,11 @@ public class DeviceConfigurationDTO implements IsSerializable {
|
|||||||
public static class ESSConfigurationDTO extends RacingProcedureConfigurationDTO {
|
public static class ESSConfigurationDTO extends RacingProcedureConfigurationDTO {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class LeagueConfigurationDTO extends RacingProcedureConfigurationDTO {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static class RacingProcedureConfigurationDTO implements IsSerializable {
|
public static class RacingProcedureConfigurationDTO implements IsSerializable {
|
||||||
public Flags classFlag;
|
public Flags classFlag;
|
||||||
public Boolean hasInidividualRecall;
|
public Boolean hasInidividualRecall;
|
||||||
@@ -34,6 +38,7 @@ public class DeviceConfigurationDTO implements IsSerializable {
|
|||||||
public GateStartConfigurationDTO gateStartConfiguration;
|
public GateStartConfigurationDTO gateStartConfiguration;
|
||||||
public ESSConfigurationDTO essConfiguration;
|
public ESSConfigurationDTO essConfiguration;
|
||||||
public RacingProcedureConfigurationDTO basicConfiguration;
|
public RacingProcedureConfigurationDTO basicConfiguration;
|
||||||
|
public LeagueConfigurationDTO leagueConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> allowedCourseAreaNames;
|
public List<String> allowedCourseAreaNames;
|
||||||
|
|||||||
+18
-1
@@ -7,9 +7,10 @@ import com.sap.sailing.domain.common.dto.NamedDTO;
|
|||||||
public class PathDTO extends NamedDTO {
|
public class PathDTO extends NamedDTO {
|
||||||
private static final long serialVersionUID = 2381814072763342186L;
|
private static final long serialVersionUID = 2381814072763342186L;
|
||||||
private List<SimulatorWindDTO> points;
|
private List<SimulatorWindDTO> points;
|
||||||
|
private boolean algorithmTimedOut;
|
||||||
|
private boolean mixedLeg;
|
||||||
|
|
||||||
public PathDTO() {
|
public PathDTO() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PathDTO(final String name) {
|
public PathDTO(final String name) {
|
||||||
@@ -31,5 +32,21 @@ public class PathDTO extends NamedDTO {
|
|||||||
|
|
||||||
return points.get(points.size() - 1).timepoint - points.get(0).timepoint;
|
return points.get(points.size() - 1).timepoint - points.get(0).timepoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getAlgorithmTimedOut() {
|
||||||
|
return this.algorithmTimedOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlgorithmTimedOut(boolean algorithmTimedOut) {
|
||||||
|
this.algorithmTimedOut = algorithmTimedOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getMixedLeg() {
|
||||||
|
return this.mixedLeg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMixedLeg(boolean mixedLeg) {
|
||||||
|
this.mixedLeg = mixedLeg;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
@@ -12,4 +12,5 @@ public class RaceMapDataDTO implements IsSerializable {
|
|||||||
public CoursePositionsDTO coursePositions;
|
public CoursePositionsDTO coursePositions;
|
||||||
public List<SidelineDTO> courseSidelines;
|
public List<SidelineDTO> courseSidelines;
|
||||||
public LinkedHashMap<CompetitorDTO, QuickRankDTO> quickRanks;
|
public LinkedHashMap<CompetitorDTO, QuickRankDTO> quickRanks;
|
||||||
|
public int simulationResultVersion;
|
||||||
}
|
}
|
||||||
+12
-1
@@ -6,6 +6,7 @@ import com.google.gwt.user.client.rpc.IsSerializable;
|
|||||||
|
|
||||||
public class SimulatorResultsDTO implements IsSerializable {
|
public class SimulatorResultsDTO implements IsSerializable {
|
||||||
|
|
||||||
|
private int version;
|
||||||
private Date startTime;
|
private Date startTime;
|
||||||
private long timeStep;
|
private long timeStep;
|
||||||
private long legDuration;
|
private long legDuration;
|
||||||
@@ -15,6 +16,7 @@ public class SimulatorResultsDTO implements IsSerializable {
|
|||||||
private String notificationMessage;
|
private String notificationMessage;
|
||||||
|
|
||||||
public SimulatorResultsDTO(){
|
public SimulatorResultsDTO(){
|
||||||
|
this.version = 0;
|
||||||
this.startTime = null;
|
this.startTime = null;
|
||||||
this.timeStep = 0;
|
this.timeStep = 0;
|
||||||
this.legDuration = 0;
|
this.legDuration = 0;
|
||||||
@@ -24,7 +26,8 @@ public class SimulatorResultsDTO implements IsSerializable {
|
|||||||
this.notificationMessage = "";
|
this.notificationMessage = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimulatorResultsDTO(final Date startTime, final long timeStep, final long legDuration, final RaceMapDataDTO raceCourse, final PathDTO[] paths, final WindFieldDTO windField, final String notificationMessage) {
|
public SimulatorResultsDTO(final int version, final Date startTime, final long timeStep, final long legDuration, final RaceMapDataDTO raceCourse, final PathDTO[] paths, final WindFieldDTO windField, final String notificationMessage) {
|
||||||
|
this.version = version;
|
||||||
this.startTime = startTime;
|
this.startTime = startTime;
|
||||||
this.timeStep = timeStep;
|
this.timeStep = timeStep;
|
||||||
this.legDuration = legDuration;
|
this.legDuration = legDuration;
|
||||||
@@ -34,6 +37,14 @@ public class SimulatorResultsDTO implements IsSerializable {
|
|||||||
this.notificationMessage = notificationMessage;
|
this.notificationMessage = notificationMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getVersion() {
|
||||||
|
return this.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(int version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
public Date getStartTime() {
|
public Date getStartTime() {
|
||||||
return this.startTime;
|
return this.startTime;
|
||||||
}
|
}
|
||||||
|
|||||||
+95
-32
@@ -14,6 +14,8 @@ import com.google.gwt.maps.client.base.Point;
|
|||||||
import com.google.gwt.maps.client.controls.ControlPosition;
|
import com.google.gwt.maps.client.controls.ControlPosition;
|
||||||
import com.google.gwt.user.client.Window;
|
import com.google.gwt.user.client.Window;
|
||||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||||
|
import com.sap.sailing.domain.common.LegIdentifier;
|
||||||
|
import com.sap.sailing.domain.common.LegIdentifierImpl;
|
||||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||||
import com.sap.sailing.gwt.ui.actions.GetSimulationAction;
|
import com.sap.sailing.gwt.ui.actions.GetSimulationAction;
|
||||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||||
@@ -40,6 +42,8 @@ public class RaceSimulationOverlay extends FullCanvasOverlay {
|
|||||||
public static final String GET_SIMULATION_CATEGORY = "getSimulation";
|
public static final String GET_SIMULATION_CATEGORY = "getSimulation";
|
||||||
private final String textColor = "Black";
|
private final String textColor = "Black";
|
||||||
private final String textFont = "10pt OpenSansRegular";
|
private final String textFont = "10pt OpenSansRegular";
|
||||||
|
private String algorithmTimedOutText = "out-of-bounds";
|
||||||
|
private String mixedLegText = "ambiguous wind";
|
||||||
private int xOffset = 0;
|
private int xOffset = 0;
|
||||||
private int yOffset = 0; //150;
|
private int yOffset = 0; //150;
|
||||||
private double rectWidth = 20;
|
private double rectWidth = 20;
|
||||||
@@ -52,7 +56,6 @@ public class RaceSimulationOverlay extends FullCanvasOverlay {
|
|||||||
private SimulatorResultsDTO simulationResult;
|
private SimulatorResultsDTO simulationResult;
|
||||||
private PathDTO racePath;
|
private PathDTO racePath;
|
||||||
private int raceLeg = 0;
|
private int raceLeg = 0;
|
||||||
private Date prevStartTime;
|
|
||||||
private Canvas simulationLegend;
|
private Canvas simulationLegend;
|
||||||
|
|
||||||
public RaceSimulationOverlay(MapWidget map, int zIndex, RegattaAndRaceIdentifier raceIdentifier, SailingServiceAsync sailingService, StringMessages stringMessages, AsyncActionsExecutor asyncActionsExecutor, CoordinateSystem coordinateSystem) {
|
public RaceSimulationOverlay(MapWidget map, int zIndex, RegattaAndRaceIdentifier raceIdentifier, SailingServiceAsync sailingService, StringMessages stringMessages, AsyncActionsExecutor asyncActionsExecutor, CoordinateSystem coordinateSystem) {
|
||||||
@@ -64,16 +67,28 @@ public class RaceSimulationOverlay extends FullCanvasOverlay {
|
|||||||
this.colors = new ColorPaletteGenerator();
|
this.colors = new ColorPaletteGenerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateLeg(int newLeg, Date newTime, boolean clearCanvas) {
|
public void updateLeg(int newLeg, boolean clearCanvas, int newVersion) {
|
||||||
if ((newLeg != raceLeg) && (this.isVisible())) {
|
if (((newLeg != raceLeg)||((newLeg == raceLeg)&&(newVersion != (simulationResult==null ? 0 : simulationResult.getVersion())))) && (this.isVisible())) {
|
||||||
raceLeg = newLeg;
|
raceLeg = newLeg;
|
||||||
if (clearCanvas) {
|
if (clearCanvas) {
|
||||||
this.clearCanvas();
|
this.clearCanvas();
|
||||||
}
|
}
|
||||||
this.simulate(newTime);
|
this.simulate(newLeg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LegIdentifier getLegIdentifier() {
|
||||||
|
return new LegIdentifierImpl(raceIdentifier, String.valueOf(raceLeg));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVersion() {
|
||||||
|
if (this.simulationResult == null) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return this.simulationResult.getVersion();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setVisible(boolean isVisible) {
|
public void setVisible(boolean isVisible) {
|
||||||
super.setVisible(isVisible);
|
super.setVisible(isVisible);
|
||||||
@@ -146,8 +161,12 @@ public class RaceSimulationOverlay extends FullCanvasOverlay {
|
|||||||
Context2d ctxt = canvas.getContext2d();
|
Context2d ctxt = canvas.getContext2d();
|
||||||
PathDTO[] paths = simulationResult.getPaths();
|
PathDTO[] paths = simulationResult.getPaths();
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
int colorIdx = paths.length - 1;
|
int colorIdx = paths.length;
|
||||||
for (PathDTO path : paths) {
|
for (PathDTO path : paths) {
|
||||||
|
colorIdx--;
|
||||||
|
if (path.getMixedLeg()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
List<SimulatorWindDTO> points = path.getPoints();
|
List<SimulatorWindDTO> points = path.getPoints();
|
||||||
ctxt.setLineWidth(3.0);
|
ctxt.setLineWidth(3.0);
|
||||||
ctxt.setGlobalAlpha(0.7);
|
ctxt.setGlobalAlpha(0.7);
|
||||||
@@ -175,7 +194,6 @@ public class RaceSimulationOverlay extends FullCanvasOverlay {
|
|||||||
ctxt.closePath();
|
ctxt.closePath();
|
||||||
ctxt.stroke();
|
ctxt.stroke();
|
||||||
}
|
}
|
||||||
colorIdx--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,22 +208,57 @@ public class RaceSimulationOverlay extends FullCanvasOverlay {
|
|||||||
txtmet = context2d.measureText("00:00:00");
|
txtmet = context2d.measureText("00:00:00");
|
||||||
double timewidth = txtmet.getWidth();
|
double timewidth = txtmet.getWidth();
|
||||||
double txtmaxwidth = 0.0;
|
double txtmaxwidth = 0.0;
|
||||||
txtmet = context2d.measureText(racePath.getName().split("#")[1]);
|
if (racePath != null) {
|
||||||
txtmaxwidth = Math.max(txtmaxwidth, txtmet.getWidth());
|
txtmet = context2d.measureText(racePath.getName().split("#")[1]);
|
||||||
PathDTO[] paths = this.simulationResult.getPaths();
|
|
||||||
for (PathDTO path : paths) {
|
|
||||||
txtmet = context2d.measureText(path.getName());
|
|
||||||
txtmaxwidth = Math.max(txtmaxwidth, txtmet.getWidth());
|
txtmaxwidth = Math.max(txtmaxwidth, txtmet.getWidth());
|
||||||
}
|
}
|
||||||
//canvas.setSize(xOffset + rectWidth + txtmaxwidth + timewidth + 10.0+"px", rectHeight*(paths.length+1)+"px");
|
boolean containsTimeOut = false;
|
||||||
int canvasWidth = (int)Math.ceil(xOffset + rectWidth + txtmaxwidth + timewidth + 10.0 + 5.0);
|
boolean containsMixedLeg = false;
|
||||||
int canvasHeight = (int)Math.ceil(yOffset + rectHeight*(paths.length+1));
|
PathDTO[] paths = this.simulationResult.getPaths();
|
||||||
setCanvasSize(canvas, canvasWidth, canvasHeight);
|
|
||||||
drawRectangleWithText(context2d, xOffset, yOffset, "rgba(255,255,255,0.8);",
|
|
||||||
racePath.getName().split("#")[1], getFormattedTime(racePath.getPathTime()), txtmaxwidth, timewidth);
|
|
||||||
for (PathDTO path : paths) {
|
for (PathDTO path : paths) {
|
||||||
drawRectangleWithText(context2d, xOffset, yOffset + (paths.length-index) * rectHeight, this.colors.getColor(paths.length-1-index),
|
if (path.getAlgorithmTimedOut()) {
|
||||||
path.getName().split("#")[1], getFormattedTime(path.getPathTime()), txtmaxwidth, timewidth);
|
containsTimeOut = true;
|
||||||
|
}
|
||||||
|
if (path.getMixedLeg()) {
|
||||||
|
containsMixedLeg = true;
|
||||||
|
}
|
||||||
|
txtmet = context2d.measureText(path.getName().split("#")[1]);
|
||||||
|
txtmaxwidth = Math.max(txtmaxwidth, txtmet.getWidth());
|
||||||
|
}
|
||||||
|
double newwidth = 0;
|
||||||
|
double deltaTime = 0;
|
||||||
|
double deltaMixedLeg = 0;
|
||||||
|
double deltaTimeOut = 0;
|
||||||
|
double mixedLegWidth = 0;
|
||||||
|
if (containsMixedLeg) {
|
||||||
|
txtmet = context2d.measureText(mixedLegText);
|
||||||
|
mixedLegWidth = txtmet.getWidth();
|
||||||
|
newwidth = Math.max(timewidth, mixedLegWidth);
|
||||||
|
}
|
||||||
|
double timeOutWidth = 0;
|
||||||
|
if (containsTimeOut) {
|
||||||
|
txtmet = context2d.measureText(algorithmTimedOutText);
|
||||||
|
timeOutWidth = txtmet.getWidth();
|
||||||
|
newwidth = Math.max(newwidth, timeOutWidth);
|
||||||
|
}
|
||||||
|
if (containsMixedLeg||containsTimeOut) {
|
||||||
|
deltaTime = newwidth - timewidth;
|
||||||
|
deltaMixedLeg = newwidth - mixedLegWidth;
|
||||||
|
deltaTimeOut = newwidth - timeOutWidth;
|
||||||
|
timewidth = newwidth;
|
||||||
|
}
|
||||||
|
//canvas.setSize(xOffset + rectWidth + txtmaxwidth + timewidth + 10.0+"px", rectHeight*(paths.length+1)+"px");
|
||||||
|
int canvasWidth = (int)Math.ceil(xOffset + rectWidth + txtmaxwidth + timewidth + 10.0 + 10.0);
|
||||||
|
int canvasHeight = (int)Math.ceil(yOffset + rectHeight*(paths.length + (racePath == null? 0 : 1)));
|
||||||
|
setCanvasSize(canvas, canvasWidth, canvasHeight);
|
||||||
|
if (racePath != null) {
|
||||||
|
drawRectangleWithText(context2d, xOffset, yOffset, null,
|
||||||
|
racePath.getName().split("#")[1], getFormattedTime(racePath.getPathTime()), txtmaxwidth, timewidth, deltaTime);
|
||||||
|
}
|
||||||
|
for (PathDTO path : paths) {
|
||||||
|
String timeText = (path.getMixedLeg() ? mixedLegText : (path.getAlgorithmTimedOut() ? algorithmTimedOutText : getFormattedTime(path.getPathTime())));
|
||||||
|
drawRectangleWithText(context2d, xOffset, yOffset + (paths.length-index-(racePath==null?1:0)) * rectHeight, this.colors.getColor(paths.length-1-index),
|
||||||
|
path.getName().split("#")[1], timeText, txtmaxwidth, timewidth, (path.getMixedLeg()?deltaMixedLeg:(path.getAlgorithmTimedOut()?deltaTimeOut:deltaTime)));
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,17 +276,19 @@ public class RaceSimulationOverlay extends FullCanvasOverlay {
|
|||||||
context2d.fillRect(x, y, rectWidth, rectHeight);
|
context2d.fillRect(x, y, rectWidth, rectHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void drawRectangleWithText(Context2d context2d, double x, double y, String color, String text, String time, double textmaxwidth, double timewidth) {
|
protected void drawRectangleWithText(Context2d context2d, double x, double y, String color, String text, String time, double textmaxwidth, double timewidth, double xdelta) {
|
||||||
double offset = 3.0;
|
double offset = 3.0;
|
||||||
context2d.setFont(textFont);
|
context2d.setFont(textFont);
|
||||||
drawRectangle(context2d, x, y, color);
|
if (color != null) {
|
||||||
|
drawRectangle(context2d, x, y, color);
|
||||||
|
}
|
||||||
context2d.setGlobalAlpha(0.80);
|
context2d.setGlobalAlpha(0.80);
|
||||||
context2d.setFillStyle("white");
|
context2d.setFillStyle("white");
|
||||||
context2d.fillRect(x + rectWidth, y, 15.0 + textmaxwidth + timewidth, rectHeight);
|
context2d.fillRect(x + (color==null?0:rectWidth), y, 20.0 + textmaxwidth + timewidth + (color==null?rectWidth:0), rectHeight);
|
||||||
context2d.setGlobalAlpha(1.0);
|
context2d.setGlobalAlpha(1.0);
|
||||||
context2d.setFillStyle(textColor);
|
context2d.setFillStyle(textColor);
|
||||||
context2d.fillText(text, x + rectWidth + 5.0, y + 12.0 + offset);
|
context2d.fillText(text, x + rectWidth + 5.0, y + 12.0 + offset);
|
||||||
context2d.fillText(time, x + rectWidth + textmaxwidth + 10.0, y + 12.0 + offset);
|
context2d.fillText(time, x + rectWidth + textmaxwidth + xdelta + 15.0, y + 12.0 + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getFormattedTime(long pathTime) {
|
protected String getFormattedTime(long pathTime) {
|
||||||
@@ -244,8 +299,9 @@ public class RaceSimulationOverlay extends FullCanvasOverlay {
|
|||||||
return pathTimeStr;
|
return pathTimeStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void simulate(Date from) {
|
public void simulate(int leg) {
|
||||||
GetSimulationAction getSimulation = new GetSimulationAction(sailingService, raceIdentifier, from, prevStartTime);
|
LegIdentifier legIdentifier = new LegIdentifierImpl(raceIdentifier, String.valueOf(leg));
|
||||||
|
GetSimulationAction getSimulation = new GetSimulationAction(sailingService, legIdentifier);
|
||||||
asyncActionsExecutor.execute(getSimulation, GET_SIMULATION_CATEGORY,
|
asyncActionsExecutor.execute(getSimulation, GET_SIMULATION_CATEGORY,
|
||||||
new MarkedAsyncCallback<>(new AsyncCallback<SimulatorResultsDTO>() {
|
new MarkedAsyncCallback<>(new AsyncCallback<SimulatorResultsDTO>() {
|
||||||
@Override
|
@Override
|
||||||
@@ -259,19 +315,26 @@ public class RaceSimulationOverlay extends FullCanvasOverlay {
|
|||||||
public void onSuccess(SimulatorResultsDTO result) {
|
public void onSuccess(SimulatorResultsDTO result) {
|
||||||
// store results
|
// store results
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
prevStartTime = result.getStartTime();
|
|
||||||
if (result.getPaths() != null) {
|
if (result.getPaths() != null) {
|
||||||
simulationResult = result;
|
simulationResult = result;
|
||||||
PathDTO[] paths = result.getPaths();
|
PathDTO[] paths = result.getPaths();
|
||||||
racePath = new PathDTO();
|
if (result.getLegDuration() > 0) {
|
||||||
List<SimulatorWindDTO> racePathPoints = new ArrayList<SimulatorWindDTO>();
|
racePath = new PathDTO();
|
||||||
racePathPoints.add(new SimulatorWindDTO(null, 0, 0, paths[0].getPoints().get(0).timepoint));
|
List<SimulatorWindDTO> racePathPoints = new ArrayList<SimulatorWindDTO>();
|
||||||
racePathPoints.add(new SimulatorWindDTO(null, 0, 0, paths[0].getPoints().get(0).timepoint + result.getLegDuration()));
|
racePathPoints.add(new SimulatorWindDTO(null, 0, 0, paths[0].getPoints().get(0).timepoint));
|
||||||
racePath.setPoints(racePathPoints);
|
racePathPoints.add(new SimulatorWindDTO(null, 0, 0, paths[0].getPoints().get(0).timepoint + result.getLegDuration()));
|
||||||
racePath.setName("0#Race");
|
racePath.setPoints(racePathPoints);
|
||||||
|
racePath.setName("0#Race");
|
||||||
|
} else {
|
||||||
|
racePath = null;
|
||||||
|
}
|
||||||
clearCanvas();
|
clearCanvas();
|
||||||
drawPaths();
|
drawPaths();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
raceLeg = 0;
|
||||||
|
simulationResult = null;
|
||||||
|
clearCanvas();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|||||||
+13
-1
@@ -43,6 +43,8 @@ public class PathCanvasOverlay extends WindFieldCanvasOverlay implements Named {
|
|||||||
private long totalTimeMilliseconds = 0;
|
private long totalTimeMilliseconds = 0;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
private boolean algorithmTimedOut;
|
||||||
|
private boolean mixedLeg;
|
||||||
|
|
||||||
private String pathColor = "Green";
|
private String pathColor = "Green";
|
||||||
|
|
||||||
@@ -56,9 +58,11 @@ public class PathCanvasOverlay extends WindFieldCanvasOverlay implements Named {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PathCanvasOverlay(MapWidget map, int zIndex, String name, Timer timer, WindFieldGenParamsDTO windParams, CoordinateSystem coordinateSystem) {
|
public PathCanvasOverlay(MapWidget map, int zIndex, String name, Timer timer, WindFieldGenParamsDTO windParams, boolean algorithmTimedOut, boolean mixedLeg, CoordinateSystem coordinateSystem) {
|
||||||
super(map, zIndex, timer, windParams, coordinateSystem);
|
super(map, zIndex, timer, windParams, coordinateSystem);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.algorithmTimedOut = algorithmTimedOut;
|
||||||
|
this.mixedLeg = mixedLeg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PathCanvasOverlay(MapWidget map, int zIndex, String name, long totalTimeMilliseconds, CoordinateSystem coordinateSystem) {
|
public PathCanvasOverlay(MapWidget map, int zIndex, String name, long totalTimeMilliseconds, CoordinateSystem coordinateSystem) {
|
||||||
@@ -250,6 +254,14 @@ public class PathCanvasOverlay extends WindFieldCanvasOverlay implements Named {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getAlgorithmTimedOut() {
|
||||||
|
return algorithmTimedOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getMixedLeg() {
|
||||||
|
return mixedLeg;
|
||||||
|
}
|
||||||
|
|
||||||
public long getPathTime() {
|
public long getPathTime() {
|
||||||
if (totalTimeIsGiven) {
|
if (totalTimeIsGiven) {
|
||||||
return totalTimeMilliseconds;
|
return totalTimeMilliseconds;
|
||||||
|
|||||||
+37
-4
@@ -40,6 +40,8 @@ public class PathLegendCanvasOverlay extends FullCanvasOverlay {
|
|||||||
|
|
||||||
private String textColor = "Black";
|
private String textColor = "Black";
|
||||||
private String textFont = "10pt OpenSansRegular";
|
private String textFont = "10pt OpenSansRegular";
|
||||||
|
private String algorithmTimedOutText = "out-of-bounds";
|
||||||
|
private String mixedLegText = "ambiguous wind";
|
||||||
|
|
||||||
public PathLegendCanvasOverlay(MapWidget map, int zIndex, char mode, CoordinateSystem coordinateSystem) {
|
public PathLegendCanvasOverlay(MapWidget map, int zIndex, char mode, CoordinateSystem coordinateSystem) {
|
||||||
super(map, zIndex, coordinateSystem);
|
super(map, zIndex, coordinateSystem);
|
||||||
@@ -82,13 +84,44 @@ public class PathLegendCanvasOverlay extends FullCanvasOverlay {
|
|||||||
txtmet = context2d.measureText("00:00:00");
|
txtmet = context2d.measureText("00:00:00");
|
||||||
double timewidth = txtmet.getWidth();
|
double timewidth = txtmet.getWidth();
|
||||||
double txtmaxwidth = 0.0;
|
double txtmaxwidth = 0.0;
|
||||||
|
boolean containsTimeOut = false;
|
||||||
|
boolean containsMixedLeg = false;
|
||||||
for (PathCanvasOverlay path : pathOverlays) {
|
for (PathCanvasOverlay path : pathOverlays) {
|
||||||
|
if (path.getAlgorithmTimedOut()) {
|
||||||
|
containsTimeOut = true;
|
||||||
|
}
|
||||||
|
if (path.getMixedLeg()) {
|
||||||
|
containsMixedLeg = true;
|
||||||
|
}
|
||||||
txtmet = context2d.measureText(path.getName());
|
txtmet = context2d.measureText(path.getName());
|
||||||
txtmaxwidth = Math.max(txtmaxwidth, txtmet.getWidth());
|
txtmaxwidth = Math.max(txtmaxwidth, txtmet.getWidth());
|
||||||
}
|
}
|
||||||
|
double newwidth = 0;
|
||||||
|
double deltaTime = 0;
|
||||||
|
double deltaMixedLeg = 0;
|
||||||
|
double deltaTimeOut = 0;
|
||||||
|
double mixedLegWidth = 0;
|
||||||
|
if (containsMixedLeg) {
|
||||||
|
txtmet = context2d.measureText(mixedLegText);
|
||||||
|
mixedLegWidth = txtmet.getWidth();
|
||||||
|
newwidth = Math.max(timewidth, mixedLegWidth);
|
||||||
|
}
|
||||||
|
double timeOutWidth = 0;
|
||||||
|
if (containsTimeOut) {
|
||||||
|
txtmet = context2d.measureText(algorithmTimedOutText);
|
||||||
|
timeOutWidth = txtmet.getWidth();
|
||||||
|
newwidth = Math.max(newwidth, timeOutWidth);
|
||||||
|
}
|
||||||
|
if (containsMixedLeg||containsTimeOut) {
|
||||||
|
deltaTime = newwidth - timewidth;
|
||||||
|
deltaMixedLeg = newwidth - mixedLegWidth;
|
||||||
|
deltaTimeOut = newwidth - timeOutWidth;
|
||||||
|
timewidth = newwidth;
|
||||||
|
}
|
||||||
for (PathCanvasOverlay path : pathOverlays) {
|
for (PathCanvasOverlay path : pathOverlays) {
|
||||||
|
String timeText = (path.getMixedLeg() ? mixedLegText : (path.getAlgorithmTimedOut() ? algorithmTimedOutText : getFormattedTime(path.getPathTime())));
|
||||||
drawRectangleWithText(xOffset, yOffset + (pathOverlays.size()-1-index) * rectHeight, path.getPathColor(),
|
drawRectangleWithText(xOffset, yOffset + (pathOverlays.size()-1-index) * rectHeight, path.getPathColor(),
|
||||||
path.getName(), getFormattedTime(path.getPathTime()),txtmaxwidth,timewidth);
|
path.getName(), timeText, txtmaxwidth, timewidth, (path.getMixedLeg()?deltaMixedLeg:(path.getAlgorithmTimedOut()?deltaTimeOut:deltaTime)));
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@@ -170,7 +203,7 @@ public class PathLegendCanvasOverlay extends FullCanvasOverlay {
|
|||||||
context2d.fillRect(x, y, rectWidth, rectHeight);
|
context2d.fillRect(x, y, rectWidth, rectHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void drawRectangleWithText(double x, double y, String color, String text, String time, double textmaxwidth, double timewidth) {
|
protected void drawRectangleWithText(double x, double y, String color, String text, String time, double textmaxwidth, double timewidth, double xdelta) {
|
||||||
|
|
||||||
double offset = 3.0;
|
double offset = 3.0;
|
||||||
|
|
||||||
@@ -179,11 +212,11 @@ public class PathLegendCanvasOverlay extends FullCanvasOverlay {
|
|||||||
drawRectangle(x, y, color);
|
drawRectangle(x, y, color);
|
||||||
context2d.setGlobalAlpha(0.80);
|
context2d.setGlobalAlpha(0.80);
|
||||||
context2d.setFillStyle("white");
|
context2d.setFillStyle("white");
|
||||||
context2d.fillRect(x + rectWidth, y, 15.0 + textmaxwidth + timewidth, rectHeight);
|
context2d.fillRect(x + rectWidth, y, 20.0 + textmaxwidth + timewidth, rectHeight);
|
||||||
context2d.setGlobalAlpha(1.0);
|
context2d.setGlobalAlpha(1.0);
|
||||||
context2d.setFillStyle(textColor);
|
context2d.setFillStyle(textColor);
|
||||||
context2d.fillText(text, x + rectWidth + 5.0, y + 12.0 + offset);
|
context2d.fillText(text, x + rectWidth + 5.0, y + 12.0 + offset);
|
||||||
context2d.fillText(time, x + rectWidth + textmaxwidth + 10.0, y + 12.0 + offset);
|
context2d.fillText(time, x + rectWidth + textmaxwidth + xdelta + 15.0, y + 12.0 + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getFormattedTime(long pathTime) {
|
protected String getFormattedTime(long pathTime) {
|
||||||
|
|||||||
+10
-3
@@ -18,8 +18,8 @@ public class ReplayPathCanvasOverlay extends PathCanvasOverlay {
|
|||||||
private List<SimulatorWindDTO> windDTOToDraw;
|
private List<SimulatorWindDTO> windDTOToDraw;
|
||||||
|
|
||||||
public ReplayPathCanvasOverlay(MapWidget map, int zIndex, final String name, final Timer timer,
|
public ReplayPathCanvasOverlay(MapWidget map, int zIndex, final String name, final Timer timer,
|
||||||
WindFieldGenParamsDTO windParams, CoordinateSystem coordinateSystem) {
|
WindFieldGenParamsDTO windParams, boolean algorithmTimedOut, boolean mixedLeg, CoordinateSystem coordinateSystem) {
|
||||||
super(map, zIndex, name, timer, windParams, coordinateSystem);
|
super(map, zIndex, name, timer, windParams, algorithmTimedOut, mixedLeg, coordinateSystem);
|
||||||
this.displayWindAlongPath = false;
|
this.displayWindAlongPath = false;
|
||||||
windDTOToDraw = null;
|
windDTOToDraw = null;
|
||||||
canvas.setStyleName("replayPanel");
|
canvas.setStyleName("replayPanel");
|
||||||
@@ -34,6 +34,10 @@ public class ReplayPathCanvasOverlay extends PathCanvasOverlay {
|
|||||||
@Override
|
@Override
|
||||||
public void timeChanged(final Date newTime, Date oldTime) {
|
public void timeChanged(final Date newTime, Date oldTime) {
|
||||||
|
|
||||||
|
if (windFieldDTO == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
canvas.getContext2d().clearRect(0/* canvas.getAbsoluteLeft() */, 0/* canvas.getAbsoluteTop() */,
|
canvas.getContext2d().clearRect(0/* canvas.getAbsoluteLeft() */, 0/* canvas.getAbsoluteTop() */,
|
||||||
canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
|
canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
|
||||||
|
|
||||||
@@ -50,7 +54,10 @@ public class ReplayPathCanvasOverlay extends PathCanvasOverlay {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shallStop() {
|
public boolean shallStop() {
|
||||||
if (!isVisible() || windDTOToDraw == null || windFieldDTO == null) {
|
if (windDTOToDraw == null || windFieldDTO == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!isVisible()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (windDTOToDraw.size() >= (windFieldDTO.getMatrix().size()-1)) {
|
if (windDTOToDraw.size() >= (windFieldDTO.getMatrix().size()-1)) {
|
||||||
|
|||||||
+10
-6
@@ -158,27 +158,31 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
|
|||||||
PathDTO currentPath = null;
|
PathDTO currentPath = null;
|
||||||
//String color = null;
|
//String color = null;
|
||||||
String pathName = null;
|
String pathName = null;
|
||||||
|
boolean algorithmTimedOut = false;
|
||||||
int noOfPaths = paths.length;
|
int noOfPaths = paths.length;
|
||||||
|
|
||||||
for (int index = 0; index < noOfPaths; ++index) {
|
for (int index = 0; index < noOfPaths; ++index) {
|
||||||
|
|
||||||
currentPath = paths[index];
|
currentPath = paths[index];
|
||||||
pathName = currentPath.getName();
|
pathName = currentPath.getName();
|
||||||
|
algorithmTimedOut = currentPath.getAlgorithmTimedOut();
|
||||||
//color = colorPalette.getColor(noOfPaths - 1 - index);
|
//color = colorPalette.getColor(noOfPaths - 1 - index);
|
||||||
|
|
||||||
if (pathName.equals("Polyline")) {
|
if (pathName.equals("Polyline")) {
|
||||||
pathPolyline = createPathPolyline(currentPath);
|
pathPolyline = createPathPolyline(currentPath);
|
||||||
} else if (pathName.equals("GPS Poly")) {
|
} else if (pathName.equals("GPS Poly")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
|
|
||||||
/* TODO Revisit for now creating a WindFieldDTO from the path */
|
/* TODO Revisit for now creating a WindFieldDTO from the path */
|
||||||
WindFieldDTO pathWindDTO = new WindFieldDTO();
|
WindFieldDTO pathWindDTO = null;
|
||||||
pathWindDTO.setMatrix(currentPath.getPoints());
|
if (!currentPath.getMixedLeg()) {
|
||||||
|
pathWindDTO = new WindFieldDTO();
|
||||||
|
pathWindDTO.setMatrix(currentPath.getPoints());
|
||||||
|
}
|
||||||
|
|
||||||
ReplayPathCanvasOverlay replayPathCanvasOverlay = new ReplayPathCanvasOverlay(map, SimulatorMapOverlaysZIndexes.PATH_ZINDEX,
|
ReplayPathCanvasOverlay replayPathCanvasOverlay = new ReplayPathCanvasOverlay(map, SimulatorMapOverlaysZIndexes.PATH_ZINDEX,
|
||||||
pathName.split("#")[1], timer, windParams, coordinateSystem);
|
pathName.split("#")[1], timer, windParams, algorithmTimedOut, currentPath.getMixedLeg(), coordinateSystem);
|
||||||
replayPathCanvasOverlays.add(replayPathCanvasOverlay);
|
replayPathCanvasOverlays.add(replayPathCanvasOverlay);
|
||||||
replayPathCanvasOverlay.setPathColor(colorPalette.getColor(Integer.parseInt(pathName.split("#")[0])-1));
|
replayPathCanvasOverlay.setPathColor(colorPalette.getColor(Integer.parseInt(pathName.split("#")[0])-1));
|
||||||
|
|
||||||
@@ -205,7 +209,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
|
|||||||
legendCanvasOverlay.setPathOverlays(replayPathCanvasOverlays);
|
legendCanvasOverlay.setPathOverlays(replayPathCanvasOverlays);
|
||||||
|
|
||||||
long tmpDurationTime = currentPath.getPathTime();
|
long tmpDurationTime = currentPath.getPathTime();
|
||||||
if (tmpDurationTime > maxDurationTime) {
|
if ((!currentPath.getMixedLeg())&&(!currentPath.getAlgorithmTimedOut())&&(tmpDurationTime > maxDurationTime)) {
|
||||||
maxDurationTime = tmpDurationTime;
|
maxDurationTime = tmpDurationTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+56
-4
@@ -4,12 +4,64 @@
|
|||||||
<div id="mainContent">
|
<div id="mainContent">
|
||||||
<h4 class="articleHeadline">What's New - Strategy Simulator</h4>
|
<h4 class="articleHeadline">What's New - Strategy Simulator</h4>
|
||||||
<div class="innerContent">
|
<div class="innerContent">
|
||||||
<h5 class="articleSubheadline">September 2014</h5>
|
<h5 class="articleSubheadline">October 2014</h5>
|
||||||
|
|
||||||
<ul class="bulletList">
|
<ul class="bulletList">
|
||||||
<li>Point 1...
|
<li>Simulation is being integrated into the race board (see What's New in Sailing Analytics)</li>
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<h5 class="articleSubheadline">August 2014</h5>
|
||||||
|
<ul class="bulletList">
|
||||||
|
<li>Accuracy of optimal course calculation has been improved</li>
|
||||||
|
<li>Streamlet motion is now calibrated to physical reality on large zoom levels of the map</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h5 class="articleSubheadline">April 2014</h5>
|
||||||
|
<ul class="bulletList">
|
||||||
|
<li>Wind is visualized using animated streamlets based on a swarm of particles which locally follow the wind</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h5 class="articleSubheadline">September 2013</h5>
|
||||||
|
<ul class="bulletList">
|
||||||
|
<li>Windbot based on RaspberryPi to construct real, spatially resolved wind vector fields from wind measurements</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h5 class="articleSubheadline">June 2013</h5>
|
||||||
|
<ul class="bulletList">
|
||||||
|
<li>Optimal courses shown as "Omniscient" are determined by an heuristic search algorithm greatly improving accuracy and runtime performance</li>
|
||||||
|
<li>Sailing angles are represented with full numeric accuracy</li>
|
||||||
|
<li>Water current is taken into account</li>
|
||||||
|
<li>Support up- and downwind legs</li>
|
||||||
|
<li>1-Click Simulation simplifies the user interaction</li>
|
||||||
|
<li>Race course map for Kieler Woche and Travemuender Woche</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h5 class="articleSubheadline">March 2013</h5>
|
||||||
|
<ul class="bulletList">
|
||||||
|
<li>What-if simulation comparing sailed GPS-track and simulated course with changed locations of turns for
|
||||||
|
answering questions like: would it have been advantageous to do the second turn a bit later?</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h5 class="articleSubheadline">February 2013</h5>
|
||||||
|
<ul class="bulletList">
|
||||||
|
<li>Strategy Simulator becomes a part of SAP's Sailing Analytics suite</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h5 class="articleSubheadline">December 2012</h5>
|
||||||
|
<ul class="bulletList">
|
||||||
|
<li>Polar diagram chart is available</li>
|
||||||
|
<li>Multiple boat classes are supported based on polar diagrams in tabular format provided as CSV-files</li>
|
||||||
|
<li>Several wind visualization approaches are supported: arrows on a grid, as well as, heatmap combined with bearing lines (either grid or integrated across race course)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h5 class="articleSubheadline">June 2012</h5>
|
||||||
|
<ul class="bulletList">
|
||||||
|
<li>First upwind-only prototype of sailing simulation is available</li>
|
||||||
|
<li>Optimal courses shown as "Omniscient" are calculated with an implementation of Dijkstra's algorithm on a rectangular spatial grid</li>
|
||||||
|
<li>Wind is visualized by arrows which scale with wind speed</li>
|
||||||
|
<li>Race course definition with 2 mouse clicks for start and end</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -13,4 +13,5 @@ Require-Bundle: org.hamcrest;bundle-version="1.1.0",
|
|||||||
com.sap.sailing.domain.test,
|
com.sap.sailing.domain.test,
|
||||||
com.sap.sse.common,
|
com.sap.sse.common,
|
||||||
com.sap.sailing.domain.tractracadapter,
|
com.sap.sailing.domain.tractracadapter,
|
||||||
com.tractrac.clientmodule;bundle-version="3.0.7"
|
com.tractrac.clientmodule;bundle-version="3.0.7",
|
||||||
|
com.sap.sailing.domain
|
||||||
+1
-1
@@ -42,6 +42,7 @@ import com.sap.sailing.domain.common.impl.PolarSheetGenerationSettingsImpl;
|
|||||||
import com.sap.sailing.domain.common.impl.WindImpl;
|
import com.sap.sailing.domain.common.impl.WindImpl;
|
||||||
import com.sap.sailing.domain.common.impl.WindSpeedSteppingWithMaxDistance;
|
import com.sap.sailing.domain.common.impl.WindSpeedSteppingWithMaxDistance;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
@@ -49,7 +50,6 @@ import com.sap.sailing.domain.tracking.WindWithConfidence;
|
|||||||
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl;
|
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl;
|
||||||
import com.sap.sailing.domain.tracking.impl.WindWithConfidenceImpl;
|
import com.sap.sailing.domain.tracking.impl.WindWithConfidenceImpl;
|
||||||
import com.sap.sailing.polars.mining.PolarDataMiner;
|
import com.sap.sailing.polars.mining.PolarDataMiner;
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
import com.sap.sse.common.Util.Pair;
|
import com.sap.sse.common.Util.Pair;
|
||||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||||
|
|||||||
+1
-1
@@ -12,8 +12,8 @@ import java.util.Random;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
import com.sap.sailing.polars.regression.IncrementalLeastSquares;
|
import com.sap.sailing.polars.regression.IncrementalLeastSquares;
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
|
||||||
import com.sap.sailing.polars.regression.impl.IncrementalAnyOrderLeastSquaresImpl;
|
import com.sap.sailing.polars.regression.impl.IncrementalAnyOrderLeastSquaresImpl;
|
||||||
|
|
||||||
public class IncrementalLeastSquaresTest {
|
public class IncrementalLeastSquaresTest {
|
||||||
|
|||||||
+1
-1
@@ -7,8 +7,8 @@ import static org.junit.Assert.assertTrue;
|
|||||||
import org.hamcrest.number.IsCloseTo;
|
import org.hamcrest.number.IsCloseTo;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
import com.sap.sailing.polars.regression.IncrementalLeastSquares;
|
import com.sap.sailing.polars.regression.IncrementalLeastSquares;
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
|
||||||
import com.sap.sailing.polars.regression.impl.IncrementalAnyOrderLeastSquaresImpl;
|
import com.sap.sailing.polars.regression.impl.IncrementalAnyOrderLeastSquaresImpl;
|
||||||
|
|
||||||
public class IncrementalLinearRegressionOrderOneTest {
|
public class IncrementalLinearRegressionOrderOneTest {
|
||||||
|
|||||||
+3
-4
@@ -12,7 +12,6 @@ import java.text.ParseException;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -27,11 +26,11 @@ import com.sap.sailing.domain.common.confidence.impl.ScalableDouble;
|
|||||||
import com.sap.sailing.domain.common.confidence.impl.ScalableWind;
|
import com.sap.sailing.domain.common.confidence.impl.ScalableWind;
|
||||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||||
import com.sap.sailing.domain.common.scalablevalue.impl.ScalableBearing;
|
import com.sap.sailing.domain.common.scalablevalue.impl.ScalableBearing;
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
import com.sap.sailing.domain.test.OnlineTracTracBasedTest;
|
import com.sap.sailing.domain.test.OnlineTracTracBasedTest;
|
||||||
import com.sap.sailing.domain.tracking.Maneuver;
|
import com.sap.sailing.domain.tracking.Maneuver;
|
||||||
import com.sap.sailing.domain.tractracadapter.ReceiverType;
|
import com.sap.sailing.domain.tractracadapter.ReceiverType;
|
||||||
import com.sap.sailing.polars.impl.PolarDataServiceImpl;
|
import com.sap.sailing.polars.impl.PolarDataServiceImpl;
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
|
||||||
import com.sap.sailing.polars.windestimation.ManeuverBasedWindEstimationTrackImpl.ManeuverClassification;
|
import com.sap.sailing.polars.windestimation.ManeuverBasedWindEstimationTrackImpl.ManeuverClassification;
|
||||||
import com.sap.sse.common.Util.Pair;
|
import com.sap.sse.common.Util.Pair;
|
||||||
import com.sap.sse.util.kmeans.Cluster;
|
import com.sap.sse.util.kmeans.Cluster;
|
||||||
@@ -117,7 +116,7 @@ public class TestWindEstimationFromManeuversOnAFew505Races extends OnlineTracTra
|
|||||||
IOException, InterruptedException, URISyntaxException, ParseException, SubscriberInitializationException,
|
IOException, InterruptedException, URISyntaxException, ParseException, SubscriberInitializationException,
|
||||||
CreateModelException {
|
CreateModelException {
|
||||||
setUp("event_20110609_KielerWoch-505_Race_3");
|
setUp("event_20110609_KielerWoch-505_Race_3");
|
||||||
ManeuverBasedWindEstimationTrackImpl windTrack = new ManeuverBasedWindEstimationTrackImpl(new PolarDataServiceImpl(Executors.newFixedThreadPool(4)),
|
ManeuverBasedWindEstimationTrackImpl windTrack = new ManeuverBasedWindEstimationTrackImpl(new PolarDataServiceImpl(),
|
||||||
getTrackedRace(), /* millisecondsOverWhichToAverage */ 30000, /* waitForLatest */ true);
|
getTrackedRace(), /* millisecondsOverWhichToAverage */ 30000, /* waitForLatest */ true);
|
||||||
final Map<Maneuver, Competitor> maneuvers = windTrack.getAllManeuvers(/* waitForLatest */ true);
|
final Map<Maneuver, Competitor> maneuvers = windTrack.getAllManeuvers(/* waitForLatest */ true);
|
||||||
final int numberOfClusters = 16;
|
final int numberOfClusters = 16;
|
||||||
@@ -153,7 +152,7 @@ public class TestWindEstimationFromManeuversOnAFew505Races extends OnlineTracTra
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Wind getManeuverBasedAverageWind() throws NotEnoughDataHasBeenAddedException {
|
private Wind getManeuverBasedAverageWind() throws NotEnoughDataHasBeenAddedException {
|
||||||
ManeuverBasedWindEstimationTrackImpl windTrack = new ManeuverBasedWindEstimationTrackImpl(new PolarDataServiceImpl(Executors.newFixedThreadPool(4)),
|
ManeuverBasedWindEstimationTrackImpl windTrack = new ManeuverBasedWindEstimationTrackImpl(new PolarDataServiceImpl(),
|
||||||
getTrackedRace(), /* millisecondsOverWhichToAverage */ 30000, /* waitForLatest */ true);
|
getTrackedRace(), /* millisecondsOverWhichToAverage */ 30000, /* waitForLatest */ true);
|
||||||
ScalableWind windSum = null;
|
ScalableWind windSum = null;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|||||||
@@ -7,9 +7,7 @@ Bundle-Vendor: SAP
|
|||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||||
Bundle-ClassPath: .
|
Bundle-ClassPath: .
|
||||||
Export-Package:
|
Export-Package:
|
||||||
com.sap.sailing.polars,
|
|
||||||
com.sap.sailing.polars.data,
|
com.sap.sailing.polars.data,
|
||||||
com.sap.sailing.polars.factory,
|
|
||||||
com.sap.sailing.polars.regression,
|
com.sap.sailing.polars.regression,
|
||||||
com.sap.sailing.polars.windestimation
|
com.sap.sailing.polars.windestimation
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
@@ -21,7 +19,9 @@ Require-Bundle:
|
|||||||
com.sap.sse.common,
|
com.sap.sse.common,
|
||||||
com.sap.sse,
|
com.sap.sse,
|
||||||
com.sap.sse.shared.android,
|
com.sap.sse.shared.android,
|
||||||
org.apache.commons.math;bundle-version="2.1.0"
|
org.apache.commons.math;bundle-version="2.1.0",
|
||||||
|
org.eclipse.osgi
|
||||||
Import-Package:
|
Import-Package:
|
||||||
com.sap.sailing.util,
|
com.sap.sailing.util,
|
||||||
com.sap.sse.common
|
com.sap.sse.common
|
||||||
|
Bundle-Activator: com.sap.sailing.polars.impl.Activator
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
package com.sap.sailing.polars.factory;
|
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
|
||||||
import com.sap.sailing.polars.factory.impl.PolarDataServiceImplFactory;
|
|
||||||
|
|
||||||
public abstract class PolarDataServiceFactory {
|
|
||||||
|
|
||||||
public static PolarDataService createStandardPolarDataService(Executor executor) {
|
|
||||||
PolarDataServiceFactory factory = new PolarDataServiceImplFactory();
|
|
||||||
return factory.createPolarDataService(executor);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract PolarDataService createPolarDataService(Executor executor);
|
|
||||||
|
|
||||||
}
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
package com.sap.sailing.polars.factory.impl;
|
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
|
||||||
import com.sap.sailing.polars.factory.PolarDataServiceFactory;
|
|
||||||
import com.sap.sailing.polars.impl.PolarDataServiceImpl;
|
|
||||||
|
|
||||||
public class PolarDataServiceImplFactory extends PolarDataServiceFactory {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PolarDataService createPolarDataService(Executor executor) {
|
|
||||||
return new PolarDataServiceImpl(executor);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.sap.sailing.polars.impl;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.osgi.framework.BundleActivator;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
import org.osgi.framework.ServiceRegistration;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
|
|
||||||
|
public class Activator implements BundleActivator {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(Activator.class.getName());
|
||||||
|
|
||||||
|
private final Set<ServiceRegistration<?>> registrations = new HashSet<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(BundleContext context) throws Exception {
|
||||||
|
logger.info("Registering PolarDataService");
|
||||||
|
registrations.add(context.registerService(PolarDataService.class, new PolarDataServiceImpl(), null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop(BundleContext context) throws Exception {
|
||||||
|
logger.info("Unregistering PolarDataService");
|
||||||
|
for (ServiceRegistration<?> reg : registrations) {
|
||||||
|
reg.unregister();
|
||||||
|
}
|
||||||
|
registrations.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+34
-3
@@ -17,15 +17,18 @@ import com.sap.sailing.domain.common.PolarSheetGenerationSettings;
|
|||||||
import com.sap.sailing.domain.common.PolarSheetsData;
|
import com.sap.sailing.domain.common.PolarSheetsData;
|
||||||
import com.sap.sailing.domain.common.Speed;
|
import com.sap.sailing.domain.common.Speed;
|
||||||
import com.sap.sailing.domain.common.Tack;
|
import com.sap.sailing.domain.common.Tack;
|
||||||
|
import com.sap.sailing.domain.common.confidence.BearingWithConfidence;
|
||||||
|
import com.sap.sailing.domain.common.confidence.impl.BearingWithConfidenceImpl;
|
||||||
|
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
|
||||||
import com.sap.sailing.polars.aggregation.PolarFixAggregator;
|
import com.sap.sailing.polars.aggregation.PolarFixAggregator;
|
||||||
import com.sap.sailing.polars.aggregation.SimplePolarFixRaceInterval;
|
import com.sap.sailing.polars.aggregation.SimplePolarFixRaceInterval;
|
||||||
import com.sap.sailing.polars.data.PolarFix;
|
import com.sap.sailing.polars.data.PolarFix;
|
||||||
import com.sap.sailing.polars.generation.PolarSheetGenerator;
|
import com.sap.sailing.polars.generation.PolarSheetGenerator;
|
||||||
import com.sap.sailing.polars.mining.PolarDataMiner;
|
import com.sap.sailing.polars.mining.PolarDataMiner;
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
|
||||||
import com.sap.sse.common.Util.Pair;
|
import com.sap.sse.common.Util.Pair;
|
||||||
import com.sap.sse.util.SmartFutureCache;
|
import com.sap.sse.util.SmartFutureCache;
|
||||||
|
|
||||||
@@ -41,7 +44,7 @@ public class PolarDataServiceImpl implements PolarDataService {
|
|||||||
|
|
||||||
private final PolarDataMiner polarDataMiner;
|
private final PolarDataMiner polarDataMiner;
|
||||||
|
|
||||||
public PolarDataServiceImpl(Executor executor) {
|
public PolarDataServiceImpl() {
|
||||||
this.polarDataMiner = new PolarDataMiner();
|
this.polarDataMiner = new PolarDataMiner();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,4 +161,32 @@ public class PolarDataServiceImpl implements PolarDataService {
|
|||||||
polarDataMiner.raceFinishedTracking(race);
|
polarDataMiner.raceFinishedTracking(race);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BearingWithConfidence<Void> getManeuverAngle(BoatClass boatClass, ManeuverType maneuverType, Speed windSpeed)
|
||||||
|
throws NotEnoughDataHasBeenAddedException {
|
||||||
|
if (maneuverType != ManeuverType.TACK && maneuverType != ManeuverType.JIBE) {
|
||||||
|
throw new IllegalArgumentException("ManeuverType needs to be tack or jibe.");
|
||||||
|
}
|
||||||
|
LegType legType = maneuverType == ManeuverType.TACK ? LegType.UPWIND : LegType.DOWNWIND;
|
||||||
|
if (boatClass == null || windSpeed == null) {
|
||||||
|
throw new IllegalArgumentException("Boatclass and windspeed cannot be null.");
|
||||||
|
}
|
||||||
|
SpeedWithBearingWithConfidence<Void> port = getAverageSpeedWithBearing(boatClass, windSpeed, legType, Tack.PORT);
|
||||||
|
SpeedWithBearingWithConfidence<Void> starboard = getAverageSpeedWithBearing(boatClass, windSpeed, legType,
|
||||||
|
Tack.STARBOARD);
|
||||||
|
double angleSumInDeg = Math.abs(port.getObject().getBearing().getDegrees())
|
||||||
|
+ Math.abs(starboard.getObject().getBearing().getDegrees());
|
||||||
|
Bearing bearing = new DegreeBearingImpl(angleSumInDeg);
|
||||||
|
double confidence = (port.getConfidence() + starboard.getConfidence()) / 2;
|
||||||
|
BearingWithConfidence<Void> bearingWithConfidence = new BearingWithConfidenceImpl<Void>(bearing, confidence,
|
||||||
|
null);
|
||||||
|
return bearingWithConfidence;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SpeedWithBearingWithConfidence<Void> getAverageSpeedWithBearing(BoatClass boatClass, Speed windSpeed,
|
||||||
|
LegType legType, Tack tack) throws NotEnoughDataHasBeenAddedException {
|
||||||
|
return getAverageSpeedWithBearing(boatClass, windSpeed, legType, tack, true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
-2
@@ -14,10 +14,10 @@ import com.sap.sailing.domain.common.SpeedWithBearing;
|
|||||||
import com.sap.sailing.domain.common.confidence.BearingWithConfidence;
|
import com.sap.sailing.domain.common.confidence.BearingWithConfidence;
|
||||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
||||||
import com.sap.sailing.polars.impl.CubicEquation;
|
import com.sap.sailing.polars.impl.CubicEquation;
|
||||||
import com.sap.sailing.polars.regression.IncrementalLeastSquares;
|
import com.sap.sailing.polars.regression.IncrementalLeastSquares;
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
|
||||||
import com.sap.sailing.polars.regression.impl.IncrementalAnyOrderLeastSquaresImpl;
|
import com.sap.sailing.polars.regression.impl.IncrementalAnyOrderLeastSquaresImpl;
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
import com.sap.sse.common.Util.Pair;
|
import com.sap.sse.common.Util.Pair;
|
||||||
@@ -48,7 +48,7 @@ public class AngleAndSpeedRegression {
|
|||||||
double estimatedAngle = angleRegression.getOrCreatePolynomialFunction().value(windSpeedInKnots);
|
double estimatedAngle = angleRegression.getOrCreatePolynomialFunction().value(windSpeedInKnots);
|
||||||
Bearing bearing = new DegreeBearingImpl(estimatedAngle);
|
Bearing bearing = new DegreeBearingImpl(estimatedAngle);
|
||||||
SpeedWithBearing speedWithBearing = new KnotSpeedWithBearingImpl(estimatedSpeed, bearing);
|
SpeedWithBearing speedWithBearing = new KnotSpeedWithBearingImpl(estimatedSpeed, bearing);
|
||||||
return new SpeedWithBearingWithConfidenceImpl<Void>(speedWithBearing, /*FIXME*/ 0.5, null);
|
return new SpeedWithBearingWithConfidenceImpl<Void>(speedWithBearing, Math.min(1, speedRegression.getNumberOfAddedPoints() / 100.0), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<SpeedWithBearingWithConfidence<Void>> estimateTrueWindSpeedAndAngleCandidates(Speed speedOverGround) throws NotEnoughDataHasBeenAddedException {
|
public Set<SpeedWithBearingWithConfidence<Void>> estimateTrueWindSpeedAndAngleCandidates(Speed speedOverGround) throws NotEnoughDataHasBeenAddedException {
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ import com.sap.sailing.domain.base.SpeedWithBearingWithConfidence;
|
|||||||
import com.sap.sailing.domain.common.LegType;
|
import com.sap.sailing.domain.common.LegType;
|
||||||
import com.sap.sailing.domain.common.Speed;
|
import com.sap.sailing.domain.common.Speed;
|
||||||
import com.sap.sailing.domain.common.Tack;
|
import com.sap.sailing.domain.common.Tack;
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
import com.sap.sse.datamining.AdditionalResultDataBuilder;
|
import com.sap.sse.datamining.AdditionalResultDataBuilder;
|
||||||
import com.sap.sse.datamining.components.Processor;
|
import com.sap.sse.datamining.components.Processor;
|
||||||
import com.sap.sse.datamining.factories.GroupKeyFactory;
|
import com.sap.sse.datamining.factories.GroupKeyFactory;
|
||||||
|
|||||||
+1
-29
@@ -34,7 +34,6 @@ public class GPSFixMovingWithPolarContext implements MovingAveragePolarClusterKe
|
|||||||
private final TrackedRace race;
|
private final TrackedRace race;
|
||||||
private final Competitor competitor;
|
private final Competitor competitor;
|
||||||
private final ClusterGroup<Speed> windSpeedClusterGroup;
|
private final ClusterGroup<Speed> windSpeedClusterGroup;
|
||||||
private final Set<WindSource> windSourcesToExcludeForBearing;
|
|
||||||
private final Set<WindSource> windSourcesToExcludeForSpeed;
|
private final Set<WindSource> windSourcesToExcludeForSpeed;
|
||||||
private final ClusterGroup<Bearing> angleClusterGroup;
|
private final ClusterGroup<Bearing> angleClusterGroup;
|
||||||
private final BearingWithConfidence<Integer> trueWindAngle;
|
private final BearingWithConfidence<Integer> trueWindAngle;
|
||||||
@@ -48,7 +47,6 @@ public class GPSFixMovingWithPolarContext implements MovingAveragePolarClusterKe
|
|||||||
this.competitor = competitor;
|
this.competitor = competitor;
|
||||||
this.windSpeedClusterGroup = windSpeedClusterGroup;
|
this.windSpeedClusterGroup = windSpeedClusterGroup;
|
||||||
this.angleClusterGroup = angleClusterGroup;
|
this.angleClusterGroup = angleClusterGroup;
|
||||||
this.windSourcesToExcludeForBearing = collectWindSourcesToIgnoreForBearing();
|
|
||||||
this.windSourcesToExcludeForSpeed = collectWindSourcesToIgnoreForSpeed();
|
this.windSourcesToExcludeForSpeed = collectWindSourcesToIgnoreForSpeed();
|
||||||
this.trueWindAngle = computeTrueWindAngle();
|
this.trueWindAngle = computeTrueWindAngle();
|
||||||
this.wind = race.getWindWithConfidence(fix.getPosition(), fix.getTimePoint(), windSourcesToExcludeForSpeed);
|
this.wind = race.getWindWithConfidence(fix.getPosition(), fix.getTimePoint(), windSourcesToExcludeForSpeed);
|
||||||
@@ -73,7 +71,7 @@ public class GPSFixMovingWithPolarContext implements MovingAveragePolarClusterKe
|
|||||||
|
|
||||||
private BearingWithConfidence<Integer> computeTrueWindAngle() {
|
private BearingWithConfidence<Integer> computeTrueWindAngle() {
|
||||||
SpeedWithBearing boatSpeed = race.getTrack(competitor).getEstimatedSpeed(fix.getTimePoint());
|
SpeedWithBearing boatSpeed = race.getTrack(competitor).getEstimatedSpeed(fix.getTimePoint());
|
||||||
WindWithConfidence<Pair<Position, TimePoint>> wind = race.getWindWithConfidence(fix.getPosition(), fix.getTimePoint(), windSourcesToExcludeForBearing);
|
WindWithConfidence<Pair<Position, TimePoint>> wind = race.getWindWithConfidence(fix.getPosition(), fix.getTimePoint());
|
||||||
|
|
||||||
BearingWithConfidenceImpl<Integer> result = null;
|
BearingWithConfidenceImpl<Integer> result = null;
|
||||||
if (wind != null && boatSpeed != null) {
|
if (wind != null && boatSpeed != null) {
|
||||||
@@ -105,32 +103,6 @@ public class GPSFixMovingWithPolarContext implements MovingAveragePolarClusterKe
|
|||||||
track.getMillisecondsOverWhichToAverageSpeed()/2, /* minimumConfidence */ 0.00000001));
|
track.getMillisecondsOverWhichToAverageSpeed()/2, /* minimumConfidence */ 0.00000001));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<WindSource> collectWindSourcesToIgnoreForBearing() {
|
|
||||||
Set<WindSource> windSourcesToExclude = new HashSet<WindSource>();
|
|
||||||
Iterable<WindSource> combinedSources = race.getWindSources(WindSourceType.COMBINED);
|
|
||||||
for (WindSource combinedSource : combinedSources) {
|
|
||||||
windSourcesToExclude.add(combinedSource);
|
|
||||||
}
|
|
||||||
Iterable<WindSource> courseSources = race.getWindSources(WindSourceType.COURSE_BASED);
|
|
||||||
for (WindSource courseSource : courseSources) {
|
|
||||||
windSourcesToExclude.add(courseSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterable<WindSource> expSources = race.getWindSources(WindSourceType.EXPEDITION);
|
|
||||||
for (WindSource expSource : expSources) {
|
|
||||||
windSourcesToExclude.add(expSource);
|
|
||||||
}
|
|
||||||
Iterable<WindSource> rcSources = race.getWindSources(WindSourceType.RACECOMMITTEE);
|
|
||||||
for (WindSource rcSource : rcSources) {
|
|
||||||
windSourcesToExclude.add(rcSource);
|
|
||||||
}
|
|
||||||
Iterable<WindSource> webSources = race.getWindSources(WindSourceType.WEB);
|
|
||||||
for (WindSource webSource : webSources) {
|
|
||||||
windSourcesToExclude.add(webSource);
|
|
||||||
}
|
|
||||||
return windSourcesToExclude;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<WindSource> collectWindSourcesToIgnoreForSpeed() {
|
private Set<WindSource> collectWindSourcesToIgnoreForSpeed() {
|
||||||
Set<WindSource> windSourcesToExclude = new HashSet<WindSource>();
|
Set<WindSource> windSourcesToExclude = new HashSet<WindSource>();
|
||||||
Iterable<WindSource> combinedSources = race.getWindSources(WindSourceType.COMBINED);
|
Iterable<WindSource> combinedSources = race.getWindSources(WindSourceType.COMBINED);
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ import com.sap.sailing.domain.base.SpeedWithBearingWithConfidence;
|
|||||||
import com.sap.sailing.domain.common.LegType;
|
import com.sap.sailing.domain.common.LegType;
|
||||||
import com.sap.sailing.domain.common.Speed;
|
import com.sap.sailing.domain.common.Speed;
|
||||||
import com.sap.sailing.domain.common.Tack;
|
import com.sap.sailing.domain.common.Tack;
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
import com.sap.sse.datamining.components.Processor;
|
import com.sap.sse.datamining.components.Processor;
|
||||||
import com.sap.sse.datamining.impl.components.GroupedDataEntry;
|
import com.sap.sse.datamining.impl.components.GroupedDataEntry;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -20,9 +20,9 @@ import com.sap.sailing.domain.common.Tack;
|
|||||||
import com.sap.sailing.domain.common.confidence.BearingWithConfidence;
|
import com.sap.sailing.domain.common.confidence.BearingWithConfidence;
|
||||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
||||||
import com.sap.sailing.polars.regression.MovingAverageBoatSpeedEstimator;
|
import com.sap.sailing.polars.regression.MovingAverageBoatSpeedEstimator;
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
import com.sap.sse.common.Util.Pair;
|
import com.sap.sse.common.Util.Pair;
|
||||||
import com.sap.sse.datamining.AdditionalResultDataBuilder;
|
import com.sap.sse.datamining.AdditionalResultDataBuilder;
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ import com.sap.sailing.domain.common.impl.PolarSheetGenerationSettingsImpl;
|
|||||||
import com.sap.sailing.domain.common.impl.PolarSheetsDataImpl;
|
import com.sap.sailing.domain.common.impl.PolarSheetsDataImpl;
|
||||||
import com.sap.sailing.domain.common.impl.PolarSheetsHistogramDataImpl;
|
import com.sap.sailing.domain.common.impl.PolarSheetsHistogramDataImpl;
|
||||||
import com.sap.sailing.domain.common.impl.WindSpeedSteppingWithMaxDistance;
|
import com.sap.sailing.domain.common.impl.WindSpeedSteppingWithMaxDistance;
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
import com.sap.sailing.polars.impl.CubicEquation;
|
import com.sap.sailing.polars.impl.CubicEquation;
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
|
||||||
import com.sap.sse.datamining.components.FilterCriterion;
|
import com.sap.sse.datamining.components.FilterCriterion;
|
||||||
import com.sap.sse.datamining.components.Processor;
|
import com.sap.sse.datamining.components.Processor;
|
||||||
import com.sap.sse.datamining.data.ClusterGroup;
|
import com.sap.sse.datamining.data.ClusterGroup;
|
||||||
|
|||||||
+1
-1
@@ -13,8 +13,8 @@ import com.sap.sailing.domain.common.Bearing;
|
|||||||
import com.sap.sailing.domain.common.Speed;
|
import com.sap.sailing.domain.common.Speed;
|
||||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||||
import com.sap.sailing.domain.common.impl.KnotSpeedImpl;
|
import com.sap.sailing.domain.common.impl.KnotSpeedImpl;
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
import com.sap.sailing.polars.regression.IncrementalLeastSquares;
|
import com.sap.sailing.polars.regression.IncrementalLeastSquares;
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
|
||||||
import com.sap.sailing.polars.regression.impl.IncrementalAnyOrderLeastSquaresImpl;
|
import com.sap.sailing.polars.regression.impl.IncrementalAnyOrderLeastSquaresImpl;
|
||||||
import com.sap.sse.datamining.AdditionalResultDataBuilder;
|
import com.sap.sse.datamining.AdditionalResultDataBuilder;
|
||||||
import com.sap.sse.datamining.components.Processor;
|
import com.sap.sse.datamining.components.Processor;
|
||||||
|
|||||||
+4
@@ -2,6 +2,8 @@ package com.sap.sailing.polars.regression;
|
|||||||
|
|
||||||
import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
|
import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support incremental regression linear in one variable but potentially of higher order.
|
* Support incremental regression linear in one variable but potentially of higher order.
|
||||||
*
|
*
|
||||||
@@ -28,4 +30,6 @@ public interface IncrementalLeastSquares {
|
|||||||
*/
|
*/
|
||||||
public abstract PolynomialFunction getOrCreatePolynomialFunction() throws NotEnoughDataHasBeenAddedException;
|
public abstract PolynomialFunction getOrCreatePolynomialFunction() throws NotEnoughDataHasBeenAddedException;
|
||||||
|
|
||||||
|
public abstract long getNumberOfAddedPoints();
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
@@ -5,6 +5,7 @@ import java.io.Serializable;
|
|||||||
|
|
||||||
import com.sap.sailing.domain.common.Speed;
|
import com.sap.sailing.domain.common.Speed;
|
||||||
import com.sap.sailing.domain.common.impl.KnotSpeedImpl;
|
import com.sap.sailing.domain.common.impl.KnotSpeedImpl;
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
import com.sap.sailing.polars.mining.MovingAverageProcessorImpl;
|
import com.sap.sailing.polars.mining.MovingAverageProcessorImpl;
|
||||||
import com.sap.sse.concurrent.LockUtil;
|
import com.sap.sse.concurrent.LockUtil;
|
||||||
import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
|
import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
|
||||||
|
|||||||
+6
-1
@@ -12,8 +12,8 @@ import org.apache.commons.math.linear.RealMatrixPreservingVisitor;
|
|||||||
import org.apache.commons.math.linear.RealVector;
|
import org.apache.commons.math.linear.RealVector;
|
||||||
import org.apache.commons.math.linear.SingularMatrixException;
|
import org.apache.commons.math.linear.SingularMatrixException;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
import com.sap.sailing.polars.regression.IncrementalLeastSquares;
|
import com.sap.sailing.polars.regression.IncrementalLeastSquares;
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
|
||||||
import com.sap.sse.concurrent.LockUtil;
|
import com.sap.sse.concurrent.LockUtil;
|
||||||
import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
|
import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
|
||||||
|
|
||||||
@@ -297,4 +297,9 @@ public class IncrementalAnyOrderLeastSquaresImpl implements IncrementalLeastSqua
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getNumberOfAddedPoints() {
|
||||||
|
return numberOfPointsAdded.get();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
-2
@@ -35,11 +35,11 @@ import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
|||||||
import com.sap.sailing.domain.common.impl.WindImpl;
|
import com.sap.sailing.domain.common.impl.WindImpl;
|
||||||
import com.sap.sailing.domain.common.scalablevalue.impl.ScalableBearing;
|
import com.sap.sailing.domain.common.scalablevalue.impl.ScalableBearing;
|
||||||
import com.sap.sailing.domain.common.scalablevalue.impl.ScalableSpeed;
|
import com.sap.sailing.domain.common.scalablevalue.impl.ScalableSpeed;
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.domain.tracking.Maneuver;
|
import com.sap.sailing.domain.tracking.Maneuver;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.impl.WindTrackImpl;
|
import com.sap.sailing.domain.tracking.impl.WindTrackImpl;
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
import com.sap.sse.common.Util;
|
import com.sap.sse.common.Util;
|
||||||
import com.sap.sse.common.Util.Pair;
|
import com.sap.sse.common.Util.Pair;
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ import java.util.function.Function;
|
|||||||
import com.sap.sailing.domain.common.ManeuverType;
|
import com.sap.sailing.domain.common.ManeuverType;
|
||||||
import com.sap.sailing.domain.common.confidence.ConfidenceBasedAverager;
|
import com.sap.sailing.domain.common.confidence.ConfidenceBasedAverager;
|
||||||
import com.sap.sailing.domain.common.confidence.HasConfidenceAndIsScalable;
|
import com.sap.sailing.domain.common.confidence.HasConfidenceAndIsScalable;
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.polars.windestimation.ManeuverBasedWindEstimationTrackImpl.ManeuverClassification;
|
import com.sap.sailing.polars.windestimation.ManeuverBasedWindEstimationTrackImpl.ManeuverClassification;
|
||||||
import com.sap.sse.common.scalablevalue.ScalableValue;
|
import com.sap.sse.common.scalablevalue.ScalableValue;
|
||||||
|
|
||||||
|
|||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
package com.sap.sailing.server.gateway.serialization.impl;
|
||||||
|
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration;
|
||||||
|
import com.sap.sailing.domain.base.configuration.procedures.LeagueConfiguration;
|
||||||
|
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
|
||||||
|
|
||||||
|
public class LeagueConfigurationJsonSerializer extends RacingProcedureConfigurationJsonSerializer implements
|
||||||
|
JsonSerializer<RacingProcedureConfiguration> {
|
||||||
|
|
||||||
|
public static LeagueConfigurationJsonSerializer create() {
|
||||||
|
return new LeagueConfigurationJsonSerializer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LeagueConfigurationJsonSerializer() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject serialize(RacingProcedureConfiguration baseObject) {
|
||||||
|
JSONObject result = super.serialize(baseObject);
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
LeagueConfiguration object = (LeagueConfiguration) baseObject;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+9
-2
@@ -11,7 +11,7 @@ public class RegattaConfigurationJsonSerializer implements JsonSerializer<Regatt
|
|||||||
public static RegattaConfigurationJsonSerializer create() {
|
public static RegattaConfigurationJsonSerializer create() {
|
||||||
return new RegattaConfigurationJsonSerializer(RRS26ConfigurationJsonSerializer.create(),
|
return new RegattaConfigurationJsonSerializer(RRS26ConfigurationJsonSerializer.create(),
|
||||||
GateStartConfigurationJsonSerializer.create(), ESSConfigurationJsonSerializer.create(),
|
GateStartConfigurationJsonSerializer.create(), ESSConfigurationJsonSerializer.create(),
|
||||||
RacingProcedureConfigurationJsonSerializer.create());
|
RacingProcedureConfigurationJsonSerializer.create(), LeagueConfigurationJsonSerializer.create());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Object FIELD_DEFAULT_RACING_PROCEDURE_TYPE = "defaultRacingProcedureType";
|
public static final Object FIELD_DEFAULT_RACING_PROCEDURE_TYPE = "defaultRacingProcedureType";
|
||||||
@@ -19,20 +19,23 @@ public class RegattaConfigurationJsonSerializer implements JsonSerializer<Regatt
|
|||||||
public static final String FIELD_RRS26 = "rrs26";
|
public static final String FIELD_RRS26 = "rrs26";
|
||||||
public static final String FIELD_GATE_START = "gateStart";
|
public static final String FIELD_GATE_START = "gateStart";
|
||||||
public static final String FIELD_ESS = "ess";
|
public static final String FIELD_ESS = "ess";
|
||||||
|
public static final String FIELD_LEAGUE = "league";
|
||||||
public static final String FIELD_BASIC = "basic";
|
public static final String FIELD_BASIC = "basic";
|
||||||
|
|
||||||
private final JsonSerializer<RacingProcedureConfiguration> rrs26Serializer;
|
private final JsonSerializer<RacingProcedureConfiguration> rrs26Serializer;
|
||||||
private final JsonSerializer<RacingProcedureConfiguration> gateStartSerializer;
|
private final JsonSerializer<RacingProcedureConfiguration> gateStartSerializer;
|
||||||
private final JsonSerializer<RacingProcedureConfiguration> essSerializer;
|
private final JsonSerializer<RacingProcedureConfiguration> essSerializer;
|
||||||
private final JsonSerializer<RacingProcedureConfiguration> basicSerializer;
|
private final JsonSerializer<RacingProcedureConfiguration> basicSerializer;
|
||||||
|
private final JsonSerializer<RacingProcedureConfiguration> leagueSerializer;
|
||||||
|
|
||||||
public RegattaConfigurationJsonSerializer(JsonSerializer<RacingProcedureConfiguration> rrs26,
|
public RegattaConfigurationJsonSerializer(JsonSerializer<RacingProcedureConfiguration> rrs26,
|
||||||
JsonSerializer<RacingProcedureConfiguration> gateStart, JsonSerializer<RacingProcedureConfiguration> ess,
|
JsonSerializer<RacingProcedureConfiguration> gateStart, JsonSerializer<RacingProcedureConfiguration> ess,
|
||||||
JsonSerializer<RacingProcedureConfiguration> basicSerializer) {
|
JsonSerializer<RacingProcedureConfiguration> basicSerializer, JsonSerializer<RacingProcedureConfiguration> leagueSerializer) {
|
||||||
this.rrs26Serializer = rrs26;
|
this.rrs26Serializer = rrs26;
|
||||||
this.gateStartSerializer = gateStart;
|
this.gateStartSerializer = gateStart;
|
||||||
this.essSerializer = ess;
|
this.essSerializer = ess;
|
||||||
this.basicSerializer = basicSerializer;
|
this.basicSerializer = basicSerializer;
|
||||||
|
this.leagueSerializer = leagueSerializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -59,6 +62,10 @@ public class RegattaConfigurationJsonSerializer implements JsonSerializer<Regatt
|
|||||||
if (object.getBasicConfiguration() != null) {
|
if (object.getBasicConfiguration() != null) {
|
||||||
result.put(FIELD_BASIC, basicSerializer.serialize(object.getBasicConfiguration()));
|
result.put(FIELD_BASIC, basicSerializer.serialize(object.getBasicConfiguration()));
|
||||||
}
|
}
|
||||||
|
if (object.getLeagueConfiguration() != null) {
|
||||||
|
result.put(FIELD_LEAGUE, leagueSerializer.serialize(object.getLeagueConfiguration()));
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,7 @@ Bundle-SymbolicName: com.sap.sailing.server.gateway
|
|||||||
Bundle-Version: 1.0.0.qualifier
|
Bundle-Version: 1.0.0.qualifier
|
||||||
Bundle-Vendor: SAP
|
Bundle-Vendor: SAP
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||||
Import-Package: com.sap.sailing.polars,
|
Import-Package: com.sap.sailing.server,
|
||||||
com.sap.sailing.polars.regression,
|
|
||||||
com.sap.sailing.polars.windestimation,
|
|
||||||
com.sap.sailing.server,
|
|
||||||
com.sap.sailing.server.operationaltransformation,
|
com.sap.sailing.server.operationaltransformation,
|
||||||
javax.ws.rs;version="1.1.1",
|
javax.ws.rs;version="1.1.1",
|
||||||
javax.ws.rs.core;version="1.1.1",
|
javax.ws.rs.core;version="1.1.1",
|
||||||
@@ -55,7 +52,8 @@ Require-Bundle: com.sap.sailing.domain,
|
|||||||
org.apache.shiro.core;bundle-version="1.2.2",
|
org.apache.shiro.core;bundle-version="1.2.2",
|
||||||
org.apache.shiro.web;bundle-version="1.2.2",
|
org.apache.shiro.web;bundle-version="1.2.2",
|
||||||
org.apache.shiro.ehcache;bundle-version="1.2.3",
|
org.apache.shiro.ehcache;bundle-version="1.2.3",
|
||||||
org.jvnet.mimepull;bundle-version="1.9.4"
|
org.jvnet.mimepull;bundle-version="1.9.4",
|
||||||
|
com.sap.sailing.polars
|
||||||
Bundle-ClassPath: .
|
Bundle-ClassPath: .
|
||||||
Web-ContextPath: /sailingserver
|
Web-ContextPath: /sailingserver
|
||||||
Export-Package: com.sap.sailing.server.gateway,
|
Export-Package: com.sap.sailing.server.gateway,
|
||||||
|
|||||||
+2
-2
@@ -31,9 +31,9 @@ import com.sap.sailing.domain.common.confidence.impl.ScalableDouble;
|
|||||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||||
import com.sap.sailing.domain.common.impl.KnotSpeedImpl;
|
import com.sap.sailing.domain.common.impl.KnotSpeedImpl;
|
||||||
import com.sap.sailing.domain.common.scalablevalue.impl.ScalableBearing;
|
import com.sap.sailing.domain.common.scalablevalue.impl.ScalableBearing;
|
||||||
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
|
||||||
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
|
|
||||||
import com.sap.sailing.polars.windestimation.ManeuverBasedWindEstimationTrackImpl;
|
import com.sap.sailing.polars.windestimation.ManeuverBasedWindEstimationTrackImpl;
|
||||||
import com.sap.sailing.polars.windestimation.ManeuverBasedWindEstimationTrackImpl.ManeuverClassification;
|
import com.sap.sailing.polars.windestimation.ManeuverBasedWindEstimationTrackImpl.ManeuverClassification;
|
||||||
import com.sap.sailing.polars.windestimation.ScalableBearingAndScalableDouble;
|
import com.sap.sailing.polars.windestimation.ScalableBearingAndScalableDouble;
|
||||||
|
|||||||
+13
@@ -691,6 +691,19 @@ public class MasterDataImportTest {
|
|||||||
} finally {
|
} finally {
|
||||||
windTrackOnDest.unlockAfterRead();
|
windTrackOnDest.unlockAfterRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Reimport again to see if db throws exceptions (see console for error for now, since exception is caught deep inside)
|
||||||
|
try {
|
||||||
|
streamingOutput.write(os);
|
||||||
|
os.flush();
|
||||||
|
|
||||||
|
inputStream = new ByteArrayInputStream(os.toByteArray());
|
||||||
|
MasterDataImporter importer = new MasterDataImporter(domainFactory, destService);
|
||||||
|
importer.importFromStream(inputStream, randomUUID, false);
|
||||||
|
} finally {
|
||||||
|
os.close();
|
||||||
|
inputStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ Bundle-Version: 1.0.0.qualifier
|
|||||||
Bundle-Activator: com.sap.sailing.server.impl.Activator
|
Bundle-Activator: com.sap.sailing.server.impl.Activator
|
||||||
Bundle-Vendor: SAP
|
Bundle-Vendor: SAP
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||||
Import-Package: com.sap.sailing.polars,
|
Import-Package: com.sap.sailing.server.gateway.deserialization,
|
||||||
com.sap.sailing.polars.factory,
|
|
||||||
com.sap.sailing.server.gateway.deserialization,
|
|
||||||
org.json.simple,
|
org.json.simple,
|
||||||
org.json.simple.parser,
|
org.json.simple.parser,
|
||||||
org.osgi.framework;version="1.3.0",
|
org.osgi.framework;version="1.3.0",
|
||||||
@@ -24,14 +22,14 @@ Require-Bundle: com.sap.sailing.domain,
|
|||||||
com.sap.sailing.udpconnector,
|
com.sap.sailing.udpconnector,
|
||||||
com.sap.sailing.domain.shared.android,
|
com.sap.sailing.domain.shared.android,
|
||||||
com.sap.sailing.server.gateway.serialization,
|
com.sap.sailing.server.gateway.serialization,
|
||||||
com.sap.sailing.polars,
|
|
||||||
com.sap.sse.common,
|
com.sap.sse.common,
|
||||||
com.sap.sse.operationaltransformation,
|
com.sap.sse.operationaltransformation,
|
||||||
com.sap.sse.replication,
|
com.sap.sse.replication,
|
||||||
com.sap.sse,
|
com.sap.sse,
|
||||||
com.sap.sailing.server.gateway.serialization.shared.android,
|
com.sap.sailing.server.gateway.serialization.shared.android,
|
||||||
com.sap.sse.shared.android,
|
com.sap.sse.shared.android,
|
||||||
com.sap.sse.filestorage
|
com.sap.sse.filestorage,
|
||||||
|
com.sap.sailing.simulator;bundle-version="1.0.0"
|
||||||
Bundle-ClassPath: .
|
Bundle-ClassPath: .
|
||||||
Export-Package: com.sap.sailing.server,
|
Export-Package: com.sap.sailing.server,
|
||||||
com.sap.sailing.server.impl;
|
com.sap.sailing.server.impl;
|
||||||
@@ -43,5 +41,6 @@ Export-Package: com.sap.sailing.server,
|
|||||||
com.sap.sailing.server.replication.test,
|
com.sap.sailing.server.replication.test,
|
||||||
com.sap.sailing.domain.racelogtrackingadapter.test",
|
com.sap.sailing.domain.racelogtrackingadapter.test",
|
||||||
com.sap.sailing.server.masterdata,
|
com.sap.sailing.server.masterdata,
|
||||||
com.sap.sailing.server.operationaltransformation
|
com.sap.sailing.server.operationaltransformation,
|
||||||
|
com.sap.sailing.server.simulation
|
||||||
|
|
||||||
@@ -55,6 +55,7 @@ import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
|||||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||||
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
||||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||||
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||||
import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike;
|
import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
@@ -65,8 +66,8 @@ import com.sap.sailing.domain.tracking.TrackedRegatta;
|
|||||||
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
|
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
|
||||||
import com.sap.sailing.domain.tracking.TrackerManager;
|
import com.sap.sailing.domain.tracking.TrackerManager;
|
||||||
import com.sap.sailing.domain.tracking.WindStore;
|
import com.sap.sailing.domain.tracking.WindStore;
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
|
||||||
import com.sap.sailing.server.masterdata.DataImportLockWithProgress;
|
import com.sap.sailing.server.masterdata.DataImportLockWithProgress;
|
||||||
|
import com.sap.sailing.server.simulation.SimulationService;
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
||||||
import com.sap.sse.common.Util;
|
import com.sap.sse.common.Util;
|
||||||
@@ -521,7 +522,9 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
|
|||||||
WindStore getWindStore();
|
WindStore getWindStore();
|
||||||
|
|
||||||
PolarDataService getPolarDataService();
|
PolarDataService getPolarDataService();
|
||||||
|
|
||||||
|
SimulationService getSimulationService();
|
||||||
|
|
||||||
GPSFixStore getGPSFixStore();
|
GPSFixStore getGPSFixStore();
|
||||||
|
|
||||||
RaceTracker getRaceTrackerById(Object id);
|
RaceTracker getRaceTrackerById(Object id);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
|||||||
import com.sap.sailing.domain.persistence.racelog.tracking.GPSFixMongoHandler;
|
import com.sap.sailing.domain.persistence.racelog.tracking.GPSFixMongoHandler;
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.impl.GPSFixMongoHandlerImpl;
|
import com.sap.sailing.domain.persistence.racelog.tracking.impl.GPSFixMongoHandlerImpl;
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.impl.GPSFixMovingMongoHandlerImpl;
|
import com.sap.sailing.domain.persistence.racelog.tracking.impl.GPSFixMovingMongoHandlerImpl;
|
||||||
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.server.MasterDataImportClassLoaderService;
|
import com.sap.sailing.server.MasterDataImportClassLoaderService;
|
||||||
import com.sap.sailing.server.RacingEventService;
|
import com.sap.sailing.server.RacingEventService;
|
||||||
import com.sap.sailing.server.RacingEventServiceMXBean;
|
import com.sap.sailing.server.RacingEventServiceMXBean;
|
||||||
@@ -55,6 +56,8 @@ public class Activator implements BundleActivator {
|
|||||||
|
|
||||||
private ServiceTracker<MasterDataImportClassLoaderService, MasterDataImportClassLoaderService> masterDataImportClassLoaderServiceTracker;
|
private ServiceTracker<MasterDataImportClassLoaderService, MasterDataImportClassLoaderService> masterDataImportClassLoaderServiceTracker;
|
||||||
|
|
||||||
|
private ServiceTracker<PolarDataService, PolarDataService> polarDataServiceTracker;
|
||||||
|
|
||||||
public Activator() {
|
public Activator() {
|
||||||
clearPersistentCompetitors = Boolean.valueOf(System.getProperty(CLEAR_PERSISTENT_COMPETITORS_PROPERTY_NAME, ""+false));
|
clearPersistentCompetitors = Boolean.valueOf(System.getProperty(CLEAR_PERSISTENT_COMPETITORS_PROPERTY_NAME, ""+false));
|
||||||
logger.log(Level.INFO, "setting "+CLEAR_PERSISTENT_COMPETITORS_PROPERTY_NAME+" to "+clearPersistentCompetitors);
|
logger.log(Level.INFO, "setting "+CLEAR_PERSISTENT_COMPETITORS_PROPERTY_NAME+" to "+clearPersistentCompetitors);
|
||||||
@@ -77,6 +80,10 @@ public class Activator implements BundleActivator {
|
|||||||
context, MasterDataImportClassLoaderService.class,
|
context, MasterDataImportClassLoaderService.class,
|
||||||
new MasterDataImportClassLoaderServiceTrackerCustomizer(context, racingEventService));
|
new MasterDataImportClassLoaderServiceTrackerCustomizer(context, racingEventService));
|
||||||
masterDataImportClassLoaderServiceTracker.open();
|
masterDataImportClassLoaderServiceTracker.open();
|
||||||
|
|
||||||
|
polarDataServiceTracker = new ServiceTracker<PolarDataService, PolarDataService>(context,
|
||||||
|
PolarDataService.class, new PolarDataServiceTrackerCustomizer(context, racingEventService));
|
||||||
|
polarDataServiceTracker.open();
|
||||||
|
|
||||||
// register the racing service in the OSGi registry
|
// register the racing service in the OSGi registry
|
||||||
racingEventService.setBundleContext(context);
|
racingEventService.setBundleContext(context);
|
||||||
@@ -86,14 +93,22 @@ public class Activator implements BundleActivator {
|
|||||||
context.registerService(RacingEventService.class.getName(), racingEventService, null);
|
context.registerService(RacingEventService.class.getName(), racingEventService, null);
|
||||||
context.registerService(ClearStateTestSupport.class.getName(), racingEventService, null);
|
context.registerService(ClearStateTestSupport.class.getName(), racingEventService, null);
|
||||||
Dictionary<String, String> properties = new Hashtable<String, String>();
|
Dictionary<String, String> properties = new Hashtable<String, String>();
|
||||||
|
final GPSFixMongoHandlerImpl gpsFixMongoHandler = new GPSFixMongoHandlerImpl(racingEventService.getMongoObjectFactory(),
|
||||||
|
racingEventService.getDomainObjectFactory());
|
||||||
properties.put(TypeBasedServiceFinder.TYPE, GPSFixImpl.class.getName());
|
properties.put(TypeBasedServiceFinder.TYPE, GPSFixImpl.class.getName());
|
||||||
registrations.add(context.registerService(GPSFixMongoHandler.class,
|
registrations.add(context.registerService(GPSFixMongoHandler.class,
|
||||||
new GPSFixMongoHandlerImpl(racingEventService.getMongoObjectFactory(),
|
gpsFixMongoHandler, properties));
|
||||||
racingEventService.getDomainObjectFactory()), properties));
|
// legacy type name; some DBs may still contain fixes marked with this old package name:
|
||||||
properties.put(TypeBasedServiceFinder.TYPE, GPSFixMovingImpl.class.getName());
|
properties.put(TypeBasedServiceFinder.TYPE, "com.sap.sailing.domain.tracking.impl.GPSFixImpl");
|
||||||
registrations.add(context.registerService(GPSFixMongoHandler.class,
|
registrations.add(context.registerService(GPSFixMongoHandler.class,
|
||||||
new GPSFixMovingMongoHandlerImpl(racingEventService.getMongoObjectFactory(),
|
gpsFixMongoHandler, properties));
|
||||||
racingEventService.getDomainObjectFactory()), properties));
|
final GPSFixMovingMongoHandlerImpl gpsFixMovingMongoHandler = new GPSFixMovingMongoHandlerImpl(racingEventService.getMongoObjectFactory(),
|
||||||
|
racingEventService.getDomainObjectFactory());
|
||||||
|
properties.put(TypeBasedServiceFinder.TYPE, GPSFixMovingImpl.class.getName());
|
||||||
|
registrations.add(context.registerService(GPSFixMongoHandler.class, gpsFixMovingMongoHandler, properties));
|
||||||
|
// legacy type name; some DBs may still contain fixes marked with this old package name:
|
||||||
|
properties.put(TypeBasedServiceFinder.TYPE, "com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl");
|
||||||
|
registrations.add(context.registerService(GPSFixMongoHandler.class, gpsFixMovingMongoHandler, properties));
|
||||||
// Add an MBean for the service to the JMX bean server:
|
// Add an MBean for the service to the JMX bean server:
|
||||||
RacingEventServiceMXBean mbean = new RacingEventServiceMXBeanImpl(racingEventService);
|
RacingEventServiceMXBean mbean = new RacingEventServiceMXBeanImpl(racingEventService);
|
||||||
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
|
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
|
||||||
@@ -156,5 +171,34 @@ public class Activator implements BundleActivator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class PolarDataServiceTrackerCustomizer implements
|
||||||
|
ServiceTrackerCustomizer<PolarDataService, PolarDataService> {
|
||||||
|
|
||||||
|
private final BundleContext context;
|
||||||
|
private RacingEventServiceImpl racingEventService;
|
||||||
|
|
||||||
|
public PolarDataServiceTrackerCustomizer(BundleContext context, RacingEventServiceImpl racingEventService) {
|
||||||
|
this.context = context;
|
||||||
|
this.racingEventService = racingEventService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PolarDataService addingService(ServiceReference<PolarDataService> reference) {
|
||||||
|
PolarDataService service = context.getService(reference);
|
||||||
|
racingEventService.setPolarDataService(service);
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void modifiedService(ServiceReference<PolarDataService> reference, PolarDataService service) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removedService(ServiceReference<PolarDataService> reference, PolarDataService service) {
|
||||||
|
racingEventService.unsetPolarDataService(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+53
-10
@@ -127,6 +127,7 @@ import com.sap.sailing.domain.persistence.PersistenceFactory;
|
|||||||
import com.sap.sailing.domain.persistence.media.MediaDB;
|
import com.sap.sailing.domain.persistence.media.MediaDB;
|
||||||
import com.sap.sailing.domain.persistence.media.MediaDBFactory;
|
import com.sap.sailing.domain.persistence.media.MediaDBFactory;
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.MongoGPSFixStoreFactory;
|
import com.sap.sailing.domain.persistence.racelog.tracking.MongoGPSFixStoreFactory;
|
||||||
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
|
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
|
||||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||||
@@ -153,8 +154,6 @@ import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
|
|||||||
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixTrackImpl;
|
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixTrackImpl;
|
||||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
|
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
|
||||||
import com.sap.sailing.expeditionconnector.ExpeditionWindTrackerFactory;
|
import com.sap.sailing.expeditionconnector.ExpeditionWindTrackerFactory;
|
||||||
import com.sap.sailing.polars.PolarDataService;
|
|
||||||
import com.sap.sailing.polars.factory.PolarDataServiceFactory;
|
|
||||||
import com.sap.sailing.server.RacingEventService;
|
import com.sap.sailing.server.RacingEventService;
|
||||||
import com.sap.sailing.server.Replicator;
|
import com.sap.sailing.server.Replicator;
|
||||||
import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer;
|
||||||
@@ -200,6 +199,8 @@ import com.sap.sailing.server.operationaltransformation.UpdateStartTimeReceived;
|
|||||||
import com.sap.sailing.server.operationaltransformation.UpdateTrackedRaceStatus;
|
import com.sap.sailing.server.operationaltransformation.UpdateTrackedRaceStatus;
|
||||||
import com.sap.sailing.server.operationaltransformation.UpdateWindAveragingTime;
|
import com.sap.sailing.server.operationaltransformation.UpdateWindAveragingTime;
|
||||||
import com.sap.sailing.server.operationaltransformation.UpdateWindSourcesToExclude;
|
import com.sap.sailing.server.operationaltransformation.UpdateWindSourcesToExclude;
|
||||||
|
import com.sap.sailing.server.simulation.SimulationService;
|
||||||
|
import com.sap.sailing.server.simulation.SimulationServiceFactory;
|
||||||
import com.sap.sse.BuildVersion;
|
import com.sap.sse.BuildVersion;
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
||||||
@@ -351,7 +352,9 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
private final AbstractLogEventAuthor raceLogEventAuthorForServer = new LogEventAuthorImpl(
|
private final AbstractLogEventAuthor raceLogEventAuthorForServer = new LogEventAuthorImpl(
|
||||||
RacingEventService.class.getName(), 0);
|
RacingEventService.class.getName(), 0);
|
||||||
|
|
||||||
private final PolarDataService polarDataService;
|
private PolarDataService polarDataService;
|
||||||
|
|
||||||
|
private final SimulationService simulationService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow only one master data import at a time to avoid situation where multiple Imports override each other in
|
* Allow only one master data import at a time to avoid situation where multiple Imports override each other in
|
||||||
@@ -504,13 +507,13 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
operationExecutionListeners = new ConcurrentHashMap<>();
|
operationExecutionListeners = new ConcurrentHashMap<>();
|
||||||
courseListeners = new ConcurrentHashMap<>();
|
courseListeners = new ConcurrentHashMap<>();
|
||||||
persistentRegattasForRaceIDs = new ConcurrentHashMap<>();
|
persistentRegattasForRaceIDs = new ConcurrentHashMap<>();
|
||||||
final int THREAD_POOL_SIZE = Math.max(Runtime.getRuntime().availableProcessors(), 3);
|
final int SIMULATION_THREAD_POOL_SIZE = Math.max(Runtime.getRuntime().availableProcessors()/3, 1);
|
||||||
// TODO find out how many executors we have on server side and how to manage them
|
Executor simulatorExecutor = new ThreadPoolExecutor(/* corePoolSize */SIMULATION_THREAD_POOL_SIZE,
|
||||||
Executor polarExecutor = new ThreadPoolExecutor(/* corePoolSize */THREAD_POOL_SIZE,
|
/* maximumPoolSize */SIMULATION_THREAD_POOL_SIZE,
|
||||||
/* maximumPoolSize */THREAD_POOL_SIZE,
|
|
||||||
/* keepAliveTime */60, TimeUnit.SECONDS,
|
/* keepAliveTime */60, TimeUnit.SECONDS,
|
||||||
/* workQueue */new LinkedBlockingQueue<Runnable>());
|
/* workQueue */new LinkedBlockingQueue<Runnable>());
|
||||||
polarDataService = PolarDataServiceFactory.createStandardPolarDataService(polarExecutor);
|
// TODO: initialize smart-future-cache for simulation-results and add to simulation-service
|
||||||
|
simulationService = SimulationServiceFactory.INSTANCE.getService(simulatorExecutor, this);
|
||||||
this.raceLogReplicator = new RaceLogReplicator(this);
|
this.raceLogReplicator = new RaceLogReplicator(this);
|
||||||
this.regattaLogReplicator = new RegattaLogReplicator(this);
|
this.regattaLogReplicator = new RegattaLogReplicator(this);
|
||||||
this.raceLogScoringReplicator = new RaceLogScoringReplicator(this);
|
this.raceLogScoringReplicator = new RaceLogScoringReplicator(this);
|
||||||
@@ -559,6 +562,11 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
return polarDataService;
|
return polarDataService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SimulationService getSimulationService() {
|
||||||
|
return simulationService;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearState() throws Exception {
|
public void clearState() throws Exception {
|
||||||
for (String leaderboardGroupName : new ArrayList<>(this.leaderboardGroupsByName.keySet())) {
|
for (String leaderboardGroupName : new ArrayList<>(this.leaderboardGroupsByName.keySet())) {
|
||||||
@@ -1526,6 +1534,10 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
PolarFixCacheUpdater polarFixCacheUpdater = new PolarFixCacheUpdater(trackedRace);
|
PolarFixCacheUpdater polarFixCacheUpdater = new PolarFixCacheUpdater(trackedRace);
|
||||||
polarFixCacheUpdaters.put(trackedRace, polarFixCacheUpdater);
|
polarFixCacheUpdaters.put(trackedRace, polarFixCacheUpdater);
|
||||||
trackedRace.addListener(polarFixCacheUpdater);
|
trackedRace.addListener(polarFixCacheUpdater);
|
||||||
|
|
||||||
|
if (polarDataService != null) {
|
||||||
|
trackedRace.setPolarDataService(polarDataService);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1539,14 +1551,18 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void competitorPositionChanged(GPSFixMoving fix, Competitor item) {
|
public void competitorPositionChanged(GPSFixMoving fix, Competitor item) {
|
||||||
polarDataService.competitorPositionChanged(fix, item, race);
|
if (polarDataService != null) {
|
||||||
|
polarDataService.competitorPositionChanged(fix, item, race);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void statusChanged(TrackedRaceStatus newStatus, TrackedRaceStatus oldStatus) {
|
public void statusChanged(TrackedRaceStatus newStatus, TrackedRaceStatus oldStatus) {
|
||||||
if (oldStatus.getStatus() == TrackedRaceStatusEnum.LOADING
|
if (oldStatus.getStatus() == TrackedRaceStatusEnum.LOADING
|
||||||
&& newStatus.getStatus() != TrackedRaceStatusEnum.LOADING) {
|
&& newStatus.getStatus() != TrackedRaceStatusEnum.LOADING) {
|
||||||
polarDataService.raceFinishedLoading(race);
|
if (polarDataService != null) {
|
||||||
|
polarDataService.raceFinishedLoading(race);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3113,4 +3129,31 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
|||||||
JoinedClassLoader joinedClassLoader = new JoinedClassLoader(masterDataClassLoaders);
|
JoinedClassLoader joinedClassLoader = new JoinedClassLoader(masterDataClassLoaders);
|
||||||
return joinedClassLoader;
|
return joinedClassLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPolarDataService(PolarDataService service) {
|
||||||
|
if (this.polarDataService == null) {
|
||||||
|
polarDataService = service;
|
||||||
|
setPolarDataServiceOnAllTrackedRaces(service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPolarDataServiceOnAllTrackedRaces(PolarDataService service) {
|
||||||
|
Iterable<Regatta> allRegattas = getAllRegattas();
|
||||||
|
for (Regatta regatta : allRegattas) {
|
||||||
|
DynamicTrackedRegatta trackedRegatta = getTrackedRegatta(regatta);
|
||||||
|
if (trackedRegatta != null) {
|
||||||
|
Iterable<DynamicTrackedRace> trackedRaces = trackedRegatta.getTrackedRaces();
|
||||||
|
for (TrackedRace trackedRace : trackedRaces) {
|
||||||
|
trackedRace.setPolarDataService(service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unsetPolarDataService(PolarDataService service) {
|
||||||
|
if (polarDataService == service) {
|
||||||
|
polarDataService = null;
|
||||||
|
setPolarDataService(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loaded 100 of 171 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user