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

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.