Merge remote-tracking branch 'origin/master'

This commit is contained in:
Axel Uhl committed 2014-04-08 16:07:18 +02:00
commit 5699b12576
22 files changed
+230 -170

No files matched your search

@@ -31,7 +31,6 @@ bin.includes = META-INF/,\
com.sap.sailing.gwt.ui.Simulator/,\
Simulator.html,\
Simulator.css,\
wind-streamlets.js,\
RegattaOverview.css,\
RegattaOverview.html,\
com.sap.sailing.gwt.ui.RegattaOverview/,\
@@ -147,6 +147,12 @@ var VectorField = function(data) {
this.rcEnd = data.rcEnd;
this.resY = data.resY;
this.resX = data.resX;
this.borderY = data.borderY;
this.borderX = data.borderX;
this.bdXi = (data.borderY + 0.5) / (this.resY - 1);
this.bdPhi = 1.0 + 2*this.bdXi;
this.bdA = { lat:this.rcEnd.lat+(this.rcEnd.lat-this.rcStart.lat)*this.bdXi, lng:this.rcEnd.lng+(this.rcEnd.lng-this.rcStart.lng)*this.bdXi };
this.bdB = { lat:(this.rcStart.lat-this.rcEnd.lat)*this.bdPhi, lng:(this.rcStart.lng-this.rcEnd.lng)*this.bdPhi };
this.xScale = data.xScale;
this.x0 = data.boundsSW.lng;
this.x1 = data.boundsNE.lng;
@@ -171,21 +177,26 @@ var VectorField = function(data) {
var nrmLng = difLat/difLen;
this.nvX = { lat: nrmLat/this.xScale/difLen*(this.resX-1), lng: nrmLng/this.xScale/difLen*(this.resX-1) };
this.gvX = { lat: nrmLat*this.xScale*difLen, lng: nrmLng/this.lngScale*this.xScale*difLen };
this.bdC = { lat:this.gvX.lat*(this.resX+2*this.borderX-1)/(this.resX-1), lng:this.gvX.lng*(this.resX+2*this.borderX-1)/(this.resX-1)};
};
VectorField.prototype.getRandomPosition = function() {
var rndY = Math.random();
var rndX = Math.random() - 0.5;
var latP = rndY * this.rcStart.lat + (1.0 - rndY) * this.rcEnd.lat + rndX * this.gvX.lat;
var lngP = rndY * this.rcStart.lng + (1.0 - rndY) * this.rcEnd.lng + rndX * this.gvX.lng;
var latP = this.bdA.lat + rndY * this.bdB.lat + rndX * this.bdC.lat;
var lngP = this.bdA.lng + rndY * this.bdB.lng + rndX * this.bdC.lng;
if (!this.inBounds(lngP, latP)) {
console.log("random-position: out of bounds");
}
return {lat:latP, lng:lngP};
};
VectorField.prototype.inBounds = function(lng, lat) {
var idx = this.getIndex(lat, lng);
var inBool = (idx.x >= 0) && (idx.x < this.resX) && (idx.y >= 0) && (idx.y < this.resY);
var inBool = (idx.x >= 0) && (idx.x < (this.resX+2*this.borderX)) && (idx.y >= 0) && (idx.y < (this.resY+2*this.borderY));
return inBool;
};
@@ -194,7 +205,7 @@ VectorField.prototype.interpolate = function(lat, lng) {
var idx = this.getNeighbors(lat, lng);
var idxOff = 0;
if ((idx.xTop >= this.resX)||(idx.yTop >= this.resY)) {
if ((idx.xTop >= (this.resX+2*this.borderX))||(idx.yTop >= (this.resY+2*this.borderY))) {
console.log("interpolate: out of range: " + idx.xTop + " " + idx.yTop);
}
@@ -211,7 +222,7 @@ VectorField.prototype.interpolate2 = function(lat, lng) {
var idx = this.getNeighbors(lat, lng);
var idxOff = 0;
if ((idx.xTop >= this.resX)||(idx.yTop >= this.resY)) {
if ((idx.xTop >= (this.resX+2*this.borderX))||(idx.yTop >= (this.resY+2*this.borderY))) {
console.log("interpolate: out of range: " + idx.xTop + " " + idx.yTop);
}
@@ -277,8 +288,8 @@ VectorField.prototype.getIndex = function(lat, lng) {
var posR = { lat: lat - this.rcStart.lat, lng: (lng - this.rcStart.lng) * this.lngScale };
// closest grid point
var yIdx = Math.round( posR.lat * this.nvY.lat + posR.lng * this.nvY.lng );
var xIdx = Math.round( posR.lat * this.nvX.lat + posR.lng * this.nvX.lng + (this.resX - 1) / 2. );
var yIdx = Math.round( posR.lat * this.nvY.lat + posR.lng * this.nvY.lng ) + this.borderY;
var xIdx = Math.round( posR.lat * this.nvX.lat + posR.lng * this.nvX.lng + (this.resX - 1) / 2. ) + this.borderX;
return { x: xIdx, y: yIdx };
};
@@ -289,8 +300,8 @@ VectorField.prototype.getNeighbors = function(lat, lng) {
var posR = { lat: lat - this.rcStart.lat, lng: (lng - this.rcStart.lng) * this.lngScale };
// surrounding grid points
var yFlt = posR.lat * this.nvY.lat + posR.lng * this.nvY.lng;
var xFlt = posR.lat * this.nvX.lat + posR.lng * this.nvX.lng + (this.resX - 1) / 2.;
var yFlt = posR.lat * this.nvY.lat + posR.lng * this.nvY.lng + this.borderY;
var xFlt = posR.lat * this.nvX.lat + posR.lng * this.nvX.lng + (this.resX - 1) / 2. + this.borderX;
var yBot = Math.floor( yFlt );
var xBot = Math.floor( xFlt );
var yTop = Math.ceil( yFlt );
@@ -306,12 +317,12 @@ VectorField.prototype.getNeighbors = function(lat, lng) {
yBot = 0;
}
if (xTop >= this.resX) {
xTop = this.resX-1;
if (xTop >= (this.resX+2*this.borderX)) {
xTop = this.resX+2*this.borderX-1;
}
if (yTop >= this.resY) {
yTop = this.resY-1;
if (yTop >= (this.resY+2*this.borderY)) {
yTop = this.resY+2*this.borderY-1;
}
return { xTop: xTop, yTop:yTop, xBot:xBot, yBot:yBot, xMod:xMod, yMod:yMod };
@@ -325,6 +336,17 @@ VectorField.prototype.particleWeight = function(p,v) {
return v.length() / this.maxLength + 0.1;
}
VectorField.prototype.getColors = function() {
var colors = [];
var alpha = 0.7;
var greyValue = 255;
for (var i = 0; i < 256; i++) {
colors[i] = 'rgba(' + (greyValue) + ',' + (greyValue) + ',' + (greyValue) + ',' + (alpha*i/255.0) + ')';
//this.colors[i] = 'hsla(' + 360*(0.55+0.9*(0.5-i/255)) + ',' + (100) + '% ,' + (50) + '%,' + (i/255) + ')';
}
return colors;
}
VectorField.prototype.lineWidth = function(s) {
return 1.0;
}
@@ -438,6 +460,17 @@ RectField.prototype.particleWeight = function(p,v) {
return 1.0 - v.length() / this.maxLength;
}
RectField.prototype.getColors = function() {
var colors = [];
var alpha = 1.0;
var greyValue = 255;
for (var i = 0; i < 256; i++) {
colors[i] = 'rgba(' + (greyValue) + ',' + (greyValue) + ',' + (greyValue) + ',' + (alpha*i/255.0) + ')';
//this.colors[i] = 'hsla(' + 360*(0.55+0.9*(0.5-i/255)) + ',' + (100) + '% ,' + (50) + '%,' + (i/255) + ')';
}
return colors;
}
RectField.prototype.lineWidth = function(s) {
return 1.0;
}
@@ -535,15 +568,10 @@ var Swarm = function(canvas, field, opt_projection) {
this.updateBounds(null);
this.makeNewParticles(null, true);
this.colors = [];
this.rgb = '40, 40, 40';
this.background = 'rgb(' + this.rgb + ')';
var greyValue = 255;
for (var i = 0; i < 256; i++) {
this.colors[i] = 'rgba(' + (greyValue) + ',' + (greyValue) + ',' + (greyValue) + ',' + (i/255) + ')';
//this.colors[i] = 'rgba(' + (255) + ',' + (255) + ',' + (255) + ',' + 1.0 + ')';
//this.colors[i] = 'hsla(' + 360*(0.55+0.9*(0.5-i/255)) + ',' + (100) + '% ,' + (50) + '%,' + (i/255) + ')';
}
this.colors = this.field.getColors();
if (this.projection) {
this.startOffsetX = this.projection.offsetX;
this.startOffsetY = this.projection.offsetY;
@@ -199,7 +199,7 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
throw new WindPatternNotFoundException("Please select a valid wind pattern.");
}
Position[][] grid = bd.extractGrid(params.getxRes(), params.getyRes());
Position[][] grid = bd.extractGrid(params.getxRes(), params.getyRes(), params.getBorderY(), params.getBorderX());
wf.setPositionGrid(grid);
TimePoint startTime = new MillisecondsTimePoint(params.getStartTime().getTime());// new
@@ -274,9 +274,11 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
wf.setGridAreaGps(gridAreaGps);
}
int[] gridRes = new int[2];
int[] gridRes = new int[4];
gridRes[0] = params.getxRes();
gridRes[1] = params.getyRes();
gridRes[2] = params.getBorderY();
gridRes[3] = params.getBorderX();
wf.setGridResolution(gridRes);
wf.generate(startTime, null, timeStep);
@@ -771,11 +773,14 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
// SouthWest
jsonField += "boundsSW:{lat:" + positionGrid[0][0].getLatDeg() + ",lng:" + positionGrid[0][0].getLngDeg() + "},";
// NorthEast
jsonField += "boundsNE:{lat:" + positionGrid[params.getyRes()-1][params.getxRes()-1].getLatDeg() + ",lng:" + positionGrid[params.getyRes()-1][params.getxRes()-1].getLngDeg() + "},";
jsonField += "boundsNE:{lat:" + positionGrid[params.getyRes()+2*params.getBorderY()-1][params.getxRes()+2*params.getBorderX()-1].getLatDeg() + ",lng:" + positionGrid[params.getyRes()+2*params.getBorderY()-1][params.getxRes()+2*params.getBorderX()-1].getLngDeg() + "},";
//this.resY = field.resY;
jsonField += "resY:" + params.getyRes() + ",";
//this.resX = field.resX;
jsonField += "resX:" + params.getxRes() + ",";
// border
jsonField += "borderY:" + params.getBorderY() + ",";
jsonField += "borderX:" + params.getBorderX() + ",";
//this.xScale = field.xScale;
jsonField += "xScale:1.5,";
@@ -12,6 +12,8 @@ public class WindFieldGenParamsDTO implements IsSerializable {
private int xRes;
private int yRes;
private int borderY;
private int borderX;
private Date startTime;
private Date endTime;
@@ -80,6 +82,19 @@ public class WindFieldGenParamsDTO implements IsSerializable {
this.yRes = yRes;
}
public int getBorderY() {
return borderY;
}
public int getBorderX() {
return borderX;
}
public void setBorder(int border) {
this.borderY = border;
this.borderX = (int)Math.round(border * ((double)xRes) / ((double)yRes));
}
public Date getStartTime() {
return startTime;
}
@@ -24,6 +24,7 @@ public class SimulatorEntryPoint extends AbstractEntryPoint {
private final SimulatorServiceAsync simulatorService = GWT.create(SimulatorService.class);
private int xRes = 40;
private int yRes = 20;
private int border = 0;
private boolean autoUpdate = false;
private char mode = SailingSimulatorConstants.ModeEvent; // default mode: 'e'vent
private char event = SailingSimulatorConstants.EventKielerWoche; // default event: 'k'ieler woche
@@ -68,6 +69,12 @@ public class SimulatorEntryPoint extends AbstractEntryPoint {
} else {
yRes = Integer.parseInt(verticalRes);
}
String border = Window.Location.getParameter("border");
if (border == null || border.isEmpty()) {
logger.config("Using default border " + this.border);
} else {
this.border = Integer.parseInt(border);
}
String autoUpdateStr = Window.Location.getParameter("autoUpdate");
if (autoUpdateStr == null || autoUpdateStr.isEmpty()) {
logger.config("Using default auto update " + autoUpdate);
@@ -125,6 +132,9 @@ public class SimulatorEntryPoint extends AbstractEntryPoint {
showStreamlets2 = true;
injectWindDataJS = true;
}
if ((showStreamlets2)&&(this.border==0)) {
this.border = 10;
}
if (windDisplayStr.contains("b")) {
seedLines = 'b';
}
@@ -153,7 +163,7 @@ public class SimulatorEntryPoint extends AbstractEntryPoint {
}
private void createSimulatorPanel() {
SimulatorMainPanel simulatorPanel = new SimulatorMainPanel(simulatorService, stringMessages, this, xRes, yRes,
SimulatorMainPanel simulatorPanel = new SimulatorMainPanel(simulatorService, stringMessages, this, xRes, yRes, border,
autoUpdate, mode, event, showGrid, showLines, seedLines, showArrows, showStreamlets, showStreamlets2, injectWindDataJS);
DockLayoutPanel p = new DockLayoutPanel(Unit.PX);
@@ -225,7 +225,7 @@ public class SimulatorMainPanel extends SimplePanel {
return NumberFormat.getFormat("0.0").format(value);
}
public SimulatorMainPanel(SimulatorServiceAsync svc, StringMessages stringMessages, ErrorReporter errorReporter, int xRes, int yRes, boolean autoUpdate,
public SimulatorMainPanel(SimulatorServiceAsync svc, StringMessages stringMessages, ErrorReporter errorReporter, int xRes, int yRes, int border, boolean autoUpdate,
char mode, char event, boolean showGrid, boolean showLines, char seedLines, boolean showArrows, boolean showStreamlets, boolean showStreamlets2, boolean injectWindDataJS) {
super();
@@ -310,7 +310,7 @@ public class SimulatorMainPanel extends SimplePanel {
busyIndicator = new SimpleBusyIndicator(false, 0.8f);
simulatorMap = new SimulatorMap(simulatorSvc, stringMessages, errorReporter, xRes, yRes, timer, timePanel,
simulatorMap = new SimulatorMap(simulatorSvc, stringMessages, errorReporter, xRes, yRes, border, timer, timePanel,
windParams, busyIndicator, mode, this);
simulatorMap.setSize("100%", "100%");
@@ -97,6 +97,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
private ColorPalette colorPalette;
private int xRes;
private int yRes;
private int border;
private boolean warningAlreadyShown = false;
private SimulatorMainPanel parent = null;
private PathPolyline pathPolyline = null;
@@ -209,6 +210,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
if (timePanel != null) {
timePanel.setMinMax(new Date(startTime), new Date(startTime + maxDurationTime), true);
timePanel.resetTimeSlider();
timePanel.timeChanged(windParams.getStartTime(), null);
}
/**
@@ -287,7 +289,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
}
public SimulatorMap(SimulatorServiceAsync simulatorSvc, StringMessages stringMessages, ErrorReporter errorReporter, int xRes, int yRes, Timer timer,
public SimulatorMap(SimulatorServiceAsync simulatorSvc, StringMessages stringMessages, ErrorReporter errorReporter, int xRes, int yRes, int border, Timer timer,
WindFieldGenParamsDTO windParams, SimpleBusyIndicator busyIndicator, char mode,
SimulatorMainPanel parent) {
this.simulatorService = simulatorSvc;
@@ -295,6 +297,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
this.errorReporter = errorReporter;
this.xRes = xRes;
this.yRes = yRes;
this.border = border;
this.timer = timer;
this.timePanel = null;
timer.addTimeListener(this);
@@ -315,13 +318,14 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
this.parent = parent;
}
public SimulatorMap(SimulatorServiceAsync simulatorSvc, StringMessages stringMessages, ErrorReporter errorReporter, int xRes, int yRes, Timer timer,
public SimulatorMap(SimulatorServiceAsync simulatorSvc, StringMessages stringMessages, ErrorReporter errorReporter, int xRes, int yRes, int border, Timer timer,
TimePanel<TimePanelSettings> timePanel, WindFieldGenParamsDTO windParams, SimpleBusyIndicator busyIndicator, char mode, SimulatorMainPanel parent) {
this.simulatorService = simulatorSvc;
this.stringMessages = stringMessages;
this.errorReporter = errorReporter;
this.xRes = xRes;
this.yRes = yRes;
this.border = border;
this.timer = timer;
this.timePanel = timePanel;
timer.addTimeListener(this);
@@ -585,6 +589,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
windParams.setSouthEast(endPointDTO);
windParams.setxRes(xRes);
windParams.setyRes(yRes);
windParams.setBorder(border);
busyIndicator.setBusy(true);
timer.setTime(windParams.getStartTime().getTime());
@@ -636,7 +641,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
}
timePanel.setMinMax(windParams.getStartTime(), windParams.getEndTime(), true);
timePanel.resetTimeSlider();
//timer.setTime(windParams.getStartTime().getTime());
timePanel.timeChanged(windParams.getStartTime(), null);
busyIndicator.setBusy(false);
}
@@ -702,6 +707,7 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
windParams.setxRes(xRes);
windParams.setyRes(yRes);
windParams.setBorder(border);
busyIndicator.setBusy(true);
timer.setTime(windParams.getStartTime().getTime());
@@ -159,15 +159,17 @@ public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements Ti
public void extendWindDataJSON() {
List<SimulatorWindDTO> data = this.windFieldDTO.getMatrix();
int steps = data.size() / (this.windParams.getxRes() * this.windParams.getyRes());
String jsonData = "data:[";
int p = 0;
int imax = this.windParams.getyRes() + 2*this.windParams.getBorderY();
int jmax = this.windParams.getxRes() + 2*this.windParams.getBorderX();
int steps = data.size() / (imax * jmax);
double maxWindSpeed = 0;
for(int s=0; s<steps; s++) {
jsonData +="[";
for(int i=0; i<this.windParams.getyRes(); i++) {
for(int i=0; i<imax; i++) {
jsonData +="[";
for(int j=0; j<this.windParams.getxRes(); j++) {
for(int j=0; j<jmax; j++) {
SimulatorWindDTO wind = data.get(p);
p++;
if (wind.trueWindSpeedInKnots > maxWindSpeed) {
@@ -176,11 +178,11 @@ public class WindStreamletsCanvasOverlay extends FullCanvasOverlay implements Ti
double y = wind.trueWindSpeedInKnots*Math.cos(wind.trueWindBearingDeg*Math.PI/180.0);
double x = wind.trueWindSpeedInKnots*Math.sin(wind.trueWindBearingDeg*Math.PI/180.0);
jsonData += x + "," + y;
if (j<(this.windParams.getxRes()-1)) {
if (j<(jmax-1)) {
jsonData += ",";
}
}
if (i<(this.windParams.getyRes()-1)) {
if (i<(imax-1)) {
jsonData += "],";
} else {
jsonData += "]";
@@ -3,7 +3,7 @@ package com.sap.sailing.gwt.ui.simulator.util;
public class ColorPaletteGenerator implements ColorPalette {
//private String[] colors = {"Green","Red","Blue","Yellow","Black"};
private String[] colors = {"#00ED00","#FFBB00","#FFEA00","#0092C7","#0092C7","#666666","Blue","Blue","Yellow","Black"};
private String[] colors = {"#00ED00","#FFBB00","#FFEA00","#0bf","#0bf","#808080","Blue","Blue","Yellow","Black"};
private int currentIndex = -1;
public ColorPaletteGenerator() {
@@ -36,7 +36,7 @@
<source path='actions'/>
<source path='simulator'/>
<script src="../wind-streamlets.js" />
<script src="../js/wind-streamlets.js" />
<inherits name='com.google.gwt.logging.Logging'/>
<set-property name="gwt.logging.enabled" value="FALSE"/>
@@ -17,7 +17,7 @@ public class RectangularBoundaryTest {
Position p2 = new DegreePosition(24.522137, -90.774536);
Boundary b = new RectangularBoundary(p1, p2, 0.1);
Position[][] grid = b.extractGrid(20,20);
Position[][] grid = b.extractGrid(20,20,0,0);
assertEquals("Number of lattice points",400,grid.length*grid[0].length);
}
@@ -42,7 +42,7 @@ public class SimulatorTest {
PolarDiagram pd = new PolarDiagram49STG();//PolarDiagram49.CreateStandard49();
RectangularBoundary bd = new RectangularBoundary(start, end, 0.1);
Position[][] positions = bd.extractGrid(10, 10);
Position[][] positions = bd.extractGrid(10, 10, 0, 0);
Bearing windBear = end.getBearingGreatCircle(start);
WindControlParameters windParameters = new WindControlParameters(12.0, windBear.getDegrees());
WindFieldGenerator wf = new WindFieldGeneratorBlastImpl(bd, windParameters);
@@ -43,7 +43,7 @@ public class TreeGrowTest {
course.add(end);
PolarDiagram pd = new PolarDiagram49STG();//PolarDiagram49.CreateStandard49();
RectangularBoundary bd = new RectangularBoundary(start, end, 0.1);
Position[][] positions = bd.extractGrid(10, 10);
Position[][] positions = bd.extractGrid(10, 10, 0, 0);
//RectangularBoundary new_bd = new RectangularBoundary(start, end, 0.1);
//Speed knotSpeed = new KnotSpeedImpl(8);
WindControlParameters windParameters = new WindControlParameters(12, start.getBearingGreatCircle(end).reverse().getDegrees());
@@ -53,7 +53,7 @@ public class WindFieldGeneratorTest {
WindFieldGeneratorImpl wf = new WindFieldGeneratorBlastImpl(bd, windParameters);
int hSteps = 10;
int vSteps = 5;
Position[][] positions = bd.extractGrid(hSteps, vSteps);
Position[][] positions = bd.extractGrid(hSteps, vSteps, 0, 0);
assert (positions.length*positions[0].length == hSteps * vSteps);
int index = 0;
for (int i = 0; i < positions.length; ++i) {
@@ -61,7 +61,7 @@ public class WindFieldGeneratorTest {
logger.info("P" + ++index + ":" + positions[i][j]);
}
}
wf.setPositionGrid(bd.extractGrid(hSteps, vSteps));
wf.setPositionGrid(bd.extractGrid(hSteps, vSteps, 0, 0));
Position[][] positionGrid = wf.getPositionGrid();
assertNotNull("Position Grid is not null", positionGrid);
assertEquals("Position Grid Number of Rows", vSteps, positionGrid.length);
@@ -95,7 +95,7 @@ public class WindFieldGeneratorTest {
int hSteps = 30;
int vSteps = 15;
wf.setPositionGrid(bd.extractGrid(hSteps, vSteps));
wf.setPositionGrid(bd.extractGrid(hSteps, vSteps, 0, 0));
Position[][] positionGrid = wf.getPositionGrid();
TimePoint startTime = new MillisecondsTimePoint(0);
TimePoint timeStep = new MillisecondsTimePoint(30 * 1000);
@@ -240,7 +240,7 @@ public class WindFieldGeneratorTest {
int hSteps = 30;
int vSteps = 15;
wf.setPositionGrid(bd.extractGrid(hSteps, vSteps));
wf.setPositionGrid(bd.extractGrid(hSteps, vSteps, 0, 0));
Position[][] positionGrid = wf.getPositionGrid();
TimePoint startTime = new MillisecondsTimePoint(0);
TimePoint timeStep = new MillisecondsTimePoint(30 * 1000);
@@ -23,10 +23,15 @@ public interface Boundary extends Serializable {
boolean isWithinBoundaries(Position P);
//List<Position> extractLattice(int hPoints, int vPoints);
Position[][] extractGrid(int hPoints, int vPoints);
Position[][] extractGrid(int hPoints, int vPoints, int borderY, int borderX);
//List<Position> extractLattice(Distance hStep, Distance vstep);
public Pair<Integer,Integer> getGridIndex(Position x);
public int getResY();
public int getResX();
public int getBorderY();
public int getBorderX();
Bearing getNorth();
Bearing getSouth();
Bearing getEast();
@@ -49,7 +49,7 @@ public class PathGeneratorDijkstra extends PathGeneratorBase {
int gridv = this.parameters.getProperty("Djikstra.gridv[int]").intValue(); // number of vertical grid steps
int gridh = this.parameters.getProperty("Djikstra.gridh[int]").intValue(); // number of horizontal grid
// steps
Position[][] sailGrid = boundary.extractGrid(gridh, gridv);
Position[][] sailGrid = boundary.extractGrid(gridh, gridv, 0, 0);
// create adjacency graph including start and end
Map<Position, List<Position>> graph = new HashMap<Position, List<Position>>();
@@ -162,7 +162,7 @@ public class PathGeneratorDynProgForward extends PathGeneratorBase {
}
// generate grid positions using sgridh and sgridv
Position[][] sailGrid = boundary.extractGrid(spatialGridsizeHorizontal, spatialGridsizeVertical);
Position[][] sailGrid = boundary.extractGrid(spatialGridsizeHorizontal, spatialGridsizeVertical, 0, 0);
// optimization grid indexes:
// vertical steps: 0, ..., v-1
@@ -20,6 +20,8 @@ public class RectangularBoundary implements Boundary {
private double[] nvHor; // horizontal normal vector with suitable length
private int vPoints; // number of vertical steps
private int hPoints; // number of horizontal steps
private int borderY;
private int borderX;
private Position northWest;
//private Position southEast;
@@ -129,11 +131,14 @@ public class RectangularBoundary implements Boundary {
}
@Override
public Position[][] extractGrid(int hPoints, int vPoints) {
public Position[][] extractGrid(int hPoints, int vPoints, int borderY, int borderX) {
this.vPoints = vPoints;
this.hPoints = hPoints;
this.borderY = borderY;
this.borderX = borderX;
double xscale = 1.5;
double alat = (rcEnd.getLatDeg() + rcStart.getLatDeg()) / 2.;
@@ -166,9 +171,9 @@ public class RectangularBoundary implements Boundary {
nHor[1] = nscHor[1] / lngScale;
// System.out.println("LngScale:"+lngScale+", Diff.Vrt:"+dVrt);
Position[][] grid = new Position[vPoints][hPoints];
Position[][] grid = new Position[vPoints+2*borderY][hPoints+2*borderX];
Position pv;
for (int i = 0; i < vPoints; i++) {
for (int i = -borderY; i < (vPoints+borderY); i++) {
// System.out.print("nrow "+i+": ");
if (i == 0) {
@@ -182,25 +187,25 @@ public class RectangularBoundary implements Boundary {
int j = 0;
// left side
while (j < hPoints / 2) {
grid[i][j] = new DegreePosition(pv.getLatDeg() - ((hPoints - 1) / 2. - j) / (hPoints - 1) * nHor[0]
* xscale * lscVrt, pv.getLngDeg() - ((hPoints - 1) / 2. - j) / (hPoints - 1) * nHor[1] * xscale
while (j < (hPoints+2*borderX) / 2) {
grid[i+borderY][j] = new DegreePosition(pv.getLatDeg() - ((hPoints + 2*borderX - 1) / 2. - j) / (hPoints - 1) * nHor[0]
* xscale * lscVrt, pv.getLngDeg() - ((hPoints + 2*borderX - 1) / 2. - j) / (hPoints - 1) * nHor[1] * xscale
* lscVrt);
// System.out.print(""+grid[i][j]+"("+((hPoints-1)/2.-j)+"), ");
j++;
}
// middle
if (hPoints % 2 == 1) {
grid[i][j] = pv;
if ((hPoints+2*borderX) % 2 == 1) {
grid[i+borderY][j] = pv;
// System.out.print(""+grid[i][j]+", ");
j++;
}
// right side
while (j < hPoints) {
grid[i][j] = new DegreePosition(pv.getLatDeg() + (j - (hPoints - 1) / 2.) / (hPoints - 1) * nHor[0]
* xscale * lscVrt, pv.getLngDeg() + (j - (hPoints - 1) / 2.) / (hPoints - 1) * nHor[1] * xscale
while (j < (hPoints+2*borderX)) {
grid[i+borderY][j] = new DegreePosition(pv.getLatDeg() + (j - (hPoints + 2*borderX - 1) / 2.) / (hPoints - 1) * nHor[0]
* xscale * lscVrt, pv.getLngDeg() + (j - (hPoints + 2*borderX - 1) / 2.) / (hPoints - 1) * nHor[1] * xscale
* lscVrt);
// System.out.print(""+grid[i][j]+"("+(j-(hPoints-1)/2.)+"), ");
j++;
@@ -224,8 +229,8 @@ public class RectangularBoundary implements Boundary {
double sPrd = scX[0] * nvHor[0] + scX[1] * nvHor[1];
int vIdx = Math.min(Math.max(0, (int) Math.round(scX[0] * nvVrt[0] + scX[1] * nvVrt[1])), vPoints - 1);
int hIdx = Math.min(Math.max(0, (int) Math.round(sPrd + (hPoints - 1) / 2.)), hPoints - 1);
int vIdx = Math.min(Math.max(-this.borderY, (int) Math.round(scX[0] * nvVrt[0] + scX[1] * nvVrt[1])), vPoints - 1 + this.borderY);
int hIdx = Math.min(Math.max(-this.borderX, (int) Math.round(sPrd + (hPoints - 1) / 2.)), hPoints - 1 + this.borderX);
// System.out.println("getGridIndex: "+vIdx+","+hIdx+"("+vPoints+","+hPoints+")");
return new Pair<Integer, Integer>(vIdx, hIdx);
@@ -262,6 +267,26 @@ public class RectangularBoundary implements Boundary {
* return lst; }
*/
@Override
public int getResY() {
return this.vPoints;
}
@Override
public int getResX() {
return this.hPoints;
}
@Override
public int getBorderY() {
return this.borderY;
}
@Override
public int getBorderX() {
return this.borderX;
}
@Override
public Bearing getNorth() {
return north;
@@ -103,7 +103,7 @@ public class SailingSimulatorImpl implements SailingSimulator {
}
wf.setBoundary(bd);
Position[][] positionGrid = bd.extractGrid(gridRes[0], gridRes[1]);
Position[][] positionGrid = bd.extractGrid(gridRes[0], gridRes[1], gridRes[2], gridRes[3]);
wf.setPositionGrid(positionGrid);
wf.generate(wf.getStartTime(), wf.getEndTime(), wf.getTimeStep());
}
@@ -67,8 +67,8 @@ public class WindFieldGeneratorBlastImpl extends WindFieldGeneratorImpl implemen
return;
}
int nrow = positions.length;
int ncol = positions[0].length;
int nrow = this.boundary.getResY() + 2*this.boundary.getBorderY();
int ncol = this.boundary.getResX() + 2*this.boundary.getBorderX();
timeUnits = nrow + defaultTimeUnits;
if (startTime != null && endTime != null) {
@@ -107,7 +107,7 @@ public class WindFieldGeneratorBlastImpl extends WindFieldGeneratorImpl implemen
int blastSize = (int) Math.min(getBlastSize(), windParameters.maxBlastSize);
logger.fine("Blast Size:" + blastSize);
int nrow = timeUnits;
int ncol = positions[0].length;
int ncol = this.boundary.getResX() + 2*this.boundary.getBorderX();
int hSpanStart = Math.max(0, colIndex - blastSize / 2);
int hSpanEnd = Math.min(colIndex + blastSize - blastSize / 2, ncol - 1);
int vSpan = Math.min(rowIndex + blastSize, nrow - 1);
@@ -184,8 +184,8 @@ public class WindFieldGeneratorBlastImpl extends WindFieldGeneratorImpl implemen
Position p = timedPosition.getPosition();
Pair<Integer, Integer> positionIndex = getPositionIndex(p);
if (positionIndex != null) {
int rowIndex = positionIndex.getA();
int colIndex = positionIndex.getB();
int rowIndex = positionIndex.getA() + this.boundary.getBorderY();
int colIndex = positionIndex.getB() + this.boundary.getBorderX();
int timeIndex = 0;
if (timedPosition.getTimePoint() != null) {
timeIndex = getTimeIndex(timedPosition.getTimePoint());
@@ -1,6 +1,5 @@
package com.sap.sailing.simulator.windfield.impl;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.logging.Logger;
@@ -30,8 +29,7 @@ public abstract class WindFieldGeneratorImpl implements WindFieldGenerator {
protected Boundary boundary;
protected WindControlParameters windParameters;
protected Position[][] positions;
protected Map<Pair<Integer, Integer>, Position> indexPositionMap;
protected Map<TimePoint, SpeedWithBearing[][]> timeSpeedWithBearingMap;
protected TimePoint startTime;
@@ -44,140 +42,102 @@ public abstract class WindFieldGeneratorImpl implements WindFieldGenerator {
* TimePoint which constitutes one unit of time
*/
protected TimePoint timeStep;
private static Logger logger = Logger.getLogger("com.sap.sailing.windfield");
/*
* private class LatLngComparator implements Comparator<Position> {
*
* @Override public int compare(Position p1, Position p2) {
*
* if (p1.getLatDeg() < p2.getLatDeg()) { return -1; } else if (p1.getLatDeg() == p2.getLngDeg()) { if
* (p1.getLngDeg() < p2.getLngDeg()) { return -1; } else if (p1.getLngDeg() == p2.getLngDeg()) { return 0; } else {
* return 1; } } else { return 1; } }
*
* }
*/
// public WindFieldGeneratorImpl() {
// this.boundary = null;
// this.windParameters = null;
// this.positions = null;
// this.indexPositionMap = new HashMap<Pair<Integer, Integer>, Position>();
// }
public WindFieldGeneratorImpl(Boundary boundary, WindControlParameters windParameters) {
this.boundary = boundary;
this.windParameters = windParameters;
this.positions = null;
this.indexPositionMap = new HashMap<Pair<Integer, Integer>, Position>();
this.boundary = boundary;
this.windParameters = windParameters;
this.positions = null;
}
@Override
public WindControlParameters getWindParameters() {
return windParameters;
return windParameters;
}
@Override
public void setBoundary(Boundary boundary) {
this.boundary = boundary;
}
@Override
public Wind getWind(TimedPosition coordinates) {
KnotSpeedImpl knotSpeedImpl = new KnotSpeedImpl(windParameters.baseWindSpeed);
KnotSpeedImpl knotSpeedImpl = new KnotSpeedImpl(windParameters.baseWindSpeed);
double wBearing = windParameters.baseWindBearing
* (1 + coordinates.getPosition().getDistance(boundary.getCorners().get("NorthWest")).getMeters()
/ boundary.getHeight().getMeters());
SpeedWithBearing wspeed = new KilometersPerHourSpeedWithBearingImpl(knotSpeedImpl.getKilometersPerHour(),
new DegreeBearingImpl(wBearing));
double wBearing = windParameters.baseWindBearing
* (1 + coordinates.getPosition().getDistance(boundary.getCorners().get("NorthWest")).getMeters()
/ boundary.getHeight().getMeters());
SpeedWithBearing wspeed = new KilometersPerHourSpeedWithBearingImpl(knotSpeedImpl.getKilometersPerHour(),
new DegreeBearingImpl(wBearing));
return new WindImpl(coordinates.getPosition(), coordinates.getTimePoint(), wspeed);
return new WindImpl(coordinates.getPosition(), coordinates.getTimePoint(), wspeed);
}
@Override
public Boundary getBoundaries() {
return boundary;
return boundary;
}
@Override
public Position[][] getPositionGrid() {
return positions;
return positions;
}
@Override
public Path getLine(TimedPosition seed, boolean forward) {
//int maxSteps = 100;
long timeStep = 10000; // in milliseconds
TimePoint currentTime = seed.getTimePoint();
TimePoint startTime = seed.getTimePoint();
Position currentPosition = seed.getPosition();
LinkedList<TimedPositionWithSpeed> path = new LinkedList<TimedPositionWithSpeed>();
path.add(new TimedPositionWithSpeedImpl(currentTime, currentPosition, null));
//for(int s=0; s<maxSteps; s++) {
while(boundary.isWithinBoundaries(currentPosition)) {
Wind currentWind = this.getWind(new TimedPositionImpl(startTime, currentPosition));
TimePoint middleTime = currentTime.plus(timeStep/2);
Position middlePosition;
if (!forward) {
middlePosition = currentWind.travelTo(currentPosition, middleTime, currentTime);
} else {
middlePosition = currentWind.travelTo(currentPosition, currentTime, middleTime);
}
Wind middleWind = this.getWind(new TimedPositionImpl(startTime, middlePosition));
//Wind middleWind = currentWind;
TimePoint nextTime = currentTime.plus(timeStep);
Position nextPosition;
if (!forward) {
nextPosition = middleWind.travelTo(currentPosition, nextTime, currentTime);
} else {
nextPosition = middleWind.travelTo(currentPosition, currentTime, nextTime);
}
//if (boundary.isWithinBoundaries(nextPosition)) {
path.add(new TimedPositionWithSpeedImpl(nextTime, nextPosition, null));
//}
currentTime = nextTime;
currentPosition = nextPosition;
}
logger.info("Added wind line with " + path.size() + "points");
return new PathImpl(path, this);
long timeStep = 10000; // in milliseconds
TimePoint currentTime = seed.getTimePoint();
TimePoint startTime = seed.getTimePoint();
Position currentPosition = seed.getPosition();
LinkedList<TimedPositionWithSpeed> path = new LinkedList<TimedPositionWithSpeed>();
path.add(new TimedPositionWithSpeedImpl(currentTime, currentPosition, null));
while(boundary.isWithinBoundaries(currentPosition)) {
Wind currentWind = this.getWind(new TimedPositionImpl(startTime, currentPosition));
TimePoint middleTime = currentTime.plus(timeStep/2);
Position middlePosition;
if (!forward) {
middlePosition = currentWind.travelTo(currentPosition, middleTime, currentTime);
} else {
middlePosition = currentWind.travelTo(currentPosition, currentTime, middleTime);
}
Wind middleWind = this.getWind(new TimedPositionImpl(startTime, middlePosition));
TimePoint nextTime = currentTime.plus(timeStep);
Position nextPosition;
if (!forward) {
nextPosition = middleWind.travelTo(currentPosition, nextTime, currentTime);
} else {
nextPosition = middleWind.travelTo(currentPosition, currentTime, nextTime);
}
path.add(new TimedPositionWithSpeedImpl(nextTime, nextPosition, null));
currentTime = nextTime;
currentPosition = nextPosition;
}
logger.info("Added wind line with " + path.size() + "points");
return new PathImpl(path, this);
}
@Override
public void setPositionGrid(Position[][] positions) {
this.positions = positions;
indexPositionMap.clear();
if (positions == null || positions.length < 1) {
return;
}
for (int i = 0; i < positions.length; ++i) {
for (int j = 0; j < positions[0].length; ++j) {
Pair<Integer, Integer> index = new Pair<Integer, Integer>(i, j);
indexPositionMap.put(index, positions[i][j]);
}
}
this.positions = positions;
}
public Position getPosition(int i, int j) {
Pair<Integer, Integer> indexKey = new Pair<Integer, Integer>(i, j);
return indexPositionMap.get(indexKey);
return this.positions[i][j];
}
public Pair<Integer, Integer> getPositionIndex(Position p) {
Pair<Integer, Integer> gIdx = boundary.getGridIndex(p);
Pair<Integer, Integer> gIdx = boundary.getGridIndex(p);
if ((gIdx.getA() != null) && (gIdx.getB() != null)) {
return gIdx;
} else {
@@ -216,7 +176,6 @@ public abstract class WindFieldGeneratorImpl implements WindFieldGenerator {
return this.endTime;
}
// params.getxRes(), params.getyRes()
@Override
public int[] getGridResolution() {
return this.gridRes;
@@ -41,7 +41,7 @@ public class WindFieldGeneratorOscillationImpl extends WindFieldGeneratorImpl im
if (positions == null || positions.length < 1) {
return;
}
int vPoints = positions.length;
int vPoints = this.boundary.getResY();
Distance vStep = boundary.getHeight().scale(1.0/(vPoints-1));
if (windParameters.baseWindSpeed > 0) {
timeScale = vStep.getNauticalMiles()/windParameters.baseWindSpeed;
@@ -56,7 +56,7 @@ public class WindFieldGeneratorOscillationImpl extends WindFieldGeneratorImpl im
return;
}
int ncol = positions[0].length;
int ncol = boundary.getResX();
speed = new Speed[ncol];
double leftSpeed = windParameters.baseWindSpeed*windParameters.leftWindSpeed/100.0;
@@ -85,6 +85,12 @@ public class WindFieldGeneratorOscillationImpl extends WindFieldGeneratorImpl im
Pair<Integer,Integer> positionIndex = getPositionIndex(p);
if (positionIndex != null) {
int colIndex = positionIndex.getB();
if (colIndex < 0) {
colIndex = 0;
}
if (colIndex >= this.boundary.getResX()) {
colIndex = this.boundary.getResX()-1;
}
return speed[colIndex];
} else {
logger.severe("Error finding position " + p);