Add activity type and a click-to-open track profile panel
Track properties gain activity_type (FIT: sport enum from the session/sport message, Garmin's own table; GPX: <trk><type> passed through as-is) alongside the existing distance/elevation/duration. Clicking a track line now opens a bottom panel with a chart per metric the track actually has (elevation always; speed/cadence/heart rate only when present — FIT's record fields or GPX's device extensions). TrackStats.build_profile computes cumulative distance the same way for both formats so they're directly comparable. One pointermove listener drives a synchronized crosshair across every chart, a single tooltip listing all series, and a map marker at the hovered point's position — hovering the chart shows where on the track that moment was.
This commit is contained in:
1 parent
cd4eef342b
commit
105651f005
14 files changed
+655
-42
No files matched your search
@@ -23,11 +23,24 @@ class GpxTest < Minitest::Test
|
||||
assert_equal "MultiLineString", track["geometry"]["type"]
|
||||
assert_equal 3, track["geometry"]["coordinates"][0].size
|
||||
assert_equal "Morning Loop", track["properties"]["name"]
|
||||
assert_equal "running", track["properties"]["activity_type"]
|
||||
assert_operator track["properties"]["distance_meters"], :>, 0
|
||||
assert_equal 50.0, track["properties"]["elevation_gain_meters"], "200->250 is the only gain, 250->230 descent not subtracted"
|
||||
assert_equal 1200, track["properties"]["duration_secs"]
|
||||
end
|
||||
|
||||
def test_track_profile_carries_extension_fields_and_tolerates_points_without_them
|
||||
geojson = Maptool::Gpx.to_geojson(fixture_path("sample.gpx"))
|
||||
profile = geojson["features"].find { |f| f["properties"]["kind"] == "track" }["properties"]["profile"]
|
||||
|
||||
assert_equal 3, profile.size
|
||||
assert_equal 140, profile[0]["heart_rate_bpm"]
|
||||
assert_equal 84, profile[1]["cadence_rpm"]
|
||||
assert_nil profile[2]["heart_rate_bpm"], "third point has no <extensions>"
|
||||
assert_equal 0.0, profile[0]["distance_meters"]
|
||||
assert_equal [17.2, 48.1], [profile[0]["lon"], profile[0]["lat"]]
|
||||
end
|
||||
|
||||
def test_invalid_xml_raises_parse_error
|
||||
path = File.join(Dir.mktmpdir, "bad.gpx")
|
||||
File.write(path, "<gpx><trk unclosed>")
|
||||
|
||||
Reference in new issue
Block a user