mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-10 06:10:56 +00:00
Merge branch 'racecommittee_app' into racecommittee_regattaoverview
This commit is contained in:
commit
7f148ed5a0
21 files changed
+470
-195
No files matched your search
+78
@@ -0,0 +1,78 @@
|
||||
package com.sap.sailing.domain.coursedesign;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
|
||||
public abstract class AbstractCourseDesign implements CourseDesign{
|
||||
Position startBoatPosition;
|
||||
Double windSpeed;
|
||||
Bearing windDirection;
|
||||
PositionedMark pinEnd;
|
||||
Position referencePoint;
|
||||
Set<PositionedMark> courseDesignSpecificMarks = new HashSet<PositionedMark>();
|
||||
|
||||
@Override
|
||||
public Set<PositionedMark> getCourseDesignSpecificMarks() {
|
||||
return courseDesignSpecificMarks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCourseDesignSpecificMarks(Set<PositionedMark> courseDesignSpecificMarks) {
|
||||
this.courseDesignSpecificMarks = courseDesignSpecificMarks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getReferencePoint() {
|
||||
return referencePoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReferencePoint(Position referencePoint) {
|
||||
this.referencePoint = referencePoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PositionedMark getPinEnd() {
|
||||
return pinEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPinEnd(PositionedMark pinEnd) {
|
||||
this.pinEnd = pinEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getStartBoatPosition() {
|
||||
return this.startBoatPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStartBoatPosition(Position startBoatPosition) {
|
||||
this.startBoatPosition = startBoatPosition;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getWindSpeed() {
|
||||
return this.windSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWindSpeed(Double windSpeed) {
|
||||
this.windSpeed = windSpeed;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bearing getWindDirection() {
|
||||
return this.windDirection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWindDirection(Bearing windDirection) {
|
||||
this.windDirection = windDirection;
|
||||
}
|
||||
}
|
||||
+80
-17
@@ -1,27 +1,90 @@
|
||||
package com.sap.sailing.domain.coursedesign;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.impl.NauticalMileDistance;
|
||||
|
||||
|
||||
public abstract class AbstractCourseDesignFactory implements CourseDesignFactory{
|
||||
public abstract class AbstractCourseDesignFactory implements CourseDesignFactory {
|
||||
protected CourseDesign product;
|
||||
private final int ANGLE_OF_START_LINE_TO_WIND = 270;
|
||||
private final Distance REFERENCE_POINT_DISTANCE_FROM_START_LINE = new NauticalMileDistance(0.05);
|
||||
|
||||
@Override
|
||||
public abstract CourseDesign createCourseDesign(Position startBoatPosition, Double windSpeed, Integer windDirection,
|
||||
abstract protected Set<PositionedMark> computeDesignSpecificMarks(Position startBoatPosition, Double windSpeed, Bearing windDirection,
|
||||
BoatClassType boatClass, CourseLayouts courseLayout, NumberOfRounds numberOfRounds, TargetTime targetTime);
|
||||
|
||||
@Override
|
||||
public abstract CourseDesign createCourseDesign(Position startBoatPosition, Double windSpeed,
|
||||
Bearing windDirection, BoatClassType boatClass, CourseLayouts courseLayout, NumberOfRounds numberOfRounds,
|
||||
TargetTime targetTime);
|
||||
|
||||
protected Position getPositionForGivenPointDistanceAndBearing(Position givenPoint, int ditanceInMeters,
|
||||
float bearingInDegree) {
|
||||
double bearingInRad = Math.toRadians(bearingInDegree);
|
||||
final int earthRadiusInMeters = 6371000;
|
||||
double lat = Math.asin(Math.sin(givenPoint.getLatDeg()) * Math.cos(ditanceInMeters / earthRadiusInMeters)
|
||||
+ Math.cos(givenPoint.getLatDeg()) * Math.sin(ditanceInMeters / earthRadiusInMeters)
|
||||
* Math.cos(bearingInRad));
|
||||
double lon = givenPoint.getLngDeg()
|
||||
+ Math.atan2(
|
||||
Math.sin(bearingInRad) * Math.sin(ditanceInMeters / earthRadiusInMeters)
|
||||
* Math.cos(givenPoint.getLatDeg()),
|
||||
Math.cos(ditanceInMeters / earthRadiusInMeters) - Math.sin(givenPoint.getLatDeg()) * Math.sin(lat));
|
||||
return new DegreePosition(lat, lon);
|
||||
protected void initializeCourseDesign(Position startBoatPosition, Double windSpeed,
|
||||
Bearing windDirection, BoatClassType boatClass, CourseLayouts courseLayout, NumberOfRounds numberOfRounds,
|
||||
TargetTime targetTime){
|
||||
this.product.setStartBoatPosition(startBoatPosition);
|
||||
this.product.setWindSpeed(windSpeed);
|
||||
this.product.setWindDirection(windDirection);
|
||||
setPinEnd(boatClass, startBoatPosition, windDirection);
|
||||
setReferencePoint(boatClass, startBoatPosition, windDirection);
|
||||
}
|
||||
|
||||
protected void finalizeCourseDesign(Position startBoatPosition, Double windSpeed,
|
||||
Bearing windDirection, BoatClassType boatClass, CourseLayouts courseLayout, NumberOfRounds numberOfRounds,
|
||||
TargetTime targetTime){
|
||||
this.product.getCourseDesignSpecificMarks().addAll(this.computeDesignSpecificMarks(startBoatPosition, windSpeed, windDirection, boatClass, courseLayout, numberOfRounds, targetTime));
|
||||
}
|
||||
|
||||
protected void setPinEnd(BoatClassType boatClass, Position startBoatPosition, Bearing windDirection) {
|
||||
|
||||
PositionedMark pinEnd = new PositionedMarkImpl("pinEnd", getPositionForGivenPointDistanceAndBearing(
|
||||
startBoatPosition, new MeterDistance(boatClass.getStartLineLengthInMeters()),
|
||||
windDirection.add(new DegreeBearingImpl(ANGLE_OF_START_LINE_TO_WIND))));
|
||||
product.setPinEnd(pinEnd);
|
||||
}
|
||||
|
||||
protected void setReferencePoint(BoatClassType boatClass, Position startBoatPosition, Bearing windDirection) {
|
||||
double halfOfStatLineLength = boatClass.getStartLineLengthInMeters()/2;
|
||||
Position startLineMid = getPositionForGivenPointDistanceAndBearing(
|
||||
startBoatPosition, new MeterDistance(halfOfStatLineLength),
|
||||
windDirection.add(new DegreeBearingImpl(ANGLE_OF_START_LINE_TO_WIND)));
|
||||
Position referencePoint = getPositionForGivenPointDistanceAndBearing(
|
||||
startLineMid, REFERENCE_POINT_DISTANCE_FROM_START_LINE,
|
||||
windDirection);
|
||||
product.setReferencePoint(referencePoint);
|
||||
}
|
||||
|
||||
protected Position getPositionForGivenPointDistanceAndBearing(Position givenPoint, Distance distance,
|
||||
Bearing windDirection) {
|
||||
final double earthRadiusInMeters = 6371000.0;
|
||||
double brng = windDirection.getRadians();
|
||||
double lat1 = givenPoint.getLatRad();
|
||||
double lon1 = givenPoint.getLngRad();
|
||||
double dist = distance.getMeters() / earthRadiusInMeters;
|
||||
|
||||
double lat2 = Math.asin(Math.sin(lat1) * Math.cos(dist) + Math.cos(lat1) * Math.sin(dist) * Math.cos(brng));
|
||||
double lon2 = lon1
|
||||
+ Math.atan2(Math.sin(brng) * Math.sin(dist) * Math.cos(lat1),
|
||||
Math.cos(dist) - Math.sin(lat1) * Math.sin(lat2));
|
||||
lon2 = (lon2 + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
|
||||
|
||||
return new DegreePosition(Math.toDegrees(lat2), Math.toDegrees(lon2));
|
||||
|
||||
/*
|
||||
* LatLon.prototype.destinationPoint = function(brng, dist) { dist = typeof(dist)=='number' ? dist :
|
||||
* typeof(dist)=='string' && dist.trim()!='' ? +dist : NaN; dist = dist/this._radius; // convert dist to angular
|
||||
* distance in radians brng = brng.toRad(); // var lat1 = this._lat.toRad(), lon1 = this._lon.toRad();
|
||||
*
|
||||
* var lat2 = Math.asin( Math.sin(lat1)*Math.cos(dist) + Math.cos(lat1)*Math.sin(dist)*Math.cos(brng) ); var
|
||||
* lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(dist)*Math.cos(lat1),
|
||||
* Math.cos(dist)-Math.sin(lat1)*Math.sin(lat2)); lon2 = (lon2+3*Math.PI) % (2*Math.PI) - Math.PI; // normalise
|
||||
* to -180..+180º
|
||||
*
|
||||
* return new LatLon(lat2.toDeg(), lon2.toDeg()); }
|
||||
*/
|
||||
}
|
||||
}
|
||||
+16
-6
@@ -10,8 +10,8 @@ public enum BoatClassType {
|
||||
{
|
||||
put(TrapezoidCourseLayouts.innerLoopTrapezoid60, 60);
|
||||
put(TrapezoidCourseLayouts.outerLoopTrapezoid60, 60);
|
||||
put(LeewardWindWardCourseLayouts.windWardLeewardLeeward, 30);
|
||||
put(LeewardWindWardCourseLayouts.windWardLeewardWindward, 30);
|
||||
put(WindWardLeeWardCourseLayouts.windWardLeewardLeeward, 30);
|
||||
put(WindWardLeeWardCourseLayouts.windWardLeewardWindward, 30);
|
||||
}
|
||||
}, new TreeMap<WindRange, Map<PointOfSail, Float>>() {
|
||||
{
|
||||
@@ -49,8 +49,8 @@ public enum BoatClassType {
|
||||
{
|
||||
put(TrapezoidCourseLayouts.innerLoopTrapezoid60, 60);
|
||||
put(TrapezoidCourseLayouts.outerLoopTrapezoid60, 60);
|
||||
put(LeewardWindWardCourseLayouts.windWardLeewardLeeward, 30);
|
||||
put(LeewardWindWardCourseLayouts.windWardLeewardWindward, 30);
|
||||
put(WindWardLeeWardCourseLayouts.windWardLeewardLeeward, 30);
|
||||
put(WindWardLeeWardCourseLayouts.windWardLeewardWindward, 30);
|
||||
}
|
||||
}, new TreeMap<WindRange, Map<PointOfSail, Float>>() {
|
||||
{
|
||||
@@ -86,8 +86,8 @@ public enum BoatClassType {
|
||||
}, 110),
|
||||
boatClass49er("49er", new HashMap<CourseLayouts, Integer>() {
|
||||
{
|
||||
put(LeewardWindWardCourseLayouts.windWardLeewardLeeward, 30);
|
||||
put(LeewardWindWardCourseLayouts.windWardLeewardWindward, 30);
|
||||
put(WindWardLeeWardCourseLayouts.windWardLeewardLeeward, 30);
|
||||
put(WindWardLeeWardCourseLayouts.windWardLeewardWindward, 30);
|
||||
}
|
||||
}, new TreeMap<WindRange, Map<PointOfSail, Float>>() {
|
||||
{
|
||||
@@ -120,15 +120,25 @@ public enum BoatClassType {
|
||||
|
||||
private String displayName;
|
||||
private Map<CourseLayouts, Integer> possipleCourseLayoutsWithStandardTargetTime;
|
||||
private Map<WindRange, Map<PointOfSail, Float>> boatSpeedTable;
|
||||
private Integer startLineLengthInMeters;
|
||||
|
||||
private BoatClassType(String displayName, Map<CourseLayouts, Integer> possipleCourseLayoutsWithStandardTargetTime,
|
||||
Map<WindRange, Map<PointOfSail, Float>> boatSpeedTable, Integer startLineLengthInMeters) {
|
||||
this.displayName = displayName;
|
||||
this.possipleCourseLayoutsWithStandardTargetTime = possipleCourseLayoutsWithStandardTargetTime;
|
||||
this.boatSpeedTable = boatSpeedTable;
|
||||
this.startLineLengthInMeters = startLineLengthInMeters;
|
||||
}
|
||||
|
||||
public Map<WindRange, Map<PointOfSail, Float>> getBoatSpeedTable() {
|
||||
return boatSpeedTable;
|
||||
}
|
||||
|
||||
public void setBoatSpeedTable(Map<WindRange, Map<PointOfSail, Float>> boatSpeedTable) {
|
||||
this.boatSpeedTable = boatSpeedTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return displayName;
|
||||
|
||||
+17
@@ -1,6 +1,23 @@
|
||||
package com.sap.sailing.domain.coursedesign;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
|
||||
public interface CourseDesign {
|
||||
Position getStartBoatPosition();
|
||||
void setStartBoatPosition(Position startBoatPosition);
|
||||
Double getWindSpeed();
|
||||
void setWindSpeed(Double windSpeed);
|
||||
Bearing getWindDirection();
|
||||
void setWindDirection(Bearing windDirection);
|
||||
|
||||
PositionedMark getPinEnd();
|
||||
public void setPinEnd(PositionedMark pinEnd);
|
||||
|
||||
Position getReferencePoint();
|
||||
public void setReferencePoint(Position referencePoint);
|
||||
void setCourseDesignSpecificMarks(Set<PositionedMark> courseDesignSpecificMarks);
|
||||
Set<PositionedMark> getCourseDesignSpecificMarks();
|
||||
}
|
||||
+2
-1
@@ -1,8 +1,9 @@
|
||||
package com.sap.sailing.domain.coursedesign;
|
||||
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
|
||||
|
||||
public interface CourseDesignFactory {
|
||||
CourseDesign createCourseDesign(Position startBoatPosition, Double windSpeed, Integer windDirection, BoatClassType boatClass, CourseLayouts courseLayout, NumberOfRounds numberOfRounds, TargetTime targetTime);
|
||||
CourseDesign createCourseDesign(Position startBoatPosition, Double windSpeed, Bearing windDirection, BoatClassType boatClass, CourseLayouts courseLayout, NumberOfRounds numberOfRounds, TargetTime targetTime);
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.sap.sailing.domain.coursedesign;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
|
||||
public class TrapezoidCourseDesignFactoryImpl extends AbstractCourseDesignFactory {
|
||||
|
||||
@Override
|
||||
public CourseDesign createCourseDesign(Position startBoatPosition, Double windSpeed, Bearing windDirection,
|
||||
BoatClassType boatClass, CourseLayouts courseLayout, NumberOfRounds numberOfRounds, TargetTime targetTime) {
|
||||
this.product = new TrapezoidCourseDesignImpl();
|
||||
this.product.setStartBoatPosition(startBoatPosition);
|
||||
this.product.setWindSpeed(windSpeed);
|
||||
this.product.setWindDirection(windDirection);
|
||||
setPinEnd(boatClass, startBoatPosition, windDirection);
|
||||
return this.product;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<PositionedMark> computeDesignSpecificMarks(Position startBoatPosition, Double windSpeed,
|
||||
Bearing windDirection, BoatClassType boatClass, CourseLayouts courseLayout, NumberOfRounds numberOfRounds,
|
||||
TargetTime targetTime) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.sap.sailing.domain.coursedesign;
|
||||
|
||||
|
||||
public class TrapezoidCourseDesignImpl extends AbstractCourseDesign {
|
||||
|
||||
|
||||
}
|
||||
+1
-2
@@ -9,7 +9,6 @@ public enum TrapezoidCourseLayouts implements CourseLayouts{
|
||||
private String displayName;
|
||||
private String shortName;
|
||||
private Integer reachAngle;
|
||||
private Class<? extends CourseDesignFactory> courseDesignFactoryClass;
|
||||
|
||||
public Integer getReachAngle() {
|
||||
return reachAngle;
|
||||
@@ -32,6 +31,6 @@ public enum TrapezoidCourseLayouts implements CourseLayouts{
|
||||
|
||||
@Override
|
||||
public Class<? extends CourseDesignFactory> getCourseDesignFactoryClass() {
|
||||
return this.courseDesignFactoryClass;
|
||||
return TrapezoidCourseDesignFactoryImpl.class;
|
||||
}
|
||||
}
|
||||
+4
@@ -16,6 +16,10 @@ public class WindRange implements Comparable<WindRange>{
|
||||
public Integer getUpperBound() {
|
||||
return upperBound;
|
||||
}
|
||||
|
||||
public boolean isInRange(Double windSpeed){
|
||||
return (lowerBound <= windSpeed && windSpeed <= upperBound) ? true : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(WindRange o) {
|
||||
|
||||
+5
-7
@@ -1,20 +1,18 @@
|
||||
package com.sap.sailing.domain.coursedesign;
|
||||
|
||||
public enum LeewardWindWardCourseLayouts implements CourseLayouts{
|
||||
windWardLeewardWindward("Windward/Leeward with Windward finish", "W", WindWardLeewardCourseDesignFactoryImpl.class),
|
||||
windWardLeewardLeeward("Windward/Leeward with Leeward finish", "L", WindWardLeewardCourseDesignFactoryImpl.class);
|
||||
public enum WindWardLeeWardCourseLayouts implements CourseLayouts{
|
||||
windWardLeewardWindward("Windward/Leeward with Windward finish", "W"),
|
||||
windWardLeewardLeeward("Windward/Leeward with Leeward finish", "L");
|
||||
|
||||
private String displayName;
|
||||
private String shortName;
|
||||
private Class<? extends CourseDesignFactory> courseDesignFactoryClass;
|
||||
|
||||
@Override
|
||||
public String getShortName() {
|
||||
return shortName;
|
||||
}
|
||||
|
||||
private LeewardWindWardCourseLayouts(String displayName, String shortName, Class<? extends CourseDesignFactory> courseDesignFactoryClass){
|
||||
this.courseDesignFactoryClass = courseDesignFactoryClass;
|
||||
private WindWardLeeWardCourseLayouts(String displayName, String shortName){
|
||||
this.displayName = displayName;
|
||||
this.shortName = shortName;
|
||||
}
|
||||
@@ -26,6 +24,6 @@ public enum LeewardWindWardCourseLayouts implements CourseLayouts{
|
||||
|
||||
@Override
|
||||
public Class<? extends CourseDesignFactory> getCourseDesignFactoryClass() {
|
||||
return this.courseDesignFactoryClass;
|
||||
return WindWardLeeWardCourseDesignFactoryImpl.class;
|
||||
}
|
||||
}
|
||||
+54
-15
@@ -1,22 +1,61 @@
|
||||
package com.sap.sailing.domain.coursedesign;
|
||||
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
public class WindWardLeewardCourseDesignFactoryImpl extends AbstractCourseDesignFactory {
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.impl.NauticalMileDistance;
|
||||
|
||||
public class WindWardLeeWardCourseDesignFactoryImpl extends AbstractCourseDesignFactory {
|
||||
private final int LUV_BUOY1_ANGLE_TO_WIND = 0;
|
||||
private final int LUV_BUOY2_ANGLE_TO_WIND = 100;
|
||||
private final Distance LUV_BUOY1_TO_LUV_BUOY2_DISTANCE = new NauticalMileDistance(0.03);
|
||||
@Override
|
||||
public CourseDesign createCourseDesign(Position startBoatPosition, Double windSpeed, Bearing windDirection,
|
||||
BoatClassType boatClass, CourseLayouts courseLayout, NumberOfRounds numberOfRounds, TargetTime targetTime) {
|
||||
this.product = new WindWardLeeWardCourseDesignImpl();
|
||||
this.initializeCourseDesign(startBoatPosition, windSpeed, windDirection, boatClass, courseLayout,
|
||||
numberOfRounds, targetTime);
|
||||
this.finalizeCourseDesign(startBoatPosition, windSpeed, windDirection, boatClass, courseLayout, numberOfRounds,
|
||||
targetTime);
|
||||
return this.product;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CourseDesign createCourseDesign(Position startBoatPosition, Double windSpeed, Integer windDirection,
|
||||
BoatClassType boatClass, CourseLayouts courseLayout, NumberOfRounds numberOfRounds, TargetTime targetTime) {
|
||||
CourseDesign windWardLeewardCourseDesign = new WindwardLeewardCourseDesignImpl();
|
||||
setPinEnd(windWardLeewardCourseDesign, boatClass, startBoatPosition, windDirection);
|
||||
return windWardLeewardCourseDesign;
|
||||
protected Set<PositionedMark> computeDesignSpecificMarks(Position startBoatPosition, Double windSpeed,
|
||||
Bearing windDirection, BoatClassType boatClass, CourseLayouts courseLayout, NumberOfRounds numberOfRounds,
|
||||
TargetTime targetTime) {
|
||||
Set<PositionedMark> result = new HashSet<PositionedMark>();
|
||||
Map<PointOfSail, Float> speedTable = null;
|
||||
for (Entry<WindRange, Map<PointOfSail, Float>> windRangeToSpeedTable : boatClass.getBoatSpeedTable().entrySet()) {
|
||||
if (windRangeToSpeedTable.getKey().isInRange(windSpeed)) {
|
||||
speedTable = windRangeToSpeedTable.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(speedTable==null){
|
||||
throw new IllegalArgumentException("There was no speed diagram for the given boat class and the given wind.");
|
||||
}
|
||||
double roundLength = targetTime.getTimeInMinutes()/numberOfRounds.getNumberOfRounds();
|
||||
double legLength = roundLength/(speedTable.get(PointOfSail.Upwind)+speedTable.get(PointOfSail.Downwind));
|
||||
Distance legDistance = new NauticalMileDistance(legLength);
|
||||
Position luvBuoyPosition = getPositionForGivenPointDistanceAndBearing(
|
||||
this.product.getReferencePoint(), legDistance,
|
||||
windDirection.add(new DegreeBearingImpl(LUV_BUOY1_ANGLE_TO_WIND)));
|
||||
DecimalFormat legLengthFormat = new DecimalFormat("0.00");
|
||||
result.add(new PositionedMarkImpl("luv buoy 1 "+legLengthFormat.format(legDistance.getNauticalMiles()) , luvBuoyPosition));
|
||||
|
||||
result.add(new PositionedMarkImpl("luv buoy 2" , getPositionForGivenPointDistanceAndBearing(
|
||||
luvBuoyPosition, LUV_BUOY1_TO_LUV_BUOY2_DISTANCE,
|
||||
windDirection.add(new DegreeBearingImpl(LUV_BUOY2_ANGLE_TO_WIND)))));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void setPinEnd(CourseDesign windWardLeewardCourseDesign, BoatClassType boatClass,
|
||||
Position startBoatPosition, Integer windDirection) {
|
||||
PositionedMark pinEnd = new PositionedMarkImpl("pinEnd", getPositionForGivenPointDistanceAndBearing(
|
||||
startBoatPosition, boatClass.getStartLineLengthInMeters(), windDirection));
|
||||
windWardLeewardCourseDesign.setPinEnd(pinEnd);
|
||||
}
|
||||
|
||||
}
|
||||
+4
-12
@@ -1,16 +1,8 @@
|
||||
package com.sap.sailing.domain.coursedesign;
|
||||
|
||||
public class WindwardLeewardCourseDesignImpl implements CourseDesign{
|
||||
|
||||
PositionedMark pinEnd;
|
||||
|
||||
@Override
|
||||
public PositionedMark getPinEnd() {
|
||||
return pinEnd;
|
||||
}
|
||||
@Override
|
||||
public void setPinEnd(PositionedMark pinEnd) {
|
||||
this.pinEnd = pinEnd;
|
||||
}
|
||||
|
||||
|
||||
public class WindWardLeeWardCourseDesignImpl extends AbstractCourseDesign {
|
||||
|
||||
|
||||
}
|
||||
@@ -1,3 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/com/sap/sailing/domain/base/impl/AbstractSpeedWithAbstractBearingImpl.java=UTF-8
|
||||
encoding//src/com/sap/sailing/domain/tracking/impl/CompactGPSFixMovingImpl.java=UTF-8
|
||||
+74
-14
@@ -11,7 +11,9 @@ import org.json.simple.JSONObject;
|
||||
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceColumnInSeries;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Series;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
@@ -72,27 +74,85 @@ public class LeaderboardGroupJsonGetServlet extends AbstractJsonHttpServlet {
|
||||
|
||||
jsonLeaderboard.put("scoringScheme", leaderboard.getScoringScheme().getType());
|
||||
jsonLeaderboard.put("regattaName", regatta.getName());
|
||||
|
||||
JSONArray jsonSeriesEntries = new JSONArray();
|
||||
jsonLeaderboard.put("series", jsonSeriesEntries);
|
||||
for (Series series: regatta.getSeries()) {
|
||||
JSONObject jsonSeries = new JSONObject();
|
||||
jsonSeries.put("name", series.getName());
|
||||
jsonSeries.put("isMedalSeries", series.isMedal());
|
||||
|
||||
JSONArray jsonFleetsEntries = new JSONArray();
|
||||
jsonSeries.put("fleets", jsonFleetsEntries);
|
||||
for(Fleet fleet: series.getFleets()) {
|
||||
|
||||
JSONObject jsonFleet = new JSONObject();
|
||||
jsonFleet.put("name", fleet.getName());
|
||||
jsonFleet.put("color", fleet.getColor() != null ? fleet.getColor().getAsHtml() : null);
|
||||
jsonFleet.put("ordering", fleet.getOrdering());
|
||||
jsonFleetsEntries.add(jsonFleet);
|
||||
|
||||
JSONArray jsonRacesEntries = new JSONArray();
|
||||
jsonFleet.put("races", jsonRacesEntries);
|
||||
for(RaceColumnInSeries raceColumn: series.getRaceColumns()) {
|
||||
JSONObject jsonRaceColumn = new JSONObject();
|
||||
jsonRaceColumn.put("name", raceColumn.getName());
|
||||
jsonRaceColumn.put("isMedalRace" , raceColumn.isMedalRace());
|
||||
|
||||
TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
|
||||
if(trackedRace != null) {
|
||||
jsonRaceColumn.put("isTracked", true);
|
||||
jsonRaceColumn.put("trackedRaceName", trackedRace.getRace().getName());
|
||||
} else {
|
||||
jsonRaceColumn.put("isTracked", false);
|
||||
jsonRaceColumn.put("trackedRaceName", null);
|
||||
}
|
||||
jsonRacesEntries.add(jsonRaceColumn);
|
||||
}
|
||||
jsonSeriesEntries.add(jsonSeries);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
jsonLeaderboard.put("scoringScheme", leaderboard.getScoringScheme().getType());
|
||||
jsonLeaderboard.put("regattaName", null);
|
||||
|
||||
JSONArray jsonRacesEntries = new JSONArray();
|
||||
jsonLeaderboard.put("races", jsonRacesEntries);
|
||||
for(RaceColumn raceColumn: leaderboard.getRaceColumns()) {
|
||||
JSONObject jsonRaceColumn = new JSONObject();
|
||||
jsonRaceColumn.put("name", raceColumn.getName());
|
||||
jsonRaceColumn.put("isMedalRace" , raceColumn.isMedalRace());
|
||||
JSONArray jsonSeriesEntries = new JSONArray();
|
||||
jsonLeaderboard.put("series", jsonSeriesEntries);
|
||||
|
||||
// write a 'default' series to be conform with our common regatta structure
|
||||
JSONObject jsonSeries = new JSONObject();
|
||||
jsonSeriesEntries.add(jsonSeries);
|
||||
jsonSeries.put("name", LeaderboardNameConstants.DEFAULT_SERIES_NAME);
|
||||
jsonSeries.put("isMedalSeries", null);
|
||||
|
||||
JSONArray jsonFleetsEntries = new JSONArray();
|
||||
jsonSeries.put("fleets", jsonFleetsEntries);
|
||||
|
||||
Fleet fleet = leaderboard.getFleet(LeaderboardNameConstants.DEFAULT_FLEET_NAME);
|
||||
if(fleet != null) {
|
||||
JSONObject jsonFleet = new JSONObject();
|
||||
jsonFleet.put("name", fleet.getName());
|
||||
jsonFleet.put("color", fleet.getColor() != null ? fleet.getColor().getAsHtml() : null);
|
||||
jsonFleet.put("ordering", fleet.getOrdering());
|
||||
jsonFleetsEntries.add(jsonFleet);
|
||||
|
||||
JSONArray jsonRacesEntries = new JSONArray();
|
||||
jsonFleet.put("races", jsonRacesEntries);
|
||||
for(RaceColumn raceColumn: leaderboard.getRaceColumns()) {
|
||||
JSONObject jsonRaceColumn = new JSONObject();
|
||||
jsonRaceColumn.put("name", raceColumn.getName());
|
||||
jsonRaceColumn.put("isMedalRace" , raceColumn.isMedalRace());
|
||||
|
||||
Fleet fleet = leaderboard.getFleet(LeaderboardNameConstants.DEFAULT_FLEET_NAME);
|
||||
if(fleet != null && raceColumn.getTrackedRace(fleet) != null) {
|
||||
TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
|
||||
jsonRaceColumn.put("isTracked", true);
|
||||
jsonRaceColumn.put("trackedRaceName", trackedRace.getRace().getName());
|
||||
} else {
|
||||
jsonRaceColumn.put("isTracked", false);
|
||||
jsonRaceColumn.put("trackedRaceName", null);
|
||||
if(trackedRace != null) {
|
||||
jsonRaceColumn.put("isTracked", true);
|
||||
jsonRaceColumn.put("trackedRaceName", trackedRace.getRace().getName());
|
||||
} else {
|
||||
jsonRaceColumn.put("isTracked", false);
|
||||
jsonRaceColumn.put("trackedRaceName", null);
|
||||
}
|
||||
jsonRacesEntries.add(jsonRaceColumn);
|
||||
}
|
||||
jsonRacesEntries.add(jsonRaceColumn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-9
@@ -1,7 +1,7 @@
|
||||
package com.sap.sailing.racecommittee.app.coursedesigner;
|
||||
|
||||
import com.google.android.gms.maps.model.LatLng;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.coursedesign.BoatClassType;
|
||||
import com.sap.sailing.domain.coursedesign.CourseDesign;
|
||||
import com.sap.sailing.domain.coursedesign.CourseLayouts;
|
||||
@@ -9,19 +9,19 @@ import com.sap.sailing.domain.coursedesign.NumberOfRounds;
|
||||
import com.sap.sailing.domain.coursedesign.TargetTime;
|
||||
|
||||
public class CourseDesignComputer {
|
||||
private LatLng startBoatPosition;
|
||||
private Position startBoatPosition;
|
||||
private Double windSpeed;
|
||||
private Integer windDirection;
|
||||
private Bearing windDirection;
|
||||
private BoatClassType boatClass;
|
||||
private CourseLayouts courseLayout;
|
||||
private NumberOfRounds numberOfRounds;
|
||||
private TargetTime targetTime;
|
||||
|
||||
public LatLng getStartBoatPosition() {
|
||||
public Position getStartBoatPosition() {
|
||||
return startBoatPosition;
|
||||
}
|
||||
|
||||
public CourseDesignComputer setStartBoatPosition(LatLng startBoatPosition) {
|
||||
public CourseDesignComputer setStartBoatPosition(Position startBoatPosition) {
|
||||
this.startBoatPosition = startBoatPosition;
|
||||
return this;
|
||||
}
|
||||
@@ -35,11 +35,11 @@ public class CourseDesignComputer {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Integer getWindDirection() {
|
||||
public Bearing getWindDirection() {
|
||||
return windDirection;
|
||||
}
|
||||
|
||||
public CourseDesignComputer setWindDirection(Integer windDirection) {
|
||||
public CourseDesignComputer setWindDirection(Bearing windDirection) {
|
||||
this.windDirection = windDirection;
|
||||
return this;
|
||||
}
|
||||
@@ -86,7 +86,7 @@ public class CourseDesignComputer {
|
||||
&& courseLayout != null && numberOfRounds != null && targetTime != null) {
|
||||
try {
|
||||
computedCourseDesign = courseLayout.getCourseDesignFactoryClass().newInstance()
|
||||
.createCourseDesign(new DegreePosition(startBoatPosition.latitude, startBoatPosition.longitude), windSpeed, windDirection, boatClass, courseLayout, numberOfRounds, targetTime);
|
||||
.createCourseDesign(startBoatPosition, windSpeed, windDirection, boatClass, courseLayout, numberOfRounds, targetTime);
|
||||
} catch (InstantiationException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
|
||||
-8
@@ -3,7 +3,6 @@ package com.sap.sailing.racecommittee.app.data;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.google.android.gms.maps.model.LatLng;
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
import com.sap.sailing.domain.base.CourseBase;
|
||||
import com.sap.sailing.domain.base.EventBase;
|
||||
@@ -36,11 +35,4 @@ public interface DataStore {
|
||||
|
||||
public CourseBase getLastPublishedCourseDesign();
|
||||
public void setLastPublishedCourseDesign(CourseBase courseData);
|
||||
|
||||
public LatLng getLastWindPosition();
|
||||
public void setLastWindPosition(LatLng lastWindPosition);
|
||||
public Integer getLastWindDirection();
|
||||
public void setLastWindDirection(Integer lastWindDirection);
|
||||
public Double getLastWindSpeed();
|
||||
public void setLastWindSpeed(Double lastWindSpeed);
|
||||
}
|
||||
-37
@@ -4,7 +4,6 @@ import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.google.android.gms.maps.model.LatLng;
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
import com.sap.sailing.domain.base.CourseBase;
|
||||
import com.sap.sailing.domain.base.EventBase;
|
||||
@@ -19,9 +18,6 @@ public enum InMemoryDataStore implements DataStore {
|
||||
private HashMap<Serializable, ManagedRace> managedRaceById;
|
||||
private HashMap<Serializable, Mark> marksById;
|
||||
private CourseBase courseData;
|
||||
private Double lastWindSpeed;
|
||||
private Integer lastWindDirection;
|
||||
private LatLng lastWindPosition;
|
||||
|
||||
private InMemoryDataStore() {
|
||||
reset();
|
||||
@@ -166,37 +162,4 @@ public enum InMemoryDataStore implements DataStore {
|
||||
public void setLastPublishedCourseDesign(CourseBase courseData) {
|
||||
this.courseData = courseData;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* * * * * * *
|
||||
* Wind *
|
||||
* * * * * * *
|
||||
*/
|
||||
@Override
|
||||
public Integer getLastWindDirection() {
|
||||
return lastWindDirection;
|
||||
}
|
||||
@Override
|
||||
public void setLastWindDirection(Integer lastWindDirection) {
|
||||
this.lastWindDirection = lastWindDirection;
|
||||
}
|
||||
@Override
|
||||
public Double getLastWindSpeed() {
|
||||
return lastWindSpeed;
|
||||
}
|
||||
@Override
|
||||
public void setLastWindSpeed(Double lastWindSpeed) {
|
||||
this.lastWindSpeed = lastWindSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastWindPosition(LatLng lastWindPosition) {
|
||||
this.lastWindPosition = lastWindPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LatLng getLastWindPosition() {
|
||||
return this.lastWindPosition;
|
||||
}
|
||||
}
|
||||
+1
@@ -9,6 +9,7 @@ import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
||||
import com.sap.sailing.domain.common.racelog.StartProcedureType;
|
||||
import com.sap.sailing.domain.coursedesign.CourseDesign;
|
||||
import com.sap.sailing.domain.racelog.RaceLog;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
import com.sap.sailing.racecommittee.app.domain.startprocedure.StartProcedure;
|
||||
|
||||
+4
-2
@@ -15,6 +15,7 @@ import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
||||
import com.sap.sailing.domain.common.racelog.StartProcedureType;
|
||||
import com.sap.sailing.domain.coursedesign.CourseDesign;
|
||||
import com.sap.sailing.domain.racelog.RaceLog;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEvent;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEventFactory;
|
||||
@@ -160,7 +161,8 @@ public class RaceStateImpl implements RaceState, RaceLogChangedListener {
|
||||
public CourseBase getCourseDesign() {
|
||||
return lastCourseDesignFinder.analyze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setCourseDesign(CourseBase newCourseData) {
|
||||
TimePoint eventTime = MillisecondsTimePoint.now();
|
||||
|
||||
@@ -170,7 +172,7 @@ public class RaceStateImpl implements RaceState, RaceLogChangedListener {
|
||||
|
||||
fireCourseDesignChanged();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRaceAborted(TimePoint eventTime) {
|
||||
/*RaceLogEvent abortEvent = RaceLogEventFactory.INSTANCE.createRaceStatusEvent(eventTime, raceLog.getCurrentPassId(), RaceLogRaceStatus.UNSCHEDULED);
|
||||
|
||||
+8
-6
@@ -5,6 +5,7 @@ import java.text.DecimalFormat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.location.Criteria;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.location.LocationManager;
|
||||
@@ -64,10 +65,13 @@ public class WindActivity extends BaseActivity implements CompassDirectionListen
|
||||
windSpeedSeekBar = (SeekBar) findViewById(R.id.seekbar_wind_speed);
|
||||
sendButton = (Button) findViewById(R.id.btn_wind_send);
|
||||
|
||||
currentLocation = null;
|
||||
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
|
||||
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, FIVE_SEC, EVERY_POSITION_CHANGE, this);
|
||||
|
||||
Criteria crit = new Criteria();
|
||||
crit.setAccuracy(Criteria.ACCURACY_FINE);
|
||||
String provider = locationManager.getBestProvider(crit, true);
|
||||
onLocationChanged(locationManager.getLastKnownLocation(provider));
|
||||
|
||||
windSpeedSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
|
||||
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
@@ -86,7 +90,6 @@ public class WindActivity extends BaseActivity implements CompassDirectionListen
|
||||
}
|
||||
});
|
||||
|
||||
sendButton.setEnabled(false);
|
||||
sendButton.setOnClickListener(new OnClickListener() {
|
||||
|
||||
public void onClick(View v) {
|
||||
@@ -120,7 +123,7 @@ public class WindActivity extends BaseActivity implements CompassDirectionListen
|
||||
|
||||
});
|
||||
|
||||
speedFormat = new DecimalFormat("##.0");
|
||||
speedFormat = new DecimalFormat("#0.0");
|
||||
bearingFormat = new DecimalFormat("###");
|
||||
|
||||
double enteredWindSpeed = AppPreferences.getWindSpeed(getBaseContext());
|
||||
@@ -158,7 +161,6 @@ public class WindActivity extends BaseActivity implements CompassDirectionListen
|
||||
currentLocation = location;
|
||||
latitudeEditText.setText(String.valueOf(location.getLatitude()));
|
||||
longitudeEditText.setText(String.valueOf(location.getLongitude()));
|
||||
sendButton.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -188,7 +190,7 @@ public class WindActivity extends BaseActivity implements CompassDirectionListen
|
||||
}
|
||||
|
||||
Position currentPosition = new DegreePosition(currentLocation.getLatitude(), currentLocation.getLongitude());
|
||||
double windSpeed = Double.valueOf(windSpeedEditText.getText().toString());
|
||||
double windSpeed = Double.valueOf(windSpeedEditText.getText().toString().replace(",", "."));
|
||||
double windBearing = Double.valueOf(windBearingEditText.getText().toString());
|
||||
Bearing bearing = new DegreeBearingImpl(windBearing);
|
||||
SpeedWithBearing speedBearing = new KnotSpeedWithBearingImpl(windSpeed, bearing);
|
||||
|
||||
+77
-58
@@ -27,17 +27,18 @@ import com.google.android.gms.maps.MapsInitializer;
|
||||
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
|
||||
import com.google.android.gms.maps.model.LatLng;
|
||||
import com.google.android.gms.maps.model.MarkerOptions;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.coursedesign.BoatClassType;
|
||||
import com.sap.sailing.domain.coursedesign.CourseDesign;
|
||||
import com.sap.sailing.domain.coursedesign.CourseLayouts;
|
||||
import com.sap.sailing.domain.coursedesign.NumberOfRounds;
|
||||
import com.sap.sailing.domain.coursedesign.PositionedMark;
|
||||
import com.sap.sailing.domain.coursedesign.TargetTime;
|
||||
import com.sap.sailing.domain.racelog.analyzing.impl.LastWindFixFinder;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
import com.sap.sailing.racecommittee.app.AppConstants;
|
||||
import com.sap.sailing.racecommittee.app.R;
|
||||
import com.sap.sailing.racecommittee.app.coursedesigner.CourseDesignComputer;
|
||||
import com.sap.sailing.racecommittee.app.data.DataStore;
|
||||
import com.sap.sailing.racecommittee.app.data.InMemoryDataStore;
|
||||
import com.sap.sailing.racecommittee.app.ui.activities.WindActivity;
|
||||
|
||||
public class ClassicCourseDesignDialogFragment extends RaceDialogFragment {
|
||||
@@ -70,7 +71,8 @@ public class ClassicCourseDesignDialogFragment extends RaceDialogFragment {
|
||||
|
||||
public ClassicCourseDesignDialogFragment() {
|
||||
super();
|
||||
// handle bug "Dark overlay of MapFragment in Activity with Dialog theme" - https://code.google.com/p/gmaps-api-issues/issues/detail?id=4865
|
||||
// handle bug "Dark overlay of MapFragment in Activity with Dialog theme" -
|
||||
// https://code.google.com/p/gmaps-api-issues/issues/detail?id=4865
|
||||
this.setStyle(DialogFragment.STYLE_NORMAL, R.style.Theme_DimDisabledDialog);
|
||||
}
|
||||
|
||||
@@ -94,7 +96,7 @@ public class ClassicCourseDesignDialogFragment extends RaceDialogFragment {
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
getDialog().setTitle(getActivity().getText(R.string.course_design_dialog_title));
|
||||
|
||||
setUpMapIfNeeded(getView());
|
||||
publishButton = (Button) getView().findViewById(R.id.publishCourseDesignButton);
|
||||
publishButton.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@@ -114,7 +116,11 @@ public class ClassicCourseDesignDialogFragment extends RaceDialogFragment {
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
courseDesignComputer = new CourseDesignComputer().setBoatClass(selectedBoatClass)
|
||||
.setCourseLayout(selectedCourseLayout).setNumberOfRounds(selectedNumberOfRounds)
|
||||
.setTargetTime(selectedTargetTime);
|
||||
|
||||
spinnerBoatClass = (Spinner) getView().findViewById(R.id.classic_course_designer_boat_class);
|
||||
setupBoatClassSpinner();
|
||||
spinnerCourseLayout = (Spinner) getView().findViewById(R.id.classic_course_designer_course_layout);
|
||||
@@ -124,12 +130,17 @@ public class ClassicCourseDesignDialogFragment extends RaceDialogFragment {
|
||||
spinnerTargetTime = (Spinner) getView().findViewById(R.id.classic_course_designer_target_time);
|
||||
setupTargetTimeSpinner();
|
||||
|
||||
DataStore ds = InMemoryDataStore.INSTANCE;
|
||||
courseDesignComputer = new CourseDesignComputer().setStartBoatPosition(ds.getLastWindPosition())
|
||||
.setWindDirection(ds.getLastWindDirection()).setWindSpeed(ds.getLastWindSpeed())
|
||||
.setBoatClass(selectedBoatClass).setCourseLayout(selectedCourseLayout)
|
||||
.setNumberOfRounds(selectedNumberOfRounds).setTargetTime(selectedTargetTime);
|
||||
setUpMapIfNeeded(getView());
|
||||
LastWindFixFinder lastWindFixFinder = new LastWindFixFinder(getRace().getRaceLog());
|
||||
Wind lastWind = lastWindFixFinder.analyze();
|
||||
|
||||
if (lastWind != null) {
|
||||
courseDesignComputer.setWindSpeed(lastWind.getKnots());
|
||||
courseDesignComputer.setWindDirection(lastWind.getBearing());
|
||||
courseDesignComputer.setStartBoatPosition(lastWind.getPosition());
|
||||
recomputeCourseDesign();
|
||||
} else {
|
||||
Toast.makeText(getActivity(), "Set the wind information, please!", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -141,33 +152,26 @@ public class ClassicCourseDesignDialogFragment extends RaceDialogFragment {
|
||||
Wind windFix = (Wind) data.getSerializableExtra(AppConstants.EXTRAS_WIND_FIX);
|
||||
onWindEntered(windFix);
|
||||
}
|
||||
DataStore ds = InMemoryDataStore.INSTANCE;
|
||||
courseDesignComputer = courseDesignComputer.setStartBoatPosition(ds.getLastWindPosition())
|
||||
.setWindDirection(ds.getLastWindDirection()).setWindSpeed(ds.getLastWindSpeed());
|
||||
recomputeCourseDesign();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onWindEntered(Wind windFix) {
|
||||
getRace().getState().setWindFix(windFix);
|
||||
//TODO integrate the wind fix into the course designer
|
||||
courseDesignComputer.setStartBoatPosition(windFix.getPosition());
|
||||
courseDesignComputer.setWindDirection(windFix.getBearing());
|
||||
courseDesignComputer.setWindSpeed(windFix.getKnots());
|
||||
recomputeCourseDesign();
|
||||
}
|
||||
|
||||
private CourseDesign recomputeCourseDesign() {
|
||||
CourseDesign courseDesign = null;
|
||||
try {
|
||||
courseDesign = courseDesignComputer.compute();
|
||||
} catch (IllegalStateException ise) {
|
||||
Toast.makeText(getActivity(), ise.getMessage(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
/*
|
||||
* DataStore ds = InMemoryDataStore.INSTANCE; Toast.makeText( getActivity(), "" + ds.getLastWindPosition() +
|
||||
* ds.getLastWindDirection() + ds.getLastWindSpeed() + selectedBoatClass + selectedCourseLayout +
|
||||
* selectedNumberOfRounds + selectedTargetTime, Toast.LENGTH_LONG).show()
|
||||
*/;
|
||||
return courseDesign;
|
||||
|
||||
private void recomputeCourseDesign() {
|
||||
try {
|
||||
drawMap(courseDesignComputer.compute());
|
||||
} catch (IllegalStateException ise) {
|
||||
Toast.makeText(getActivity(), ise.getMessage(), Toast.LENGTH_LONG).show();
|
||||
} catch (IllegalArgumentException iae) {
|
||||
Toast.makeText(getActivity(), iae.getMessage(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void setupBoatClassSpinner() {
|
||||
@@ -178,9 +182,17 @@ public class ClassicCourseDesignDialogFragment extends RaceDialogFragment {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
|
||||
selectedBoatClass = (BoatClassType) adapterView.getItemAtPosition(position);
|
||||
|
||||
//update possible course layouts
|
||||
courseLayoutAdapter.clear();
|
||||
courseLayoutAdapter.addAll(selectedBoatClass.getPossibleCourseLayoutsWithTargetTime().keySet());
|
||||
courseLayoutAdapter.notifyDataSetChanged();
|
||||
selectedCourseLayout = (CourseLayouts) selectedBoatClass
|
||||
.getPossibleCourseLayoutsWithTargetTime().keySet().toArray().clone()[0];
|
||||
spinnerCourseLayout.setSelection(courseLayoutAdapter.getPosition(selectedCourseLayout));
|
||||
|
||||
|
||||
courseDesignComputer.setBoatClass(selectedBoatClass);
|
||||
if (selectedBoatClass.getPossibleCourseLayoutsWithTargetTime().keySet().contains(selectedCourseLayout)) {
|
||||
recomputeCourseDesign();
|
||||
}
|
||||
@@ -203,6 +215,7 @@ public class ClassicCourseDesignDialogFragment extends RaceDialogFragment {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
|
||||
selectedCourseLayout = (CourseLayouts) adapterView.getItemAtPosition(position);
|
||||
courseDesignComputer.setCourseLayout(selectedCourseLayout);
|
||||
recomputeCourseDesign();
|
||||
}
|
||||
|
||||
@@ -222,6 +235,7 @@ public class ClassicCourseDesignDialogFragment extends RaceDialogFragment {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
|
||||
selectedNumberOfRounds = (NumberOfRounds) adapterView.getItemAtPosition(position);
|
||||
courseDesignComputer.setNumberOfRounds(selectedNumberOfRounds);
|
||||
recomputeCourseDesign();
|
||||
}
|
||||
|
||||
@@ -241,6 +255,7 @@ public class ClassicCourseDesignDialogFragment extends RaceDialogFragment {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
|
||||
selectedTargetTime = (TargetTime) adapterView.getItemAtPosition(position);
|
||||
courseDesignComputer.setTargetTime(selectedTargetTime);
|
||||
recomputeCourseDesign();
|
||||
}
|
||||
|
||||
@@ -256,7 +271,6 @@ public class ClassicCourseDesignDialogFragment extends RaceDialogFragment {
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mMapView.onResume();
|
||||
setUpMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -273,43 +287,48 @@ public class ClassicCourseDesignDialogFragment extends RaceDialogFragment {
|
||||
private void setUpMapIfNeeded(View inflatedView) {
|
||||
if (courseAreaMap == null) {
|
||||
courseAreaMap = ((MapView) inflatedView.findViewById(R.id.mapView)).getMap();
|
||||
if (courseAreaMap != null) {
|
||||
setUpMap();
|
||||
}
|
||||
courseAreaMap.getUiSettings().setRotateGesturesEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpMap() {
|
||||
private void drawMap(CourseDesign courseDesign) {
|
||||
courseAreaMap.clear();
|
||||
DataStore ds = InMemoryDataStore.INSTANCE;
|
||||
if (ds.getLastWindPosition() != null && ds.getLastWindDirection() != null && ds.getLastWindSpeed() != null) {
|
||||
courseAreaMap.animateCamera(CameraUpdateFactory.newLatLngZoom(ds.getLastWindPosition(), 17.0f));
|
||||
courseAreaMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
|
||||
position2LatLng(courseDesign.getStartBoatPosition()), 16.0f));
|
||||
|
||||
Bitmap bmpOriginal = BitmapFactory.decodeResource(this.getResources(), R.drawable.boat);
|
||||
Bitmap bmResult = Bitmap.createBitmap(bmpOriginal.getHeight(), bmpOriginal.getHeight(),
|
||||
Bitmap.Config.ARGB_8888);
|
||||
Canvas tempCanvas = new Canvas(bmResult);
|
||||
tempCanvas.rotate(ds.getLastWindDirection(), bmpOriginal.getWidth() / 2, bmpOriginal.getHeight() / 2);
|
||||
tempCanvas.drawBitmap(bmpOriginal, 0, 0, null);
|
||||
Bitmap bmpOriginal = BitmapFactory.decodeResource(this.getResources(), R.drawable.boat);
|
||||
Bitmap bmResult = Bitmap
|
||||
.createBitmap(bmpOriginal.getHeight(), bmpOriginal.getHeight(), Bitmap.Config.ARGB_8888);
|
||||
Canvas tempCanvas = new Canvas(bmResult);
|
||||
tempCanvas.rotate((float) courseDesign.getWindDirection().getDegrees(), bmpOriginal.getWidth() / 2,
|
||||
bmpOriginal.getHeight() / 2);
|
||||
tempCanvas.drawBitmap(bmpOriginal, 0, 0, null);
|
||||
|
||||
courseAreaMap.addMarker(new MarkerOptions()
|
||||
.position(ds.getLastWindPosition())
|
||||
.icon(BitmapDescriptorFactory.fromBitmap(bmResult))
|
||||
.draggable(false)
|
||||
.title(ds.getLastWindPosition() + ", " + ds.getLastWindSpeed() + "kn, " + ds.getLastWindDirection()
|
||||
+ "°"));
|
||||
}
|
||||
CourseDesign courseDesign = recomputeCourseDesign();
|
||||
if (courseDesign != null) {
|
||||
LatLng pinEndPosition = new LatLng(courseDesign.getPinEnd().getPosition().getLatDeg(), courseDesign
|
||||
.getPinEnd().getPosition().getLngDeg());
|
||||
courseAreaMap.addMarker(new MarkerOptions().position(pinEndPosition)
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.buoy_red)).draggable(false)
|
||||
.title(courseDesign.getPinEnd().getName()));
|
||||
courseAreaMap.addMarker(new MarkerOptions()
|
||||
.position(position2LatLng(courseDesign.getStartBoatPosition()))
|
||||
.icon(BitmapDescriptorFactory.fromBitmap(bmResult))
|
||||
.draggable(false)
|
||||
.title(position2LatLng(courseDesign.getStartBoatPosition()) + ", " + courseDesign.getWindSpeed()
|
||||
+ "kn, " + courseDesign.getWindDirection()));
|
||||
LatLng pinEndPosition = new LatLng(courseDesign.getPinEnd().getPosition().getLatDeg(), courseDesign.getPinEnd()
|
||||
.getPosition().getLngDeg());
|
||||
courseAreaMap.addMarker(new MarkerOptions().position(pinEndPosition)
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.buoy_red)).draggable(false)
|
||||
.title(courseDesign.getPinEnd().getName()));
|
||||
|
||||
for(PositionedMark mark : courseDesign.getCourseDesignSpecificMarks()){
|
||||
LatLng markPosition = new LatLng(mark.getPosition().getLatDeg(), mark.getPosition().getLngDeg());
|
||||
courseAreaMap.addMarker(new MarkerOptions().position(markPosition)
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.buoy_black_cone)).draggable(false)
|
||||
.title(mark.getName()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private LatLng position2LatLng(Position p) {
|
||||
return new LatLng(p.getLatDeg(), p.getLngDeg());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
Reference in new issue
Block a user