I try to buffer a huge road network using ST_Buffer. After 8h of processing I get an error message:

ERROR: GEOSBuffer: TopologyException: No forward edges found in buffer subgraph

Here is my query (adapted from: memory issue when trying to buffer/union large dataset using postgis):

CREATE TABLE Nebenstrassen050 ("geom" geometry(multipolygon,3857), gid serial primary key);

WITH ordered AS (
  SELECT wkb_geometry AS geom
  FROM Nebenstrassen
  ORDER BY ST_GeoHash(st_transform(wkb_geometry,4326))
grouped AS (
  SELECT nextval('bseq') / 100000 AS id, ST_Buffer(ST_Collect(ST_MakeValid(geom)),50) AS geom
  FROM ordered
groupedfinal AS (
  SELECT (ST_Dump(ST_Union(geom))).geom AS geom
  FROM grouped
INSERT INTO Nebenstrassen050 SELECT * FROM groupedfinal;

I tried to implement ST_MakeValid to avoid this error but it doesn’t show any effect. I’ working on a Win7 64bit machine with Postgres 9.3 and PostGIS 2.1. Any Ideas?


Why grouped collects and buffers geom by id , and then in groupedfinal unions all geoms and the dumps them ? I would do just this:

      select ST_Buffer(geom , 50) as geom, ST_GeoHash(st_transform(wkb_geometry,4326)) as hash into Nebenstrassen050 from FROM Nebenstrassen ;
ALTER table Nebenstrassen050 add gid serial ;

Now every geom is buffered by 50, after this you can union (dissolve boundaries) on polygon depending your needs. Your query probably fails on last groupedfinal where you try union all geometries and then dump, if your road network is big and its build correctly you will get 1 or 2 huge polygons spanning whole area which is filled with holes if your roads tend to be more than 100m from each other.

So actually this answer should be question : what you try to do ? get all "holes" on area which are not in 50m from road or something else ?

  • If you collect the geom first the buffers are dissolved and its much faster than buffer first and union later. The geohash is just used to run the querry sequentialy to avoid memory overload. – Julian Jun 11 '14 at 14:49
  • Dismiss the last union helps to avoid the error, but i didn't understad why... – Julian Jun 12 '14 at 7:22
  • see @Paul Ramsey answer. I still have question why you need polygons. If you do something like: is point near some road then st_dwithin is "faster" solution than st_intersects over big table filled with polygons... – simplexio Jun 12 '14 at 7:34
  • I'm mapping suitable sites for wind farms in Germany, therefore I have to know which areas are restricted. I have to keep a security distance to roads for instance. But this distance is varying over the regions. The Idea is to preprocess polygons with a couple of distances for the whole area to make it possible to select what’s necessary in a specific case and to visualize it on a map. – Julian Jun 12 '14 at 8:09
  • interesting. geospatialelucubrations.blogspot.ca/2014/05/… may be helpful if you really need to get polygon count down and you like working with rasters – simplexio Jun 12 '14 at 8:28

One of the collections is somehow confusing the buffer routine. So, first create a table of collections, then bisect the table (test the first half and the last half to find what half the bad collection is in, then test the first and last half of that half, etc, etc) to find the degenerate collection.

Simply changing the size of your grouping (change 100000 to 10000 perhaps) might help, but that's a guess. Simple testing of the buffer function doesn't seem to indicate that zero-length lines or empty lines cause errors, so probably it's just a particular combination of geometry in one of the collections. You could try running a very light ST_SnapToGrid to move the vertices around a little, which might resolve the error.

Sorry no definitive solution, it's a topology failure in the overlay code, which generally is a coordinate precision issue, and just shaking things up a bit can make (apparently nonsensical) differences.

  • The error occours seldom even without the last union, in this case it helps to vary the size of grouping. – Julian Jun 12 '14 at 9:44

I found myself in a similar situation. I was merging incomplete road networks from different sources by making a small buffer of the main network in order to identify roads from the 2nd network far enough to be different roads (Haussdorf distance wasn't working for me to filter similarities).

To solve the "no forward edges" problem I made a script in plpgsql to evaluate every road from the second network individually using only the roads from the 1st network with bounding boxes intersecting the box of the road in turn. Also, this was, obviously, much faster.

So, I believe the problem has more to do with the size of the data set than with inherent problems.

DO $$
DECLARE tupla record; filtrado record;
    FOR tupla IN SELECT * FROM caminos_topo_20 LOOP
    WITH buffer_temp AS (SELECT st_buffer(st_collect(geom),15) geom, st_collect(geom) snapea FROM vial_mixto WHERE vial_mixto.geom&&tupla.geom)
        INSERT INTO vial_mixto(geom) SELECT st_multi(st_snap(st_difference(tupla.geom,st_intersection(tupla.geom,buffer_temp.geom)),buffer_temp.snapea,15)) FROM buffer_temp WHERE st_covers(buffer_temp.geom,tupla.geom)=false;
END $$
LANGUAGE 'plpgsql';

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.