TraceCodec

object TraceCodec

Read and write recorded GPS traces, so a real drive becomes a regression test.

Every claim about a mileage algorithm — "this is more accurate", "this threshold helps", "the new version didn't regress" — is unfalsifiable until the same drive can be replayed through two algorithms and the numbers compared. A recorded trace plus a trusted reference distance is the only thing that turns tuning from taste into measurement.

Why CSV and not JSON. :location has zero dependencies, and it must stay that way to keep compiling for wasmJs. That leaves hand-rolling a parser, and a hand-rolled JSON parser is a genuine source of bugs for no benefit here: a GPS trace is a table. CSV is a few lines of split, trivially diffable in git, and openable in any spreadsheet when someone wants to eyeball a bad drive. If richer structure is ever needed, serialize at the app edge where dependencies are allowed.

ponytail: positional columns with a header line, no quoting or escaping support. Fields are numbers, a boolean and a short provider token — none of which contain commas. If a provider name ever does, quote it at the source; do not grow a CSV dialect in here.

Properties

Link copied to clipboard
const val HEADER: String

Functions

Link copied to clipboard
fun decode(line: String, lineNumber: Int = -1): Fix

Parse one CSV row into a Fix, or throw with the line number and the offending text.

Link copied to clipboard
fun decodeAll(text: String): List<Fix>

Parse a whole file. Blank lines, # comments and a leading header row are skipped.

Link copied to clipboard
fun encode(fix: Fix): String

Serialize one fix. Absent optional values are written as empty fields, not as 0, because "no speed reported" and "stationary" are different facts and conflating them silently changes how a jitter gate behaves.

Link copied to clipboard
fun encodeAll(fixes: List<Fix>): String