Use activity title from GPX file when present
This commit is contained in:
parent
6afd7a5dad
commit
d4427ebd85
3 changed files with 46 additions and 14 deletions
|
|
@ -378,10 +378,16 @@ public class ActivityFileService {
|
||||||
byte[] rawFile,
|
byte[] rawFile,
|
||||||
ProcessingOptions options
|
ProcessingOptions options
|
||||||
) throws JsonProcessingException {
|
) throws JsonProcessingException {
|
||||||
|
String activityTitle;
|
||||||
|
if (title != null && !title.isBlank()) {
|
||||||
|
activityTitle = title;
|
||||||
|
} else if (parsedData.getTitle() != null) {
|
||||||
|
// Try to use title from input file
|
||||||
|
activityTitle = parsedData.getTitle();
|
||||||
|
} else {
|
||||||
// Generate title if not provided
|
// Generate title if not provided
|
||||||
String activityTitle = title != null && !title.isBlank()
|
activityTitle = ActivityFormatter.generateActivityTitle(parsedData.getStartTime(), parsedData.getActivityType());
|
||||||
? title
|
}
|
||||||
: ActivityFormatter.generateActivityTitle(parsedData.getStartTime(), parsedData.getActivityType());
|
|
||||||
|
|
||||||
// Default to PUBLIC if visibility not specified
|
// Default to PUBLIC if visibility not specified
|
||||||
Activity.Visibility activityVisibility = visibility != null ? visibility : Activity.Visibility.PRIVATE;
|
Activity.Visibility activityVisibility = visibility != null ? visibility : Activity.Visibility.PRIVATE;
|
||||||
|
|
|
||||||
|
|
@ -80,8 +80,12 @@ public class GpxParser {
|
||||||
// Calculate duration
|
// Calculate duration
|
||||||
parsedData.setTotalDuration(Duration.between(firstPoint.getTimestamp(), lastPoint.getTimestamp()));
|
parsedData.setTotalDuration(Duration.between(firstPoint.getTimestamp(), lastPoint.getTimestamp()));
|
||||||
|
|
||||||
// Extract activity type from metadata
|
// Extract activity type and title from metadata
|
||||||
extractActivityType(doc, parsedData);
|
Optional<Element> track = getFirstTrack(doc);
|
||||||
|
if (track.isPresent()) {
|
||||||
|
extractActivityType(track.get(), parsedData);
|
||||||
|
extractActivityTitle(track.get(), parsedData);
|
||||||
|
}
|
||||||
|
|
||||||
// Determine timezone from first GPS coordinate
|
// Determine timezone from first GPS coordinate
|
||||||
determineTimezone(parsedData);
|
determineTimezone(parsedData);
|
||||||
|
|
@ -111,6 +115,8 @@ public class GpxParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts track points from GPX document.
|
* Extracts track points from GPX document.
|
||||||
*/
|
*/
|
||||||
|
|
@ -245,22 +251,41 @@ public class GpxParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Extracts activity type from GPX metadata.
|
* Returns the first <trk> element from the GPS XML
|
||||||
*/
|
*/
|
||||||
private void extractActivityType(Document doc, ParsedActivityData parsedData) {
|
private Optional<Element> getFirstTrack(Document doc) {
|
||||||
NodeList tracks = doc.getElementsByTagName("trk");
|
NodeList tracks = doc.getElementsByTagName("trk");
|
||||||
if (tracks.getLength() == 0) {
|
if (tracks.getLength() == 0) {
|
||||||
tracks = doc.getElementsByTagNameNS("*", "trk");
|
tracks = doc.getElementsByTagNameNS("*", "trk");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tracks.getLength() > 0) {
|
return tracks.getLength() > 0 ? Optional.of((Element) tracks.item(0)) : Optional.empty();
|
||||||
Element track = (Element) tracks.item(0);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts activity type from GPX metadata.
|
||||||
|
*/
|
||||||
|
private void extractActivityType(Element track, ParsedActivityData parsedData) {
|
||||||
String type = getElementText(track, "type");
|
String type = getElementText(track, "type");
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
parsedData.setActivityType(mapGpxTypeToActivityType(type));
|
parsedData.setActivityType(mapGpxTypeToActivityType(type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts activity title from GPX metadata.
|
||||||
|
*/
|
||||||
|
private void extractActivityTitle(Element track, ParsedActivityData parsedData) {
|
||||||
|
String title = getElementText(track, "name");
|
||||||
|
if (title != null) {
|
||||||
|
String shortenedTitle = title;
|
||||||
|
if (title.length() > 255) {
|
||||||
|
log.debug("Activity title was shortened to 255 characters: {}", title);
|
||||||
|
shortenedTitle = title.substring(0, 255);
|
||||||
|
}
|
||||||
|
parsedData.setTitle(shortenedTitle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ public class ParsedActivityData {
|
||||||
private BigDecimal elevationGain;
|
private BigDecimal elevationGain;
|
||||||
private BigDecimal elevationLoss;
|
private BigDecimal elevationLoss;
|
||||||
private Activity.ActivityType activityType = Activity.ActivityType.OTHER;
|
private Activity.ActivityType activityType = Activity.ActivityType.OTHER;
|
||||||
|
private String title;
|
||||||
private ActivityMetricsData metrics;
|
private ActivityMetricsData metrics;
|
||||||
private String sourceFormat; // "FIT" or "GPX"
|
private String sourceFormat; // "FIT" or "GPX"
|
||||||
private Boolean indoor = false; // Indicates if this is an indoor activity
|
private Boolean indoor = false; // Indicates if this is an indoor activity
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue