mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-25 21:43:49 +00:00
Changed polar sheet generation to support advanced histograms
This commit is contained in:
1 parent
51e990bd74
commit
e8f461bf75
10 files changed
+183
-109
No files matched your search
+49
-45
@@ -44,6 +44,7 @@ import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
import com.sap.sailing.domain.common.impl.WindSteppingWithMaxDistance;
|
||||
import com.sap.sailing.domain.polarsheets.DataPointWithOriginInfo;
|
||||
import com.sap.sailing.domain.polarsheets.PerRaceAndCompetitorPolarSheetGenerationWorker;
|
||||
import com.sap.sailing.domain.polarsheets.PolarSheetGenerationWorker;
|
||||
import com.sap.sailing.domain.polarsheets.PolarSheetHistogramBuilder;
|
||||
@@ -117,16 +118,16 @@ public class PolarSheetGenerationTest {
|
||||
PolarSheetHistogramBuilder builder = new PolarSheetHistogramBuilder(settings);
|
||||
|
||||
|
||||
List<Double> rawData = new ArrayList<Double>();
|
||||
rawData.add(1.09);
|
||||
rawData.add(1.0);
|
||||
rawData.add(1.11);
|
||||
rawData.add(1.46);
|
||||
rawData.add(1.56);
|
||||
rawData.add(2.05);
|
||||
rawData.add(2.09);
|
||||
rawData.add(3.0);
|
||||
rawData.add(2.999);
|
||||
List<DataPointWithOriginInfo> rawData = new ArrayList<DataPointWithOriginInfo>();
|
||||
rawData.add(new DataPointWithOriginInfo(1.09, ""));
|
||||
rawData.add(new DataPointWithOriginInfo(1.0, ""));
|
||||
rawData.add(new DataPointWithOriginInfo(1.11, ""));
|
||||
rawData.add(new DataPointWithOriginInfo(1.46, ""));
|
||||
rawData.add(new DataPointWithOriginInfo(1.56, ""));
|
||||
rawData.add(new DataPointWithOriginInfo(2.05, ""));
|
||||
rawData.add(new DataPointWithOriginInfo(2.09, ""));
|
||||
rawData.add(new DataPointWithOriginInfo(3.0, ""));
|
||||
rawData.add(new DataPointWithOriginInfo(2.999, ""));
|
||||
PolarSheetsHistogramData result = builder.build(rawData, 0, 0);
|
||||
Number[] xValues = result.getxValues();
|
||||
Assert.assertEquals(10, xValues.length);
|
||||
@@ -142,47 +143,50 @@ public class PolarSheetGenerationTest {
|
||||
@Test
|
||||
public void testOutlierNeighborhoodAlgorithm() {
|
||||
PolarSheetGenerationSettings settings = PolarSheetGenerationSettingsImpl.createStandardPolarSettings();
|
||||
List<Double> values = new ArrayList<Double>();
|
||||
values.add(0.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
values.add(20.);
|
||||
List<DataPointWithOriginInfo> values = new ArrayList<DataPointWithOriginInfo>();
|
||||
values.add(new DataPointWithOriginInfo(0., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
values.add(new DataPointWithOriginInfo(20., ""));
|
||||
int[] count = new int[1];
|
||||
count[0] = values.size();
|
||||
Map<Integer, List<Double>> valuesInMap = new HashMap<Integer, List<Double>>();
|
||||
Map<Integer, List<DataPointWithOriginInfo>> valuesInMap = new HashMap<Integer, List<DataPointWithOriginInfo>>();
|
||||
valuesInMap.put(0, values);
|
||||
double pct = PolarSheetGenerationWorker.getNeighboorhoodSizePercentage(count, valuesInMap, 0, 0, 0., settings);
|
||||
double pct = PolarSheetGenerationWorker.getNeighboorhoodSizePercentage(count, valuesInMap, 0, 0,
|
||||
new DataPointWithOriginInfo(0.0, ""), settings);
|
||||
|
||||
Assert.assertTrue(pct < 0.05);
|
||||
|
||||
pct = PolarSheetGenerationWorker.getNeighboorhoodSizePercentage(count, valuesInMap, 0, 2, 20., settings);
|
||||
pct = PolarSheetGenerationWorker.getNeighboorhoodSizePercentage(count, valuesInMap, 0, 2,
|
||||
new DataPointWithOriginInfo(20.0, ""), settings);
|
||||
|
||||
Assert.assertTrue(pct > 0.05);
|
||||
|
||||
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
package com.sap.sailing.domain.polarsheets;
|
||||
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
|
||||
public class BoatAndWindSpeedImpl implements BoatAndWindSpeed{
|
||||
|
||||
private Speed boatSpeed;
|
||||
private Speed windSpeed;
|
||||
|
||||
|
||||
|
||||
public BoatAndWindSpeedImpl(Speed boatSpeed, Speed windSpeed) {
|
||||
this.boatSpeed = boatSpeed;
|
||||
this.windSpeed = windSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Speed getBoatSpeed() {
|
||||
return boatSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Speed getWindSpeed() {
|
||||
return windSpeed;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+3
-1
@@ -2,10 +2,12 @@ package com.sap.sailing.domain.polarsheets;
|
||||
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
|
||||
public interface BoatAndWindSpeed {
|
||||
public interface BoatAndWindSpeedWithOriginInfo {
|
||||
|
||||
public Speed getBoatSpeed();
|
||||
|
||||
public Speed getWindSpeed();
|
||||
|
||||
public String getWindGaugesIdString();
|
||||
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.sap.sailing.domain.polarsheets;
|
||||
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
|
||||
public class BoatAndWindSpeedWithOriginInfoImpl implements BoatAndWindSpeedWithOriginInfo {
|
||||
|
||||
private Speed boatSpeed;
|
||||
private Speed windSpeed;
|
||||
private String windGaugesIdString;
|
||||
|
||||
public BoatAndWindSpeedWithOriginInfoImpl(Speed boatSpeed, Speed windSpeed, String windGaugesIdString) {
|
||||
this.boatSpeed = boatSpeed;
|
||||
this.windSpeed = windSpeed;
|
||||
this.windGaugesIdString = windGaugesIdString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Speed getBoatSpeed() {
|
||||
return boatSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Speed getWindSpeed() {
|
||||
return windSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWindGaugesIdString() {
|
||||
return windGaugesIdString;
|
||||
}
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.sap.sailing.domain.polarsheets;
|
||||
|
||||
public class DataPointWithOriginInfo implements Comparable<DataPointWithOriginInfo>{
|
||||
|
||||
private Double rawData;
|
||||
|
||||
private String windGaugeIdString;
|
||||
|
||||
public DataPointWithOriginInfo(Double rawData, String windGaugeIdString) {
|
||||
this.rawData = rawData;
|
||||
this.windGaugeIdString = windGaugeIdString;
|
||||
}
|
||||
|
||||
public Double getRawData() {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
public String getWindGaugeIdString() {
|
||||
return windGaugeIdString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(DataPointWithOriginInfo o) {
|
||||
return getRawData().compareTo(o.getRawData());
|
||||
}
|
||||
|
||||
}
|
||||
+1
-2
@@ -152,8 +152,7 @@ public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Runnable{
|
||||
//continue;
|
||||
}
|
||||
|
||||
polarSheetGenerationWorker.addPolarData(Math.round(polarFix.getAngleToWind()),
|
||||
polarFix.getBoatSpeed(), polarFix.getWindSpeed());
|
||||
polarSheetGenerationWorker.addPolarData(polarFix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ public class PolarFix {
|
||||
private SpeedWithBearing boatSpeed;
|
||||
private Speed windSpeed;
|
||||
private double angleToWind;
|
||||
private String gaugeIdString;
|
||||
|
||||
public PolarFix(GPSFixMoving fix, TrackedRace race, GPSFixTrack<Competitor, GPSFixMoving> track, Wind windSpeed,
|
||||
PolarSheetGenerationSettings settings) {
|
||||
@@ -28,6 +29,7 @@ public class PolarFix {
|
||||
Bearing bearing = boatSpeed.getBearing();
|
||||
|
||||
Position position = fix.getPosition();
|
||||
gaugeIdString = createWindGaugesString(race);
|
||||
this.windSpeed = windSpeed;
|
||||
Set<WindSource> windSourcesToExclude;
|
||||
if (settings.useOnlyEstimatedForWindDirection()) {
|
||||
@@ -45,6 +47,15 @@ public class PolarFix {
|
||||
angleToWind = bearing.getDifferenceTo(windBearing).getDegrees();
|
||||
}
|
||||
|
||||
private String createWindGaugesString(TrackedRace race) {
|
||||
Iterable<WindSource> gaugeWindSources = race.getWindSources(WindSourceType.EXPEDITION);
|
||||
String gaugeIdString = "";
|
||||
for (WindSource source : gaugeWindSources) {
|
||||
gaugeIdString = gaugeIdString + "+" + source.getId();
|
||||
}
|
||||
return gaugeIdString;
|
||||
}
|
||||
|
||||
public Set<WindSource> collectWindSourcesToIgnoreForBearing(TrackedRace race, boolean excludeCourseBased) {
|
||||
Set<WindSource> windSourcesToExclude = new HashSet<WindSource>();
|
||||
Iterable<WindSource> combinedSources = race.getWindSources(WindSourceType.COMBINED);
|
||||
@@ -84,6 +95,8 @@ public class PolarFix {
|
||||
return angleToWind;
|
||||
}
|
||||
|
||||
|
||||
public String getGaugeIdString() {
|
||||
return gaugeIdString;
|
||||
}
|
||||
|
||||
}
|
||||
+29
-24
@@ -36,7 +36,7 @@ public class PolarSheetGenerationWorker implements Future<PolarSheetsData>{
|
||||
|
||||
private final Set<PerRaceAndCompetitorPolarSheetGenerationWorker> workers;
|
||||
|
||||
private final List<List<BoatAndWindSpeed>> polarData;
|
||||
private final List<List<BoatAndWindSpeedWithOriginInfo>> polarData;
|
||||
|
||||
private final Executor executor;
|
||||
|
||||
@@ -80,10 +80,10 @@ public class PolarSheetGenerationWorker implements Future<PolarSheetsData>{
|
||||
}
|
||||
}
|
||||
|
||||
private List<List<BoatAndWindSpeed>> initializePolarDataContainer() {
|
||||
List<List<BoatAndWindSpeed>> container = new ArrayList<List<BoatAndWindSpeed>>();
|
||||
private List<List<BoatAndWindSpeedWithOriginInfo>> initializePolarDataContainer() {
|
||||
List<List<BoatAndWindSpeedWithOriginInfo>> container = new ArrayList<List<BoatAndWindSpeedWithOriginInfo>>();
|
||||
for (int i = 0; i < 360; i++) {
|
||||
container.add(new ArrayList<BoatAndWindSpeed>());
|
||||
container.add(new ArrayList<BoatAndWindSpeedWithOriginInfo>());
|
||||
}
|
||||
return container;
|
||||
}
|
||||
@@ -108,12 +108,16 @@ public class PolarSheetGenerationWorker implements Future<PolarSheetsData>{
|
||||
* @param windSpeed
|
||||
* wind's speed in knots
|
||||
*/
|
||||
protected void addPolarData(long roundedAngle, Speed boatSpeed, Speed windSpeed) {
|
||||
protected void addPolarData(PolarFix polarFix) {
|
||||
long roundedAngle = Math.round(polarFix.getAngleToWind());
|
||||
Speed boatSpeed = polarFix.getBoatSpeed();
|
||||
Speed windSpeed = polarFix.getWindSpeed();
|
||||
int angle = (int) roundedAngle;
|
||||
if (angle < 0) {
|
||||
angle = (360 + angle);
|
||||
}
|
||||
BoatAndWindSpeed speeds = new BoatAndWindSpeedImpl(boatSpeed, windSpeed);
|
||||
BoatAndWindSpeedWithOriginInfo speeds = new BoatAndWindSpeedWithOriginInfoImpl(boatSpeed, windSpeed,
|
||||
polarFix.getGaugeIdString());
|
||||
polarData.get(angle).add(speeds);
|
||||
}
|
||||
|
||||
@@ -145,14 +149,14 @@ public class PolarSheetGenerationWorker implements Future<PolarSheetsData>{
|
||||
}
|
||||
for (int angleIndex = 0; angleIndex < 360; angleIndex++) {
|
||||
// Avoid Concurrent modification of lists, so get current state as an array; lock would slow things down
|
||||
BoatAndWindSpeed[] values = polarData.get(angleIndex).toArray(
|
||||
new BoatAndWindSpeed[polarData.get(angleIndex).size()]);
|
||||
BoatAndWindSpeedWithOriginInfo[] values = polarData.get(angleIndex).toArray(
|
||||
new BoatAndWindSpeedWithOriginInfo[polarData.get(angleIndex).size()]);
|
||||
dataCount = dataCount + values.length;
|
||||
dataCountPerAngle[angleIndex] = values.length;
|
||||
double[] sumsPerWindSpeed = new double[levelCount];
|
||||
int[] dataCountPerWindSpeed = new int[levelCount];
|
||||
Map<Integer, List<Double>> dataSetForWindLevel = new HashMap<Integer, List<Double>>();
|
||||
for (BoatAndWindSpeed singleDataPoint : values) {
|
||||
Map<Integer, List<DataPointWithOriginInfo>> dataSetForWindLevel = new HashMap<Integer, List<DataPointWithOriginInfo>>();
|
||||
for (BoatAndWindSpeedWithOriginInfo singleDataPoint : values) {
|
||||
if (singleDataPoint != null) {
|
||||
double windSpeed = singleDataPoint.getWindSpeed().getKnots();
|
||||
int level = stepping.getLevelIndexForValue(windSpeed);
|
||||
@@ -160,10 +164,11 @@ public class PolarSheetGenerationWorker implements Future<PolarSheetsData>{
|
||||
continue;
|
||||
}
|
||||
double speed = singleDataPoint.getBoatSpeed().getKnots();
|
||||
String windGaugesIdString = singleDataPoint.getWindGaugesIdString();
|
||||
if (!dataSetForWindLevel.containsKey(level)) {
|
||||
dataSetForWindLevel.put(level, new ArrayList<Double>());
|
||||
dataSetForWindLevel.put(level, new ArrayList<DataPointWithOriginInfo>());
|
||||
}
|
||||
dataSetForWindLevel.get(level).add(speed);
|
||||
dataSetForWindLevel.get(level).add(new DataPointWithOriginInfo(speed, windGaugesIdString));
|
||||
sumsPerWindSpeed[level] = sumsPerWindSpeed[level] + speed;
|
||||
dataCountPerWindSpeed[level]++;
|
||||
}
|
||||
@@ -171,17 +176,17 @@ public class PolarSheetGenerationWorker implements Future<PolarSheetsData>{
|
||||
|
||||
for (int levelIndex = 0; levelIndex < levelCount; levelIndex++) {
|
||||
if (settings.shouldRemoveOutliers() && dataSetForWindLevel.get(levelIndex) != null) {
|
||||
List<Double> withoutOutliers = new ArrayList<Double>();
|
||||
List<DataPointWithOriginInfo> withoutOutliers = new ArrayList<DataPointWithOriginInfo>();
|
||||
Collections.sort(dataSetForWindLevel.get(levelIndex));
|
||||
if (dataCountPerWindSpeed[levelIndex] > /* Minimum data count for outlier detection */10) {
|
||||
for (int dataIndex = 0; dataIndex < dataSetForWindLevel.get(levelIndex).size(); dataIndex++) {
|
||||
Double dataPoint = dataSetForWindLevel.get(levelIndex).get(dataIndex);
|
||||
DataPointWithOriginInfo dataPoint = dataSetForWindLevel.get(levelIndex).get(dataIndex);
|
||||
double pct = getNeighboorhoodSizePercentage(dataCountPerWindSpeed, dataSetForWindLevel,
|
||||
levelIndex, dataIndex, dataPoint, settings);
|
||||
if (pct >= settings.getOutlierMinimumNeighborhoodPct()) {
|
||||
withoutOutliers.add(dataPoint);
|
||||
} else {
|
||||
sumsPerWindSpeed[levelIndex] = sumsPerWindSpeed[levelIndex] - dataPoint;
|
||||
sumsPerWindSpeed[levelIndex] = sumsPerWindSpeed[levelIndex] - dataPoint.getRawData();
|
||||
dataCountPerWindSpeed[levelIndex]--;
|
||||
}
|
||||
}
|
||||
@@ -191,7 +196,7 @@ public class PolarSheetGenerationWorker implements Future<PolarSheetsData>{
|
||||
}
|
||||
|
||||
if (dataCountPerWindSpeed[levelIndex] < settings.getMinimumDataCountPerAngle()) {
|
||||
dataSetForWindLevel.put(levelIndex, new ArrayList<Double>());
|
||||
dataSetForWindLevel.put(levelIndex, new ArrayList<DataPointWithOriginInfo>());
|
||||
sumsPerWindSpeed[levelIndex] = 0;
|
||||
dataCountPerWindSpeed[levelIndex] = 0;
|
||||
}
|
||||
@@ -209,7 +214,7 @@ public class PolarSheetGenerationWorker implements Future<PolarSheetsData>{
|
||||
Double standardDeviation = Math.sqrt(variance);
|
||||
coefficiantOfVariation = standardDeviation / average;
|
||||
}
|
||||
List<Double> rawData = dataSetForWindLevel.get(levelIndex);
|
||||
List<DataPointWithOriginInfo> rawData = dataSetForWindLevel.get(levelIndex);
|
||||
if (rawData == null || rawData.size() <= 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -239,8 +244,8 @@ public class PolarSheetGenerationWorker implements Future<PolarSheetsData>{
|
||||
* to the complete dataset.
|
||||
*/
|
||||
public static double getNeighboorhoodSizePercentage(int[] dataCountPerWindSpeed,
|
||||
Map<Integer, List<Double>> dataSetForWindLevel, int levelIndex, int dataIndex, Double dataPoint,
|
||||
PolarSheetGenerationSettings settings) {
|
||||
Map<Integer, List<DataPointWithOriginInfo>> dataSetForWindLevel, int levelIndex, int dataIndex,
|
||||
DataPointWithOriginInfo dataPoint, PolarSheetGenerationSettings settings) {
|
||||
int neighborCount = 0;
|
||||
double pct = .0;
|
||||
|
||||
@@ -253,8 +258,8 @@ public class PolarSheetGenerationWorker implements Future<PolarSheetsData>{
|
||||
done = true;
|
||||
} else {
|
||||
Double dataPointToCheckForNeighborStatus = dataSetForWindLevel.get(levelIndex).get(
|
||||
index);
|
||||
if (dataPoint - dataPointToCheckForNeighborStatus <= settings
|
||||
index).getRawData();
|
||||
if (dataPoint.getRawData() - dataPointToCheckForNeighborStatus <= settings
|
||||
.getOutlierDetectionNeighborhoodRadius()) {
|
||||
neighborCount++;
|
||||
} else {
|
||||
@@ -275,8 +280,8 @@ public class PolarSheetGenerationWorker implements Future<PolarSheetsData>{
|
||||
done = true;
|
||||
} else {
|
||||
Double dataPointToCheckForNeighborStatus = dataSetForWindLevel.get(levelIndex).get(
|
||||
index);
|
||||
if (dataPointToCheckForNeighborStatus - dataPoint <= settings
|
||||
index).getRawData();
|
||||
if (dataPointToCheckForNeighborStatus - dataPoint.getRawData() <= settings
|
||||
.getOutlierDetectionNeighborhoodRadius()) {
|
||||
neighborCount++;
|
||||
} else {
|
||||
@@ -309,7 +314,7 @@ public class PolarSheetGenerationWorker implements Future<PolarSheetsData>{
|
||||
* @return The complete set of datapoints that have been added. Can be quite big, depending on the amount of races
|
||||
* and competitors.
|
||||
*/
|
||||
public List<List<BoatAndWindSpeed>> getCompleteData() {
|
||||
public List<List<BoatAndWindSpeedWithOriginInfo>> getCompleteData() {
|
||||
return polarData;
|
||||
}
|
||||
|
||||
|
||||
+25
-6
@@ -1,7 +1,9 @@
|
||||
package com.sap.sailing.domain.polarsheets;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.common.PolarSheetGenerationSettings;
|
||||
import com.sap.sailing.domain.common.PolarSheetsHistogramData;
|
||||
@@ -15,9 +17,13 @@ public class PolarSheetHistogramBuilder {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public PolarSheetsHistogramData build(List<Double> rawData, int angleIndex, double coefficiantOfVariation) {
|
||||
Double min = Collections.min(rawData);
|
||||
Double max = Collections.max(rawData);
|
||||
public PolarSheetsHistogramData build(List<DataPointWithOriginInfo> dataPointsWithOriginInfo, int angleIndex,
|
||||
double coefficiantOfVariation) {
|
||||
DataPointWithOriginInfo minPoint = Collections.min(dataPointsWithOriginInfo);
|
||||
DataPointWithOriginInfo maxPoint = Collections.max(dataPointsWithOriginInfo);
|
||||
|
||||
Double min = minPoint.getRawData();
|
||||
Double max = maxPoint.getRawData();
|
||||
|
||||
int numberOfColumns = settings.getNumberOfHistogramColumns();
|
||||
double range = (max - min) / numberOfColumns;
|
||||
@@ -26,9 +32,10 @@ public class PolarSheetHistogramBuilder {
|
||||
xValues[u] = min + u * range + (0.5 * range);
|
||||
}
|
||||
|
||||
Map<String, Integer[]> yValuesByGaugeIds = new HashMap<String, Integer[]>();
|
||||
Integer[] yValues = new Integer[numberOfColumns];
|
||||
for (Double dataPoint : rawData) {
|
||||
double notRoundedYet = (dataPoint - min) / range;
|
||||
for (DataPointWithOriginInfo dataPoint : dataPointsWithOriginInfo) {
|
||||
double notRoundedYet = (dataPoint.getRawData() - min) / range;
|
||||
int u = (int) notRoundedYet;
|
||||
if (u == numberOfColumns) {
|
||||
// For max value
|
||||
@@ -38,10 +45,22 @@ public class PolarSheetHistogramBuilder {
|
||||
yValues[u] = 0;
|
||||
}
|
||||
yValues[u]++;
|
||||
|
||||
String gaugeIdsString = dataPoint.getWindGaugeIdString();
|
||||
if (!yValuesByGaugeIds.containsKey(gaugeIdsString)) {
|
||||
yValuesByGaugeIds.put(gaugeIdsString, new Integer[numberOfColumns]);
|
||||
}
|
||||
Integer[] yValuesForThatGaugeIdsString = yValuesByGaugeIds.get(gaugeIdsString);
|
||||
if (yValuesForThatGaugeIdsString[u] == null) {
|
||||
yValuesForThatGaugeIdsString[u] = 0;
|
||||
}
|
||||
yValuesForThatGaugeIdsString[u]++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
PolarSheetsHistogramData histogramData = new PolarSheetsHistogramDataImpl(angleIndex, xValues, yValues,
|
||||
rawData.size(), coefficiantOfVariation);
|
||||
dataPointsWithOriginInfo.size(), coefficiantOfVariation);
|
||||
return histogramData;
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -42,8 +42,9 @@ public class PolarSheetsHistogramPanel extends DockLayoutPanel {
|
||||
|
||||
public void setData(PolarSheetsHistogramData data) {
|
||||
chart.removeAllSeries();
|
||||
chart.setTitle(new ChartTitle().setText(stringMessages.histogram()),
|
||||
new ChartSubtitle().setText(stringMessages.angleAndTotalNumberOfDataPointsAndCovAndCm(data.getAngle(), data.getDataCount(), data.getCoefficiantOfVariation(), data.getConfidenceMeasure())));
|
||||
chart.setTitle(new ChartTitle().setText(stringMessages.histogram()), new ChartSubtitle().setText(stringMessages
|
||||
.angleAndTotalNumberOfDataPointsAndCovAndCm(data.getAngle(), data.getDataCount(),
|
||||
data.getCoefficiantOfVariation(), data.getConfidenceMeasure())));
|
||||
Point[] points = toPoints(data);
|
||||
Series series = chart.createSeries();
|
||||
series.setPoints(points);
|
||||
|
||||
Reference in new issue
Block a user