Skip to content

Build1 publisher3 min readPublished

Checking spline error between samples put 82% of tracks outside their 10 m tolerance

Fitting cubic B-splines to 200 GeoLife tracks looked like a search-accuracy problem until a dense error check showed the fitter had only ever validated at sample points, and the corrected fitter still lost to Douglas-Peucker.

The Engineer · Build desk

Illustration accompanying Checking spline error between samples put 82% of tracks outside their 10 m tolerance

What happened

  • A first benchmark on 200 GeoLife tracks at a 10 m tolerance gave the cubic B-spline a Frechet recall of 0.707 against a Douglas-Peucker simplified polyline, so nearly a third of returned neighbours were wrong.
  • A dense check between samples found the fit broke its 10 m promise on 82% of tracks, by about 110 m for the median track and by kilometres for the worst.
  • On synthetic clothoid roads the spline looked 22% more compact at 1 m with no noise, until identical feasibility counts of 3/30, 25/30, 24/30 and 26/30 showed it was tethered to the polyline.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • constraint A simplified polyline satisfies its tolerance along the whole line by construction; a spline satisfies it only where the fitter checked, so anyone adopting splines owns a dense-grid validator and knot insertion in the write path.
  • decision For Frechet nearest-neighbour search on vehicle GPS at metre-scale tolerances, this evidence favours the simplified polyline, and the compactness case for splines only improves as the tolerance tightens toward 2 m.
  • capability Identical feasibility counts across two methods that should fail differently is a cheap coupling test, and it cost nothing here beyond reading the table column by column.
  • precedent The next proposal to store trajectories as splines has to show its error was measured between samples, because the first benchmark here compared a correct algorithm against a broken one.

Fit a cubic to a GPS track parametrised by time and nothing constrains the curve between two samples. The fitter's residual is evaluated where samples exist [5]. When the recorder drops out for a minute the curve crosses that gap on its own, and the post reports it drawing loops [8]. Douglas-Peucker cannot do that, because its simplified polyline satisfies the tolerance along the whole line by construction [9]. The correlations locate the cause: error tracks the longest gap between samples at r = 0.69, and spatial jumps at only 0.22 [7].

The author, who publishes as artsensiva, wrote the lesson as "verify a method's guarantee where the method is used, not where it's convenient to check" [10]. Two of the four comparisons described end by finding a bug in his own fitter [5][23].

Splitting at gaps over 30 s and at physically impossible speeds turned 200 files into 585 trips, about 2.9 per file [11][1]. With error checked on a dense grid and knots added where the tolerance broke, all 585 passed [12]. Recall went to 0.972 against Douglas-Peucker's 0.996, intervals not overlapping [13]. In miss rates that is 2.8% against 0.4%, so the corrected spline still returns about seven times as many wrong nearest neighbours [2]. The dense-grid fix bought roughly a tenfold cut in misses, from 29.3% to 2.8% [4]. For those recall figures to say anything about another store, the queries have to be Frechet nearest neighbour at a 10 m tolerance on tracks sampled densely enough that a 30 s split is the right cut [3][11].

The compactness test was set up against the harder opponent. Because the spline holds accuracy at every point in time, the fair baseline is the time-aware DP+SED, synchronized Euclidean distance [14]. The spline lost to that and to plain DP at every tolerance [15]. The narrowing gap, 3.4x at 50 m down to 1.4x at 2 m, is what approximation theory predicts for a polyline against a cubic on a smooth curve [15][16]. That pointed at clean, high-precision data as the place a spline might win, so the next run used synthetic roads made of straights, arcs and clothoids [17]. With zero noise the spline came out 22% more compact at a 1 m tolerance [18].

That 22% came from the sweep whose feasibility counts were suspicious. In every cell the share of tracks where a method could hit the tolerance at all was identical for spline and polyline: 3/30, 25/30, 24/30, 26/30 [19]. A 20 cm tolerance was unreachable almost everywhere even with no noise [20]. For a polyline that follows from the chord error L^2/8R, which the post puts at 1.7 m for 20 m/s on a 30 m radius [21]. Invert it and the chord is 20 m, so those samples sit about a second apart [3]. A cubic through exact samples should have tracked the arc to centimetres [22]. It could not, because the earlier fix tethered it to the straight segments joining the samples, and on clean data that tether obliged it to reproduce the polyline's error [23].

The second lesson in the post reads: "a fix that's correct in one experiment becomes a constraint in the next. Matching numbers across methods that should behave differently are almost always a signal." [24] The fifth experiment answers it with least squares straight on x(t) and y(t), no tethering, plus an oracle spline fitted to the true curve with no noise [25]. The published text breaks off mid-sentence there, before those numbers and before it identifies the by-product the author says was worth the trip: "along the road a different result appeared, and that one was probably worth the whole exercise" [27][26]. The code, the per-milestone reports and the decision history are public, under DOI 10.5281/zenodo.22850469 [2].

What to watch

  • Whether anyone reproduces the non-overlapping 0.972 versus 0.996 recall intervals from the published per-milestone reports.
  • Whether the recall gap survives on denser, more regular sampling, where splitting at 30 s gaps changes almost nothing.
  • Whether splitting trajectories at recording gaps becomes standard preprocessing for similarity search regardless of the stored representation.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories