Draw a LiveTrack session's planned course alongside the actual track
Garmin's own LiveTrack page already shows both when the activity was
started from a saved course — the session payload carries the course's
geoPoints right alongside the track points (LiveTrackClient found it
nested under the same React Query cache the session/points come from).
Rendered as a second, dashed LineString distinct from the actual
track's own line ("kind": "actual" vs "planned" on each GeoJSON
feature) — muted gray rather than matching Garmin's own purple-for-
planned, since this app's actual track is already purple and reusing
it would make the two indistinguishable.
This commit is contained in:
1 parent
8eada07869
commit
3106f8c103
4 files changed
+66
-21
No files matched your search
@@ -743,24 +743,36 @@ module Maptool
|
||||
halt 502, json(error: "track has no positions") if coordinates.empty?
|
||||
last = points.last
|
||||
|
||||
json(
|
||||
type: "FeatureCollection",
|
||||
features: [
|
||||
{ type: "Feature", geometry: { type: "LineString", coordinates: coordinates }, properties: {} },
|
||||
{
|
||||
type: "Feature",
|
||||
geometry: { type: "Point", coordinates: coordinates.last },
|
||||
# Merges the session summary in too — the point layer's hover
|
||||
# popup (public/js/livetrack.js) reads it straight off here
|
||||
# rather than needing a second fetch against /sessions.
|
||||
properties: summary.merge(
|
||||
"time" => last["dateTime"],
|
||||
"speed_meters_per_sec" => last["speedMetersPerSec"],
|
||||
"heart_rate_beats_per_min" => last["heartRateBeatsPerMin"]
|
||||
),
|
||||
},
|
||||
]
|
||||
)
|
||||
features = [
|
||||
{ type: "Feature", geometry: { type: "LineString", coordinates: coordinates }, properties: { "kind" => "actual" } },
|
||||
{
|
||||
type: "Feature",
|
||||
geometry: { type: "Point", coordinates: coordinates.last },
|
||||
# Merges the session summary in too — the point layer's hover
|
||||
# popup (public/js/livetrack.js) reads it straight off here
|
||||
# rather than needing a second fetch against /sessions.
|
||||
properties: summary.merge(
|
||||
"time" => last["dateTime"],
|
||||
"speed_meters_per_sec" => last["speedMetersPerSec"],
|
||||
"heart_rate_beats_per_min" => last["heartRateBeatsPerMin"]
|
||||
),
|
||||
},
|
||||
]
|
||||
|
||||
# Only present when the activity was started from a saved Garmin
|
||||
# course (see LiveTrackClient#fetch) — plotted separately from the
|
||||
# actual track ("kind" distinguishes the two LineStrings) since it's
|
||||
# the planned route, not where the person has actually been.
|
||||
course_coordinates = result.course&.[]("geoPoints")&.filter_map { |p| p.dig("position", "lon") && p.dig("position", "lat") && [p["position"]["lon"], p["position"]["lat"]] }
|
||||
if course_coordinates&.any?
|
||||
features << {
|
||||
type: "Feature",
|
||||
geometry: { type: "LineString", coordinates: course_coordinates },
|
||||
properties: { "kind" => "planned", "name" => result.course["name"] },
|
||||
}
|
||||
end
|
||||
|
||||
json(type: "FeatureCollection", features: features)
|
||||
end
|
||||
|
||||
get "/api/gnss/position" do
|
||||
|
||||
Reference in new issue
Block a user