mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-10 21:02:40 +00:00
avoid code duplication in certificate importers
Change-Id: Ifc44bbabf03610294a95788b82640c925c2b606b
This commit is contained in:
1 parent
d687bb590b
commit
ef2a2ae0b1
4 files changed
+41
-36
No files matched your search
Executable
+16
@@ -0,0 +1,16 @@
|
||||
package com.sap.sailing.domain.orc.impl;
|
||||
|
||||
import com.sap.sailing.domain.orc.ORCCertificateImporter;
|
||||
|
||||
public abstract class AbstractORCCertificateImporter implements ORCCertificateImporter {
|
||||
|
||||
/**
|
||||
* From a sail number which may contain spaces, also redundantly and repeatedly, as well
|
||||
* as dashes, slashes or other special characters, and where upper and lower case may be mixed,
|
||||
* constructs a canonicalized version such that the chances for producing a match when searching
|
||||
* for a sail number is maximized, while still minimizing the chances for a false match.
|
||||
*/
|
||||
protected String getCanonicalizedSailNumber(String sailNumber) {
|
||||
return sailNumber.replaceAll(" ", "").toUpperCase();
|
||||
}
|
||||
}
|
||||
+6
-8
@@ -18,7 +18,6 @@ import org.json.simple.parser.ParseException;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.orc.ORCCertificate;
|
||||
import com.sap.sailing.domain.common.orc.impl.ORCCertificateImpl;
|
||||
import com.sap.sailing.domain.orc.ORCCertificateImporter;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.Duration;
|
||||
@@ -38,9 +37,8 @@ import com.sap.sse.common.impl.SecondsDurationImpl;
|
||||
* @author Daniel Lisunkin (i505543)
|
||||
*
|
||||
*/
|
||||
public class ORCCertificateImporterJSON implements ORCCertificateImporter {
|
||||
|
||||
private Map<String, Object> data;
|
||||
public class ORCCertificateImporterJSON extends AbstractORCCertificateImporter {
|
||||
private Map<String, JSONObject> data;
|
||||
private static final String RUN = "Run";
|
||||
private static final String BEAT = "Beat";
|
||||
private static final String WINDWARD_LEEWARD = "WL";
|
||||
@@ -53,7 +51,7 @@ public class ORCCertificateImporterJSON implements ORCCertificateImporter {
|
||||
* {@code .json} file.
|
||||
*/
|
||||
public ORCCertificateImporterJSON(InputStream in) throws IOException, ParseException {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
Map<String, JSONObject> result = new HashMap<>();
|
||||
String defaultEncoding = "UTF-8";
|
||||
BOMInputStream bomInputStream = new BOMInputStream(in);
|
||||
ByteOrderMark bom = bomInputStream.getBOM();
|
||||
@@ -63,7 +61,7 @@ public class ORCCertificateImporterJSON implements ORCCertificateImporter {
|
||||
JSONArray dataArray = (JSONArray) parsedJson.get("rms");
|
||||
for (int i = 0; i < dataArray.size(); i++) {
|
||||
JSONObject object = (JSONObject) dataArray.get(i);
|
||||
result.put(((String) object.get("SailNo")).replaceAll(" ", "").toUpperCase(), object);
|
||||
result.put(getCanonicalizedSailNumber((String) object.get("SailNo")), object);
|
||||
}
|
||||
data = result;
|
||||
}
|
||||
@@ -83,8 +81,8 @@ public class ORCCertificateImporterJSON implements ORCCertificateImporter {
|
||||
Map<Speed, Map<Bearing, Speed>> velocityPredictionPerTrueWindSpeedAndAngle = new HashMap<>();
|
||||
Map<Bearing, Map<Speed, Duration>> allowanceDurationsPerTrueWindAngleAndSpeed = new HashMap<>(); //per nautical mile
|
||||
Map<String, Map<Speed, Duration>> predefinedAllowanceDurationsPerTrueWindSpeed = new HashMap<>(); //per nautical mile
|
||||
String searchString = sailnumber.replaceAll(" ", "").toUpperCase();
|
||||
JSONObject object = (JSONObject) data.get(searchString);
|
||||
String searchString = getCanonicalizedSailNumber(sailnumber);
|
||||
JSONObject object = data.get(searchString);
|
||||
if (object == null) {
|
||||
//TODO Throw Exception for sailnumber not found. InvalidArgumentException?
|
||||
return null;
|
||||
|
||||
+10
-23
@@ -6,9 +6,9 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -22,7 +22,6 @@ import org.apache.commons.io.input.BOMInputStream;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.orc.ORCCertificate;
|
||||
import com.sap.sailing.domain.common.orc.impl.ORCCertificateImpl;
|
||||
import com.sap.sailing.domain.orc.ORCCertificateImporter;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.Duration;
|
||||
@@ -50,7 +49,7 @@ import com.sap.sse.common.impl.SecondsDurationImpl;
|
||||
*
|
||||
*/
|
||||
|
||||
public class ORCCertificateImporterRMS implements ORCCertificateImporter {
|
||||
public class ORCCertificateImporterRMS extends AbstractORCCertificateImporter {
|
||||
//Codes used in the RMS document as column names for different information
|
||||
private static final String TWA_COURSES = "R";
|
||||
private static final String CDL = "CDL";
|
||||
@@ -95,30 +94,22 @@ public class ORCCertificateImporterRMS implements ORCCertificateImporter {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
final Map<String, String> parsedLine = parseLine(line);
|
||||
certificateValuesBySailnumber.put(parsedLine.get(sailnumberColumnName).replaceAll(" ", "").toUpperCase(), parsedLine);
|
||||
certificateValuesBySailnumber.put(getCanonicalizedSailNumber(parsedLine.get(sailnumberColumnName)), parsedLine);
|
||||
}
|
||||
}
|
||||
|
||||
public ORCCertificateImporterRMS(InputStream in) throws IOException {
|
||||
this(getReaderForInputStream(in));
|
||||
}
|
||||
|
||||
private static BufferedReader getReaderForInputStream(InputStream in) throws IOException, UnsupportedEncodingException {
|
||||
String defaultEncoding = "UTF-8";
|
||||
BOMInputStream bomInputStream = new BOMInputStream(in);
|
||||
ByteOrderMark bom = bomInputStream.getBOM();
|
||||
String charsetName = bom == null ? defaultEncoding : bom.getCharsetName();
|
||||
InputStreamReader reader = new InputStreamReader(new BufferedInputStream(bomInputStream), charsetName);
|
||||
BufferedReader br = new BufferedReader(reader);
|
||||
columnNamesAndWidths = readColumnWidthsFromFirstLine(br.readLine());
|
||||
Iterator<String> iterator = columnNamesAndWidths.keySet().iterator();
|
||||
iterator.next(); // the first column contains the IDs of the certificates
|
||||
final String sailnumberColumnName = iterator.next(); // the second column contains the sail numbers, which are easier to use for identification
|
||||
certificateValuesBySailnumber = new HashMap<>();
|
||||
String line;
|
||||
|
||||
while ((line = br.readLine()) != null) {
|
||||
final Map<String, String> parsedLine = parseLine(line);
|
||||
certificateValuesBySailnumber.put(parsedLine.get(sailnumberColumnName).replaceAll(" ", "").toUpperCase(), parsedLine);
|
||||
}
|
||||
|
||||
br.close();
|
||||
return br;
|
||||
}
|
||||
|
||||
private Map<String, String> parseLine(final String line) {
|
||||
@@ -145,7 +136,6 @@ public class ORCCertificateImporterRMS implements ORCCertificateImporter {
|
||||
splitBySpaceMode = true;
|
||||
}
|
||||
start = end;
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -171,13 +161,13 @@ public class ORCCertificateImporterRMS implements ORCCertificateImporter {
|
||||
}
|
||||
|
||||
public ORCCertificateValues getValuesForSailnumber(String sailnumber) {
|
||||
String searchString = sailnumber.replaceAll(" ", "").toUpperCase();
|
||||
String searchString = getCanonicalizedSailNumber(sailnumber);
|
||||
return certificateValuesBySailnumber.containsKey(searchString) ? new ORCCertificateValues(searchString) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ORCCertificate getCertificate(String sailnumber) {
|
||||
String searchString = sailnumber.replaceAll(" ", "").toUpperCase();
|
||||
String searchString = getCanonicalizedSailNumber(sailnumber);
|
||||
ORCCertificateValues certificateValues = getValuesForSailnumber(searchString);
|
||||
final String boatclass = certificateValues.getValue(BOATCLASS);
|
||||
final Distance length = new MeterDistance(Double.parseDouble(certificateValues.getValue(LENGTH)));
|
||||
@@ -194,7 +184,6 @@ public class ORCCertificateImporterRMS implements ORCCertificateImporter {
|
||||
final Map<Speed, Speed> longDistanceSpeedPredictionPerTrueWindSpeed = new HashMap<>();
|
||||
final Map<Speed, Speed> circularRandomSpeedPredictionPerTrueWindSpeed = new HashMap<>();
|
||||
final Map<Speed, Speed> nonSpinnakerSpeedPredictionPerTrueWindSpeed = new HashMap<>();
|
||||
|
||||
for (Speed tws : ORCCertificateImpl.ALLOWANCES_TRUE_WIND_SPEEDS) {
|
||||
String windSpeed = Integer.toString((int) tws.getKnots());
|
||||
String beatAngleKey = BEAT_ANGLE + windSpeed;
|
||||
@@ -227,7 +216,6 @@ public class ORCCertificateImporterRMS implements ORCCertificateImporter {
|
||||
}
|
||||
velocityPredictionsPerTrueWindSpeedAndAngle.put(tws, velocityPredictionPerTrueWindAngle);
|
||||
}
|
||||
|
||||
return new ORCCertificateImpl(searchString, boatclass, length, gph, cdl,
|
||||
velocityPredictionsPerTrueWindSpeedAndAngle, beatAngles, beatVMGPredictionPerTrueWindSpeed,
|
||||
beatAllowancePerTrueWindSpeed, runAngles, runVMGPredictionPerTrueWindSpeed,
|
||||
@@ -239,7 +227,6 @@ public class ORCCertificateImporterRMS implements ORCCertificateImporter {
|
||||
@Override
|
||||
public Map<String, ORCCertificate> getCertificates(String[] sailnumbers) {
|
||||
Map<String, ORCCertificate> result = new HashMap<>();
|
||||
|
||||
for (String sailnumber : sailnumbers) {
|
||||
result.put(sailnumber, getCertificate(sailnumber));
|
||||
}
|
||||
|
||||
+9
-5
@@ -532,11 +532,15 @@ public class ORCPerformanceCurveRankingMetric extends AbstractRankingMetric {
|
||||
try {
|
||||
timeForCompetitorImpliedWindCalculation = nowOrLegFinishTimeIfFinishedAtTimePoint(trackedLegOfCompetitor, timePoint, cache);
|
||||
final ORCPerformanceCurve competitorPerformanceCurveForLeg = getPerformanceCurveForPartialCourse(competitor, timeForCompetitorImpliedWindCalculation, cache);
|
||||
final TimePoint timeForLegLeaderImpliedWindCalculation = nowOrLegFinishTimeIfFinishedAtTimePoint(
|
||||
getTrackedRace().getTrackedLeg(legLeader, trackedLegOfCompetitor.getLeg()), timePoint, cache);
|
||||
final Speed legLeaderImpliedWindInOrAtEndOfLeg = getImpliedWind(legLeader, timeForLegLeaderImpliedWindCalculation, cache);
|
||||
final Duration correctedTimeOfLegLeaderInCompetitorsPerformanceCurve = competitorPerformanceCurveForLeg.getAllowancePerCourse(legLeaderImpliedWindInOrAtEndOfLeg);
|
||||
result = actualRaceDurationForCompetitor.minus(correctedTimeOfLegLeaderInCompetitorsPerformanceCurve);
|
||||
if (competitorPerformanceCurveForLeg == null) {
|
||||
result = null;
|
||||
} else {
|
||||
final TimePoint timeForLegLeaderImpliedWindCalculation = nowOrLegFinishTimeIfFinishedAtTimePoint(
|
||||
getTrackedRace().getTrackedLeg(legLeader, trackedLegOfCompetitor.getLeg()), timePoint, cache);
|
||||
final Speed legLeaderImpliedWindInOrAtEndOfLeg = getImpliedWind(legLeader, timeForLegLeaderImpliedWindCalculation, cache);
|
||||
final Duration correctedTimeOfLegLeaderInCompetitorsPerformanceCurve = competitorPerformanceCurveForLeg.getAllowancePerCourse(legLeaderImpliedWindInOrAtEndOfLeg);
|
||||
result = actualRaceDurationForCompetitor.minus(correctedTimeOfLegLeaderInCompetitorsPerformanceCurve);
|
||||
}
|
||||
} catch (FunctionEvaluationException | MaxIterationsExceededException e) {
|
||||
logger.log(Level.WARNING, "Problem with performance curve calculation for competitor "+competitor+" or "+legLeader, e);
|
||||
result = null;
|
||||
|
||||
Reference in new issue
Block a user