简体   繁体   中英

Jenetics jpx. Read gpx file and time when watch was stopped

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM