diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/fixtracker/FixLoaderAndTracker.java b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/fixtracker/FixLoaderAndTracker.java index 107eb1aeae4..42bacca9cbb 100755 --- a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/fixtracker/FixLoaderAndTracker.java +++ b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/fixtracker/FixLoaderAndTracker.java @@ -1,5 +1,6 @@ package com.sap.sailing.domain.racelogtracking.impl.fixtracker; +import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; @@ -160,6 +161,51 @@ public class FixLoaderAndTracker implements TrackingDataLoader { startTracking(); } + private void loadFixesForNewMappings(List> mappings, WithID item) { + TimeRange trackingTimeRange = getTrackingTimeRange(); + if(item instanceof Mark) { + Mark mark = (Mark) item; + final boolean loadAllMappedFixes; + if(containsMappingThatIntersectsTimeRange(mappings, trackingTimeRange)) { + loadFixesInTimeRange(mappings, trackingTimeRange); + DynamicGPSFixTrack track = trackedRace.getOrCreateTrack(mark); + // load all mapped fixes if there was no fix in the tracking TimeRange + loadAllMappedFixes = (track.getFirstRawFix() == null); + } else { + // There is no mapping that intersects the tracking TimeRange at all + // Loading all mapped fixes instead + loadAllMappedFixes = true; + } + if(loadAllMappedFixes) { + // either got an empty track of there is no mapping for the TimeRange of the race at all. + // try again without constraining the mapping interval by start/end of tracking to at + // least attempt to get fixes at all in case there were any within the device mapping interval specified + mappings.forEach(mapping -> loadFixes(mapping.getTimeRange(), mapping)); + } + } else { + loadFixesInTimeRange(mappings, trackingTimeRange); + } + } + + private void loadFixesInTimeRange(List> mappings, TimeRange trackingTimeRange) { + mappings.forEach(mapping -> loadFixes(trackingTimeRange.intersection(mapping.getTimeRange()), mapping)); + } + + + /** + * Calls the given callback for every known mapping of the given item. + * + * @param callback the callback to call for every known mapping + */ + public boolean containsMappingThatIntersectsTimeRange(List> mappings, TimeRange timeRange) { + for (DeviceMappingWithRegattaLogEvent mapping : mappings) { + if(timeRange.intersects(mapping.getTimeRange())) { + return true; + } + } + return false; + } + private void loadFixes(TimeRange timeRangeToLoad, DeviceMappingWithRegattaLogEvent mapping) { if(timeRangeToLoad == null) { return; @@ -211,16 +257,8 @@ public class FixLoaderAndTracker implements TrackingDataLoader { try { @SuppressWarnings("unchecked") DeviceMapping markMapping = (DeviceMapping) mapping; + gpsFixStore.loadMarkTrack(track, markMapping, timeRangeToLoad.from(), timeRangeToLoad.to()); - if (track.getFirstRawFix() == null) { - logger.fine("Loading mark positions from outside of start/end of tracking interval (" + timeRangeToLoad.from() - + ".." + timeRangeToLoad.to() + ") because no fixes were found in that interval"); - // got an empty track for the mark; try again without constraining the mapping interval - // by start/end of tracking to at least attempt to get fixes at all in case there were any - // within the device mapping interval specified - gpsFixStore.loadMarkTrack(track, markMapping, /* startOfTimeWindowToLoad */ null, - /* endOfTimeWindowToLoad */ null); - } } catch (TransformationException | NoCorrespondingServiceRegisteredException e) { logger.log(Level.WARNING, "Could not load mark track " + mapping.getMappedTo()); } @@ -355,10 +393,10 @@ public class FixLoaderAndTracker implements TrackingDataLoader { } @Override - protected void mappingAdded(DeviceMappingWithRegattaLogEvent mapping) { + protected void mappingsAdded(List> mappings, WithID item) { // The listener is first added to not lose any fix after loading the initial fixes and adding the listener. - sensorFixStore.addListener(listener, mapping.getDevice()); - loadFixes(getTrackingTimeRange().intersection(mapping.getTimeRange()), mapping); + mappings.forEach(mapping -> sensorFixStore.addListener(listener, mapping.getDevice())); + loadFixesForNewMappings(mappings, item); } @Override diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/fixtracker/RegattaLogDeviceMappings.java b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/fixtracker/RegattaLogDeviceMappings.java index e61d9abd4a9..b5595afc217 100644 --- a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/fixtracker/RegattaLogDeviceMappings.java +++ b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/fixtracker/RegattaLogDeviceMappings.java @@ -277,15 +277,17 @@ public abstract class RegattaLogDeviceMappings { final List> oldMappings = previousMappings.containsKey(item) ? previousMappings.get(item) : Collections.emptyList(); + final List> addedMappings= new ArrayList<>(); for (DeviceMappingWithRegattaLogEvent newMapping : newMappings.get(item)) { DeviceMappingWithRegattaLogEvent oldMapping = findAndRemoveMapping(newMapping, oldMappings); if (oldMapping == null) { - mappingAddedInternal(newMapping); + addedMappings.add(newMapping); } else if (!newMapping.getTimeRange().equals(oldMapping.getTimeRange())) { mappingChangedInternal(oldMapping, newMapping); } } + mappingsAddedInternal(addedMappings, item); oldMappings.forEach(this::mappingRemovedInternal); } } @@ -310,12 +312,13 @@ public abstract class RegattaLogDeviceMappings { * Called when a {@link DeviceMapping} was added. * * @param mapping the new mapping + * @param item */ - protected abstract void mappingAdded(DeviceMappingWithRegattaLogEvent mapping); + protected abstract void mappingsAdded(List> mapping, ItemT item); - private void mappingAddedInternal(DeviceMappingWithRegattaLogEvent mapping) { + private void mappingsAddedInternal(List> mapping, ItemT item) { try { - mappingAdded(mapping); + mappingsAdded(mapping, item); } catch(Exception e) { logger.log(Level.SEVERE, "error while adding mapping " + mapping, e); }