mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-13 14:12:11 +00:00
improved ORC certificate display in AdminConsole
This commit is contained in:
1 parent
45b5669b0d
commit
3228ee4841
18 files changed
+217
-37
No files matched your search
+6
@@ -5,6 +5,7 @@ import com.sap.sailing.domain.common.impl.NauticalMileDistance;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.Speed;
|
||||
import com.sap.sse.common.impl.SecondsDurationImpl;
|
||||
|
||||
public abstract class AbstractDistance implements Distance {
|
||||
|
||||
@@ -41,6 +42,11 @@ public abstract class AbstractDistance implements Distance {
|
||||
return inSeconds(duration.asSeconds());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration atSpeed(Speed speed) {
|
||||
return new SecondsDurationImpl(getMeters() / speed.getMetersPerSecond());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNauticalMiles() {
|
||||
return getMeters() / Mile.METERS_PER_NAUTICAL_MILE;
|
||||
|
||||
+3
@@ -4,6 +4,7 @@ import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedImpl;
|
||||
import com.sap.sailing.domain.common.impl.NauticalMileDistance;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.CountryCode;
|
||||
import com.sap.sse.common.Distance;
|
||||
@@ -64,6 +65,8 @@ public interface ORCCertificate extends WithID, Serializable {
|
||||
Bearing[] ALLOWANCES_TRUE_WIND_ANGLES = { new DegreeBearingImpl(52), new DegreeBearingImpl(60),
|
||||
new DegreeBearingImpl(75), new DegreeBearingImpl(90), new DegreeBearingImpl(110),
|
||||
new DegreeBearingImpl(120), new DegreeBearingImpl(135), new DegreeBearingImpl(150) };
|
||||
|
||||
Distance NAUTICAL_MILE = new NauticalMileDistance(1);
|
||||
|
||||
/**
|
||||
* We use the {@link #getReferenceNumber() reference number ("RefNo")} as the ID of a certificate document.
|
||||
|
||||
-3
@@ -3,7 +3,6 @@ package com.sap.sailing.domain.common.orc.impl;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.common.impl.NauticalMileDistance;
|
||||
import com.sap.sailing.domain.common.orc.ORCCertificate;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.CountryCode;
|
||||
@@ -27,8 +26,6 @@ public class ORCCertificateImpl implements ORCCertificate {
|
||||
|
||||
private final String referenceNumber;
|
||||
|
||||
public final static Distance NAUTICAL_MILE = new NauticalMileDistance(1);
|
||||
|
||||
private final String sailNumber;
|
||||
private final String boatName;
|
||||
private final String boatClassName;
|
||||
|
||||
+2
-3
@@ -14,7 +14,6 @@ import org.json.simple.parser.ParseException;
|
||||
import org.junit.Rule;
|
||||
|
||||
import com.sap.sailing.domain.common.orc.ORCCertificate;
|
||||
import com.sap.sailing.domain.common.orc.impl.ORCCertificateImpl;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
|
||||
@@ -50,7 +49,7 @@ public abstract class AbstractORCCertificateImporterTest {
|
||||
" was found when importing the country document from "+url, someValidCert);
|
||||
assertNotNull(referenceCert);
|
||||
assertEquals(referenceCert.getGPHInSecondsToTheMile(), someValidCert.getGPHInSecondsToTheMile(), 0.0000001);
|
||||
assertTrue(referenceCert.getWindwardLeewardSpeedPrediction().get(ORCCertificate.ALLOWANCES_TRUE_WIND_SPEEDS[0]).getDuration(ORCCertificateImpl.NAUTICAL_MILE).asSeconds() > 10);
|
||||
assertTrue(referenceCert.getLongDistanceSpeedPredictions().get(ORCCertificate.ALLOWANCES_TRUE_WIND_SPEEDS[0]).getDuration(ORCCertificateImpl.NAUTICAL_MILE).asSeconds() > 10);
|
||||
assertTrue(referenceCert.getWindwardLeewardSpeedPrediction().get(ORCCertificate.ALLOWANCES_TRUE_WIND_SPEEDS[0]).getDuration(ORCCertificate.NAUTICAL_MILE).asSeconds() > 10);
|
||||
assertTrue(referenceCert.getLongDistanceSpeedPredictions().get(ORCCertificate.ALLOWANCES_TRUE_WIND_SPEEDS[0]).getDuration(ORCCertificate.NAUTICAL_MILE).asSeconds() > 10);
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -27,7 +27,6 @@ import com.sap.sailing.domain.common.orc.ORCCertificate;
|
||||
import com.sap.sailing.domain.common.orc.ORCPerformanceCurveCourse;
|
||||
import com.sap.sailing.domain.common.orc.ORCPerformanceCurveLeg;
|
||||
import com.sap.sailing.domain.common.orc.ORCPerformanceCurveLegTypes;
|
||||
import com.sap.sailing.domain.common.orc.impl.ORCCertificateImpl;
|
||||
import com.sap.sailing.domain.common.orc.impl.ORCPerformanceCurveCourseImpl;
|
||||
import com.sap.sailing.domain.common.orc.impl.ORCPerformanceCurveLegImpl;
|
||||
import com.sap.sailing.domain.orc.impl.ORCCertificatesJsonImporter;
|
||||
@@ -133,7 +132,7 @@ public class TestORCPerformanceCurve {
|
||||
|
||||
private void testAllowancePerLeg(ORCCertificate certificate, double twa, double... expectedAllowancesPerTrueWindSpeed) throws FunctionEvaluationException {
|
||||
Double accuracy = 0.1;
|
||||
final ORCPerformanceCurveCourse course = new ORCPerformanceCurveCourseImpl(Arrays.asList(new ORCPerformanceCurveLegImpl(ORCCertificateImpl.NAUTICAL_MILE, new DegreeBearingImpl(twa))));
|
||||
final ORCPerformanceCurveCourse course = new ORCPerformanceCurveCourseImpl(Arrays.asList(new ORCPerformanceCurveLegImpl(ORCCertificate.NAUTICAL_MILE, new DegreeBearingImpl(twa))));
|
||||
final ORCPerformanceCurve performanceCurve = new ORCPerformanceCurveImpl(certificate, course);
|
||||
for (int i=0; i<expectedAllowancesPerTrueWindSpeed.length; i++) {
|
||||
assertEquals(expectedAllowancesPerTrueWindSpeed[i], performanceCurve.getAllowancePerCourse(ORCCertificate.ALLOWANCES_TRUE_WIND_SPEEDS[i]).asSeconds(), accuracy);
|
||||
|
||||
+7
-7
@@ -230,7 +230,7 @@ public class ORCCertificatesCollectionJSON extends AbstractORCCertificatesCollec
|
||||
trueWindSpeedMap.values().forEach(tws -> velocityPredictionPerTrueWindSpeedAndAngle.put(tws, new HashMap<>()));
|
||||
for (final Bearing keyTWA : allowanceDurationsPerTrueWindAngleAndSpeed.keySet()) {
|
||||
for (final Speed keyTWS : allowanceDurationsPerTrueWindAngleAndSpeed.get(keyTWA).keySet()) {
|
||||
velocityPredictionPerTrueWindSpeedAndAngle.get(keyTWS).put(keyTWA, ORCCertificateImpl.NAUTICAL_MILE
|
||||
velocityPredictionPerTrueWindSpeedAndAngle.get(keyTWS).put(keyTWA, ORCCertificate.NAUTICAL_MILE
|
||||
.inTime(allowanceDurationsPerTrueWindAngleAndSpeed.get(keyTWA).get(keyTWS)));
|
||||
}
|
||||
}
|
||||
@@ -243,19 +243,19 @@ public class ORCCertificatesCollectionJSON extends AbstractORCCertificatesCollec
|
||||
final Map<Speed, Speed> circularRandomSpeedPredictionPerTrueWindSpeed = new HashMap<>();
|
||||
final Map<Speed, Speed> nonSpinnakerSpeedPredictionPerTrueWindSpeed = new HashMap<>();
|
||||
for (final Speed tws : velocityPredictionPerTrueWindSpeedAndAngle.keySet()) {
|
||||
beatVMGPredictionPerTrueWindSpeed.put(tws, ORCCertificateImpl.NAUTICAL_MILE
|
||||
beatVMGPredictionPerTrueWindSpeed.put(tws, ORCCertificate.NAUTICAL_MILE
|
||||
.inTime(predefinedAllowanceDurationsPerTrueWindSpeed.get(BEAT).get(tws)));
|
||||
beatAllowancePerTrueWindSpeed.put(tws, predefinedAllowanceDurationsPerTrueWindSpeed.get(BEAT).get(tws));
|
||||
runVMGPredictionPerTrueWindSpeed.put(tws, ORCCertificateImpl.NAUTICAL_MILE
|
||||
runVMGPredictionPerTrueWindSpeed.put(tws, ORCCertificate.NAUTICAL_MILE
|
||||
.inTime(predefinedAllowanceDurationsPerTrueWindSpeed.get(RUN).get(tws)));
|
||||
runAllowancePerTrueWindSpeed.put(tws, predefinedAllowanceDurationsPerTrueWindSpeed.get(RUN).get(tws));
|
||||
windwardLeewardSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificateImpl.NAUTICAL_MILE
|
||||
windwardLeewardSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificate.NAUTICAL_MILE
|
||||
.inTime(predefinedAllowanceDurationsPerTrueWindSpeed.get(WINDWARD_LEEWARD).get(tws)));
|
||||
longDistanceSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificateImpl.NAUTICAL_MILE
|
||||
longDistanceSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificate.NAUTICAL_MILE
|
||||
.inTime(predefinedAllowanceDurationsPerTrueWindSpeed.get(LONG_DISTANCE).get(tws)));
|
||||
circularRandomSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificateImpl.NAUTICAL_MILE
|
||||
circularRandomSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificate.NAUTICAL_MILE
|
||||
.inTime(predefinedAllowanceDurationsPerTrueWindSpeed.get(CIRCULAR_RANDOM).get(tws)));
|
||||
nonSpinnakerSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificateImpl.NAUTICAL_MILE
|
||||
nonSpinnakerSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificate.NAUTICAL_MILE
|
||||
.inTime(predefinedAllowanceDurationsPerTrueWindSpeed.get(NON_SPINNAKER).get(tws)));
|
||||
}
|
||||
final Bearing[] dynamicAllowancesTrueWindAngles = trueWindAngleMap.values().toArray(new Bearing[trueWindAngleMap.values().size()]);
|
||||
|
||||
+7
-7
@@ -155,22 +155,22 @@ public class ORCCertificatesCollectionRMS extends AbstractORCCertificatesCollect
|
||||
String nonSpinnakerKey = NON_SPINNAKER + windSpeed;
|
||||
beatAngles.put(tws, new DegreeBearingImpl(Double.parseDouble(certificateValues.getValue(beatAngleKey))));
|
||||
beatAllowancePerTrueWindSpeed.put(tws, new SecondsDurationImpl(Double.parseDouble(certificateValues.getValue(beatAllowanceKey))));
|
||||
beatVMGPredictionPerTrueWindSpeed.put(tws, ORCCertificateImpl.NAUTICAL_MILE.inTime(beatAllowancePerTrueWindSpeed.get(tws)));
|
||||
beatVMGPredictionPerTrueWindSpeed.put(tws, ORCCertificate.NAUTICAL_MILE.inTime(beatAllowancePerTrueWindSpeed.get(tws)));
|
||||
runAngles.put(tws, new DegreeBearingImpl(Double.parseDouble(certificateValues.getValue(runAngleKey))));
|
||||
runAllowancePerTrueWindSpeed.put(tws, new SecondsDurationImpl(Double.parseDouble(certificateValues.getValue(runAllowanceKey))));
|
||||
runVMGPredictionPerTrueWindSpeed.put(tws, ORCCertificateImpl.NAUTICAL_MILE.inTime(runAllowancePerTrueWindSpeed.get(tws)));
|
||||
windwardLeewardSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificateImpl.NAUTICAL_MILE.inTime(
|
||||
runVMGPredictionPerTrueWindSpeed.put(tws, ORCCertificate.NAUTICAL_MILE.inTime(runAllowancePerTrueWindSpeed.get(tws)));
|
||||
windwardLeewardSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificate.NAUTICAL_MILE.inTime(
|
||||
new SecondsDurationImpl(Double.parseDouble(certificateValues.getValue(windwardLeewardKey)))));
|
||||
longDistanceSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificateImpl.NAUTICAL_MILE.inTime(
|
||||
longDistanceSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificate.NAUTICAL_MILE.inTime(
|
||||
new SecondsDurationImpl(Double.parseDouble(certificateValues.getValue(longDistanceKey)))));
|
||||
circularRandomSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificateImpl.NAUTICAL_MILE.inTime(
|
||||
circularRandomSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificate.NAUTICAL_MILE.inTime(
|
||||
new SecondsDurationImpl(Double.parseDouble(certificateValues.getValue(circularRandomKey)))));
|
||||
nonSpinnakerSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificateImpl.NAUTICAL_MILE.inTime(
|
||||
nonSpinnakerSpeedPredictionPerTrueWindSpeed.put(tws, ORCCertificate.NAUTICAL_MILE.inTime(
|
||||
new SecondsDurationImpl(Double.parseDouble(certificateValues.getValue(nonSpinnakerKey)))));
|
||||
Map<Bearing, Speed> velocityPredictionPerTrueWindAngle = new HashMap<>();
|
||||
for (Bearing twa : ORCCertificate.ALLOWANCES_TRUE_WIND_ANGLES ) {
|
||||
String twaCoursesKey = TWA_COURSES + Integer.toString((int) twa.getDegrees()) + windSpeed;
|
||||
velocityPredictionPerTrueWindAngle.put(twa, ORCCertificateImpl.NAUTICAL_MILE.inTime(
|
||||
velocityPredictionPerTrueWindAngle.put(twa, ORCCertificate.NAUTICAL_MILE.inTime(
|
||||
new SecondsDurationImpl(Double.parseDouble(certificateValues.getValue(twaCoursesKey)))));
|
||||
}
|
||||
velocityPredictionsPerTrueWindSpeedAndAngle.put(tws, velocityPredictionPerTrueWindAngle);
|
||||
|
||||
+1
-1
@@ -375,7 +375,7 @@ public class ORCPerformanceCurveImpl implements Serializable, ORCPerformanceCurv
|
||||
result.append(e.getKey());
|
||||
result.append(':');
|
||||
final Speed averageSpeed = getCourse().getTotalLength().inTime(e.getValue());
|
||||
result.append(averageSpeed.getDuration(ORCCertificateImpl.NAUTICAL_MILE).asSeconds());
|
||||
result.append(averageSpeed.getDuration(ORCCertificate.NAUTICAL_MILE).asSeconds());
|
||||
result.append("s/NM, ");
|
||||
result.append(e.getValue().asSeconds());
|
||||
result.append("s total; ");
|
||||
|
||||
+2
-2
@@ -26,7 +26,7 @@ public class ORCCertificateImpl_CustomFieldSerializer extends CustomFieldSeriali
|
||||
serialize(streamWriter, instance);
|
||||
}
|
||||
|
||||
public static void serialize(SerializationStreamWriter streamWriter, ORCCertificateImpl instance)
|
||||
public static void serialize(SerializationStreamWriter streamWriter, ORCCertificate instance)
|
||||
throws SerializationException {
|
||||
streamWriter.writeString(instance.getReferenceNumber());
|
||||
streamWriter.writeString(instance.getFileId());
|
||||
@@ -120,7 +120,7 @@ public class ORCCertificateImpl_CustomFieldSerializer extends CustomFieldSeriali
|
||||
deserialize(streamReader, instance);
|
||||
}
|
||||
|
||||
public static void deserialize(SerializationStreamReader streamReader, ORCCertificateImpl instance) {
|
||||
public static void deserialize(SerializationStreamReader streamReader, ORCCertificate instance) {
|
||||
// Done by instantiateInstance
|
||||
}
|
||||
|
||||
|
||||
+15
-5
@@ -15,8 +15,8 @@ import com.google.gwt.user.cellview.client.AbstractCellTable;
|
||||
import com.google.gwt.user.cellview.client.Column;
|
||||
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
|
||||
import com.google.gwt.user.cellview.client.TextColumn;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.orc.ORCCertificate;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
@@ -27,6 +27,7 @@ import com.sap.sse.gwt.client.ErrorReporter;
|
||||
import com.sap.sse.gwt.client.celltable.EntityIdentityComparator;
|
||||
import com.sap.sse.gwt.client.celltable.ImagesBarColumn;
|
||||
import com.sap.sse.gwt.client.celltable.RefreshableSelectionModel;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
|
||||
import com.sap.sse.gwt.client.panels.LabeledAbstractFilterablePanel;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
|
||||
@@ -174,10 +175,19 @@ public class CertificatesTableWrapper<S extends RefreshableSelectionModel<ORCCer
|
||||
table.ensureDebugId("BoatsWithVertificateTable");
|
||||
}
|
||||
|
||||
protected void showCertificate(ORCCertificate certificate) {
|
||||
// TODO embed <a href=\"http://data.orc.org/public/WPub.dll/CC/"+certificate.getReferenceNumber()+"\"> to link to the certificate PDF
|
||||
Window.confirm("Certificate: "+certificate);
|
||||
// TODO Implement CertificatesTableWrapper.showCertificate(...)
|
||||
protected void showCertificate(final ORCCertificate certificate) {
|
||||
new DataEntryDialog<Void>(getStringMessages().orcCertificate(), /* message */ null,
|
||||
getStringMessages().ok(), getStringMessages().cancel(), /* validator */ null, /* animation */ false, /* callback */ null) {
|
||||
@Override
|
||||
protected Widget getAdditionalWidget() {
|
||||
return new ORCCertificateDisplayPanel(certificate, getStringMessages());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void getResult() {
|
||||
return null;
|
||||
}
|
||||
}.show();
|
||||
}
|
||||
|
||||
public void setCertificates(Collection<ORCCertificate> result) {
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.google.gwt.dom.client.Style;
|
||||
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
|
||||
import com.google.gwt.user.client.ui.Anchor;
|
||||
import com.google.gwt.user.client.ui.CaptionPanel;
|
||||
import com.google.gwt.user.client.ui.DockPanel;
|
||||
import com.google.gwt.user.client.ui.Grid;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.sap.sailing.domain.common.orc.ORCCertificate;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.CountryCode;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.Speed;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class ORCCertificateDisplayPanel extends DockPanel {
|
||||
public ORCCertificateDisplayPanel(ORCCertificate certificate, StringMessages stringMessages) {
|
||||
final VerticalPanel panel = new VerticalPanel();
|
||||
add(panel, DockPanel.CENTER);
|
||||
// header
|
||||
final CaptionPanel headerCaptionPanel = new CaptionPanel();
|
||||
final Grid headerData = new Grid(10, 2);
|
||||
headerCaptionPanel.add(headerData);
|
||||
panel.add(headerCaptionPanel);
|
||||
int row=0;
|
||||
headerData.setWidget(row, 0, new Label(stringMessages.certificateIssuingDate()));
|
||||
headerData.setWidget(row++, 1, new Label(certificate.getIssueDate().toString()));
|
||||
headerData.setWidget(row, 0, new Label(stringMessages.issuingCountry()));
|
||||
final CountryCode issuingCountry = certificate.getIssuingCountry();
|
||||
headerData.setWidget(row++, 1,
|
||||
new Label(issuingCountry==null ? stringMessages.empty() : (issuingCountry.getThreeLetterIOCCode() + " (" + issuingCountry.getName() + ")")));
|
||||
headerData.setWidget(row, 0, new Label(stringMessages.orcFileId()));
|
||||
headerData.setWidget(row++, 1, new Label(certificate.getFileId()));
|
||||
headerData.setWidget(row, 0, new Label(stringMessages.orcCertificateReferenceNumber()));
|
||||
headerData.setWidget(row++, 1, new Label(certificate.getReferenceNumber()));
|
||||
headerData.setWidget(row, 0, new Label(stringMessages.boat()));
|
||||
headerData.setWidget(row++, 1, new Label(certificate.getBoatName()));
|
||||
headerData.setWidget(row, 0, new Label(stringMessages.sailID()));
|
||||
headerData.setWidget(row++, 1, new Label(certificate.getSailNumber()));
|
||||
headerData.setWidget(row, 0, new Label(stringMessages.boatClass()));
|
||||
headerData.setWidget(row++, 1, new Label(certificate.getBoatClassName()));
|
||||
headerData.setWidget(row, 0, new Label(stringMessages.gph()));
|
||||
headerData.setWidget(row++, 1, new Label(Util.padPositiveValue(certificate.getGPHInSecondsToTheMile(), 1, 1, /* round */ true)));
|
||||
headerData.setWidget(row, 0, new Label(stringMessages.cdl()));
|
||||
headerData.setWidget(row++, 1, new Label(Util.padPositiveValue(certificate.getCDL(), 1, 3, /* round */ true)));
|
||||
headerData.setWidget(row, 0, new Label(stringMessages.lengthOverAllInMeters()));
|
||||
headerData.setWidget(row++, 1, new Label(Util.padPositiveValue(certificate.getLengthOverAll().getMeters(), 1, 3, /* round */ true)));
|
||||
// time allowances
|
||||
final CaptionPanel timeAllowancesCaptionPanel = new CaptionPanel(stringMessages.timeAllowances());
|
||||
panel.add(timeAllowancesCaptionPanel);
|
||||
// the number of rows is one for the wind velocity header, plus the number of TWA values, plus beat VMG,
|
||||
// plus run VMG, plus four allowances for the selected courses, plus beat angles, plus gybe angles
|
||||
final Grid timeAllowancesData = new Grid(1+certificate.getTrueWindAngles().length+1+1+4+1+1, 1+certificate.getTrueWindSpeeds().length);
|
||||
timeAllowancesCaptionPanel.add(timeAllowancesData);
|
||||
row=0;
|
||||
fillLine(certificate, stringMessages.windSpeed(), row++, timeAllowancesData, tws->Util.padPositiveValue(tws.getKnots(), 1, 1, /* round */ true)+stringMessages.knotsUnit());
|
||||
final Map<Speed, Duration> beatAllowances = certificate.getBeatAllowances();
|
||||
fillLine(certificate, stringMessages.beatVMG(), row++, timeAllowancesData, tws->Util.padPositiveValue(beatAllowances.get(tws).asSeconds(), 1, 1, /* round */ true));
|
||||
for (final Bearing twa : certificate.getTrueWindAngles()) {
|
||||
final Map<Speed, Map<Bearing, Speed>> allowances = certificate
|
||||
.getVelocityPredictionPerTrueWindSpeedAndAngle();
|
||||
fillLine(certificate, Util.padPositiveValue(twa.getDegrees(), 1, 1, /* round */ true), row++,
|
||||
timeAllowancesData, tws -> getVelocityPredictionAsSecondsToTheNauticalMileRoundedToOneTenth(allowances.get(tws).get(twa)));
|
||||
}
|
||||
final Map<Speed, Duration> runAllowances = certificate.getRunAllowances();
|
||||
fillLine(certificate, stringMessages.runVMG(), row++, timeAllowancesData, tws->Util.padPositiveValue(runAllowances.get(tws).asSeconds(), 1, 1, /* round */ true));
|
||||
// selected courses:
|
||||
final Map<Speed, Speed> windwardLeewardSpeedPrediction = certificate.getWindwardLeewardSpeedPrediction();
|
||||
fillLine(certificate, "Windward/Leeward", row++, timeAllowancesData, tws->getVelocityPredictionAsSecondsToTheNauticalMileRoundedToOneTenth(windwardLeewardSpeedPrediction.get(tws)));
|
||||
final Map<Speed, Speed> circularRandomSpeedPrediction = certificate.getCircularRandomSpeedPredictions();
|
||||
fillLine(certificate, "Circular Random", row++, timeAllowancesData, tws->getVelocityPredictionAsSecondsToTheNauticalMileRoundedToOneTenth(circularRandomSpeedPrediction.get(tws)));
|
||||
final Map<Speed, Speed> coastalLongDistanceSpeedPrediction = certificate.getLongDistanceSpeedPredictions();
|
||||
fillLine(certificate, "Coastal / Long Distance", row++, timeAllowancesData, tws->getVelocityPredictionAsSecondsToTheNauticalMileRoundedToOneTenth(coastalLongDistanceSpeedPrediction.get(tws)));
|
||||
final Map<Speed, Speed> nonSpinnakerSpeedPrediction = certificate.getNonSpinnakerSpeedPredictions();
|
||||
fillLine(certificate, "Non Spinnaker", row++, timeAllowancesData, tws->getVelocityPredictionAsSecondsToTheNauticalMileRoundedToOneTenth(nonSpinnakerSpeedPrediction.get(tws)));
|
||||
final Map<Speed, Bearing> beatAngles = certificate.getBeatAngles();
|
||||
fillLine(certificate, stringMessages.beatAngles(), row++, timeAllowancesData, tws->Util.padPositiveValue(beatAngles.get(tws).getDegrees(), 1, 1, /* round */ true));
|
||||
final Map<Speed, Bearing> runAngles = certificate.getRunAngles();
|
||||
fillLine(certificate, stringMessages.runAngles(), row++, timeAllowancesData, tws->Util.padPositiveValue(runAngles.get(tws).getDegrees(), 1, 1, /* round */ true));
|
||||
final Anchor linkToCertificate = new Anchor(new SafeHtmlBuilder().appendEscaped(stringMessages.linkToOrcCertificate()).toSafeHtml(),
|
||||
"https://data.orc.org/public/WPub.dll/CC/"+certificate.getReferenceNumber(), /* target */ "_blank");
|
||||
panel.add(linkToCertificate);
|
||||
}
|
||||
|
||||
private String getVelocityPredictionAsSecondsToTheNauticalMileRoundedToOneTenth(Speed velocityPrediction) {
|
||||
return Util.padPositiveValue(ORCCertificate.NAUTICAL_MILE.atSpeed(velocityPrediction).asSeconds(), 1, 1, /* round */ true);
|
||||
}
|
||||
|
||||
private void fillLine(ORCCertificate certificate, String lineLabel, int row, final Grid grid, Function<Speed, String> twsToValueLabel) {
|
||||
int column=0;
|
||||
grid.setWidget(row, column++, new Label(lineLabel));
|
||||
for (final Speed trueWindSpeed : certificate.getTrueWindSpeeds()) {
|
||||
final Label valueLabel = new Label(twsToValueLabel.apply(trueWindSpeed));
|
||||
valueLabel.setHorizontalAlignment(ALIGN_RIGHT);
|
||||
grid.setWidget(row, column++, valueLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -2362,4 +2362,16 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages,
|
||||
String spareMarksAndTheirOptionalDefaultMarkRoles();
|
||||
String impliedWind();
|
||||
String impliedWindTooltip();
|
||||
String orcCertificate();
|
||||
String linkToOrcCertificate();
|
||||
String orcFileId();
|
||||
String orcCertificateReferenceNumber();
|
||||
String cdl();
|
||||
String gph();
|
||||
String lengthOverAllInMeters();
|
||||
String timeAllowances();
|
||||
String beatVMG();
|
||||
String runVMG();
|
||||
String beatAngles();
|
||||
String runAngles();
|
||||
}
|
||||
+13
-1
@@ -2365,4 +2365,16 @@ setPosition=Set position
|
||||
spareMarksAndTheirOptionalDefaultMarkRoles=Spare marks and their optional default mark roles
|
||||
impliedWind=Implied Wind
|
||||
impliedWindTooltip=The implied wind is the hypothetical true wind speed at which the competitor would have completed the part of the course it has sailed so far in the time elapsed so far, according to its polar sheet / velocity predictions.
|
||||
additionalInformation=Additional information
|
||||
additionalInformation=Additional information
|
||||
orcCertificate=ORC Certificate
|
||||
linkToOrcCertificate=PDF version of certificate
|
||||
orcFileId=File ID
|
||||
orcCertificateReferenceNumber=Reference number
|
||||
cdl=Class Division Length (CDL)
|
||||
gph=General-Purpose Handicap (GPH)
|
||||
lengthOverAllInMeters=Length over all (LOA) in meters
|
||||
timeAllowances=Time allowances
|
||||
beatVMG=Beat VMG
|
||||
runVMG=Run VMG
|
||||
beatAngles=Beat angles
|
||||
runAngles=Run angles
|
||||
+13
-1
@@ -2380,4 +2380,16 @@ setPosition=Position setzen
|
||||
spareMarksAndTheirOptionalDefaultMarkRoles=Ersatzbahnmarken und ihre optionalen Standard-Rollen
|
||||
impliedWind=Implizierter Wind
|
||||
impliedWindTooltip=Der implizierte Wind ist die hypothetische Geschwindigkeit des wahren Windes, mit dem der Teilnehmer den bisher absolvierten Teil des Kurses in der bisher benötigten Zeit laut seinem Polardiagramm gesegelt sein würde.
|
||||
additionalInformation=Weiterführende Information
|
||||
additionalInformation=Weiterführende Information
|
||||
orcCertificate=ORC-Zertifikat
|
||||
linkToOrcCertificate=PDF-Version des Zertifikats
|
||||
orcFileId=Datei-Kennung
|
||||
orcCertificateReferenceNumber=Referenz-Nummer
|
||||
cdl=Klassen-Unterteilungslänge (CDL)
|
||||
gph=Allgemeiner Handicap-Wert (GPH)
|
||||
lengthOverAllInMeters=Länge über alles (LüA) in Metern
|
||||
timeAllowances=Zeitgutschriften
|
||||
beatVMG=VMG an der Kreuz
|
||||
runVMG=VMG vor dem Wind
|
||||
beatAngles=Kreuzwinkel
|
||||
runAngles=Vorwindwinkel
|
||||
@@ -17,10 +17,17 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="yield_content">
|
||||
<div class="contentWrapper">
|
||||
<div class="mainContent">
|
||||
<h2 class="releaseHeadline">Release Notes - Administration Console</h2>
|
||||
<div class="innerContent">
|
||||
<div class="contentWrapper">
|
||||
<div class="mainContent">
|
||||
<h2 class="releaseHeadline">Release Notes - Administration Console</h2>
|
||||
<div class="innerContent">
|
||||
<h2 class="articleSubheadline">March 2020</h2>
|
||||
<ul class="bulletList">
|
||||
<li>The visualization for ORC certificates has been much improved. It now shows all the
|
||||
time allowances relevant for Performance Curve Scoring (PCS) and offers a link to the
|
||||
official PDF version of the respective certificate, based on its reference number.
|
||||
</li>
|
||||
</ul>
|
||||
<h2 class="articleSubheadline">February 2020</h2>
|
||||
<ul class="bulletList">
|
||||
<li>The "Local Server" tab now refreshes automatically when it comes into view.</li>
|
||||
|
||||
@@ -21,6 +21,11 @@ public class NumberPaddingTest {
|
||||
assertEquals("10.1", padPositiveValue(10.1, 0, 1, /* round */ false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValueGreaterThanTenWithOneDigitLeftOfDecimalRequested() {
|
||||
assertEquals("10.1", padPositiveValue(10.1, 1, 1, /* round */ false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTruncation() {
|
||||
assertEquals("10.1", padPositiveValue(10.179, 0, 1, /* round */ false));
|
||||
|
||||
@@ -39,6 +39,11 @@ public interface Distance extends Comparable<Distance>, Serializable {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration atSpeed(Speed speed) {
|
||||
return Duration.NULL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getKilometers() {
|
||||
return 0;
|
||||
@@ -123,6 +128,11 @@ public interface Distance extends Comparable<Distance>, Serializable {
|
||||
|
||||
Speed inTime(Duration duration);
|
||||
|
||||
/**
|
||||
* Computes the duration it takes to travel this distance at the given {@code speed}.
|
||||
*/
|
||||
Duration atSpeed(Speed speed);
|
||||
|
||||
Distance add(Distance d);
|
||||
|
||||
/**
|
||||
|
||||
@@ -846,7 +846,11 @@ public class Util {
|
||||
* the integer part of the {@code value}'s magnitude.
|
||||
*
|
||||
* @param digitsLeftOfDecimal
|
||||
* a non-negative number; if zero,
|
||||
* a non-negative number; if zero, no "0" will be used left of the decimal point if the value is less than 1.
|
||||
* Padding occurs only if the number of digits requested is greater than the number of digits the value has
|
||||
* left of the decimal point. If the number of digits requested left of the decimal point is less than what
|
||||
* the number has, no cropping takes place and the result will have more digits left of the decimal point
|
||||
* than requested.
|
||||
* @param digitsRightOfDecimal
|
||||
* a non-negative number; if zero, no decimal point will appear at all
|
||||
* @param round
|
||||
|
||||
Reference in new issue
Block a user