diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/AbstractCourseDesign.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/AbstractCourseDesign.java new file mode 100644 index 00000000000..02dfb2152c8 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/AbstractCourseDesign.java @@ -0,0 +1,53 @@ +package com.sap.sailing.domain.coursedesign; + +import com.sap.sailing.domain.common.Bearing; +import com.sap.sailing.domain.common.Position; + +public class AbstractCourseDesign implements CourseDesign{ + Position startBoatPosition; + Double windSpeed; + Bearing windDirection; + PositionedMark pinEnd; + + @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; + } +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/AbstractCourseDesignFactory.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/AbstractCourseDesignFactory.java index bec11358f15..e63828b7da8 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/AbstractCourseDesignFactory.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/AbstractCourseDesignFactory.java @@ -1,27 +1,52 @@ package com.sap.sailing.domain.coursedesign; +import com.sap.sailing.domain.common.Bearing; import com.sap.sailing.domain.common.Position; +import com.sap.sailing.domain.common.impl.DegreeBearingImpl; import com.sap.sailing.domain.common.impl.DegreePosition; +public abstract class AbstractCourseDesignFactory implements CourseDesignFactory { + protected CourseDesign product; -public abstract class AbstractCourseDesignFactory implements CourseDesignFactory{ - @Override - public abstract CourseDesign createCourseDesign(Position startBoatPosition, Double windSpeed, Integer windDirection, - BoatClassType boatClass, CourseLayouts courseLayout, NumberOfRounds numberOfRounds, TargetTime targetTime); - + public abstract CourseDesign createCourseDesign(Position startBoatPosition, Double windSpeed, + Bearing windDirection, BoatClassType boatClass, CourseLayouts courseLayout, NumberOfRounds numberOfRounds, + TargetTime targetTime); + + protected void setPinEnd(BoatClassType boatClass, Position startBoatPosition, Bearing windDirection) { + PositionedMark pinEnd = new PositionedMarkImpl("pinEnd", getPositionForGivenPointDistanceAndBearing( + startBoatPosition, boatClass.getStartLineLengthInMeters(), + windDirection.add(new DegreeBearingImpl(270)))); + product.setPinEnd(pinEnd); + } + 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); + Bearing windDirection) { + final double earthRadiusInMeters = 6371000.0; + double brng = windDirection.getRadians(); + double lat1 = givenPoint.getLatRad(); + double lon1 = givenPoint.getLngRad(); + double dist = ditanceInMeters / 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()); } + */ } } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/BoatClassType.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/BoatClassType.java index 29ee486b9c5..d26d767dfac 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/BoatClassType.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/BoatClassType.java @@ -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>() { { @@ -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>() { { @@ -86,8 +86,8 @@ public enum BoatClassType { }, 110), boatClass49er("49er", new HashMap() { { - put(LeewardWindWardCourseLayouts.windWardLeewardLeeward, 30); - put(LeewardWindWardCourseLayouts.windWardLeewardWindward, 30); + put(WindWardLeeWardCourseLayouts.windWardLeewardLeeward, 30); + put(WindWardLeeWardCourseLayouts.windWardLeewardWindward, 30); } }, new TreeMap>() { { diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/CourseDesign.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/CourseDesign.java index bec16d4349f..f0331dd0c34 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/CourseDesign.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/CourseDesign.java @@ -1,6 +1,16 @@ package com.sap.sailing.domain.coursedesign; +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); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/CourseDesignFactory.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/CourseDesignFactory.java index 6e34d97c13c..5a4ad6bbc99 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/CourseDesignFactory.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/CourseDesignFactory.java @@ -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); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/TrapezoidCourseDesignFactoryImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/TrapezoidCourseDesignFactoryImpl.java new file mode 100644 index 00000000000..aeed5ed091d --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/TrapezoidCourseDesignFactoryImpl.java @@ -0,0 +1,18 @@ +package com.sap.sailing.domain.coursedesign; + +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; + } +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/TrapezoidCourseDesignImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/TrapezoidCourseDesignImpl.java new file mode 100644 index 00000000000..c41b67ab9cd --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/TrapezoidCourseDesignImpl.java @@ -0,0 +1,5 @@ +package com.sap.sailing.domain.coursedesign; + +public class TrapezoidCourseDesignImpl extends AbstractCourseDesign { + +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/TrapezoidCourseLayouts.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/TrapezoidCourseLayouts.java index f993422691e..454c1c5f97f 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/TrapezoidCourseLayouts.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/TrapezoidCourseLayouts.java @@ -9,7 +9,6 @@ public enum TrapezoidCourseLayouts implements CourseLayouts{ private String displayName; private String shortName; private Integer reachAngle; - private Class courseDesignFactoryClass; public Integer getReachAngle() { return reachAngle; @@ -32,6 +31,6 @@ public enum TrapezoidCourseLayouts implements CourseLayouts{ @Override public Class getCourseDesignFactoryClass() { - return this.courseDesignFactoryClass; + return TrapezoidCourseDesignFactoryImpl.class; } } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/LeewardWindWardCourseLayouts.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/WindWardLeeWardCourseLayouts.java similarity index 54% rename from java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/LeewardWindWardCourseLayouts.java rename to java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/WindWardLeeWardCourseLayouts.java index c67e106fc5e..c5998620eee 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/LeewardWindWardCourseLayouts.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/WindWardLeeWardCourseLayouts.java @@ -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 courseDesignFactoryClass; @Override public String getShortName() { return shortName; } - private LeewardWindWardCourseLayouts(String displayName, String shortName, Class 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 getCourseDesignFactoryClass() { - return this.courseDesignFactoryClass; + return WindWardLeeWardCourseDesignFactoryImpl.class; } } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/WindWardLeewardCourseDesignFactoryImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/WindWardLeewardCourseDesignFactoryImpl.java index eab88d97628..31c044563c9 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/WindWardLeewardCourseDesignFactoryImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/WindWardLeewardCourseDesignFactoryImpl.java @@ -1,22 +1,18 @@ package com.sap.sailing.domain.coursedesign; +import com.sap.sailing.domain.common.Bearing; import com.sap.sailing.domain.common.Position; -public class WindWardLeewardCourseDesignFactoryImpl extends AbstractCourseDesignFactory { +public class WindWardLeeWardCourseDesignFactoryImpl extends AbstractCourseDesignFactory { @Override - public CourseDesign createCourseDesign(Position startBoatPosition, Double windSpeed, Integer windDirection, + public CourseDesign createCourseDesign(Position startBoatPosition, Double windSpeed, Bearing windDirection, BoatClassType boatClass, CourseLayouts courseLayout, NumberOfRounds numberOfRounds, TargetTime targetTime) { - CourseDesign windWardLeewardCourseDesign = new WindwardLeewardCourseDesignImpl(); - setPinEnd(windWardLeewardCourseDesign, boatClass, startBoatPosition, windDirection); - return windWardLeewardCourseDesign; + this.product = new WindWardLeeWardCourseDesignImpl(); + this.product.setStartBoatPosition(startBoatPosition); + this.product.setWindSpeed(windSpeed); + this.product.setWindDirection(windDirection); + setPinEnd(boatClass, startBoatPosition, windDirection); + return this.product; } - - private void setPinEnd(CourseDesign windWardLeewardCourseDesign, BoatClassType boatClass, - Position startBoatPosition, Integer windDirection) { - PositionedMark pinEnd = new PositionedMarkImpl("pinEnd", getPositionForGivenPointDistanceAndBearing( - startBoatPosition, boatClass.getStartLineLengthInMeters(), windDirection)); - windWardLeewardCourseDesign.setPinEnd(pinEnd); - } - } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/WindwardLeewardCourseDesignImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/WindwardLeewardCourseDesignImpl.java index 2670c3a4890..75e5f9f2baf 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/WindwardLeewardCourseDesignImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursedesign/WindwardLeewardCourseDesignImpl.java @@ -1,16 +1,6 @@ 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 { + } diff --git a/java/com.sap.sailing.domain/.settings/org.eclipse.core.resources.prefs b/java/com.sap.sailing.domain/.settings/org.eclipse.core.resources.prefs index 5dfd5763bfd..a75e8e21989 100755 --- a/java/com.sap.sailing.domain/.settings/org.eclipse.core.resources.prefs +++ b/java/com.sap.sailing.domain/.settings/org.eclipse.core.resources.prefs @@ -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 diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/courseDesigner/CourseDesignComputer.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/courseDesigner/CourseDesignComputer.java index bff80e7588b..0b72dc09476 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/courseDesigner/CourseDesignComputer.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/courseDesigner/CourseDesignComputer.java @@ -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(); diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataStore.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataStore.java index e2b528f05c1..cc9566d5aff 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataStore.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataStore.java @@ -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); } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/InMemoryDataStore.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/InMemoryDataStore.java index 5741f763417..eac2d253fc3 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/InMemoryDataStore.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/InMemoryDataStore.java @@ -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 managedRaceById; private HashMap 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; - } } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/domain/state/RaceState.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/domain/state/RaceState.java index 24a2731d370..61a8af83a9d 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/domain/state/RaceState.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/domain/state/RaceState.java @@ -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; diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/domain/state/impl/RaceStateImpl.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/domain/state/impl/RaceStateImpl.java index ec817ccbaab..ddf29cf3d90 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/domain/state/impl/RaceStateImpl.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/domain/state/impl/RaceStateImpl.java @@ -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); diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/WindActivity.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/WindActivity.java index 6c0a1481de0..c07bd5882b6 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/WindActivity.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/WindActivity.java @@ -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); diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/dialogs/ClassicCourseDesignDialogFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/dialogs/ClassicCourseDesignDialogFragment.java index 76c80931d18..e918fdcca88 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/dialogs/ClassicCourseDesignDialogFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/dialogs/ClassicCourseDesignDialogFragment.java @@ -27,17 +27,17 @@ 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.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 +70,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 +95,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 +115,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 +129,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 +151,29 @@ 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(); + } + /* + * DataStore ds = InMemoryDataStore.INSTANCE; Toast.makeText( getActivity(), "" + ds.getLastWindPosition() + + * ds.getLastWindDirection() + ds.getLastWindSpeed() + selectedBoatClass + selectedCourseLayout + + * selectedNumberOfRounds + selectedTargetTime, Toast.LENGTH_LONG).show() + */; } private void setupBoatClassSpinner() { @@ -178,9 +184,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 +217,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 +237,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 +257,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 +273,6 @@ public class ClassicCourseDesignDialogFragment extends RaceDialogFragment { public void onResume() { super.onResume(); mMapView.onResume(); - setUpMap(); } @Override @@ -273,43 +289,41 @@ 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())); } + private LatLng position2LatLng(Position p) { + return new LatLng(p.getLatDeg(), p.getLngDeg()); + } + @Override public void onPause() { super.onPause();