From 060d39d5b0fd0ca8b1aaa11ad6201c05d491d292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sat, 21 Sep 2024 10:09:57 +0100 Subject: [PATCH] GpxParser: Parse heart rate --- .../gadgetbridge/util/gpx/GpxParser.java | 32 +++++++++++++++++- .../gadgetbridge/util/gpx/model/GpxFile.java | 11 +++++++ .../util/gpx/model/GpxTrackPoint.java | 33 +++++++++++++++++-- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/gpx/GpxParser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/gpx/GpxParser.java index f68bc9690..1ebda1043 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/gpx/GpxParser.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/gpx/GpxParser.java @@ -32,7 +32,6 @@ import java.io.InputStream; import java.text.ParsePosition; import java.util.Date; -import nodomain.freeyourgadget.gadgetbridge.model.GPSCoordinate; import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils; import nodomain.freeyourgadget.gadgetbridge.util.gpx.model.GpxFile; import nodomain.freeyourgadget.gadgetbridge.util.gpx.model.GpxTrack; @@ -211,6 +210,9 @@ public class GpxParser { case "time": trackPointBuilder.withTime(parseTime()); continue; + case "extensions": + parseExtensions(trackPointBuilder); + continue; } } @@ -220,6 +222,34 @@ public class GpxParser { return trackPointBuilder.build(); } + private void parseExtensions(final GpxTrackPoint.Builder trackPointBuilder) throws Exception { + while (eventType != XmlPullParser.END_TAG || !parser.getName().equals("extensions")) { + if (parser.getEventType() == XmlPullParser.START_TAG) { + switch (parser.getName()) { + case "gpxtpx:TrackPointExtension": + parseTrackPointExtensions(trackPointBuilder); + continue; + } + } + + eventType = parser.next(); + } + } + + private void parseTrackPointExtensions(final GpxTrackPoint.Builder trackPointBuilder) throws Exception { + while (eventType != XmlPullParser.END_TAG || !parser.getName().equals("gpxtpx:TrackPointExtension")) { + if (parser.getEventType() == XmlPullParser.START_TAG) { + switch (parser.getName()) { + case "gpxtpx:hr": + trackPointBuilder.withHeartRate(Integer.parseInt(parseStringContent("gpxtpx:hr"))); + continue; + } + } + + eventType = parser.next(); + } + } + private GpxWaypoint parseWaypoint() throws Exception { final GpxWaypoint.Builder waypointBuilder = new GpxWaypoint.Builder(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/gpx/model/GpxFile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/gpx/model/GpxFile.java index cc94b00b0..9099a5d80 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/gpx/model/GpxFile.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/gpx/model/GpxFile.java @@ -18,6 +18,9 @@ package nodomain.freeyourgadget.gadgetbridge.util.gpx.model; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; + +import nodomain.freeyourgadget.gadgetbridge.model.ActivityPoint; public class GpxFile { private final String name; @@ -61,6 +64,14 @@ public class GpxFile { return allPoints; } + public List getActivityPoints() { + return tracks.stream() + .flatMap(t -> t.getTrackSegments().stream()) + .flatMap(s -> s.getTrackPoints().stream()) + .map(GpxTrackPoint::toActivityPoint) + .collect(Collectors.toList()); + } + public static class Builder { private String name; private String author; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/gpx/model/GpxTrackPoint.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/gpx/model/GpxTrackPoint.java index 0aac5b4cc..9e746d56d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/gpx/model/GpxTrackPoint.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/gpx/model/GpxTrackPoint.java @@ -19,32 +19,53 @@ package nodomain.freeyourgadget.gadgetbridge.util.gpx.model; import java.util.Date; import java.util.Objects; +import nodomain.freeyourgadget.gadgetbridge.model.ActivityPoint; import nodomain.freeyourgadget.gadgetbridge.model.GPSCoordinate; public class GpxTrackPoint extends GPSCoordinate { private final Date time; + private final int heartRate; public GpxTrackPoint(final double longitude, final double latitude, final double altitude, final Date time) { + this(longitude, latitude, altitude, time, -1); + } + + public GpxTrackPoint(final double longitude, final double latitude, final double altitude, final Date time, final int heartRate) { super(longitude, latitude, altitude); this.time = time; + this.heartRate = heartRate; } public Date getTime() { return time; } + public int getHeartRate() { + return heartRate; + } + @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof GpxTrackPoint)) return false; if (!super.equals(o)) return false; final GpxTrackPoint that = (GpxTrackPoint) o; - return Objects.equals(time, that.time); + return Objects.equals(time, that.time) && + Objects.equals(heartRate, that.heartRate); } @Override public int hashCode() { - return Objects.hash(super.hashCode(), time); + return Objects.hash(super.hashCode(), time, heartRate); + } + + public ActivityPoint toActivityPoint() { + final ActivityPoint activityPoint = new ActivityPoint(); + activityPoint.setTime(time); + activityPoint.setLocation(this); + activityPoint.setHeartRate(heartRate); + + return activityPoint; } public static class Builder { @@ -52,6 +73,7 @@ public class GpxTrackPoint extends GPSCoordinate { private double latitude; private double altitude; private Date time; + private int heartRate; public Builder withLongitude(final double longitude) { this.longitude = longitude; @@ -73,8 +95,13 @@ public class GpxTrackPoint extends GPSCoordinate { return this; } + public Builder withHeartRate(final int heartRate) { + this.heartRate = heartRate; + return this; + } + public GpxTrackPoint build() { - return new GpxTrackPoint(longitude, latitude, altitude, time); + return new GpxTrackPoint(longitude, latitude, altitude, time, heartRate); } } }