Merge remote-tracking branch 'origin/simulator_dev' into simulator_dev

Conflicts:
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/simulator/SimulatorMap.java
This commit is contained in:
Christopher Ronnewinkel (D036654) committed 2012-12-05 15:43:52 +01:00
commit ab13e3602e
6 files changed
+328 -129

No files matched your search

@@ -38,9 +38,9 @@ import com.sap.sailing.gwt.ui.shared.RequestPolarDiagramDataDTO;
import com.sap.sailing.gwt.ui.shared.SimulatedPathsEvenTimedResultDTO;
import com.sap.sailing.gwt.ui.shared.SimulatorResultsDTO;
import com.sap.sailing.gwt.ui.shared.SimulatorResultsDTOAndNotificationMessage;
import com.sap.sailing.gwt.ui.shared.SimulatorWindDTO;
import com.sap.sailing.gwt.ui.shared.SpeedBearingPositionDTO;
import com.sap.sailing.gwt.ui.shared.SpeedWithBearingDTO;
import com.sap.sailing.gwt.ui.shared.SimulatorWindDTO;
import com.sap.sailing.gwt.ui.shared.WindFieldDTO;
import com.sap.sailing.gwt.ui.shared.WindFieldGenParamsDTO;
import com.sap.sailing.gwt.ui.shared.WindLatticeDTO;
@@ -327,14 +327,14 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
windFieldDTO.setMatrix(wList);
if (isShowLines) {
if (seedLines == 'f') {
getWindLinesFromStartLine(wf, windFieldDTO, startTime, endTime, timeStep);
}
if (seedLines == 'b') {
getWindLinesFromEndLine(wf, windFieldDTO, startTime, endTime, timeStep);
}
}
return windFieldDTO;
}
@@ -352,9 +352,9 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
for (int j = 1; j < positionGrid[0].length - 1; ++j) {
// for (int j = 0; j < positionGrid[0].length; ++j) {
TimePoint t = startTime;
Position p0 = positionGrid[0][j];
Position p1 = positionGrid[1][j];
Position seed = new DegreePosition(p0.getLatDeg() + 0.5*(p0.getLatDeg()-p1.getLatDeg()), p0.getLngDeg() + 0.5*(p0.getLngDeg()-p1.getLngDeg()));
final Position p0 = positionGrid[0][j];
final Position p1 = positionGrid[1][j];
final Position seed = new DegreePosition(p0.getLatDeg() + 0.5*(p0.getLatDeg()-p1.getLatDeg()), p0.getLngDeg() + 0.5*(p0.getLngDeg()-p1.getLngDeg()));
final PositionDTO startPosition = new PositionDTO(seed.getLatDeg(), seed.getLngDeg());
while (t.compareTo(endTime) <= 0) {
final TimedPosition tp = new TimedPositionImpl(t, seed);
@@ -392,9 +392,9 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
for (int j = 1; j < positionGrid[lastRowIndex].length - 1; ++j) {
TimePoint t = startTime;
Position p0 = positionGrid[lastRowIndex][j];
Position p1 = positionGrid[lastRowIndex-1][j];
Position seed = new DegreePosition(p0.getLatDeg() + 0.5*(p0.getLatDeg()-p1.getLatDeg()), p0.getLngDeg() + 0.5*(p0.getLngDeg()-p1.getLngDeg()));
final Position p0 = positionGrid[lastRowIndex][j];
final Position p1 = positionGrid[lastRowIndex-1][j];
final Position seed = new DegreePosition(p0.getLatDeg() + 0.5*(p0.getLatDeg()-p1.getLatDeg()), p0.getLngDeg() + 0.5*(p0.getLngDeg()-p1.getLngDeg()));
final PositionDTO startPosition = new PositionDTO(seed.getLatDeg(), seed.getLngDeg());
while (t.compareTo(endTime) <= 0) {
final TimedPosition tp = new TimedPositionImpl(t, seed);
@@ -466,7 +466,7 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
final List<TimedPositionWithSpeed> path = paths.get(pathName);
// TODO: cleanup getAllPathsEvenTimed to return Paths instead of PathPoints
if (pathName.equals("6#GPS Poly")) {
if (pathName.equals("6#GPS Poly") || pathName.equals("7#GPS Track")) {
// special initialization for polyline
pathDTO[pathIndex] = this.convertToPathDTOAndMarkTurns(new PathImpl(paths.get(pathName), null), pathName.split("#")[1]);
@@ -784,7 +784,7 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
speeds.add(new SpeedBearingPositionDTO(positionDTO,
new SpeedWithBearingDTO(speedWithBearing.getKnots(),
speedWithBearing.getBearing().getDegrees())));
speedWithBearing.getBearing().getDegrees())));
}
return new ReceivePolarDiagramDataDTO(speeds, polarDiagramAndNotificationMessage.getNotificationMesssage());
@@ -4,19 +4,49 @@ import com.google.gwt.user.client.rpc.IsSerializable;
public class SimulatorWindDTO implements IsSerializable {
public boolean isTurn;
//public Double trueWindSpeedInMetersPerSecond;
public Double trueWindSpeedInKnots;
public Double trueWindBearingDeg;
//public Double trueWindFromDeg;
//public Double dampenedTrueWindSpeedInMetersPerSecond;
//public Double dampenedTrueWindSpeedInKnots;
//public Double dampenedTrueWindBearingDeg;
//public Double dampenedTrueWindFromDeg;
public PositionDTO position;
public Long timepoint;
//public Long originTimepoint;
//public Double confidence;
public SimulatorWindDTO() {
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp = 0;
temp = this.trueWindSpeedInKnots.intValue();
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = this.trueWindBearingDeg.intValue();
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = this.timepoint.intValue();
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = this.position.hashCode();
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(final Object o) {
if (o == null) {
return false;
} else {
if (o instanceof SimulatorWindDTO) {
final SimulatorWindDTO other = (SimulatorWindDTO) o;
return this.position.equals(other.position) && (Math.abs(this.timepoint - other.timepoint) < 9999);
}
return false;
}
}
}
@@ -3,7 +3,6 @@ package com.sap.sailing.gwt.ui.simulator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.i18n.client.DateTimeFormat;
@@ -33,13 +32,15 @@ public class PathCanvasOverlay extends WindFieldCanvasOverlay implements Named {
*/
private static final long serialVersionUID = -6284996043723173190L;
private static Logger logger = Logger.getLogger(PathCanvasOverlay.class.getName());
// private static Logger logger = Logger.getLogger(PathCanvasOverlay.class.getName());
private static final int MinimumPxDistanceBetweenArrows = 60;
private LatLng startPoint;
private LatLng endPoint;
private boolean totalTimeIsGiven = false;
private long totalTimeMilliseconds = 0;
protected String name;
public String pathColor = "Green";
@@ -48,21 +49,44 @@ public class PathCanvasOverlay extends WindFieldCanvasOverlay implements Named {
*/
public boolean displayWindAlongPath = true;
public PathCanvasOverlay(String name) {
public PathCanvasOverlay(final String name) {
super();
this.name = name;
}
public PathCanvasOverlay(String name, Timer timer) {
public PathCanvasOverlay(final String name, final Timer timer) {
super(timer);
this.name = name;
}
public void setRaceCourse(LatLng startPoint, LatLng endPoint) {
this.startPoint = startPoint;
this.endPoint = endPoint;
public PathCanvasOverlay(final String name, final long totalTimeMilliseconds) {
super();
this.name = name;
this.totalTimeIsGiven = true;
this.totalTimeMilliseconds = totalTimeMilliseconds;
}
public PathCanvasOverlay(final String name, final Timer timer, final long totalTimeMilliseconds) {
super(timer);
this.name = name;
this.totalTimeIsGiven = true;
this.totalTimeMilliseconds = totalTimeMilliseconds;
}
public void setTotalTimeMilliseconds(final long totalTimeMilliseconds) {
this.totalTimeIsGiven = true;
this.totalTimeMilliseconds = totalTimeMilliseconds;
}
public long getTotalTimeMilliseconds() {
return this.totalTimeMilliseconds;
}
public void setRaceCourse(final LatLng startPoint, final LatLng endPoint) {
this.startPoint = startPoint;
this.endPoint = endPoint;
}
/*
@Override
protected void drawWindField() {
@@ -71,41 +95,43 @@ public class PathCanvasOverlay extends WindFieldCanvasOverlay implements Named {
drawWindField(windDTOList);
}
*/
@Override
protected void drawWindField(final List<SimulatorWindDTO> windDTOList) {
WindFieldGenParamsDTO windParams = new WindFieldGenParamsDTO();
final WindFieldGenParamsDTO windParams = new WindFieldGenParamsDTO();
int numPoints = windDTOList.size();
final int numPoints = windDTOList.size();
if (numPoints < 1) {
return;
}
String title = "Path at " + numPoints + " points.";
long totalTime = windDTOList.get(numPoints - 1).timepoint - windDTOList.get(0).timepoint;
final long totalTime = windDTOList.get(numPoints - 1).timepoint - windDTOList.get(0).timepoint;
//LatLng start = LatLng.newInstance(windDTOList.get(0).position.latDeg, windDTOList.get(0).position.latDeg);
//LatLng end = LatLng.newInstance(windDTOList.get(numPoints - 1).position.latDeg, windDTOList.get(numPoints - 1).position.latDeg);
double distance = startPoint.distanceFrom(endPoint) / Mile.METERS_PER_NAUTICAL_MILE;
final double distance = startPoint.distanceFrom(endPoint) / Mile.METERS_PER_NAUTICAL_MILE;
Point startPx = getMap().convertLatLngToDivPixel(startPoint);
Point endPx = getMap().convertLatLngToDivPixel(endPoint);
double rcLengthPx = Math.sqrt(Math.pow(startPx.getX() - endPx.getX(), 2) + Math.pow(startPx.getY() - endPx.getY(), 2));
//System.out.println("Race Course Pixel Length: "+rcLengthPx);
// final Point startPx = getMap().convertLatLngToDivPixel(startPoint);
// final Point endPx = getMap().convertLatLngToDivPixel(endPoint);
// final double rcLengthPx = Math.sqrt(Math.pow(startPx.getX() - endPx.getX(), 2) + Math.pow(startPx.getY() -
// endPx.getY(), 2));
// System.out.println("Race Course Pixel Length: "+rcLengthPx);
double arrowDistPx = 60;
long arrowInterleave = Math.max(1, Math.round(arrowDistPx * numPoints / rcLengthPx));
// final double arrowDistPx = 60;
// final long arrowInterleave = Math.max(1, Math.round(arrowDistPx * numPoints / rcLengthPx));
// System.out.print("Arrow Interleave: "+arrowInterleave+"\n");
//arrowInterleave = 3;
// arrowInterleave = 3;
if (windDTOList != null && windDTOList.size() > 0) {
Context2d context2d = canvas.getContext2d();
final Context2d context2d = canvas.getContext2d();
context2d.setGlobalAlpha(0.8);
Iterator<SimulatorWindDTO> windDTOIter = windDTOList.iterator();
SimulatorWindDTO prevWindDTO = null;
while (windDTOIter.hasNext()) {
SimulatorWindDTO windDTO = windDTOIter.next();
final SimulatorWindDTO windDTO = windDTOIter.next();
if (prevWindDTO != null) {
drawLine(prevWindDTO, windDTO);
}
@@ -114,24 +140,24 @@ public class PathCanvasOverlay extends WindFieldCanvasOverlay implements Named {
windDTOIter = windDTOList.iterator();
int index = 0;
long startTime = windDTOList.get(0).timepoint;
final long startTime = windDTOList.get(0).timepoint;
prevWindDTO = null; //For the last time arrow was displayed
while (windDTOIter.hasNext()) {
SimulatorWindDTO windDTO = windDTOIter.next();
final SimulatorWindDTO windDTO = windDTOIter.next();
//if ((displayWindAlongPath) && ((index % arrowInterleave) == 0)) {
if (displayWindAlongPath) {
if (checkPointsAreFarEnough(windDTO,prevWindDTO)) {
DegreeBearingImpl dbi = new DegreeBearingImpl(windDTO.trueWindBearingDeg);
// System.out.print("index: "+index+"\n");
final DegreeBearingImpl dbi = new DegreeBearingImpl(windDTO.trueWindBearingDeg);
// System.out.print("index: "+index+"\n");
drawScaledArrow(windDTO, dbi.getRadians(), index, true);
prevWindDTO = windDTO;
}
}
index++;
long timeStep = windParams.getTimeStep().getTime();
final long timeStep = windParams.getTimeStep().getTime();
if ((windDTO.timepoint - startTime) % (timeStep) == 0) {
drawPoint(windDTO);
}
@@ -141,8 +167,8 @@ public class PathCanvasOverlay extends WindFieldCanvasOverlay implements Named {
context2d.setGlobalAlpha(1.0);
// MeterDistance meterDistance = new MeterDistance(distance);
Date timeDiffDate = new Date(totalTime);
TimeZone gmt = TimeZone.createTimeZone(0);
final Date timeDiffDate = new Date(totalTime);
final TimeZone gmt = TimeZone.createTimeZone(0);
title += " " + NumberFormat.getFormat("0.00").format(distance) + " nmi";
title += " in " + DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.HOUR24_MINUTE_SECOND).format(timeDiffDate, gmt);
@@ -151,23 +177,23 @@ public class PathCanvasOverlay extends WindFieldCanvasOverlay implements Named {
}
}
private void drawLine(SimulatorWindDTO p1, SimulatorWindDTO p2) {
private void drawLine(final SimulatorWindDTO p1, final SimulatorWindDTO p2) {
double weight = 3.0;
final double weight = 3.0;
PositionDTO position = p1.position;
LatLng positionLatLng = LatLng.newInstance(position.latDeg, position.lngDeg);
Point canvasPositionInPx = getMap().convertLatLngToDivPixel(positionLatLng);
int x1 = canvasPositionInPx.getX() - this.getWidgetPosLeft();
int y1 = canvasPositionInPx.getY() - this.getWidgetPosTop();
final int x1 = canvasPositionInPx.getX() - this.getWidgetPosLeft();
final int y1 = canvasPositionInPx.getY() - this.getWidgetPosTop();
position = p2.position;
positionLatLng = LatLng.newInstance(position.latDeg, position.lngDeg);
canvasPositionInPx = getMap().convertLatLngToDivPixel(positionLatLng);
int x2 = canvasPositionInPx.getX() - this.getWidgetPosLeft();
int y2 = canvasPositionInPx.getY() - this.getWidgetPosTop();
final int x2 = canvasPositionInPx.getX() - this.getWidgetPosLeft();
final int y2 = canvasPositionInPx.getY() - this.getWidgetPosTop();
// Context2d context2d = canvas.getContext2d();
// context2d.setShadowBlur(weight);
@@ -176,17 +202,17 @@ public class PathCanvasOverlay extends WindFieldCanvasOverlay implements Named {
// System.out.print("x1:"+x1+" y1:"+y1+" x2:"+x2+" y2:"+y2+"\n");
}
private void drawPoint(SimulatorWindDTO p) {
private void drawPoint(final SimulatorWindDTO p) {
double weight = 3.0;
final double weight = 3.0;
PositionDTO position = p.position;
final PositionDTO position = p.position;
LatLng positionLatLng = LatLng.newInstance(position.latDeg, position.lngDeg);
Point canvasPositionInPx = getMap().convertLatLngToDivPixel(positionLatLng);
final LatLng positionLatLng = LatLng.newInstance(position.latDeg, position.lngDeg);
final Point canvasPositionInPx = getMap().convertLatLngToDivPixel(positionLatLng);
int x1 = canvasPositionInPx.getX() - this.getWidgetPosLeft();
int y1 = canvasPositionInPx.getY() - this.getWidgetPosTop();
final int x1 = canvasPositionInPx.getX() - this.getWidgetPosLeft();
final int y1 = canvasPositionInPx.getY() - this.getWidgetPosTop();
drawCircle(x1, y1, weight / 2., pathColor);
}
@@ -196,7 +222,7 @@ public class PathCanvasOverlay extends WindFieldCanvasOverlay implements Named {
* @return true if the pixel distance between the two points is greater than
* a threshold. returns true if either of the points is null
*/
private boolean checkPointsAreFarEnough(SimulatorWindDTO p1, SimulatorWindDTO p2) {
private boolean checkPointsAreFarEnough(final SimulatorWindDTO p1, final SimulatorWindDTO p2) {
if (p1 == null || p2 == null) {
return true;
}
@@ -205,32 +231,36 @@ public class PathCanvasOverlay extends WindFieldCanvasOverlay implements Named {
LatLng positionLatLng = LatLng.newInstance(position.latDeg, position.lngDeg);
Point canvasPositionInPx = getMap().convertLatLngToDivPixel(positionLatLng);
int x1 = canvasPositionInPx.getX();
int y1 = canvasPositionInPx.getY();
final int x1 = canvasPositionInPx.getX();
final int y1 = canvasPositionInPx.getY();
position = p2.position;
positionLatLng = LatLng.newInstance(position.latDeg, position.lngDeg);
canvasPositionInPx = getMap().convertLatLngToDivPixel(positionLatLng);
int x2 = canvasPositionInPx.getX();
int y2 = canvasPositionInPx.getY();
final int x2 = canvasPositionInPx.getX();
final int y2 = canvasPositionInPx.getY();
double pxDistance = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
final double pxDistance = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
if (pxDistance >= MinimumPxDistanceBetweenArrows) {
return true;
} else {
return false;
return false;
}
}
@Override
public String getName() {
return name;
}
public long getPathTime() {
List<SimulatorWindDTO> windDTOList = wl.getMatrix();
int numPoints = windDTOList.size();
long totalTime = windDTOList.get(numPoints - 1).timepoint - windDTOList.get(0).timepoint;
return totalTime;
if (this.totalTimeIsGiven) {
return this.totalTimeMilliseconds;
} else {
final List<SimulatorWindDTO> windDTOList = wl.getMatrix();
final int numPoints = windDTOList.size();
final long totalTime = windDTOList.get(numPoints - 1).timepoint - windDTOList.get(0).timepoint;
return totalTime;
}
}
}
@@ -1,5 +1,6 @@
package com.sap.sailing.gwt.ui.simulator;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -38,7 +39,7 @@ public class PathLegendCanvasOverlay extends CanvasOverlay {
public String textColor = "Black";
public String textFont = "normal 10pt UbuntuRegular";
public PathLegendCanvasOverlay() {
this.setPathOverlays(null);
}
@@ -49,46 +50,46 @@ public class PathLegendCanvasOverlay extends CanvasOverlay {
}
@Override
protected void redraw(boolean force) {
protected void redraw(final boolean force) {
if (pathOverlays == null || pathOverlays.size() < 1) {
return;
}
setCanvasSettings();
int index = 0;
Context2d context2d = canvas.getContext2d();
final Context2d context2d = canvas.getContext2d();
context2d.setFont(textFont);
TextMetrics txtmet;
txtmet = context2d.measureText("00:00:00");
double timewidth = txtmet.getWidth();
final double timewidth = txtmet.getWidth();
double txtmaxwidth = 0.0;
for (PathCanvasOverlay path : pathOverlays) {
txtmet = context2d.measureText(path.name);
txtmaxwidth = Math.max(txtmaxwidth, txtmet.getWidth());
for (final PathCanvasOverlay path : pathOverlays) {
txtmet = context2d.measureText(path.name);
txtmaxwidth = Math.max(txtmaxwidth, txtmet.getWidth());
}
for (PathCanvasOverlay path : pathOverlays) {
drawRectangleWithText(xOffset, yOffset + (pathOverlays.size()-1-index) * rectHeight, path.pathColor,
for (final PathCanvasOverlay path : pathOverlays) {
drawRectangleWithText(xOffset, yOffset + (pathOverlays.size()-1-index) * rectHeight, path.pathColor,
path.name, getFormattedTime(path.getPathTime()),txtmaxwidth,timewidth);
index++;
}
}
protected void setCanvasSettings() {
int canvasWidth = (int) rectWidth + 200;
int canvasHeight = getMap().getSize().getHeight();
final int canvasWidth = (int) rectWidth + 200;
final int canvasHeight = getMap().getSize().getHeight();
canvas.setWidth(String.valueOf(canvasWidth));
canvas.setHeight(String.valueOf(canvasHeight));
canvas.setCoordinateSpaceWidth(canvasWidth);
canvas.setCoordinateSpaceHeight(canvasHeight);
Point sw = getMap().convertLatLngToDivPixel(getMap().getBounds().getSouthWest());
Point ne = getMap().convertLatLngToDivPixel(getMap().getBounds().getNorthEast());
final Point sw = getMap().convertLatLngToDivPixel(getMap().getBounds().getSouthWest());
final Point ne = getMap().convertLatLngToDivPixel(getMap().getBounds().getNorthEast());
setWidgetPosLeft(Math.min(sw.getX(), ne.getX()));
setWidgetPosTop(Math.min(sw.getY(), ne.getY()));
//setWidgetPosLeft(xOffset);
//setWidgetPosTop(yOffset);
getPane().setWidgetPosition(getCanvas(), getWidgetPosLeft(), getWidgetPosTop());
}
@@ -97,15 +98,39 @@ public class PathLegendCanvasOverlay extends CanvasOverlay {
return pathOverlays;
}
public void setPathOverlays(List<PathCanvasOverlay> pathOverlays) {
public void setPathOverlays(final List<PathCanvasOverlay> pathOverlays) {
this.pathOverlays = pathOverlays;
}
public void addPathOverlay(final PathCanvasOverlay pathOverlay) {
if (this.pathOverlays == null) {
this.pathOverlays = new ArrayList<PathCanvasOverlay>();
}
boolean found = false;
if (pathOverlay.name.equals("Polyline")) {
for (final PathCanvasOverlay overlay : this.pathOverlays) {
if (overlay.name.equals("Polyline")) {
overlay.setTotalTimeMilliseconds(pathOverlay.getTotalTimeMilliseconds());
found = true;
break;
}
}
}
if (found == false) {
this.pathOverlays.add(pathOverlay);
}
}
public int getWidgetPosLeft() {
return widgetPosLeft;
}
public void setWidgetPosLeft(int widgetPosLeft) {
public void setWidgetPosLeft(final int widgetPosLeft) {
this.widgetPosLeft = widgetPosLeft;
}
@@ -113,23 +138,23 @@ public class PathLegendCanvasOverlay extends CanvasOverlay {
return widgetPosTop;
}
public void setWidgetPosTop(int widgetPosTop) {
public void setWidgetPosTop(final int widgetPosTop) {
this.widgetPosTop = widgetPosTop;
}
protected void drawRectangle(double x, double y, String color) {
Context2d context2d = canvas.getContext2d();
protected void drawRectangle(final double x, final double y, final String color) {
final Context2d context2d = canvas.getContext2d();
context2d.setFillStyle(color);
context2d.setLineWidth(3);
context2d.fillRect(x, y, rectWidth, rectHeight);
}
protected void drawRectangleWithText(double x, double y, String color, String text, String time, double textmaxwidth, double timewidth) {
protected void drawRectangleWithText(final double x, final double y, final String color, final String text, final String time, final double textmaxwidth, final double timewidth) {
double offset = 3.0;
Context2d context2d = canvas.getContext2d();
final double offset = 3.0;
final Context2d context2d = canvas.getContext2d();
context2d.setFont(textFont);
drawRectangle(x, y, color);
context2d.setGlobalAlpha(0.80);
@@ -141,10 +166,10 @@ public class PathLegendCanvasOverlay extends CanvasOverlay {
context2d.fillText(time, x + rectWidth + textmaxwidth + 10.0, y + 12.0 + offset);
}
protected String getFormattedTime(long pathTime) {
TimeZone gmt = TimeZone.createTimeZone(0);
Date timeDiffDate = new Date(pathTime);
String pathTimeStr = DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.HOUR24_MINUTE_SECOND).format(
protected String getFormattedTime(final long pathTime) {
final TimeZone gmt = TimeZone.createTimeZone(0);
final Date timeDiffDate = new Date(pathTime);
final String pathTimeStr = DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.HOUR24_MINUTE_SECOND).format(
timeDiffDate, gmt);
return pathTimeStr;
}
@@ -16,7 +16,6 @@ import com.google.gwt.maps.client.overlay.Polyline;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.SimulatorServiceAsync;
import com.sap.sailing.gwt.ui.shared.PathDTO;
import com.sap.sailing.gwt.ui.shared.PositionDTO;
import com.sap.sailing.gwt.ui.shared.ReceivePolarDiagramDataDTO;
import com.sap.sailing.gwt.ui.shared.RequestPolarDiagramDataDTO;
@@ -33,7 +32,7 @@ public class PathPolyline {
private static final boolean SHOULD_DRAW_VERTICAL_DASHLINES = true;
private static final boolean SHOULD_DRAW_SHADOW_DASHLINES = false;
private static final String DEFAULT_COLOR = "#8B0000";
public static final String DEFAULT_COLOR = "#8B0000";
private static final int DEFAULT_WEIGHT = 3;
private static final double DEFAULT_OPACITY = 1.0;
private static final double DEFAULT_DISTANCE_PX = 25;
@@ -61,7 +60,7 @@ public class PathPolyline {
private SpeedWithBearingDTO averageWindSpeed;
private final int boatClassID;
private final PathDTO pathDTO;
private final List<SimulatorWindDTO> pathPoints;
private final SimulatorServiceAsync simulatorService;
private final MapWidget map;
private final ErrorReporter errorReporter;
@@ -69,17 +68,20 @@ public class PathPolyline {
private boolean firstTime = true;
private SimulatorMap simulatorMap = null;
// private double stepSizeMeters = 5.0;
// private static Logger logger = Logger.getLogger(PathPolyline.class.getName());
public PathPolyline(final LatLng[] points, final int boatClassID, final ErrorReporter errorReporter, final PathDTO pathDTO,
final SimulatorServiceAsync simulatorService, final MapWidget map) {
this(points, DEFAULT_COLOR, DEFAULT_WEIGHT, DEFAULT_OPACITY, boatClassID, errorReporter, pathDTO, simulatorService, map);
public PathPolyline(final LatLng[] points, final int boatClassID, final ErrorReporter errorReporter, final List<SimulatorWindDTO> pathPoints,
final SimulatorServiceAsync simulatorService, final MapWidget map, final SimulatorMap simulatorMap) {
this(points, DEFAULT_COLOR, DEFAULT_WEIGHT, DEFAULT_OPACITY, boatClassID, errorReporter, pathPoints, simulatorService, map, simulatorMap);
}
public PathPolyline(final LatLng[] points, final String color, final int weight, final double opacity, final int boatClassID,
final ErrorReporter errorReporter, final PathDTO pathDTO, final SimulatorServiceAsync simulatorService, final MapWidget map) {
final ErrorReporter errorReporter, final List<SimulatorWindDTO> pathPoints, final SimulatorServiceAsync simulatorService, final MapWidget map,
final SimulatorMap simulatorMap) {
this.points = points;
this.color = color;
this.weight = weight;
@@ -89,13 +91,15 @@ public class PathPolyline {
this.originAndHeads = new HashMap<TwoDPoint, List<TwoDPoint>>();
this.shadowPoints = new ArrayList<LatLng>();
this.pathDTO = pathDTO;
this.pathPoints = pathPoints;
this.simulatorService = simulatorService;
this.map = map;
this.averageWindSpeed = new SpeedWithBearingDTO();
this.boatClassID = boatClassID;
this.errorReporter = errorReporter;
this.simulatorMap = simulatorMap;
this.drawPolylineOnMap();
this.drawDashLinesOnMap(this.map.getZoomLevel());
@@ -388,19 +392,22 @@ public class PathPolyline {
System.err.println("==================================================");
System.err.println("total distance = " + PathPolylineUtils.getTotalDistanceMeters(points) + " meters");
System.err.println("step size = " + STEP_SIZE_METERS + " meters");
System.err.println("average wind speed = " + PathPolylineUtils.knotsToMetersPerSecond(averageWindSpeed.speedInKnots) + " meters/second");
System.err.println("total time = " + totalTime + " seconds!");
System.err.println("average wind speed = " + PathPolylineUtils.knotsToMetersPerSecond(averageWindSpeed.speedInKnots)
+ " meters/second, with bearing of " + averageWindSpeed.bearingInDegrees + " degrees");
System.err.println("total time = " + (long) totalTime + " seconds!");
System.err.println("==================================================");
simulatorMap.addLegendOverlayForPathPolyline(((long) totalTime) * 1000);
simulatorMap.redrawLegendCanvasOverlay();
}
});
}
private SpeedWithBearingDTO getAverageWindSpeed() {
final List<SimulatorWindDTO> windDTOs = this.pathDTO.getMatrix();
// PathPolylineUtils.computeMinMaxAverageWindSpeed(windDTOs)
return PathPolylineUtils.computeAverageWindSpeed(windDTOs);
return PathPolylineUtils.computeAverageWindSpeed(this.pathPoints);
}
private RequestPolarDiagramDataDTO createRequestPolarDiagramDataDTO() {
@@ -1,6 +1,7 @@
package com.sap.sailing.gwt.ui.simulator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
@@ -68,8 +69,11 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
private final int xRes;
private final int yRes;
// private PathPolyline pathPolyline;
private boolean warningAlreadyShown = false;
private boolean firstTime = true;
private PathDTO gpsPoly = null;
private PathDTO gpsTrack = null;
public enum ViewName {
SUMMARY, REPLAY, WINDDISPLAY
@@ -136,11 +140,18 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
pathName = paths[index].name;
color = colorPalette.getColor(paths.length - 1 - index);
// TODO: "GPS Poly" has wrong wind information => fix douglas-peucker "approximate", or refer to "GPS Track"
if (pathName.equals("GPS Poly")) {
// pathPolyline = createPathPolyline(currentPath, simulatorSvc, mapw);
createPathPolyline(currentPath, errorReporter, simulatorSvc, mapw);
if (pathName.equals("GPS Track")) {
gpsTrack = currentPath;
}
else if (pathName.equals("GPS Poly")) {
gpsPoly = currentPath;
}
if (firstTime && gpsTrack != null && gpsPoly != null) {
createPathPolyline(identifyPath(gpsTrack, gpsPoly));
firstTime = false;
}
/* TODO Revisit for now creating a WindFieldDTO from the path */
final WindFieldDTO pathWindDTO = new WindFieldDTO();
@@ -204,7 +215,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
if (windParams.isShowGrid()) {
timeListeners.add(windGridCanvasOverlay);
}
if (windParams.isShowLines()) {
if (windParams.isShowLines()) {
timeListeners.add(windLineCanvasOverlay);
}
for (int i = 0; i < replayPathCanvasOverlays.size(); ++i) {
@@ -687,9 +698,85 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
return value;
}
private static PathPolyline createPathPolyline(final PathDTO pathDTO, final ErrorReporter errorReporter, final SimulatorServiceAsync simulatorService,
final MapWidget map) {
final List<SimulatorWindDTO> pathPoints = pathDTO.getMatrix();
private static List<SimulatorWindDTO> identifyPath(final PathDTO gpsTrack, final PathDTO gpsPoly) {
final List<SimulatorWindDTO> windDTOs = new ArrayList<SimulatorWindDTO>();
final List<SimulatorWindDTO> gpsTrackWindDTOs = gpsTrack.getMatrix();
final List<SimulatorWindDTO> gpsPolyWindDTOs = gpsPoly.getMatrix();
final int countOfGpsPolyWindDTOs = gpsPolyWindDTOs.size();
if (countOfGpsPolyWindDTOs == 0 || countOfGpsPolyWindDTOs == 1) {
return null;
}
final SimulatorWindDTO startWindDTO = gpsPolyWindDTOs.get(0);
final SimulatorWindDTO endWindDTO = gpsPolyWindDTOs.get(countOfGpsPolyWindDTOs - 1);
final int startIndex = getIndexOfClosest(gpsTrackWindDTOs, startWindDTO);
// System.err.println("BBBB: startIndex = " + startIndex);
final int endIndex = getIndexOfClosest(gpsTrackWindDTOs, endWindDTO);
// System.err.println("BBBB: endIndex = " + endIndex);
for (int index = startIndex; index <= endIndex; index++) {
windDTOs.add(gpsTrackWindDTOs.get(index));
}
return windDTOs;
}
private static int getIndexOfClosest(final List<SimulatorWindDTO> items, final SimulatorWindDTO item) {
final int count = items.size();
final List<Double> diff_lat = new ArrayList<Double>();
final List<Double> diff_lng = new ArrayList<Double>();
final List<Long> diff_timepoint = new ArrayList<Long>();
for (int index = 0; index < count; index++) {
diff_lat.add(Math.abs(items.get(index).position.latDeg - item.position.latDeg));
diff_lng.add(Math.abs(items.get(index).position.lngDeg - item.position.lngDeg));
diff_timepoint.add(Math.abs(items.get(index).timepoint - item.timepoint));
}
final double min_diff_lat = Collections.min(diff_lat);
final double min_max_diff_lat = min_diff_lat + Collections.max(diff_lat);
final double min_diff_lng = Collections.min(diff_lng);
final double min_max_diff_lng = min_diff_lng + Collections.max(diff_lng);
final long min_diff_timepoint = Collections.min(diff_timepoint);
final double min_max_diff_timepoint = min_diff_timepoint + Collections.max(diff_timepoint);
final List<Double> norm_diff_lat = new ArrayList<Double>();
final List<Double> norm_diff_lng = new ArrayList<Double>();
final List<Double> norm_diff_timepoint = new ArrayList<Double>();
for (int index = 0; index < count; index++) {
norm_diff_lat.add((diff_lat.get(index) - min_diff_lat) / min_max_diff_lat);
norm_diff_lng.add((diff_lng.get(index) - min_diff_lng) / min_max_diff_lng);
norm_diff_timepoint.add((diff_timepoint.get(index) - min_diff_timepoint) / min_max_diff_timepoint);
}
final List<Double> deltas = new ArrayList<Double>();
for (int index = 0; index < count; index++) {
deltas.add(Math.sqrt(Math.pow(norm_diff_lat.get(index), 2) + Math.pow(norm_diff_lng.get(index), 2) + Math.pow(norm_diff_timepoint.get(index), 2)));
}
int result = 0;
double min = deltas.get(0);
for (int index = 0; index < count; index++) {
if (deltas.get(index) < min) {
result = index;
min = deltas.get(index);
}
}
return result;
}
private PathPolyline createPathPolyline(final List<SimulatorWindDTO> pathPoints) {
final int noOfPathPoints = pathPoints.size();
SimulatorWindDTO currentPathPoint = null;
@@ -704,6 +791,26 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
final int boatClassID = 3; // 49er STG
return new PathPolyline(points.toArray(new LatLng[0]), boatClassID, errorReporter, pathDTO, simulatorService, map);
return new PathPolyline(points.toArray(new LatLng[0]), boatClassID, this.errorReporter, pathPoints, this.simulatorSvc, this.mapw, this);
}
@SuppressWarnings("unused")
private PathPolyline createPathPolyline(final PathDTO pathDTO) {
return this.createPathPolyline(pathDTO.getMatrix());
}
public void addLegendOverlayForPathPolyline(final long totalTimeMilliseconds) {
final PathCanvasOverlay overlay = new PathCanvasOverlay("Polyline", totalTimeMilliseconds);
overlay.pathColor = PathPolyline.DEFAULT_COLOR;
this.legendCanvasOverlay.addPathOverlay(overlay);
}
public void redrawLegendCanvasOverlay() {
this.legendCanvasOverlay.setVisible(true);
this.legendCanvasOverlay.redraw(true);
}
}