# [postgis-users] Reducing the number of points in a GPS track

Alexandre Saunier alexandre.saunier at camptocamp.com
Fri Nov 9 06:44:44 PST 2012

```Hi Birgit and Olivier,

thank you so much for your code and tips!

Birgit, your function works fine. I have made some small changes
though. For instance, I have added a "step" argument that allows to
easily adapt the value of the tolerance increment and avoid doing too
many iterations because of a too small step (in my project, using
"meter" as unit, 0.001 is a little too small, I have used a value of
1). Here is the function:

CREATE OR REPLACE FUNCTION simplify_npoints(inGeom geometry, maxPoints
integer, step float)
RETURNS geometry AS
\$BODY\$

DECLARE
tolerance float;
outGeom geometry;

BEGIN

outGeom := inGeom;
tolerance := step;

WHILE ST_NPoints(outGeom) > maxPoints LOOP
tolerance := tolerance + step;
outGeom := ST_Simplify(inGeom, tolerance);
END LOOP;

RETURN outGeom;

END;
\$BODY\$ LANGUAGE plpgsql IMMUTABLE;

> A way could be to :
>  - Compute length of your road with ST_Length
>  - Use ST_Line_Interpolate_Point to compute each point on your line
>  - Aggregate all points computed in a new simplified line with ST_MakeLine

Is it really necessary to compute the length of the road?
ST_Line_Interpolate_Point takes as second argument a float between 0
and 1 (percentage of the line length).
I have written a small function that picks a given number of
equidistant points on the line and then recreates a new line linking
those points:

CREATE OR REPLACE FUNCTION simplify_npoints(inGeom geometry, maxPoints
integer) RETURNS geometry AS \$\$

DECLARE
nPoints integer;
outGeom geometry;
fraction float;
points geometry[];
BEGIN

nPoints := ST_NPoints(inGeom);
outGeom := inGeom;

IF nPoints > maxPoints THEN
fraction := 1 / (maxPoints - 1);
FOR i IN 1..maxPoints LOOP
points := array_append(points, ST_Line_Interpolate_Point(inGeom,
(i - 1)*fraction));
END LOOP;

outGeom := ST_MakeLine(points);
END IF;

RETURN outGeom;

END;
\$\$ LANGUAGE plpgsql IMMUTABLE;

I have not really been able to test it because my version of PostGIS
is too old (1.3) and does not support arrays of geometry as argument
of ST_MakeLine.

Thanks again!
Alexandre

2012/10/25 Olivier Courtin <olivier.courtin at oslandia.com>:
>
> On Oct 24, 2012, at 2:29 PM, Alexandre Saunier wrote:
>
> Hi Alex,
>
>> A bit like the "simplify,count=<...>" filter in GPSBabel:
>> http://www.gpsbabel.org/htmldoc-development/filter_simplify.html
>>
>> Is there a way to do that kind of simplification with PostGIS?
>
> A way could be to :
>  - Compute length of your road with ST_Length
>  - Use ST_Line_Interpolate_Point to compute each point on your line
>  - Aggregate all points computed in a new simplified line with ST_MakeLine
>
> HTH,
>
> O.
>
> _______________________________________________
> postgis-users mailing list
> postgis-users at postgis.refractions.net
> http://postgis.refractions.net/mailman/listinfo/postgis-users
```

More information about the postgis-users mailing list