Merge remote-tracking branch 'refs/remotes/external/master' into jens--media-replication

This commit is contained in:
Jens Rommel committed 2013-05-27 17:02:00 +02:00
commit e0227edcd4
23 files changed
+40 -16033

No files matched your search

Binary file not shown.
+2 -2
View File
@@ -16,9 +16,9 @@
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="highcharts/js/highcharts2_3.js"></script>
<script type="text/javascript" src="highcharts/js/highcharts.js"></script>
<script type="text/javascript" src="highcharts/js/highcharts-more.js"></script>
<script type="text/javascript" src="highcharts/js/exporting.js"></script>
<script type="text/javascript" src="highcharts/js/modules/exporting.js"></script>
<!-- <script type="text/javascript" src="highcharts/js/highcharts.js"></script>-->
<!-- Optionally, add a highcharts theme file -->
@@ -1,737 +0,0 @@
/**
* @license @product.name@ JS v@product.version@ (@product.date@)
* Exporting module
*
* (c) 2010-2011 Torstein Hønsi
*
* License: www.highcharts.com/license
*/
// JSLint options:
/*global Highcharts, document, window, Math, setTimeout */
(function () { // encapsulate
// create shortcuts
var HC = Highcharts,
Chart = HC.Chart,
addEvent = HC.addEvent,
removeEvent = HC.removeEvent,
createElement = HC.createElement,
discardElement = HC.discardElement,
css = HC.css,
merge = HC.merge,
each = HC.each,
extend = HC.extend,
math = Math,
mathMax = math.max,
doc = document,
win = window,
hasTouch = doc.documentElement.ontouchstart !== undefined,
M = 'M',
L = 'L',
DIV = 'div',
HIDDEN = 'hidden',
NONE = 'none',
PREFIX = 'highcharts-',
ABSOLUTE = 'absolute',
PX = 'px',
UNDEFINED,
defaultOptions = HC.getOptions();
// Add language
extend(defaultOptions.lang, {
downloadPNG: 'Download PNG image',
downloadJPEG: 'Download JPEG image',
downloadPDF: 'Download PDF document',
downloadSVG: 'Download SVG vector image',
exportButtonTitle: 'Export to raster or vector image',
printButtonTitle: 'Print the chart'
});
// Buttons and menus are collected in a separate config option set called 'navigation'.
// This can be extended later to add control buttons like zoom and pan right click menus.
defaultOptions.navigation = {
menuStyle: {
border: '1px solid #A0A0A0',
background: '#FFFFFF'
},
menuItemStyle: {
padding: '0 5px',
background: NONE,
color: '#303030',
fontSize: hasTouch ? '14px' : '11px'
},
menuItemHoverStyle: {
background: '#4572A5',
color: '#FFFFFF'
},
buttonOptions: {
align: 'right',
backgroundColor: {
linearGradient: [0, 0, 0, 20],
stops: [
[0.4, '#F7F7F7'],
[0.6, '#E3E3E3']
]
},
borderColor: '#B0B0B0',
borderRadius: 3,
borderWidth: 1,
//enabled: true,
height: 20,
hoverBorderColor: '#909090',
hoverSymbolFill: '#81A7CF',
hoverSymbolStroke: '#4572A5',
symbolFill: '#E0E0E0',
//symbolSize: 12,
symbolStroke: '#A0A0A0',
//symbolStrokeWidth: 1,
symbolX: 11.5,
symbolY: 10.5,
verticalAlign: 'top',
width: 24,
y: 10
}
};
// Add the export related options
defaultOptions.exporting = {
//enabled: true,
//filename: 'chart',
type: 'image/png',
url: 'http://export.highcharts.com/',
width: 800,
buttons: {
exportButton: {
//enabled: true,
symbol: 'exportIcon',
x: -10,
symbolFill: '#A8BF77',
hoverSymbolFill: '#768F3E',
_id: 'exportButton',
_titleKey: 'exportButtonTitle',
menuItems: [{
textKey: 'downloadPNG',
onclick: function () {
this.exportChart();
}
}, {
textKey: 'downloadJPEG',
onclick: function () {
this.exportChart({
type: 'image/jpeg'
});
}
}, {
textKey: 'downloadPDF',
onclick: function () {
this.exportChart({
type: 'application/pdf'
});
}
}, {
textKey: 'downloadSVG',
onclick: function () {
this.exportChart({
type: 'image/svg+xml'
});
}
}
// Enable this block to add "View SVG" to the dropdown menu
/*
,{
text: 'View SVG',
onclick: function () {
var svg = this.getSVG()
.replace(/</g, '\n&lt;')
.replace(/>/g, '&gt;');
doc.body.innerHTML = '<pre>' + svg + '</pre>';
}
} // */
]
},
printButton: {
//enabled: true,
symbol: 'printIcon',
x: -36,
symbolFill: '#B5C9DF',
hoverSymbolFill: '#779ABF',
_id: 'printButton',
_titleKey: 'printButtonTitle',
onclick: function () {
this.print();
}
}
}
};
extend(Chart.prototype, {
/**
* Return an SVG representation of the chart
*
* @param additionalOptions {Object} Additional chart options for the generated SVG representation
*/
getSVG: function (additionalOptions) {
var chart = this,
chartCopy,
sandbox,
svg,
seriesOptions,
options = merge(chart.options, additionalOptions); // copy the options and add extra options
// IE compatibility hack for generating SVG content that it doesn't really understand
if (!doc.createElementNS) {
/*jslint unparam: true*//* allow unused parameter ns in function below */
doc.createElementNS = function (ns, tagName) {
return doc.createElement(tagName);
};
/*jslint unparam: false*/
}
// create a sandbox where a new chart will be generated
sandbox = createElement(DIV, null, {
position: ABSOLUTE,
top: '-9999em',
width: chart.chartWidth + PX,
height: chart.chartHeight + PX
}, doc.body);
// override some options
extend(options.chart, {
renderTo: sandbox,
forExport: true
});
options.exporting.enabled = false; // hide buttons in print
options.chart.plotBackgroundImage = null; // the converter doesn't handle images
// prepare for replicating the chart
options.series = [];
each(chart.series, function (serie) {
seriesOptions = merge(serie.options, {
animation: false, // turn off animation
showCheckbox: false,
visible: serie.visible
});
if (!seriesOptions.isInternal) { // used for the navigator series that has its own option set
// remove image markers
if (seriesOptions && seriesOptions.marker && /^url\(/.test(seriesOptions.marker.symbol)) {
seriesOptions.marker.symbol = 'circle';
}
options.series.push(seriesOptions);
}
});
// generate the chart copy
chartCopy = new Highcharts.Chart(options);
// reflect axis extremes in the export
each(['xAxis', 'yAxis'], function (axisType) {
each(chart[axisType], function (axis, i) {
var axisCopy = chartCopy[axisType][i],
extremes = axis.getExtremes(),
userMin = extremes.userMin,
userMax = extremes.userMax;
if (userMin !== UNDEFINED || userMax !== UNDEFINED) {
axisCopy.setExtremes(userMin, userMax, true, false);
}
});
});
// get the SVG from the container's innerHTML
svg = chartCopy.container.innerHTML;
// free up memory
options = null;
chartCopy.destroy();
discardElement(sandbox);
// sanitize
svg = svg
.replace(/zIndex="[^"]+"/g, '')
.replace(/isShadow="[^"]+"/g, '')
.replace(/symbolName="[^"]+"/g, '')
.replace(/jQuery[0-9]+="[^"]+"/g, '')
.replace(/isTracker="[^"]+"/g, '')
.replace(/url\([^#]+#/g, 'url(#')
.replace(/<svg /, '<svg xmlns:xlink="http://www.w3.org/1999/xlink" ')
.replace(/ href=/g, ' xlink:href=')
.replace(/\n/, ' ')
.replace(/<\/svg>.*?$/, '</svg>') // any HTML added to the container after the SVG (#894)
/* This fails in IE < 8
.replace(/([0-9]+)\.([0-9]+)/g, function(s1, s2, s3) { // round off to save weight
return s2 +'.'+ s3[0];
})*/
// Replace HTML entities, issue #347
.replace(/&nbsp;/g, '\u00A0') // no-break space
.replace(/&shy;/g, '\u00AD') // soft hyphen
// IE specific
.replace(/<IMG /g, '<image ')
.replace(/height=([^" ]+)/g, 'height="$1"')
.replace(/width=([^" ]+)/g, 'width="$1"')
.replace(/hc-svg-href="([^"]+)">/g, 'xlink:href="$1"/>')
.replace(/id=([^" >]+)/g, 'id="$1"')
.replace(/class=([^" ]+)/g, 'class="$1"')
.replace(/ transform /g, ' ')
.replace(/:(path|rect)/g, '$1')
.replace(/style="([^"]+)"/g, function (s) {
return s.toLowerCase();
});
// IE9 beta bugs with innerHTML. Test again with final IE9.
svg = svg.replace(/(url\(#highcharts-[0-9]+)&quot;/g, '$1')
.replace(/&quot;/g, "'");
if (svg.match(/ xmlns="/g).length === 2) {
svg = svg.replace(/xmlns="[^"]+"/, '');
}
return svg;
},
/**
* Submit the SVG representation of the chart to the server
* @param {Object} options Exporting options. Possible members are url, type and width.
* @param {Object} chartOptions Additional chart options for the SVG representation of the chart
*/
exportChart: function (options, chartOptions) {
var form,
chart = this,
svg = chart.getSVG(merge(chart.options.exporting.chartOptions, chartOptions)); // docs
// merge the options
options = merge(chart.options.exporting, options);
// create the form
form = createElement('form', {
method: 'post',
action: options.url,
enctype: 'multipart/form-data'
}, {
display: NONE
}, doc.body);
// add the values
each(['filename', 'type', 'width', 'svg'], function (name) {
createElement('input', {
type: HIDDEN,
name: name,
value: {
filename: options.filename || 'chart',
type: options.type,
width: options.width,
svg: svg
}[name]
}, null, form);
});
// submit
form.submit();
// clean up
discardElement(form);
},
/**
* Print the chart
*/
print: function () {
var chart = this,
container = chart.container,
origDisplay = [],
origParent = container.parentNode,
body = doc.body,
childNodes = body.childNodes;
if (chart.isPrinting) { // block the button while in printing mode
return;
}
chart.isPrinting = true;
// hide all body content
each(childNodes, function (node, i) {
if (node.nodeType === 1) {
origDisplay[i] = node.style.display;
node.style.display = NONE;
}
});
// pull out the chart
body.appendChild(container);
// print
win.print();
// allow the browser to prepare before reverting
setTimeout(function () {
// put the chart back in
origParent.appendChild(container);
// restore all body content
each(childNodes, function (node, i) {
if (node.nodeType === 1) {
node.style.display = origDisplay[i];
}
});
chart.isPrinting = false;
}, 1000);
},
/**
* Display a popup menu for choosing the export type
*
* @param {String} name An identifier for the menu
* @param {Array} items A collection with text and onclicks for the items
* @param {Number} x The x position of the opener button
* @param {Number} y The y position of the opener button
* @param {Number} width The width of the opener button
* @param {Number} height The height of the opener button
*/
contextMenu: function (name, items, x, y, width, height) {
var chart = this,
navOptions = chart.options.navigation,
menuItemStyle = navOptions.menuItemStyle,
chartWidth = chart.chartWidth,
chartHeight = chart.chartHeight,
cacheName = 'cache-' + name,
menu = chart[cacheName],
menuPadding = mathMax(width, height), // for mouse leave detection
boxShadow = '3px 3px 10px #888',
innerMenu,
hide,
menuStyle;
// create the menu only the first time
if (!menu) {
// create a HTML element above the SVG
chart[cacheName] = menu = createElement(DIV, {
className: PREFIX + name
}, {
position: ABSOLUTE,
zIndex: 1000,
padding: menuPadding + PX
}, chart.container);
innerMenu = createElement(DIV, null,
extend({
MozBoxShadow: boxShadow,
WebkitBoxShadow: boxShadow,
boxShadow: boxShadow
}, navOptions.menuStyle), menu);
// hide on mouse out
hide = function () {
css(menu, { display: NONE });
};
addEvent(menu, 'mouseleave', hide);
// create the items
each(items, function (item) {
if (item) {
var div = createElement(DIV, {
onmouseover: function () {
css(this, navOptions.menuItemHoverStyle);
},
onmouseout: function () {
css(this, menuItemStyle);
},
innerHTML: item.text || chart.options.lang[item.textKey]
}, extend({
cursor: 'pointer'
}, menuItemStyle), innerMenu);
div[hasTouch ? 'ontouchstart' : 'onclick'] = function () {
hide();
item.onclick.apply(chart, arguments);
};
// Keep references to menu divs to be able to destroy them
chart.exportDivElements.push(div);
}
});
// Keep references to menu and innerMenu div to be able to destroy them
chart.exportDivElements.push(innerMenu, menu);
chart.exportMenuWidth = menu.offsetWidth;
chart.exportMenuHeight = menu.offsetHeight;
}
menuStyle = { display: 'block' };
// if outside right, right align it
if (x + chart.exportMenuWidth > chartWidth) {
menuStyle.right = (chartWidth - x - width - menuPadding) + PX;
} else {
menuStyle.left = (x - menuPadding) + PX;
}
// if outside bottom, bottom align it
if (y + height + chart.exportMenuHeight > chartHeight) {
menuStyle.bottom = (chartHeight - y - menuPadding) + PX;
} else {
menuStyle.top = (y + height - menuPadding) + PX;
}
css(menu, menuStyle);
},
/**
* Add the export button to the chart
*/
addButton: function (options) {
var chart = this,
renderer = chart.renderer,
btnOptions = merge(chart.options.navigation.buttonOptions, options),
onclick = btnOptions.onclick,
menuItems = btnOptions.menuItems,
buttonWidth = btnOptions.width,
buttonHeight = btnOptions.height,
box,
symbol,
button,
borderWidth = btnOptions.borderWidth,
boxAttr = {
stroke: btnOptions.borderColor
},
symbolAttr = {
stroke: btnOptions.symbolStroke,
fill: btnOptions.symbolFill
},
symbolSize = btnOptions.symbolSize || 12;
// Keeps references to the button elements
if (!chart.exportDivElements) {
chart.exportDivElements = [];
chart.exportSVGElements = [];
}
if (btnOptions.enabled === false) {
return;
}
// element to capture the click
function revert() {
symbol.attr(symbolAttr);
box.attr(boxAttr);
}
// the box border
box = renderer.rect(
0,
0,
buttonWidth,
buttonHeight,
btnOptions.borderRadius,
borderWidth
)
//.translate(buttonLeft, buttonTop) // to allow gradients
.align(btnOptions, true)
.attr(extend({
fill: btnOptions.backgroundColor,
'stroke-width': borderWidth,
zIndex: 19
}, boxAttr)).add();
// the invisible element to track the clicks
button = renderer.rect(
0,
0,
buttonWidth,
buttonHeight,
0
)
.align(btnOptions)
.attr({
id: btnOptions._id,
fill: 'rgba(255, 255, 255, 0.001)',
title: chart.options.lang[btnOptions._titleKey],
zIndex: 21
}).css({
cursor: 'pointer'
})
.on('mouseover', function () {
symbol.attr({
stroke: btnOptions.hoverSymbolStroke,
fill: btnOptions.hoverSymbolFill
});
box.attr({
stroke: btnOptions.hoverBorderColor
});
})
.on('mouseout', revert)
.on('click', revert)
.add();
// add the click event
if (menuItems) {
onclick = function () {
revert();
var bBox = button.getBBox();
chart.contextMenu('export-menu', menuItems, bBox.x, bBox.y, buttonWidth, buttonHeight);
};
}
/*addEvent(button.element, 'click', function() {
onclick.apply(chart, arguments);
});*/
button.on('click', function () {
onclick.apply(chart, arguments);
});
// the icon
symbol = renderer.symbol(
btnOptions.symbol,
btnOptions.symbolX - (symbolSize / 2),
btnOptions.symbolY - (symbolSize / 2),
symbolSize,
symbolSize
)
.align(btnOptions, true)
.attr(extend(symbolAttr, {
'stroke-width': btnOptions.symbolStrokeWidth || 1,
zIndex: 20
})).add();
// Keep references to the renderer element so to be able to destroy them later.
chart.exportSVGElements.push(box, button, symbol);
},
/**
* Destroy the buttons.
*/
destroyExport: function () {
var i,
chart = this,
elem;
// Destroy the extra buttons added
for (i = 0; i < chart.exportSVGElements.length; i++) {
elem = chart.exportSVGElements[i];
// Destroy and null the svg/vml elements
elem.onclick = elem.ontouchstart = null;
chart.exportSVGElements[i] = elem.destroy();
}
// Destroy the divs for the menu
for (i = 0; i < chart.exportDivElements.length; i++) {
elem = chart.exportDivElements[i];
// Remove the event handler
removeEvent(elem, 'mouseleave');
// Remove inline events
chart.exportDivElements[i] = elem.onmouseout = elem.onmouseover = elem.ontouchstart = elem.onclick = null;
// Destroy the div by moving to garbage bin
discardElement(elem);
}
}
});
/**
* Crisp for 1px stroke width, which is default. In the future, consider a smarter,
* global function.
*/
function crisp(arr) {
var i = arr.length;
while (i--) {
if (typeof arr[i] === 'number') {
arr[i] = Math.round(arr[i]) - 0.5;
}
}
return arr;
}
// Create the export icon
HC.Renderer.prototype.symbols.exportIcon = function (x, y, width, height) {
return crisp([
M, // the disk
x, y + width,
L,
x + width, y + height,
x + width, y + height * 0.8,
x, y + height * 0.8,
'Z',
M, // the arrow
x + width * 0.5, y + height * 0.8,
L,
x + width * 0.8, y + height * 0.4,
x + width * 0.4, y + height * 0.4,
x + width * 0.4, y,
x + width * 0.6, y,
x + width * 0.6, y + height * 0.4,
x + width * 0.2, y + height * 0.4,
'Z'
]);
};
// Create the print icon
HC.Renderer.prototype.symbols.printIcon = function (x, y, width, height) {
return crisp([
M, // the printer
x, y + height * 0.7,
L,
x + width, y + height * 0.7,
x + width, y + height * 0.4,
x, y + height * 0.4,
'Z',
M, // the upper sheet
x + width * 0.2, y + height * 0.4,
L,
x + width * 0.2, y,
x + width * 0.8, y,
x + width * 0.8, y + height * 0.4,
'Z',
M, // the lower sheet
x + width * 0.2, y + height * 0.7,
L,
x, y + height,
x + width, y + height,
x + width * 0.8, y + height * 0.7,
'Z'
]);
};
// Add the buttons on chart load
Chart.prototype.callbacks.push(function (chart) {
var n,
exportingOptions = chart.options.exporting,
buttons = exportingOptions.buttons;
if (exportingOptions.enabled !== false) {
for (n in buttons) {
chart.addButton(buttons[n]);
}
// Destroy the export elements at chart destroy
addEvent(chart, 'destroy', chart.destroyExport);
}
});
}());
window.console && console.log('--- Running modules/exporting.src.js from GitHub ---');
File diff suppressed because it is too large. Load diff
@@ -8,7 +8,6 @@ import com.sap.sailing.domain.common.dto.LeaderboardRowDTO;
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
import com.sap.sailing.domain.common.filter.AbstractNumberFilter;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardFetcher;
/**
* A filter filtering competitors by their race rank
@@ -4,7 +4,6 @@ import com.sap.sailing.domain.common.dto.CompetitorDTO;
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
import com.sap.sailing.domain.common.filter.AbstractNumberFilter;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardFetcher;
/**
* A filter filtering competitors by their total rank
@@ -1,4 +1,4 @@
package com.sap.sailing.gwt.ui.leaderboard;
package com.sap.sailing.gwt.ui.client.shared.filter;
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
@@ -1,6 +1,5 @@
package com.sap.sailing.gwt.ui.client.shared.filter;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardFetcher;
public interface LeaderboardFilterContext {
void setLeaderboardFetcher(LeaderboardFetcher leaderboardFetcher);
@@ -11,6 +11,7 @@ import com.sap.sailing.domain.common.dto.LeaderboardDTO;
import com.sap.sailing.domain.common.impl.InvertibleComparatorAdapter;
import com.sap.sailing.gwt.ui.client.Collator;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.filter.LeaderboardFetcher;
public class CompetitorColumnBase<T> {
private final LeaderboardFetcher leaderboardFetcher;
@@ -89,6 +89,7 @@ import com.sap.sailing.gwt.ui.client.shared.components.Component;
import com.sap.sailing.gwt.ui.client.shared.components.IsEmbeddableComponent;
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialog;
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialogComponent;
import com.sap.sailing.gwt.ui.client.shared.filter.LeaderboardFetcher;
import com.sap.sailing.gwt.ui.client.shared.panels.BusyIndicator;
import com.sap.sailing.gwt.ui.client.shared.panels.SimpleBusyIndicator;
import com.sap.sailing.gwt.ui.leaderboard.DetailTypeColumn.LegDetailField;
@@ -317,9 +317,10 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
mapw.setScrollWheelZoomEnabled(true);
// mapw.setContinuousZoom(true);
mapw.setTitle(stringMessages.simulator() + " " + stringMessages.map());
// PositionDTO kiel = new PositionDTO(54.46195148135232, 10.1513671875);
PositionDTO trave = new PositionDTO(54.007063, 10.838356); // 53.978276,10.880156);//53.968015,10.891331);
LatLng position = LatLng.newInstance(trave.latDeg, trave.lngDeg);
PositionDTO kiel = new PositionDTO(54.46195148135232, 10.1513671875);
//PositionDTO trave = new PositionDTO(54.007063, 10.838356); // 53.978276,10.880156);//53.968015,10.891331);
PositionDTO initialMapPosition = kiel;
LatLng position = LatLng.newInstance(initialMapPosition.latDeg, initialMapPosition.lngDeg);
mapw.panTo(position);
// mapw.panTo(LatLng.newInstance(0, 0));
add(mapw, 0, 0);
@@ -9,6 +9,7 @@ import javax.servlet.http.HttpServletResponse;
import org.json.simple.JSONArray;
import com.sap.sailing.domain.common.LeaderboardNameConstants;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.server.gateway.AbstractJsonHttpServlet;
@@ -20,7 +21,8 @@ public class LeaderboardsJsonGetServlet extends AbstractJsonHttpServlet {
JSONArray jsonLeaderboards = new JSONArray();
Map<String, Leaderboard> leaderboards = getService().getLeaderboards();
for (String leaderboardName : leaderboards.keySet()) {
jsonLeaderboards.add(leaderboardName);
if(!leaderboardName.equals(LeaderboardNameConstants.DEFAULT_LEADERBOARD_NAME))
jsonLeaderboards.add(leaderboardName);
}
setJsonResponseHeader(resp);
jsonLeaderboards.writeJSONString(resp.getWriter());
@@ -0,0 +1 @@
["ESS 2013 Muscat (Extreme40)","Extreme 40 Nice","Silbernes Band","49er Training Palma 2013","ESS 2013 singapure (Extreme40)","Star IDM 2013","SwissTimingTest","Extreme 40 Muscat","Drachen IDM 2012","Extreme Sailing Series Overall","BMW Cup Overall Overall","ESS 2012 Cardiff (Extreme40)","KW 2013 Laser Radial (Laser Radial)","BMW Cup","Extreme 40 Rio","505 WM Barbados 2013 (505)","ESS All test Overall","Test Overall","Extreme 40 Cardiff","Extreme 40 Porto","Nixdorf Pokal 2013","KW 2013 Laser (Laser)","505 Worlds 2012"]
@@ -5,6 +5,5 @@
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="resources"/>
<classpathentry kind="con" path="com.google.gwt.eclipse.core.GWT_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/com.sap.sailing.gwt.ui"/>
<classpathentry kind="output" path="bin"/>
</classpath>
@@ -21,11 +21,11 @@ public class ConfigurationManagerTest {
@Before
public void initialize() {
this._boatClassesInfo.add(new BoatClassPropertiesImpl("49er", 4.995, "resources/PolarDiagram49.csv", 0));
this._boatClassesInfo.add(new BoatClassPropertiesImpl("49er Bethwaite", 4.876, "resources/PolarDiagram49Bethwaite.csv", 1));
this._boatClassesInfo.add(new BoatClassPropertiesImpl("49er ORC", 4.995, "resources/PolarDiagram49ORC.csv", 2));
this._boatClassesInfo.add(new BoatClassPropertiesImpl("49er STG", 4.876, "resources/PolarDiagram49STG.csv", 3));
this._boatClassesInfo.add(new BoatClassPropertiesImpl("505 STG", 5.05, "resources/PolarDiagram505STG.csv", 4));
this._boatClassesInfo.add(new BoatClassPropertiesImpl("49er", 4.995, "PolarDiagram49.csv", 0));
this._boatClassesInfo.add(new BoatClassPropertiesImpl("49er Bethwaite", 4.876, "PolarDiagram49Bethwaite.csv", 1));
this._boatClassesInfo.add(new BoatClassPropertiesImpl("49er ORC", 4.995, "PolarDiagram49ORC.csv", 2));
this._boatClassesInfo.add(new BoatClassPropertiesImpl("49er STG", 4.876, "PolarDiagram49STG.csv", 3));
this._boatClassesInfo.add(new BoatClassPropertiesImpl("505 STG", 5.05, "PolarDiagram505STG.csv", 4));
this._racesInfo
.add(new RacePropertiesImpl(
@@ -55,15 +55,15 @@ public class ConfigurationManagerTest {
@Test
public void test_getPolarDiagramFileLocation() {
Assert.assertEquals("resources/PolarDiagram49.csv", ConfigurationManager.INSTANCE
Assert.assertEquals("PolarDiagram49.csv", ConfigurationManager.INSTANCE
.getPolarDiagramFileLocation(0));
Assert.assertEquals("resources/PolarDiagram49Bethwaite.csv", ConfigurationManager.INSTANCE
Assert.assertEquals("PolarDiagram49Bethwaite.csv", ConfigurationManager.INSTANCE
.getPolarDiagramFileLocation(1));
Assert.assertEquals("resources/PolarDiagram49ORC.csv", ConfigurationManager.INSTANCE
Assert.assertEquals("PolarDiagram49ORC.csv", ConfigurationManager.INSTANCE
.getPolarDiagramFileLocation(2));
Assert.assertEquals("resources/PolarDiagram49STG.csv", ConfigurationManager.INSTANCE
Assert.assertEquals("PolarDiagram49STG.csv", ConfigurationManager.INSTANCE
.getPolarDiagramFileLocation(3));
Assert.assertEquals("resources/PolarDiagram505STG.csv", ConfigurationManager.INSTANCE
Assert.assertEquals("PolarDiagram505STG.csv", ConfigurationManager.INSTANCE
.getPolarDiagramFileLocation(4));
}
@@ -19,7 +19,6 @@ import com.sap.sailing.simulator.impl.PolarDiagram49STG;
import com.sap.sailing.simulator.impl.RectangularBoundary;
import com.sap.sailing.simulator.impl.SailingSimulatorImpl;
import com.sap.sailing.simulator.impl.SimulationParametersImpl;
import com.sap.sailing.simulator.impl.SimulatorUISelectionImpl;
import com.sap.sailing.simulator.util.SailingSimulatorUtil;
import com.sap.sailing.simulator.windfield.WindControlParameters;
import com.sap.sailing.simulator.windfield.WindFieldGenerator;
@@ -54,7 +53,8 @@ public class SimulatorTest {
SimulationParameters param = new SimulationParametersImpl(course, pd, wf, SailingSimulatorUtil.freestyle);
SailingSimulatorImpl sailingSim = new SailingSimulatorImpl(param);
Map<String, Path> paths = sailingSim.getAllPathsForLeg(new SimulatorUISelectionImpl(0, 0, 0, 0));
//Map<String, Path> paths = sailingSim.getAllPathsForLeg(new SimulatorUISelectionImpl(0, 0, 0, 0));
Map<String, Path> paths = sailingSim.getAllPaths();
System.out.println("opportunistic path points: "+paths.get("2#Opportunistic").getPathPoints().size());
System.out.println("omnciscient path points: "+paths.get("1#Omniscient").getPathPoints().size());
@@ -171,8 +171,8 @@ public class WindFieldGeneratorTest {
}
@Test
public void testWindFieldGeneratorBlast() {
//@Test
/*public void testWindFieldGeneratorBlast() {
Position start = new DegreePosition(54.32447456461419, 10.15613079071045);
Position end = new DegreePosition(54.32877915239163, 10.156173706054688);
List<Position> course = new LinkedList<Position>();
@@ -198,9 +198,9 @@ public class WindFieldGeneratorTest {
SpeedWithBearing speed = new KilometersPerHourSpeedWithBearingImpl(0, new DegreeBearingImpl(0));
/*
* Check the speed & angle at the start time
*/
//
// Check the speed & angle at the start time
//
List<Wind> windList = new ArrayList<Wind>();
for (int i = 0; i < vSteps; ++i) {
for (int j = 0; j < hSteps; ++j) {
@@ -213,7 +213,7 @@ public class WindFieldGeneratorTest {
//double epsilon = 1e-6;
// Check the speed
assertEquals("StartTime First Wind Speed ", 10, windList.get(0).getKnots(), 0);
}
}*/
@Test
public void testWindFieldGeneratorCombinedNoBlast() {
@@ -1,255 +0,0 @@
package com.sap.sailing.simulator.test.util;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Leg;
import com.sap.sailing.domain.base.SpeedWithBearing;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.dto.PositionDTO;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.GPSFixTrack;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.Wind;
import com.sap.sailing.gwt.ui.server.SimulatorServiceImpl;
import com.sap.sailing.gwt.ui.shared.ConfigurationException;
import com.sap.sailing.gwt.ui.shared.RequestTotalTimeDTO;
import com.sap.sailing.gwt.ui.shared.ResponseTotalTimeDTO;
import com.sap.sailing.gwt.ui.shared.SimulatorUISelectionDTO;
import com.sap.sailing.gwt.ui.shared.SimulatorWindDTO;
import com.sap.sailing.simulator.TimedPositionWithSpeed;
import com.sap.sailing.simulator.impl.PathImpl;
import com.sap.sailing.simulator.impl.TimedPositionWithSpeedImpl;
public class TimeComparison {
private static final String RESOURCES = "resources/";
private List<PositionDTO> turnPoints = null;
private List<SimulatorWindDTO> allPoints = null;
private Map<Integer, String> boatClassesIndexes = null;
// private Map<Integer, String> averageWindFlags = null;
// private List<Integer> timeStepMillisecondsSizes = null;
private Integer timeStepMilliseconds = 1000;
public static void main(String[] args) throws Exception {
System.out.println("Collection of test methods for evaluating simulator race times for calibration.");
}
public void initialize() {
this.boatClassesIndexes = new HashMap<Integer, String>();
this.boatClassesIndexes.put(0, "49er");
this.boatClassesIndexes.put(1, "49er rBethwaite");
this.boatClassesIndexes.put(2, "49er ORC");
this.boatClassesIndexes.put(3, "49er STG");
this.boatClassesIndexes.put(4, "505 STG");
/*
* this.averageWindFlags = new HashMap<Integer, String>(); this.averageWindFlags.put(0, "default average wind");
* this.averageWindFlags.put(1, "real average wind");
*/
/*
* this.timeStepMillisecondsSizes = new ArrayList<Integer>(); this.timeStepMillisecondsSizes.add(1000);
* this.timeStepMillisecondsSizes.add(1250); this.timeStepMillisecondsSizes.add(1500);
* this.timeStepMillisecondsSizes.add(1750); this.timeStepMillisecondsSizes.add(2000);
*/
}
public void runSimulation() throws Exception {
File dir = getFile("");
String[] flist = dir.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
return filename.endsWith(".data");
}
});
TracTracReader ttreader = new TracTracReaderFromFiles(flist);
List<TrackedRace> lst = ttreader.read();
// List<String> csvRows = new ArrayList<String>();
BufferedWriter outputCSV = new BufferedWriter(new FileWriter(
getFile("test.csv")));
String header = "Event, Race, Competitor, Leg#, Leg, GPS time";
for (String pd : boatClassesIndexes.values()) {
header += ", " + pd;
}
header += ", Avg Wind Speed, Avg Wind Bearing, Avg Boat Speed, Avg Boat Bearing";
outputCSV.write(header);
outputCSV.newLine();
for (TrackedRace tr : lst) {
// String csvLine = "";
// System.out.println(tr.getRace().getBoatClass());;
RegattaAndRaceIdentifier id = tr.getRaceIdentifier();
Iterable<Competitor> competitors = tr.getRace().getCompetitors();
List<Leg> legs = tr.getRace().getCourse().getLegs();
// System.out.println(legs);
// System.out.println(id.getRaceName() + "/" + id.getRegattaName());
int competitorIndex = -1;
for (Competitor competitor : competitors) {
competitorIndex++;
GPSFixTrack<Competitor, GPSFixMoving> track = tr.getTrack(competitor);
track.lockForRead();
Iterator<GPSFixMoving> it = track.getFixes().iterator();
int legIndex = -1;
for (Leg leg : legs) {
legIndex++;
List<TimedPositionWithSpeed> polylinePoints = new ArrayList<TimedPositionWithSpeed>();
MarkPassing mp = tr.getMarkPassing(competitor, leg.getTo());
GPSFixMoving current;
while (mp.getTimePoint().after((current = it.next()).getTimePoint())) {
Position currentPosition = current.getPosition();
TimePoint currentTime = current.getTimePoint();
SpeedWithBearing currentSpeed = current.getSpeed();
TimedPositionWithSpeed currentTPWS = new TimedPositionWithSpeedImpl(currentTime,
currentPosition, currentSpeed);
polylinePoints.add(currentTPWS);
}
allPoints = new ArrayList<SimulatorWindDTO>();
List<TimedPositionWithSpeed> turns = (new PathImpl(polylinePoints, null)).getTurns();
turnPoints = new ArrayList<PositionDTO>();
boolean isTurn = false;
Position position = null;
TimePoint timePoint = null;
Wind wind = null;
for (TimedPositionWithSpeed point : polylinePoints) {
isTurn = false;
position = point.getPosition();
timePoint = point.getTimePoint();
wind = tr.getWind(position, timePoint);
for (TimedPositionWithSpeed turn : turns) {
if (turn.getPosition().getLatDeg() == point.getPosition().getLatDeg()
&& turn.getPosition().getLngDeg() == point.getPosition().getLngDeg()
&& turn.getTimePoint().asMillis() == point.getTimePoint().asMillis()
&& turn.getSpeed().getKnots() == point.getSpeed().getKnots()
&& turn.getSpeed().getBearing().getDegrees() == point.getSpeed().getBearing()
.getDegrees()) {
isTurn = true;
turnPoints.add(new PositionDTO(position.getLatDeg(), position.getLngDeg()));
break;
}
}
allPoints.add(new SimulatorWindDTO(position.getLatDeg(), position.getLngDeg(), wind.getKnots(),
wind.getBearing().getDegrees(), timePoint.asMillis(), isTurn));
// end polylinePoints loop
}
// getTotalTime(0, 0, 1000);
// System.out.println(getSummary(id, competitor, leg));
outputCSV.write(getSummary(id, competitor, leg, competitorIndex, legIndex));
outputCSV.newLine();
// end legs loop
}
// end competitors loop
}
// end tracked races loop
}
outputCSV.close();
// end method
}
/*
* private void getTotalTime(final int boatClassIndex, final int useRealAverageWindSpeed, final int
* stepDurationMilliseconds) throws ConfigurationException {
*
* final SimulatorServiceImpl simulatorService = new SimulatorServiceImpl(); final RequestTotalTimeDTO requestData =
* new RequestTotalTimeDTO(boatClassIndex, this.allPoints, this.turnPoints, useRealAverageWindSpeed == 1,
* stepDurationMilliseconds, true); final ResponseTotalTimeDTO receiveData =
* simulatorService.getTotalTime_new(requestData);
*
* final SpeedWithBearing averageWind = simulatorService.getAverageWind(); final double stepSizeMeters =
* simulatorService.getStepSizeMeters(); int stepIndex = 0;
*
* System.err.println("==================================================");
* System.err.println(this.boatClassesIndexes.get(boatClassIndex)); System.err.println("average wind speed = " +
* averageWind.getKnots() + " knots, bearing = " + averageWind.getBearing().getDegrees() + " degrees");
* System.err.println("step size = " + stepSizeMeters + " meters"); stepIndex = 0; for (final Quadruple<PositionDTO,
* PositionDTO, Double, Double> segment : receiveData.segments) { System.err.println("segment " + stepIndex +
* " from [" + segment.getA().latDeg + "," + segment.getA().lngDeg + "] to [" + segment.getB().latDeg + "," +
* segment.getB().lngDeg + "], length = " + segment.getC() + " meters, time = " + segment.getD() / 1000. +
* " seconds"); stepIndex++; } System.err.println(this.boatClassesIndexes.get(boatClassIndex) + ", " +
* this.averageWindFlags.get(useRealAverageWindSpeed) + ", " + stepDurationMilliseconds +
* "milliseconds timestep, total time: " + receiveData.totalTimeSeconds + " seconds");
* System.err.println("=================================================="); }
*/
private String getSummary(final RegattaAndRaceIdentifier id, final Competitor competitor, final Leg leg,
int competitorIndex, final int legIndex) throws ConfigurationException {
int noPoints = this.allPoints.size();
long finishTime = this.allPoints.get(noPoints - 1).timepoint;
long startTime = this.allPoints.get(0).timepoint;
double gpsTime = (finishTime - startTime) / 1000.0;
long totalDistanceMeters = 0;
Iterator<SimulatorWindDTO> it = this.allPoints.iterator();
SimulatorWindDTO prec = it.next();
SimulatorWindDTO succ = null;
double avgBearing = 0.0;
while (it.hasNext()) {
succ = it.next();
Position p1 = new DegreePosition(prec.position.latDeg, prec.position.lngDeg);
Position p2 = new DegreePosition(succ.position.latDeg, succ.position.lngDeg);
totalDistanceMeters += p2.getDistance(p1).getMeters();
avgBearing += 1.0 / noPoints * p1.getBearingGreatCircle(p2).getDegrees();
prec = succ;
}
double speedMetersPerSecond = totalDistanceMeters / gpsTime;
double speedKnots = speedMetersPerSecond * 1.94;
String result = "";
result = id.getRegattaName() + ", " + id.getRaceName();
result += ", " + competitor.getName() + ", " + legIndex + ", " + leg.toString() + ", " + gpsTime;
SpeedWithBearing averageWind = null;
for (Integer boatClassIndex : boatClassesIndexes.keySet()) {
final SimulatorServiceImpl simulatorService = new SimulatorServiceImpl();
final RequestTotalTimeDTO requestData = new RequestTotalTimeDTO(new SimulatorUISelectionDTO(boatClassIndex, 0, competitorIndex, legIndex),
this.timeStepMilliseconds, this.allPoints, this.turnPoints, true);
final ResponseTotalTimeDTO receiveData = simulatorService.getTotalTime(requestData);
averageWind = simulatorService.getAverageWind();
result += ", " + receiveData.totalTimeSeconds;
}
result += ", " + averageWind.getKnots() + ", " + averageWind.getBearing();
result += ", " + speedKnots + ", " + avgBearing;
return result;
}
private File getFile(String fileName) {
return new File(RESOURCES + fileName);
}
}
@@ -9,7 +9,7 @@ import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.TrackedRace;
public class TestTracTracReader {
public class TracTracReaderExample {
public static void main(String[] args) throws Exception {
@@ -1,7 +1,7 @@
package com.sap.sailing.simulator.test.util;
public class TestTracTracWriter {
public class TracTracWriterExample {
public static void main(String[] args) throws Exception {
@@ -391,7 +391,7 @@ public class SailingSimulatorImpl implements SailingSimulator {
} else {
throw new Exception("Unknown path name!");
}
SimulatorUtils.saveToFile(path, SimulatorUtils.getPathPrefix() + "\\src\\resources\\" + fileName);
SimulatorUtils.saveToFile(path, SimulatorUtils.getPathPrefix() + "\\resources\\" + fileName);
}
return path;
@@ -101,11 +101,11 @@ public class SimulatorUtils {
boolean result = true;
for (String name : PATH_NAMES) {
filePath = pathPrefix + "\\src\\resources\\" + name + ".dat";
filePath = pathPrefix + "\\resources\\" + name + ".dat";
result &= saveToFile(paths.get(name), filePath);
}
filePath = pathPrefix + "\\src\\resources\\" + RACECOURSE_DAT;
filePath = pathPrefix + "\\resources\\" + RACECOURSE_DAT;
result &= saveToFile(raceCourse, filePath);
return result;
@@ -133,13 +133,13 @@ public class SimulatorUtils {
fileName = SimulatorUtils.getFileName(selectedRaceIndex, selectedCompetitorIndex, selectedLegIndex,
name);
filePath = pathPrefix + "\\src\\resources\\" + fileName;
filePath = pathPrefix + "\\resources\\" + fileName;
result &= saveToFile(paths.get(name), filePath);
}
fileName = SimulatorUtils.getFileName(selectedRaceIndex, selectedCompetitorIndex, selectedLegIndex,
"racecourse");
filePath = pathPrefix + "\\src\\resources\\" + fileName;
filePath = pathPrefix + "\\resources\\" + fileName;
result &= saveToFile(raceCourse, filePath);
return result;
@@ -179,7 +179,7 @@ public class SimulatorUtils {
fileName = SimulatorUtils.getFileName(selectedRaceIndex, selectedCompetitorIndex, selectedLegIndex,
pathName);
filePath = "resources/" + fileName;
filePath = fileName;
path = (Path) readObjectFromResources(filePath);
if (path == null) {
@@ -295,7 +295,7 @@ public class SimulatorUtils {
pathPrefix = getPathPrefix();
}
String filePath = pathPrefix + "\\src\\resources\\" + fileName;
String filePath = pathPrefix + "\\resources\\" + fileName;
boolean result = true;
-2
View File
@@ -86,9 +86,7 @@
<module>net.sf.marineapi</module>
<module>net.sf.marineapi.test</module>
<module>com.sap.sailing.simulator</module>
<!-- While simulator tests fail massively, this remains commented out
<module>com.sap.sailing.simulator.test</module>
-->
</modules>
<properties>