I am using jenetics jpx to read GPX files in java. That's works well. The gpx files are taken from my watch, from running sessions. I am reading the track points and would like to know if there is a way to determine, in the GPX file, when the watch was stopped for a break. Ex: if I run for 15minutes then stop the watch for 5 minutes, then start it again and run for 15minutes the parsing of the gpx file will give me 35 minutes. But I want to record 30 minutes.
Do you know if it is possible to detect this?
If you pause your run, your watch should create a new track-segment, like
<trk>
<trkseg>
<trkpt lat="48.19949341" lon="16.40377444"></trkpt>
<trkpt lat="48.19948359" lon="16.40371021"></trkpt>
...
</trkseg>
<trkseg>
<trkpt lat="48.19949341" lon="16.40377444"></trkpt>
<trkpt lat="48.19948359" lon="16.40371021"></trkpt>
...
</trkseg>
</trk>
The JPX library lets you access the track-segments via Gpx -> getTracks -> getTrackSegments
. In your example your watch should have created one track with two track-segments. The track-segments will contain the track-points before and after the stop.
Update: TrackSegment collector
The following code lets you collect way-points into track-segments.
import static java.lang.String.format;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import io.jenetics.jpx.GPX;
import io.jenetics.jpx.Track;
import io.jenetics.jpx.TrackSegment;
import io.jenetics.jpx.WayPoint;
public final class TrackSegments {
private TrackSegments() {
}
/**
* Return a new collector, which collects a given way point list into a list
* of {@link TrackSegment}s. All way points without a timestamp are filtered
* out. A new segment is created if the timestamp of two consecutive points
* are greater than the give {@code maxGap} duration. Each segment will
* contain at least {@code minSegmentSize} points.
*
* @param maxGap the maximal allowed gap between two points within a
* track segment. If two points exceed the given gap, a new segment
* is created.
* @param minSegmentSize the minimal number of way points a segment must
* consist
* @return a new track segment collector
* @throws NullPointerException if the given {@code maxGap} is {@code null}
* @throws IllegalArgumentException if the {@code maxGap} or
* {@code minSegmentSize} is negative
*/
public static Collector<WayPoint, ?, List<TrackSegment>>
toTrackSegments(final Duration maxGap, final int minSegmentSize) {
if (maxGap.isNegative()) {
throw new IllegalArgumentException(format(
"The maximal allowed point gap must not be negative: %s",
maxGap
));
}
if (minSegmentSize < 1) {
throw new IllegalArgumentException(format(
"The minimal track segment size must be greater 0, but was %d.",
minSegmentSize
));
}
return Collectors.collectingAndThen(
Collectors.toList(),
points -> toTrackSegments(points, maxGap, minSegmentSize)
);
}
private static List<TrackSegment> toTrackSegments(
final List<WayPoint> points,
final Duration gap,
final int minSegmentSize
) {
final List<WayPoint> wps = points.stream()
.filter(wp -> wp.getTime().isPresent())
.toList();
if (wps.size() < minSegmentSize) {
return List.of();
}
final List<TrackSegment> segments = new ArrayList<>();
Instant last = wps.get(0).getTime().orElseThrow();
TrackSegment.Builder segment = TrackSegment.builder();
for (final WayPoint point : wps) {
final Instant zdt = point.getTime().orElseThrow();
if (last.plusNanos(gap.toNanos()).isAfter(zdt)) {
segment.addPoint(point);
} else {
if (segment.points().size() >= minSegmentSize) {
segments.add(segment.build());
}
segment = TrackSegment.builder();
}
last = zdt;
}
if (segment.points().size() >= minSegmentSize) {
segments.add(segment.build());
}
return segments;
}
public static void main(String[] args) throws IOException {
final GPX gpx = GPX.Reader.DEFAULT.read("some_file.gpx");
final Stream<WayPoint> points = gpx.tracks()
.flatMap(Track::segments)
.flatMap(TrackSegment::points);
final List<TrackSegment> segments = points
.collect(toTrackSegments(Duration.ofMinutes(1), 10));
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.