mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-21 19:50:01 +00:00
add border to wind field in order to enlarge area covered by wind visualization;
This commit is contained in:
1 parent
b2218270e0
commit
9944448478
18 files changed
+122
-57
No files matched your search
+8
-3
@@ -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,";
|
||||
|
||||
|
||||
+15
@@ -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;
|
||||
}
|
||||
|
||||
+8
-1
@@ -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 = 10;
|
||||
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);
|
||||
@@ -153,7 +160,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);
|
||||
|
||||
+2
-2
@@ -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%");
|
||||
|
||||
|
||||
+7
-2
@@ -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;
|
||||
@@ -288,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;
|
||||
@@ -296,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);
|
||||
@@ -316,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);
|
||||
@@ -586,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());
|
||||
|
||||
@@ -703,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());
|
||||
|
||||
+7
-5
@@ -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 += "]";
|
||||
|
||||
+1
-1
@@ -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() {
|
||||
|
||||
@@ -147,7 +147,9 @@ var VectorField = function(data) {
|
||||
this.rcEnd = data.rcEnd;
|
||||
this.resY = data.resY;
|
||||
this.resX = data.resX;
|
||||
this.bdXi = 1.0 / 2.0 / (this.resY - 1);
|
||||
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 };
|
||||
@@ -175,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 = this.bdA.lat + rndY * this.bdB.lat + rndX * this.gvX.lat;
|
||||
var lngP = this.bdA.lng + rndY * this.bdB.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;
|
||||
};
|
||||
|
||||
@@ -198,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);
|
||||
}
|
||||
|
||||
@@ -215,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);
|
||||
}
|
||||
|
||||
@@ -281,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 };
|
||||
};
|
||||
@@ -293,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 );
|
||||
@@ -310,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 };
|
||||
@@ -544,7 +551,7 @@ var Swarm = function(canvas, field, opt_projection) {
|
||||
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(' + (greyValue) + ',' + (greyValue) + ',' + (greyValue) + ',' + (0.7*i/255.0) + ')';
|
||||
//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) + ')';
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user