Added a more dynamic way of wind-stepping for polar sheets

This commit is contained in:
Frederik Petersen committed 2013-05-24 16:15:15 +02:00
1 parent ff3609e695
commit b3331c1c27
11 files changed
+91 -28

No files matched your search

@@ -12,4 +12,6 @@ public interface PolarSheetsData extends Serializable {
Integer[] getDataCountPerAngleForWindspeed(int beaufort);
Integer[] getStepping();
}
@@ -13,17 +13,20 @@ public class PolarSheetsDataImpl implements PolarSheetsData {
private boolean complete;
private int dataCount;
private Integer[] stepping;
private Map<Integer,Integer[]> dataCountPerAngleForWindspeed;
//For GWT Serialization
PolarSheetsDataImpl() {};
public PolarSheetsDataImpl(Number[][] averagedPolarDataByWindSpeed, boolean complete, int dataCount, Map<Integer,Integer[]> dataCountPerAngleForWindspeed) {
public PolarSheetsDataImpl(Number[][] averagedPolarDataByWindSpeed, boolean complete, int dataCount, Map<Integer,Integer[]> dataCountPerAngleForWindspeed, Integer[] stepping) {
this.averagedPolarDataByWindSpeed = averagedPolarDataByWindSpeed;
this.complete = complete;
this.dataCount = dataCount;
this.dataCountPerAngleForWindspeed = dataCountPerAngleForWindspeed;
this.stepping = stepping;
}
@Override
@@ -46,5 +49,10 @@ public class PolarSheetsDataImpl implements PolarSheetsData {
public Integer[] getDataCountPerAngleForWindspeed(int beaufort) {
return dataCountPerAngleForWindspeed.get(beaufort);
}
@Override
public Integer[] getStepping() {
return stepping;
}
}
@@ -72,9 +72,9 @@ public class PolarSheetGenerationTest {
PolarSheetsData data = resultContainer.getPolarData();
Assert.assertEquals(4, data.getDataCount());
Assert.assertEquals(4.0, data.getAveragedPolarDataByWindSpeed()[1][45]);
Assert.assertEquals(2.0, data.getAveragedPolarDataByWindSpeed()[1][55]);
Assert.assertEquals(6.0, data.getAveragedPolarDataByWindSpeed()[1][30]);
Assert.assertEquals(4.0, data.getAveragedPolarDataByWindSpeed()[0][45]);
Assert.assertEquals(2.0, data.getAveragedPolarDataByWindSpeed()[0][55]);
Assert.assertEquals(6.0, data.getAveragedPolarDataByWindSpeed()[0][30]);
}
@@ -32,6 +32,8 @@ public class PolarSheetGenerationWorker {
private final Executor executor;
private PolarSheetsWindStepping stepping;
/**
* Will prepare the {@link PerRaceAndCompetitorPolarSheetGenerationWorker}s per race & per competitor. This includes
* determining start and end time.
@@ -42,6 +44,8 @@ public class PolarSheetGenerationWorker {
* executes the tasks upon {@link #startPolarSheetGeneration()}
*/
public PolarSheetGenerationWorker(Set<TrackedRace> trackedRaces, Executor executor) {
Integer[] levels = {4,6,8,10,12,14,16,20,25,30};
stepping = new PolarSheetsWindStepping(levels);
polarData = initializePolarDataContainer();
this.executor = executor;
workers = new HashSet<PerRaceAndCompetitorPolarSheetGenerationWorker>();
@@ -107,11 +111,12 @@ public class PolarSheetGenerationWorker {
* product.
*/
public PolarSheetsData getPolarData() {
Number[][] averagedPolarDataByWindSpeed = new Number[13][360];
int levelCount = stepping.getNumberOfLevels();
Number[][] averagedPolarDataByWindSpeed = new Number[levelCount][360];
Integer[] dataCountPerAngle = new Integer[360];
int dataCount = 0;
Map<Integer, Integer[]> dataCountPerAngleForWindspeed = new HashMap<Integer, Integer[]>();
for (int i = 0; i < 13; i++) {
for (int i = 0; i < levelCount; i++) {
dataCountPerAngleForWindspeed.put(i, new Integer[360]);
}
for (int i = 0; i < 360; i++) {
@@ -119,22 +124,22 @@ public class PolarSheetGenerationWorker {
BoatAndWindSpeed[] values = polarData.get(i).toArray(new BoatAndWindSpeed[polarData.get(i).size()]);
dataCount = dataCount + values.length;
dataCountPerAngle[i] = values.length;
double[] sumsPerWindSpeed = new double[13];
int[] dataCountPerWindSpeed = new int[13];
double[] sumsPerWindSpeed = new double[levelCount];
int[] dataCountPerWindSpeed = new int[levelCount];
for (BoatAndWindSpeed singleDataPoint : values) {
if (singleDataPoint != null) {
int windSpeed = (int) singleDataPoint.getWindSpeed().getBeaufort();
//Somehow beaufort sometimes gets bigger than twelve. TODO: Investigation
if (windSpeed > 12) {
windSpeed = 12;
double windSpeed = singleDataPoint.getWindSpeed().getKnots();
int level = stepping.getLevelForValue(windSpeed);
if (level < 0) {
continue;
}
//TODO enable different kinds of metrics for boats speed
sumsPerWindSpeed[windSpeed] = sumsPerWindSpeed[windSpeed] + singleDataPoint.getBoatSpeed().getKnots();
dataCountPerWindSpeed[windSpeed]++;
sumsPerWindSpeed[level] = sumsPerWindSpeed[level] + singleDataPoint.getBoatSpeed().getKnots();
dataCountPerWindSpeed[level]++;
}
}
for (int j = 0; j < 13; j++) {
for (int j = 0; j < levelCount; j++) {
Double average = sumsPerWindSpeed[j] / dataCountPerWindSpeed[j];
if (average.isNaN()) {
average = new Double(0);
@@ -156,7 +161,7 @@ public class PolarSheetGenerationWorker {
}
PolarSheetsData data = new PolarSheetsDataImpl(averagedPolarDataByWindSpeed, complete, dataCount,
dataCountPerAngleForWindspeed);
dataCountPerAngleForWindspeed, stepping.getRawStepping());
return data;
}
@@ -171,4 +176,8 @@ public class PolarSheetGenerationWorker {
return polarData;
}
public PolarSheetsWindStepping getStepping() {
return stepping;
}
}
@@ -0,0 +1,33 @@
package com.sap.sailing.domain.polarsheets;
public class PolarSheetsWindStepping {
private Integer[] levels;
public PolarSheetsWindStepping(Integer[] levels) {
this.levels = levels;
}
public int getNumberOfLevels() {
return levels.length;
}
public int getLevelForValue(double speed) {
for (int i = 0; i < levels.length - 1; i++) {
if (speed < levels[i] || speed < levels[i] + ((levels[i+1] - levels[i]) / 2)) {
return i;
}
}
if (speed < levels[levels.length - 1] + 5) {
return levels.length - 1;
}
//To high over highest level
return -1;
}
public Integer[] getRawStepping() {
return levels;
}
}
@@ -77,9 +77,9 @@ public class PolarSheetGenerationServiceTest {
Assert.assertNotNull(results);
Assert.assertEquals(4, results.getDataCount());
Assert.assertEquals(4.0, results.getAveragedPolarDataByWindSpeed()[1][45]);
Assert.assertEquals(2.0, results.getAveragedPolarDataByWindSpeed()[1][55]);
Assert.assertEquals(6.0, results.getAveragedPolarDataByWindSpeed()[1][30]);
Assert.assertEquals(4.0, results.getAveragedPolarDataByWindSpeed()[0][45]);
Assert.assertEquals(2.0, results.getAveragedPolarDataByWindSpeed()[0][55]);
Assert.assertEquals(6.0, results.getAveragedPolarDataByWindSpeed()[0][30]);
@@ -288,7 +288,7 @@ public interface SailingService extends RemoteService {
PolarSheetsData getPolarSheetsGenerationResults(String id);
PolarSheetsHistogramData getPolarSheetData(String polarSheetId, int angle, int windSpeed);
PolarSheetsHistogramData getPolarSheetData(String polarSheetId, int angle, int windSpeedLevel);
EventDTO getEventById(Serializable id);
@@ -429,7 +429,7 @@ public interface SailingServiceAsync {
void getPolarSheetsGenerationResults(String id, AsyncCallback<PolarSheetsData> asyncCallback);
void getPolarSheetData(String polarSheetId, int angle, int windSpeed, AsyncCallback<PolarSheetsHistogramData> wrapperCallback);
void getPolarSheetData(String polarSheetId, int angle, int windSpeedLevel, AsyncCallback<PolarSheetsHistogramData> wrapperCallback);
void getRegattaOverviewEntriesForEvent(String eventIdAsString, AsyncCallback<List<RegattaOverviewEntryDTO>> asyncCallback);
@@ -52,12 +52,12 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize
}
}
private void createSeriesForWindspeed(String name, int windSpeed) {
private void createSeriesForWindspeed(String name, int windSpeedLevel, int windSpeed) {
Series[] seriesPerWindSpeed = seriesMap.get(name);
Number[] forEachDeg = initializeDataForNewSeries();
seriesPerWindSpeed[windSpeed] = chart.createSeries().setPoints(forEachDeg);
seriesPerWindSpeed[windSpeed].setName(name + "-" + (windSpeed));
chart.addSeries(seriesPerWindSpeed[windSpeed]);
seriesPerWindSpeed[windSpeedLevel] = chart.createSeries().setPoints(forEachDeg);
seriesPerWindSpeed[windSpeedLevel].setName(name + "-" + windSpeed);
chart.addSeries(seriesPerWindSpeed[windSpeedLevel]);
}
private Number[] initializeDataForNewSeries() {
@@ -66,11 +66,12 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize
}
private void addValuesToSeries(String seriesId, PolarSheetsData result) {
int stepCount = result.getStepping().length;
if (seriesMap.containsKey(seriesId)) {
for (int i = 0; i < 13; i++) {
for (int i = 0; i < stepCount; i++) {
if (hasSufficientDataForWindspeed(result.getDataCountPerAngleForWindspeed(i), result.getDataCount())) {
if (seriesMap.get(seriesId)[i] == null) {
createSeriesForWindspeed(seriesId, i);
createSeriesForWindspeed(seriesId, i, result.getStepping()[i]);
}
Series series = seriesMap.get(seriesId)[i];
series.setPoints(result.getAveragedPolarDataByWindSpeed()[i], false);
@@ -12,10 +12,12 @@ import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.sap.sailing.domain.common.PolarSheetGenerationTriggerResponse;
import com.sap.sailing.domain.common.PolarSheetsData;
@@ -81,6 +83,9 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi
histogramPanel = new PolarSheetsHistogramPanel(stringMessages);
histogramPanel.getElement().setAttribute("align", "top");
rightPanel.add(histogramPanel);
ListBox nameListBox = new ListBox();
rightPanel.add(nameListBox);
Button exportButton = new Button("Export");
mainPanel.add(splitPanel);
asyncActionsExecutor = new AsyncActionsExecutor();
@@ -130,6 +130,7 @@ import com.sap.sailing.domain.persistence.MongoRaceLogStoreFactory;
import com.sap.sailing.domain.persistence.MongoWindStoreFactory;
import com.sap.sailing.domain.polarsheets.BoatAndWindSpeed;
import com.sap.sailing.domain.polarsheets.PolarSheetGenerationWorker;
import com.sap.sailing.domain.polarsheets.PolarSheetsWindStepping;
import com.sap.sailing.domain.racelog.PassAwareRaceLog;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
@@ -2689,6 +2690,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
if (httpServletRequest != null) {
HttpSession session = httpServletRequest.getSession();
session.setAttribute(id, worker.getCompleteData());
session.setAttribute("stepping", worker.getStepping());
}
}
} else {
@@ -2713,11 +2715,14 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
//TODO exception handling
return null;
}
PolarSheetsWindStepping stepping = (PolarSheetsWindStepping) session.getAttribute("stepping");
List<Double> dataForAngleAndWindSpeed = new ArrayList<Double>();
int windSpeedLevel = stepping.getLevelForValue(windSpeed);
for (BoatAndWindSpeed dataPoint: dataForAngle) {
if (((int) dataPoint.getWindSpeed().getBeaufort()) == windSpeed) {
if ((stepping.getLevelForValue(dataPoint.getWindSpeed().getKnots()) == windSpeedLevel)) {
dataForAngleAndWindSpeed.add(dataPoint.getBoatSpeed().getKnots());
}
}