tcxread 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/tcxread.rb +67 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e42a89981c1614dec069270cb1315ee64d0c6a172de5c44a5370b5f5c8bd584f
|
4
|
+
data.tar.gz: dcee18bb770a1aa020d5ad8f67370f775a6f8d25139c39eb8576e76c463c1efd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 72c0b8ba80f7cd524c91417123353e6d9523551050c513d55447ae1c6d73ff8add6af60cc6ec319d26af8aa237e7bcb40771f587653ffe92766f57be7d538194
|
7
|
+
data.tar.gz: 42a2ea64072c68e786e002a5dd0fa32c4547ac0503a4eb207537c3d9442148ca958fe9038b44b826033fa94ca4ddf80feaff92f8904745bfdad7aaba96c591ae
|
data/lib/tcxread.rb
CHANGED
@@ -4,16 +4,14 @@ require "nokogiri"
|
|
4
4
|
# workout data such as activities, laps, tracks, trackpoints, and integral metrics.
|
5
5
|
class TCXRead
|
6
6
|
attr_reader :total_distance_meters, :total_time_seconds, :total_calories,
|
7
|
-
:total_ascent, :total_descent, :max_altitude, :average_heart_rate
|
7
|
+
:total_ascent, :total_descent, :max_altitude, :average_heart_rate,
|
8
|
+
:max_watts, :average_watts, :average_cadence
|
8
9
|
|
9
|
-
# Initializes the TCXRead with the path to the TCX file.
|
10
|
-
#
|
11
|
-
# @param file_path [String] the path to the TCX file.
|
12
10
|
def initialize(file_path)
|
13
11
|
@file_path = file_path
|
14
12
|
@doc = Nokogiri::XML(File.open(file_path))
|
13
|
+
@doc.root.add_namespace_definition('ns3', 'http://www.garmin.com/xmlschemas/ActivityExtension/v2')
|
15
14
|
|
16
|
-
# Init the properties
|
17
15
|
@total_distance_meters = 0
|
18
16
|
@total_time_seconds = 0
|
19
17
|
@total_calories = 0
|
@@ -21,6 +19,10 @@ class TCXRead
|
|
21
19
|
@total_descent = 0
|
22
20
|
@max_altitude = 0
|
23
21
|
@average_heart_rate = 0
|
22
|
+
# use NA if no watts exist in the TCX file
|
23
|
+
@max_watts = 'NA'
|
24
|
+
@average_watts = 'NA'
|
25
|
+
@average_cadence = 0
|
24
26
|
|
25
27
|
parse
|
26
28
|
end
|
@@ -36,6 +38,8 @@ class TCXRead
|
|
36
38
|
@total_calories = activities.sum { |activity| activity[:total_calories] }
|
37
39
|
@total_ascent, @total_descent, @max_altitude = calculate_ascent_descent_and_max_altitude_from_activities(activities)
|
38
40
|
@average_heart_rate = calculate_average_heart_rate_from_activities(activities)
|
41
|
+
@max_watts, @average_watts = calculate_watts_from_activities(activities)
|
42
|
+
@average_cadence = calculate_average_cadence_from_activities(activities)
|
39
43
|
end
|
40
44
|
|
41
45
|
{ activities: activities }
|
@@ -112,7 +116,8 @@ class TCXRead
|
|
112
116
|
distance_meters: trackpoint.xpath('xmlns:DistanceMeters').text.to_f,
|
113
117
|
heart_rate: trackpoint.xpath('xmlns:HeartRateBpm/xmlns:Value').text.to_i,
|
114
118
|
cadence: trackpoint.xpath('xmlns:Cadence').text.to_i,
|
115
|
-
sensor_state: trackpoint.xpath('xmlns:SensorState').text
|
119
|
+
sensor_state: trackpoint.xpath('xmlns:SensorState').text,
|
120
|
+
watts: trackpoint.xpath('xmlns:Extensions/ns3:TPX/ns3:Watts').text.to_f
|
116
121
|
}
|
117
122
|
end
|
118
123
|
tracks << trackpoints
|
@@ -226,4 +231,60 @@ class TCXRead
|
|
226
231
|
|
227
232
|
heart_rate_count > 0 ? total_heart_rate.to_f / heart_rate_count : 0.0
|
228
233
|
end
|
234
|
+
|
235
|
+
# Calculates the maximum and average watts from the activities.
|
236
|
+
#
|
237
|
+
# @param activities [Array<Hash>] an array of activity hashes.
|
238
|
+
# @return [Array<Float, Float>] an array containing maximum watts and average watts. Returns 'NA' for both if no watts data is available.
|
239
|
+
def calculate_watts_from_activities(activities)
|
240
|
+
max_watts = 0
|
241
|
+
total_watts = 0
|
242
|
+
watts_count = 0
|
243
|
+
|
244
|
+
activities.each do |activity|
|
245
|
+
activity[:laps].each do |lap|
|
246
|
+
lap[:tracks].flatten.each do |trackpoint|
|
247
|
+
watts = trackpoint[:watts]
|
248
|
+
if watts > 0
|
249
|
+
total_watts += watts
|
250
|
+
watts_count += 1
|
251
|
+
max_watts = watts if watts > max_watts
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
if watts_count > 0
|
258
|
+
average_watts = total_watts.to_f / watts_count
|
259
|
+
max_watts = max_watts
|
260
|
+
else
|
261
|
+
average_watts = 'NA'
|
262
|
+
max_watts = 'NA'
|
263
|
+
end
|
264
|
+
|
265
|
+
[max_watts, average_watts]
|
266
|
+
end
|
267
|
+
|
268
|
+
# Calculates the average cadence from the activities.
|
269
|
+
#
|
270
|
+
# @param activities [Array<Hash>] an array of activity hashes.
|
271
|
+
# @return [Float] the average cadence.
|
272
|
+
def calculate_average_cadence_from_activities(activities)
|
273
|
+
total_cadence = 0
|
274
|
+
cadence_count = 0
|
275
|
+
|
276
|
+
activities.each do |activity|
|
277
|
+
activity[:laps].each do |lap|
|
278
|
+
lap[:tracks].flatten.each do |trackpoint|
|
279
|
+
cadence = trackpoint[:cadence]
|
280
|
+
if cadence > 0
|
281
|
+
total_cadence += cadence
|
282
|
+
cadence_count += 1
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
cadence_count > 0 ? total_cadence.to_f / cadence_count : 0.0
|
289
|
+
end
|
229
290
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tcxread
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- firefly-cpp
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-07-
|
11
|
+
date: 2024-07-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|