mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-02 18:33:54 +00:00
Added debugging labels to polarsheetspanel
This commit is contained in:
1 parent
43eb0a5e83
commit
8ee3d50d1b
7 files changed
+109
-50
No files matched your search
+4
@@ -6,6 +6,10 @@ public interface PolarSheetsData extends Serializable {
|
||||
|
||||
Number[] getValues();
|
||||
|
||||
int getDataCount();
|
||||
|
||||
boolean isComplete();
|
||||
|
||||
Integer[] getDataCountPerAngle();
|
||||
|
||||
}
|
||||
+17
-1
@@ -10,12 +10,18 @@ public class PolarSheetsDataImpl implements PolarSheetsData {
|
||||
|
||||
private boolean complete;
|
||||
|
||||
private int dataCount;
|
||||
|
||||
private Integer[] dataCountPerAngle;
|
||||
|
||||
//For GWT Serialization
|
||||
PolarSheetsDataImpl() {};
|
||||
|
||||
public PolarSheetsDataImpl(Number[] values, boolean complete) {
|
||||
public PolarSheetsDataImpl(Number[] values, boolean complete, int dataCount, Integer[] dataCountPerAngle) {
|
||||
this.values = values;
|
||||
this.complete = complete;
|
||||
this.dataCount = dataCount;
|
||||
this.dataCountPerAngle = dataCountPerAngle;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -28,4 +34,14 @@ public class PolarSheetsDataImpl implements PolarSheetsData {
|
||||
return complete;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDataCount() {
|
||||
return dataCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer[] getDataCountPerAngle() {
|
||||
return dataCountPerAngle;
|
||||
}
|
||||
|
||||
}
|
||||
+5
-3
@@ -92,14 +92,16 @@ public class PerRaceWorker implements Runnable {
|
||||
GPSFixTrack<Competitor, GPSFixMoving> track = race.getTrack(competitor);
|
||||
track.lockForRead();
|
||||
Iterator<GPSFixMoving> fixesIterator = track.getFixesIterator(startTime, true);
|
||||
// TODO maneuver exclusion
|
||||
// List<Maneuver> maneuvers = race.getManeuvers(competitor, startTime, endTime, false);
|
||||
|
||||
while (fixesIterator.hasNext()) {
|
||||
GPSFixMoving fix = fixesIterator.next();
|
||||
if (fix.getTimePoint().after(endTime)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (track.hasDirectionChange(fix.getTimePoint(), race.getRace().getBoatClass().getManeuverDegreeAngleThreshold())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SpeedWithBearing speedWithBearing = fix.getSpeed();
|
||||
double speed = speedWithBearing.getMetersPerSecond();
|
||||
@@ -111,7 +113,7 @@ public class PerRaceWorker implements Runnable {
|
||||
|
||||
// TODO Figure out if this normalizing is okay concerning different windspeeds and bearings
|
||||
double normalizedSpeed = speed / windSpeed;
|
||||
double angleToWind = 180 + bearing.getDifferenceTo(windBearing).getDegrees();
|
||||
double angleToWind = bearing.getDifferenceTo(windBearing).getDegrees();
|
||||
|
||||
polarSheetGenerationWorker.addPolarData(Math.round(angleToWind), normalizedSpeed);
|
||||
}
|
||||
|
||||
+16
-27
@@ -5,6 +5,8 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sailing.domain.common.PolarSheetsData;
|
||||
import com.sap.sailing.domain.common.impl.PolarSheetsDataImpl;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
|
||||
public class PolarSheetGenerationWorker {
|
||||
@@ -27,7 +29,7 @@ public class PolarSheetGenerationWorker {
|
||||
|
||||
private List<List<Double>> initializePolarDataContainer() {
|
||||
List<List<Double>> container = new ArrayList<List<Double>>();
|
||||
for (int i = 0; i < 181; i++) {
|
||||
for (int i = 0; i < 360; i++) {
|
||||
container.add(new ArrayList<Double>());
|
||||
}
|
||||
return container;
|
||||
@@ -43,18 +45,22 @@ public class PolarSheetGenerationWorker {
|
||||
|
||||
public void addPolarData(long roundedAngle, double normalizedSpeed) {
|
||||
int angle = (int) roundedAngle;
|
||||
if (angle > 180) {
|
||||
angle = (360 - angle);
|
||||
if (angle < 0) {
|
||||
angle = (360 + angle);
|
||||
}
|
||||
polarData.get(angle).add(normalizedSpeed);
|
||||
}
|
||||
|
||||
public Number[] getPolarData() {
|
||||
public PolarSheetsData getPolarData() {
|
||||
Number[] averagedPolarData = new Number[360];
|
||||
for (int i = 0; i < 181; i++) {
|
||||
Integer[] dataCountPerAngle = new Integer[360];
|
||||
int dataCount = 0;
|
||||
for (int i = 0; i < 360; i++) {
|
||||
// Avoid Concurrent modification, lock would slow things down
|
||||
Double[] values = polarData.get(i).toArray(new Double[polarData.get(i).size()]);
|
||||
if (values.length < 20) {
|
||||
dataCount = dataCount + values.length;
|
||||
dataCountPerAngle[i] = values.length;
|
||||
if (values.length < 1) {
|
||||
averagedPolarData[i] = 0;
|
||||
} else {
|
||||
double sum = 0;
|
||||
@@ -67,24 +73,11 @@ public class PolarSheetGenerationWorker {
|
||||
averagedPolarData[i] = average;
|
||||
}
|
||||
}
|
||||
|
||||
PolarSheetsData data = new PolarSheetsDataImpl(averagedPolarData, finished, dataCount, dataCountPerAngle);
|
||||
|
||||
for (int i = 1; i < 180; i++) {
|
||||
if (averagedPolarData[i].doubleValue() == 0) {
|
||||
double next = 0;
|
||||
int currentIndex = i;
|
||||
while (next <= 0 && currentIndex < 181) {
|
||||
currentIndex++;
|
||||
if (averagedPolarData[currentIndex] != null) {
|
||||
next = averagedPolarData[currentIndex].doubleValue();
|
||||
}
|
||||
}
|
||||
averagedPolarData[i] = (averagedPolarData[i - 1].doubleValue() + next) / 2;
|
||||
}
|
||||
|
||||
averagedPolarData[360 - i] = averagedPolarData[i];
|
||||
}
|
||||
|
||||
return averagedPolarData;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public void workerDone(PerRaceWorker worker) {
|
||||
@@ -96,8 +89,4 @@ public class PolarSheetGenerationWorker {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return finished;
|
||||
}
|
||||
|
||||
}
|
||||
+31
-6
@@ -1,13 +1,20 @@
|
||||
package com.sap.sailing.gwt.ui.polarsheets;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.moxieapps.gwt.highcharts.client.Chart;
|
||||
import org.moxieapps.gwt.highcharts.client.Color;
|
||||
import org.moxieapps.gwt.highcharts.client.Point;
|
||||
import org.moxieapps.gwt.highcharts.client.Series;
|
||||
import org.moxieapps.gwt.highcharts.client.plotOptions.LinePlotOptions;
|
||||
import org.moxieapps.gwt.highcharts.client.plotOptions.Marker;
|
||||
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.sap.sailing.domain.common.PolarSheetsData;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
|
||||
public class PolarSheetsChartPanel extends SimplePanel {
|
||||
@@ -25,7 +32,8 @@ public class PolarSheetsChartPanel extends SimplePanel {
|
||||
}
|
||||
|
||||
private Chart createPolarSheetChart() {
|
||||
Chart polarSheetChart = new Chart().setType(Series.Type.LINE).setLinePlotOptions(new LinePlotOptions().setLineWidth(1)).setZoomType(Chart.ZoomType.X_AND_Y)
|
||||
Chart polarSheetChart = new Chart().setType(Series.Type.LINE)
|
||||
.setLinePlotOptions(new LinePlotOptions().setLineWidth(1)).setZoomType(Chart.ZoomType.X_AND_Y)
|
||||
.setPolar(true).setSize(700, 700);
|
||||
polarSheetChart.setChartTitleText(stringMessages.polarSheetChart());
|
||||
polarSheetChart.getYAxis().setMin(0);
|
||||
@@ -49,13 +57,30 @@ public class PolarSheetsChartPanel extends SimplePanel {
|
||||
return forEachDeg;
|
||||
}
|
||||
|
||||
private void addValuesToSeries(String seriesId, Number[] values) {
|
||||
private void addValuesToSeries(String seriesId, PolarSheetsData result) {
|
||||
if (seriesMap.containsKey(seriesId)) {
|
||||
Series series = seriesMap.get(seriesId);
|
||||
series.setPoints(values, false);
|
||||
series.setPoints(result.getValues(), false);
|
||||
Point[] points = createPointsWithMarkerAlphaAccordingToDataCount(result);
|
||||
series.setPoints(points);
|
||||
}
|
||||
}
|
||||
|
||||
private Point[] createPointsWithMarkerAlphaAccordingToDataCount(PolarSheetsData result) {
|
||||
Point[] points = new Point[360];
|
||||
List<Integer> dataCountList = Arrays.asList(result.getDataCountPerAngle());
|
||||
Integer max = Collections.max(dataCountList);
|
||||
if (max > 0) {
|
||||
for (int i = 0; i < 360; i++) {
|
||||
points[i] = new Point(result.getValues()[i]);
|
||||
double alpha = (double) dataCountList.get(i) / (double) max;
|
||||
// TODO set to series color and change alpha
|
||||
points[i].setMarker(new Marker().setFillColor(new Color(1, 1, 1, alpha)));
|
||||
}
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
public void removeSeries(String seriesId) {
|
||||
if (seriesMap.containsKey(seriesId)) {
|
||||
Series series = seriesMap.get(seriesId);
|
||||
@@ -69,15 +94,15 @@ public class PolarSheetsChartPanel extends SimplePanel {
|
||||
seriesMap.clear();
|
||||
}
|
||||
|
||||
public void setData(Number[] values, String id) {
|
||||
if (values == null) {
|
||||
public void setData(String id, PolarSheetsData result) {
|
||||
if (id == null) {
|
||||
// TODO Exception handling
|
||||
return;
|
||||
}
|
||||
if (!seriesMap.containsKey(id)) {
|
||||
newSeries(id);
|
||||
}
|
||||
addValuesToSeries(id, values);
|
||||
addValuesToSeries(id, result);
|
||||
chart.redraw();
|
||||
}
|
||||
|
||||
|
||||
+34
-8
@@ -10,6 +10,7 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
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.VerticalPanel;
|
||||
import com.sap.sailing.domain.common.PolarSheetsData;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
@@ -36,6 +37,9 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi
|
||||
private List<RegattaAndRaceIdentifier> selectedRaces;
|
||||
private PolarSheetsChartPanel chartPanel;
|
||||
|
||||
private Label polarSheetsGenerationLabel;
|
||||
private Label dataCountLabel;
|
||||
|
||||
public PolarSheetsPanel(SailingServiceAsync sailingService, ErrorReporter errorReporter,
|
||||
StringMessages stringMessages, PolarSheetsEntryPoint polarSheetsEntryPoint) {
|
||||
this.polarSheetsEntryPoint = polarSheetsEntryPoint;
|
||||
@@ -49,11 +53,20 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi
|
||||
mainPanel.setSize("100%", "100%");
|
||||
setWidget(mainPanel);
|
||||
HorizontalPanel splitPanel = createSplitPanel();
|
||||
addFilteredTrackedRacesList(splitPanel);
|
||||
VerticalPanel leftPanel = addFilteredTrackedRacesList(splitPanel);
|
||||
polarSheetsGenerationLabel = createPolarSheetGenerationStatusLabel();
|
||||
leftPanel.add(polarSheetsGenerationLabel);
|
||||
dataCountLabel = new Label();
|
||||
leftPanel.add(dataCountLabel);
|
||||
addPolarSheetsChartPanel(splitPanel);
|
||||
mainPanel.add(splitPanel);
|
||||
}
|
||||
|
||||
private Label createPolarSheetGenerationStatusLabel() {
|
||||
Label polarSheetsGenerationStatusLabel = new Label();
|
||||
return polarSheetsGenerationStatusLabel;
|
||||
}
|
||||
|
||||
private void addPolarSheetsChartPanel(HorizontalPanel splitPanel) {
|
||||
chartPanel = new PolarSheetsChartPanel(stringMessages);
|
||||
splitPanel.add(chartPanel);
|
||||
@@ -66,7 +79,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi
|
||||
return splitPanel;
|
||||
}
|
||||
|
||||
private void addFilteredTrackedRacesList(HorizontalPanel splitPanel) {
|
||||
private VerticalPanel addFilteredTrackedRacesList(HorizontalPanel splitPanel) {
|
||||
VerticalPanel trackedRacesPanel = new VerticalPanel();
|
||||
trackedRacesPanel.setWidth("100%");
|
||||
|
||||
@@ -75,6 +88,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi
|
||||
|
||||
splitPanel.add(trackedRacesPanel);
|
||||
splitPanel.setCellWidth(trackedRacesPanel, "50%");
|
||||
return trackedRacesPanel;
|
||||
}
|
||||
|
||||
private void createPolarSheetsTrackedRacesList() {
|
||||
@@ -93,13 +107,15 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi
|
||||
}
|
||||
|
||||
protected void startPolarSheetGeneration() {
|
||||
//List conversion, to make List serializable
|
||||
// List conversion, to make List serializable
|
||||
List<RegattaAndRaceIdentifier> selectedRacesInArrayList = new ArrayList<RegattaAndRaceIdentifier>();
|
||||
selectedRacesInArrayList.addAll(selectedRaces);
|
||||
sailingService.generatePolarSheetForRaces(selectedRacesInArrayList, new AsyncCallback<String>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(String result) {
|
||||
// TODO string messages
|
||||
setCompletionLabel("Generating...");
|
||||
startPullingResults(result);
|
||||
}
|
||||
|
||||
@@ -116,30 +132,40 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi
|
||||
|
||||
@Override
|
||||
public void onSuccess(PolarSheetsData result) {
|
||||
chartPanel.setData(result.getValues(), id);
|
||||
// TODO string messages
|
||||
setCompletionLabel("Generating...");
|
||||
dataCountLabel.setText("DataCount: " + result.getDataCount());
|
||||
chartPanel.setData(id, result);
|
||||
if (!result.isComplete()) {
|
||||
Timer timer = new Timer() {
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
startPullingResults(id);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
timer.schedule(1500);
|
||||
|
||||
|
||||
} else {
|
||||
// TODO string messages
|
||||
setCompletionLabel("Generation finished!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
// TODO Exception handling
|
||||
errorReporter.reportError(caught.getLocalizedMessage());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
protected void setCompletionLabel(String string) {
|
||||
polarSheetsGenerationLabel.setText(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRaceSelectionChange(List<RegattaAndRaceIdentifier> selectedRaces) {
|
||||
this.selectedRaces = selectedRaces;
|
||||
|
||||
+2
-5
@@ -97,7 +97,6 @@ import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KilometersPerHourSpeedImpl;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.impl.PolarSheetsDataImpl;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
@@ -3083,10 +3082,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
PolarSheetsData data = null;
|
||||
if (polarSheetGenerationWorkers.containsKey(id)) {
|
||||
PolarSheetGenerationWorker worker = polarSheetGenerationWorkers.get(id);
|
||||
boolean complete = worker.isFinished();
|
||||
Number[] values = worker.getPolarData();
|
||||
data = new PolarSheetsDataImpl(values, complete);
|
||||
if (complete) {
|
||||
data = worker.getPolarData();
|
||||
if (data.isComplete()) {
|
||||
polarSheetGenerationWorkers.remove(id);
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in new issue
Block a user