# Simplify the straight sections of (multi)Linestring in PostgreSQL/PostGIS leaving the curved sections untouched

I have (multi)linestrings containing upwards of 5000 points and I want to perform two simplifications possibly using Ramer Douglas Peucker or alternative methods in PostGIS. The (multi)linestrings consist of straight lines, 90 degree curves, 180 degree curves and loops (circles).

I understand that `ST_simplify` may remove the loops and possibly some of the bends depending on the tolerance set. I need to have a zoomed out version which can probably be done satisfactorily done with `ST_simplify`. However, on the zoomed in version, it is important to keep the loops, and curve points.

I would like to remove all the points from the straight segments (within a tolerance) which constitute 90% of the (multi)linestring and keep the points on the curve section.

How can I achieve this in PostGIS?

• one solution is dump all linestrings , then calculate azimuth between start and n+1 points on line. When azimuth between start to 1, and start to x go over tolerance ,store line_id ,start ,x-1 point and repeat process from using x-1 as start to x-1. solution will be slow in db or in code if implementation dosen't manage linestrings as set (so no for loop over over linestring). Probably not smartest way to do it Feb 24, 2014 at 10:45
• Are you certain that ST_Simplify won't do what you want? With a tight tolerance, it'll strip out the redundant points in the straight parts while leaving the curvey parts untouched. The only time you'd have to worry about losing the curvey parts is if they are actually smaller than your tolerance, which is hard to picture. Feb 25, 2014 at 4:17
• It appears this question was abandoned after Paul's comment. It is also a bit broad without clear evidence of code. Oct 17, 2016 at 15:46
• @PaulRamsey ST_Simplify won't solve this, because every single LineString of a MultiLineString is considered its own entity when it comes to simplification. So if 2 adjacent LineStrings form another straight line, the midpoint won't be removed as that would in essence create an invalid line (with 1 point) Feb 22, 2017 at 7:28
• Run an ST_LineMerge on them first maybe? Feb 22, 2017 at 13:37

Use `ST_SetEffectiveArea` in conjunction with `ST_FilterByM` on the result of `ST_LineMerge`, e.g.:

``````SELECT  ST_AsText(
ST_FilterByM(
ST_SetEffectiveArea(
ST_LineMerge('MULTILINESTRING((0 0, 0 1), (0 1, 0 2), (0 2, 0 3), (0 3, 0 4), (0 4, 1 4), (1 4, 2 4), (2 4, 3 4))'::GEOMETRY)
),
0.0001
)
)
;

SELECT  ST_AsText(
ST_FilterByM(
ST_SetEffectiveArea(
ST_Buffer('POINT(0 0)'::GEOMETRY, 0.1)
),
0.0001
)
)
;
``````
• Not really sure how I ended up on this age old post...but since I was at it I thought I might just as well leave a solid solution... Nov 27, 2019 at 13:23

This is easily achievable by using ST_SimplifyVW which is available in PostGIS from version 2.2.0 If you chose small tolerance, then points forming straight (or nearly straight) lines will be removed. As a side-effect, it will remove also points forming small triangles, if their area will be within a specified tolerance, so be aware of it...