package com.github.pfichtner.jrunalyser.base.data.segmenter; import java.util.List; import com.github.pfichtner.jrunalyser.base.data.LinkedTrackPoint; import com.github.pfichtner.jrunalyser.base.data.MathObject; import com.github.pfichtner.jrunalyser.base.data.segment.DefaultSegment; import com.github.pfichtner.jrunalyser.base.data.segment.Segment; import com.github.pfichtner.jrunalyser.base.data.stat.DefaultStatistics; import com.github.pfichtner.jrunalyser.base.data.track.DefaultTrack; import com.github.pfichtner.jrunalyser.base.data.track.Track; import com.google.common.base.Function; import com.google.common.collect.Lists; public class MathObjectSegmenter<T extends MathObject<T>> implements Segmenter { private final T targetValue; private final T zero; private final Function<LinkedTrackPoint, T> dataFunc; public MathObjectSegmenter(T targetValue, T zero, Function<LinkedTrackPoint, T> dataFunc) { this.targetValue = targetValue; this.zero = zero; this.dataFunc = dataFunc; } public Track segment(Track track) { // TODO We could compare if track's distance (or duration) < // targetValue, then we would have to do nothing List<? extends LinkedTrackPoint> trkpts = track.getTrackpoints(); List<Segment> result = Lists.newArrayList(); T actValue = this.zero; int start = 0; int end = 0; int maxEnd = trkpts.size() - 1; for (LinkedTrackPoint trkpt : trkpts) { end++; if (trkpt.getLink() != null) { T next = this.dataFunc.apply(trkpt); actValue = actValue.add(next); // create new segment if limit is reached (but a segment must // contain at least two trackpoints) if (actValue.compareTo(this.targetValue) >= 0 && end > start + 1 && end < maxEnd) { List<? extends LinkedTrackPoint> ntrkpt = trkpts.subList( start, end); result.add(new DefaultSegment(ntrkpt, DefaultStatistics .ofWaypoints(ntrkpt))); actValue = actValue.subtract(this.targetValue); start = end; } } } if (end > start) { List<? extends LinkedTrackPoint> ntrkpts = trkpts.subList(start, end); result.add(new DefaultSegment(ntrkpts, DefaultStatistics .ofWaypoints(ntrkpts))); } return new DefaultTrack(track.getId(), track.getMetadata(), track.getWaypoints(), result, track.getStatistics()); } }