mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-26 23:46:36 +00:00
Moved calculation of the start and finish for a tracked race to the sailing service
This commit is contained in:
-71
@@ -1,71 +0,0 @@
|
||||
package com.sap.sailing.domain.test;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.Buoy;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Placemark;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
import com.sap.sailing.domain.tracking.impl.GPSFixImpl;
|
||||
import com.sap.sailing.domain.tractracadapter.ReceiverType;
|
||||
|
||||
public class LongRangeRegattaGeocoderTest extends AbstractManeuverDetectionTestCase {
|
||||
|
||||
public LongRangeRegattaGeocoderTest() throws MalformedURLException, URISyntaxException {
|
||||
super();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws URISyntaxException, IOException, InterruptedException {
|
||||
super.setUp();
|
||||
super.setUp("event_20110609_KielerWoch",
|
||||
/* raceId */"357c700a-9d9a-11e0-85be-406186cbf87c", new ReceiverType[] { ReceiverType.MARKPASSINGS,
|
||||
ReceiverType.RACESTARTFINISH, ReceiverType.RACECOURSE });
|
||||
fixApproximateMarkPositionsForGeocoder(getTrackedRace());
|
||||
dateFormat = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
|
||||
}
|
||||
|
||||
private void fixApproximateMarkPositionsForGeocoder(DynamicTrackedRace race) {
|
||||
TimePoint epoch = new MillisecondsTimePoint(0l);
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
Map<String, Position> buoyPositions = new HashMap<String, Position>();
|
||||
buoyPositions.put("K Start (left)", new DegreePosition(5.90906782829855, -55.16166687011719));
|
||||
buoyPositions.put("K Start (right)", new DegreePosition(5.939801840526332, -55.17402648925781));
|
||||
buoyPositions.put("K Mark1", new DegreePosition(8.233237111274565, -31.640625));
|
||||
buoyPositions.put("K Mark4 (right)", new DegreePosition(13.63083009512624, -21.8243408203125));
|
||||
buoyPositions.put("K Mark4 (left)", new DegreePosition(13.870080100685891, -21.9122314453125));
|
||||
buoyPositions.put("K Finish (left)", new DegreePosition(14.694198629294522, -17.39307403564453));
|
||||
buoyPositions.put("K Finish (right)", new DegreePosition(14.693866535193942, -17.371788024902344));
|
||||
for (Waypoint w : race.getRace().getCourse().getWaypoints()) {
|
||||
for (Buoy buoy : w.getBuoys()) {
|
||||
race.getOrCreateTrack(buoy).addGPSFix(new GPSFixImpl(buoyPositions.get(buoy.getName()), epoch));
|
||||
race.getOrCreateTrack(buoy).addGPSFix(new GPSFixImpl(buoyPositions.get(buoy.getName()), now));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetupOK() throws ParseException, NoWindException {
|
||||
assertNotNull(getTrackedRace());
|
||||
Pair<Placemark, Placemark> placemarks = getTrackedRace().getStartFinishPlacemarks();
|
||||
assertNotNull(placemarks.getA());
|
||||
assertNotNull(placemarks.getB());
|
||||
}
|
||||
}
|
||||
-7
@@ -12,7 +12,6 @@ import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Placemark;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
@@ -421,12 +420,6 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<Placemark, Placemark> getStartFinishPlacemarks() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceIdentifier getRaceIdentifier() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
@@ -45,12 +45,6 @@ public interface TrackedRace {
|
||||
|
||||
RaceIdentifier getRaceIdentifier();
|
||||
|
||||
/**
|
||||
* @return A pair of placemarks, where A is the start placemark and B is the finish placemark.<br />
|
||||
* The returning pair is never <code>null</code>, but A and/or B can be <code>null</code>.
|
||||
*/
|
||||
Pair<Placemark, Placemark> getStartFinishPlacemarks();
|
||||
|
||||
/**
|
||||
* Computes the estimated start time for this race (not to be confused with the {@link #getStartOfTracking()} time point
|
||||
* which is expected to be before the race start time). When there are no {@link MarkPassing}s for the first mark, <code>null</code>
|
||||
|
||||
-74
@@ -1,6 +1,5 @@
|
||||
package com.sap.sailing.domain.tracking.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -18,8 +17,6 @@ import java.util.concurrent.ConcurrentSkipListSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import com.sap.sailing.domain.base.BearingWithConfidence;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Buoy;
|
||||
@@ -43,7 +40,6 @@ import com.sap.sailing.domain.common.LegType;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.NoWindError;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Placemark;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
@@ -74,19 +70,12 @@ import com.sap.sailing.domain.tracking.Wind;
|
||||
import com.sap.sailing.domain.tracking.WindStore;
|
||||
import com.sap.sailing.domain.tracking.WindTrack;
|
||||
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
||||
import com.sap.sailing.geocoding.ReverseGeocoder;
|
||||
|
||||
public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
|
||||
private static final Logger logger = Logger.getLogger(TrackedRaceImpl.class.getName());
|
||||
|
||||
private static final double PENALTY_CIRCLE_DEGREES_THRESHOLD = 320;
|
||||
|
||||
/**
|
||||
* Used in {@link #getStartFinishPlacemarks()} to calculate the radius for the
|
||||
* {@link ReverseGeocoder#getPlacemarksNear(Position, double) GetPlacemarksNear-Service}.
|
||||
*/
|
||||
private static final double GEONAMES_RADIUS_CACLCULATION_FACTOR = 10.0;
|
||||
|
||||
// TODO make this variable
|
||||
private static final long DELAY_FOR_CACHE_CLEARING_IN_MILLISECONDS = 7500;
|
||||
|
||||
@@ -1431,69 +1420,6 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<Placemark, Placemark> getStartFinishPlacemarks() {
|
||||
Pair<Placemark, Placemark> placemarks = new Pair<Placemark, Placemark>(null, null);
|
||||
Placemark startBest = null;
|
||||
Placemark finishBest = null;
|
||||
|
||||
// Get start postition
|
||||
Iterator<Buoy> startBuoys = getRace().getCourse().getFirstWaypoint().getBuoys().iterator();
|
||||
GPSFix startBuoyFix = startBuoys.hasNext() ? getOrCreateTrack(startBuoys.next()).getLastRawFix() : null;
|
||||
Position startPosition = startBuoyFix != null ? startBuoyFix.getPosition() : null;
|
||||
if (startPosition != null) {
|
||||
try {
|
||||
// Get distance to nearest placemark and calculate the search radius
|
||||
Placemark startNearest = ReverseGeocoder.INSTANCE.getPlacemarkNearest(startPosition);
|
||||
if (startNearest != null) {
|
||||
Distance startNearestDistance = startNearest.distanceFrom(startPosition);
|
||||
double startRadius = startNearestDistance.getKilometers() * GEONAMES_RADIUS_CACLCULATION_FACTOR;
|
||||
|
||||
// Get the estimated best start place
|
||||
startBest = ReverseGeocoder.INSTANCE.getPlacemarkLast(startPosition, startRadius,
|
||||
new Placemark.ByPopulationDistanceRatio(startPosition));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.throwing(TrackedRaceImpl.class.getName(), "getPlaceOrder()", e);
|
||||
} catch (ParseException e) {
|
||||
logger.throwing(TrackedRaceImpl.class.getName(), "getPlaceOrder()", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Get finish position
|
||||
Iterator<Buoy> finishBuoys = getRace().getCourse().getFirstWaypoint().getBuoys().iterator();
|
||||
GPSFix finishBuoyFix = finishBuoys.hasNext() ? getOrCreateTrack(finishBuoys.next()).getLastRawFix() : null;
|
||||
Position finishPosition = finishBuoyFix != null ? finishBuoyFix.getPosition() : null;
|
||||
if (startPosition != null && finishPosition != null) {
|
||||
if (startPosition.getDistance(finishPosition).getKilometers() <= ReverseGeocoder.POSITION_CACHE_DISTANCE_LIMIT_IN_KM) {
|
||||
finishBest = startBest;
|
||||
} else {
|
||||
try {
|
||||
// Get distance to nearest placemark and calculate the search radius
|
||||
Placemark finishNearest = ReverseGeocoder.INSTANCE.getPlacemarkNearest(finishPosition);
|
||||
Distance finishNearestDistance = finishNearest.distanceFrom(finishPosition);
|
||||
double finishRadius = finishNearestDistance.getKilometers() * GEONAMES_RADIUS_CACLCULATION_FACTOR;
|
||||
|
||||
// Get the estimated best finish place
|
||||
finishBest = ReverseGeocoder.INSTANCE.getPlacemarkLast(finishPosition, finishRadius,
|
||||
new Placemark.ByPopulationDistanceRatio(finishPosition));
|
||||
} catch (IOException e) {
|
||||
logger.throwing(TrackedRaceImpl.class.getName(), "getPlaceOrder()", e);
|
||||
} catch (ParseException e) {
|
||||
logger.throwing(TrackedRaceImpl.class.getName(), "getPlaceOrder()", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (startBest != null) {
|
||||
placemarks.setA(startBest);
|
||||
}
|
||||
if (finishBest != null) {
|
||||
placemarks.setB(finishBest);
|
||||
}
|
||||
return placemarks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint)
|
||||
throws NoWindException {
|
||||
|
||||
@@ -16,7 +16,8 @@ Require-Bundle: com.sap.sailing.domain,
|
||||
com.sap.sailing.domain.tractracadapter.persistence,
|
||||
com.google.gwt.osgi;bundle-version="2.4.0",
|
||||
com.sap.sailing.domain.common,
|
||||
org.moxieapps.gwt.highcharts;bundle-version="1.1.4"
|
||||
org.moxieapps.gwt.highcharts;bundle-version="1.1.4",
|
||||
com.sap.sailing.geocoding
|
||||
Bundle-Activator: com.sap.sailing.gwt.ui.server.Activator
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.sap.sailing.gwt.ui.client;x-friends:="com.sap.sailing.gwt.ui.test",
|
||||
|
||||
+66
-1
@@ -100,10 +100,12 @@ import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
import com.sap.sailing.domain.tracking.WindTrack;
|
||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.WindImpl;
|
||||
import com.sap.sailing.domain.tractracadapter.DomainFactory;
|
||||
import com.sap.sailing.domain.tractracadapter.RaceRecord;
|
||||
import com.sap.sailing.domain.tractracadapter.TracTracConfiguration;
|
||||
import com.sap.sailing.geocoding.ReverseGeocoder;
|
||||
import com.sap.sailing.gwt.ui.client.SailingService;
|
||||
import com.sap.sailing.gwt.ui.shared.BoatClassDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.CompetitorDTO;
|
||||
@@ -1211,7 +1213,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
|
||||
if (withAdditionalData) {
|
||||
//Getting the places of the race
|
||||
Pair<Placemark, Placemark> startAndFinish = trackedRace.getStartFinishPlacemarks();
|
||||
Pair<Placemark, Placemark> startAndFinish = getStartFinishPlacemarksForTrackedRace(trackedRace);
|
||||
PlacemarkOrderDTO racePlaces = new PlacemarkOrderDTO();
|
||||
if (startAndFinish.getA() != null) {
|
||||
racePlaces.getPlacemarks().add(convertToPlacemarkDTO(startAndFinish.getA()));
|
||||
@@ -1237,6 +1239,69 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
return dto;
|
||||
}
|
||||
|
||||
private Pair<Placemark, Placemark> getStartFinishPlacemarksForTrackedRace(TrackedRace race) {
|
||||
double radiusCalculationFactor = 10.0;
|
||||
Pair<Placemark, Placemark> placemarks = new Pair<Placemark, Placemark>(null, null);
|
||||
Placemark startBest = null;
|
||||
Placemark finishBest = null;
|
||||
|
||||
// Get start postition
|
||||
Iterator<Buoy> startBuoys = race.getRace().getCourse().getFirstWaypoint().getBuoys().iterator();
|
||||
GPSFix startBuoyFix = startBuoys.hasNext() ? race.getOrCreateTrack(startBuoys.next()).getLastRawFix() : null;
|
||||
Position startPosition = startBuoyFix != null ? startBuoyFix.getPosition() : null;
|
||||
if (startPosition != null) {
|
||||
try {
|
||||
// Get distance to nearest placemark and calculate the search radius
|
||||
Placemark startNearest = ReverseGeocoder.INSTANCE.getPlacemarkNearest(startPosition);
|
||||
if (startNearest != null) {
|
||||
Distance startNearestDistance = startNearest.distanceFrom(startPosition);
|
||||
double startRadius = startNearestDistance.getKilometers() * radiusCalculationFactor;
|
||||
|
||||
// Get the estimated best start place
|
||||
startBest = ReverseGeocoder.INSTANCE.getPlacemarkLast(startPosition, startRadius,
|
||||
new Placemark.ByPopulationDistanceRatio(startPosition));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.throwing(TrackedRaceImpl.class.getName(), "getPlaceOrder()", e);
|
||||
} catch (org.json.simple.parser.ParseException e) {
|
||||
logger.throwing(TrackedRaceImpl.class.getName(), "getPlaceOrder()", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Get finish position
|
||||
Iterator<Buoy> finishBuoys = race.getRace().getCourse().getFirstWaypoint().getBuoys().iterator();
|
||||
GPSFix finishBuoyFix = finishBuoys.hasNext() ? race.getOrCreateTrack(finishBuoys.next()).getLastRawFix() : null;
|
||||
Position finishPosition = finishBuoyFix != null ? finishBuoyFix.getPosition() : null;
|
||||
if (startPosition != null && finishPosition != null) {
|
||||
if (startPosition.getDistance(finishPosition).getKilometers() <= ReverseGeocoder.POSITION_CACHE_DISTANCE_LIMIT_IN_KM) {
|
||||
finishBest = startBest;
|
||||
} else {
|
||||
try {
|
||||
// Get distance to nearest placemark and calculate the search radius
|
||||
Placemark finishNearest = ReverseGeocoder.INSTANCE.getPlacemarkNearest(finishPosition);
|
||||
Distance finishNearestDistance = finishNearest.distanceFrom(finishPosition);
|
||||
double finishRadius = finishNearestDistance.getKilometers() * radiusCalculationFactor;
|
||||
|
||||
// Get the estimated best finish place
|
||||
finishBest = ReverseGeocoder.INSTANCE.getPlacemarkLast(finishPosition, finishRadius,
|
||||
new Placemark.ByPopulationDistanceRatio(finishPosition));
|
||||
} catch (IOException e) {
|
||||
logger.throwing(TrackedRaceImpl.class.getName(), "getPlaceOrder()", e);
|
||||
} catch (org.json.simple.parser.ParseException e) {
|
||||
logger.throwing(TrackedRaceImpl.class.getName(), "getPlaceOrder()", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (startBest != null) {
|
||||
placemarks.setA(startBest);
|
||||
}
|
||||
if (finishBest != null) {
|
||||
placemarks.setB(finishBest);
|
||||
}
|
||||
return placemarks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLeaderboard(String leaderboardName, String newLeaderboardName, int[] newDiscardingThreasholds) {
|
||||
if (!leaderboardName.equals(newLeaderboardName)) {
|
||||
|
||||
Reference in New Issue
Block a user