Re: [postgis-users] Odd st_buffer behaviour
Also in your small code snippet you did't ensure that all your line where simple linestring (and not multilinestring). Just to be sure : SELECT COUNT(*) FROM ukrds WHERE ST_IsSimple(geom)=FALSE Cheers, Rémi 2013/11/25 James David Smith james.david.sm...@gmail.com Steve, Thanks, you are of course right. I hadn't thought of that. Makes sense. James On 25 November 2013 17:58, Stephen Woodbridge wood...@swoodbridge.com wrote: This is because lines shaped like say an Omega character, will create an island inside the character at a certain offset and this can not be represented as a simple polygon. Well maybe it can but the algorithm probably does not try to reduce them to their most simple features. While the lines may not intersect, the offset lines may intersect and it is a function of how these are dealt with. -Steve On 11/25/2013 12:49 PM, James David Smith wrote: Hi Remi/all, I realise I'm digressing slightly from the point, but this seems related. This seems strange to me: I check the geometry type of a table of what I think are linestrings (roads): ukroads=# SELECT COUNT(*), geometrytype(geom) FROM ukrds GROUP BY geometrytype(geom); 395356 | LINESTRING Great. They are all linestrings. Now I check that none of them are self-intersecting: ukroads=# SELECT COUNT(*), st_issimple(geom) FROM ukrds GROUP BY st_issimple(geom); 395356 | t Ok. That's fine. They are all ok. Now I check that they are all valid: ukroads=# SELECT COUNT(*), st_isvalid(geom) FROM ukrds GROUP BY st_isvalid(geom); 395356 | t So now I buffer them all by 1000 metres wanting to make a polygon out of each line: ukroads=# SELECT COUNT(a.*), geometrytype(a.the_geom) FROM (SELECT st_buffer(geom,1000) as the_geom FROM ukrds) AS a GROUP BY geometrytype(a.the_geom); 392255 | POLYGON 3101 | MULTIPOLYGON However I am returned with 3101 multipolygons (and the rest polygons). Why is that? Should they not all be polygons? Why do some of them become a multipolygon? Thanks James On 25 November 2013 17:25, Rémi Cura remi.c...@gmail.com wrote: You could use the default ending (which is well defined), then split the resulting with the line like endcap=flat (easy to build, translate endpoint by radius and -radius in normal direction) I still fail to understand why you would need this kind of ending. Cheers, Rémi C 2013/11/25 Rémi Cura remi.c...@gmail.com Does offset curve gives the same result? (seems lile offsetting both side have same behavior) Maybe you can try several buffers with increasing size? (default appears wau before 1000) Also, can you try to simplify your line : each coordinates uses 15 digits, surely you don't need all of this ! (simplifying to 8 digits doesn't help). It seems like a bad design in algorithm ? Cheers, Rémi-C 2013/11/25 James David Smith james.david.sm...@gmail.com Hi there, Some code to illustrate my problem: 1) A linestring (SRID: 27700) LINESTRING(555936.152 200920.58202,555938.31202 200908.10202,555943.11201 200883.14201,555953.19201 200839.702,555964.47199 200798.18198,555974.312 200764.34202,555983.912 200744.18202,555990.554 200733.72103,555993.512 200729.06205,555995.77802 200726.75601,556006.95201 200715.38201,556024.232 200698.82202,556036.59799 200687.931,556050.39201 200675.78202,556055.914 200671.26502,556071.512 200658.50202,556094.91501 200640.53702,556095.45101 200640.15201,556113.99201 200628.74201,556138.47201 200616.50204,556159.11202 200605.94202,556180.23201 200589.86202,556207.592 200568.02202,556217.91202 200558.182,556228.47201 200545.702,556240.472 200527.70203,556251.99201 200509.22199,556253.23701 200506.73203,556258.952 200495.30201,556268.1 200478.2,556279.592 200458.58202,556300 200431.2,556351.2 200364,556349.253 200366.23401) 2) Now I buffer it: SELECT ST_Buffer( ST_GeomFromText( 'LINESTRING(555936.152 200920.58202,555938.31202 200908.10202,555943.11201 200883.14201,555953.19201 200839.702,555964.47199 200798.18198,555974.312 200764.34202,555983.912 200744.18202,555990.554 200733.72103,555993.512 200729.06205,555995.77802 200726.75601,556006.95201 200715.38201,556024.232 200698.82202,556036.59799 200687.931,556050.39201 200675.78202,556055.914 200671.26502,556071.512 200658.50202,556094.91501 200640.53702,556095.45101 200640.15201,556113.99201 200628.74201,556138.47201 200616.50204,556159.11202 200605.94202,556180.23201 200589.86202,556207.592
Re: [postgis-users] Odd st_buffer behaviour
On 26 November 2013 06:04, James David Smith james.david.sm...@gmail.com wrote: 2) Now I buffer it: SELECT ST_Buffer( ST_GeomFromText( 'LINESTRING(555936.152 200920.58202,555938.31202 200908.10202,555943.11201 200883.14201,555953.19201 200839.702,555964.47199 200798.18198,555974.312 200764.34202,555983.912 200744.18202,555990.554 200733.72103,555993.512 200729.06205,555995.77802 200726.75601,556006.95201 200715.38201,556024.232 200698.82202,556036.59799 200687.931,556050.39201 200675.78202,556055.914 200671.26502,556071.512 200658.50202,556094.91501 200640.53702,556095.45101 200640.15201,556113.99201 200628.74201,556138.47201 200616.50204,556159.11202 200605.94202,556180.23201 200589.86202,556207.592 200568.02202,556217.91202 200558.182,556228.47201 200545.702,556240.472 200527.70203,556251.99201 200509.22199,556253.23701 200506.73203,556258.952 200495.30201,556268.1 200478.2,556279.592 200458.58202,556300 200431.2,556351.2 200364,556349.253 200366.23401)'), 1000, 'endcap=flat join=round'); Hi James, I just had a spin with this geometry in JTS TestBuilder, in Buffer BufferWithParams. This graphical tool has similar controls as ST_Buffer, but is slightly more interactive. I get pretty much the same result, with anomalies on both ends of the linestring. GEOS (used by PostGIS) is a C++ port of JTS, so this is no surprise to see the same results. Only buffers less than 200 look normal. The oddness at the bottom is explained by a small J-shaped kink at the end of the linestring, which has a short and very sharp angle (nearly 360 degrees or 0 degrees), which makes the last segment go upwards and nearly parallel to the second-to-last segment of the linestring. Removing the last coordinate fixes things on the lower part. This is most likely a digitization error. If you have heaps of these geometries that need cleaning up, you could write a function to return the maximum vertex angle in a linestring, and filter out the sharp ones, e.g. 350 degrees or 10 degrees, then check and fix these up manually. On the upper-right part of the buffer, the polygon is clearly buffered by the correct distance from the middle of the line, but the clip from the top cap carves it a bit funny. I've seen this before too, and I'm not sure if anything can be done about this part. -Mike ___ postgis-users mailing list postgis-users@lists.osgeo.org http://lists.osgeo.org/cgi-bin/mailman/listinfo/postgis-users
Re: [postgis-users] Odd st_buffer behaviour
About sharp turns : you could use a small buffer then errosion or straight skeleton (out of the box with sfcgal). For the flat encapt I suggest you to use st_split afterward. Cheers, Rémi-C 2013/11/26 Mike Toews mwto...@gmail.com On 26 November 2013 06:04, James David Smith james.david.sm...@gmail.com wrote: 2) Now I buffer it: SELECT ST_Buffer( ST_GeomFromText( 'LINESTRING(555936.152 200920.58202,555938.31202 200908.10202,555943.11201 200883.14201,555953.19201 200839.702,555964.47199 200798.18198,555974.312 200764.34202,555983.912 200744.18202,555990.554 200733.72103,555993.512 200729.06205,555995.77802 200726.75601,556006.95201 200715.38201,556024.232 200698.82202,556036.59799 200687.931,556050.39201 200675.78202,556055.914 200671.26502,556071.512 200658.50202,556094.91501 200640.53702,556095.45101 200640.15201,556113.99201 200628.74201,556138.47201 200616.50204,556159.11202 200605.94202,556180.23201 200589.86202,556207.592 200568.02202,556217.91202 200558.182,556228.47201 200545.702,556240.472 200527.70203,556251.99201 200509.22199,556253.23701 200506.73203,556258.952 200495.30201,556268.1 200478.2,556279.592 200458.58202,556300 200431.2,556351.2 200364,556349.253 200366.23401)'), 1000, 'endcap=flat join=round'); Hi James, I just had a spin with this geometry in JTS TestBuilder, in Buffer BufferWithParams. This graphical tool has similar controls as ST_Buffer, but is slightly more interactive. I get pretty much the same result, with anomalies on both ends of the linestring. GEOS (used by PostGIS) is a C++ port of JTS, so this is no surprise to see the same results. Only buffers less than 200 look normal. The oddness at the bottom is explained by a small J-shaped kink at the end of the linestring, which has a short and very sharp angle (nearly 360 degrees or 0 degrees), which makes the last segment go upwards and nearly parallel to the second-to-last segment of the linestring. Removing the last coordinate fixes things on the lower part. This is most likely a digitization error. If you have heaps of these geometries that need cleaning up, you could write a function to return the maximum vertex angle in a linestring, and filter out the sharp ones, e.g. 350 degrees or 10 degrees, then check and fix these up manually. On the upper-right part of the buffer, the polygon is clearly buffered by the correct distance from the middle of the line, but the clip from the top cap carves it a bit funny. I've seen this before too, and I'm not sure if anything can be done about this part. -Mike ___ postgis-users mailing list postgis-users@lists.osgeo.org http://lists.osgeo.org/cgi-bin/mailman/listinfo/postgis-users ___ postgis-users mailing list postgis-users@lists.osgeo.org http://lists.osgeo.org/cgi-bin/mailman/listinfo/postgis-users
Re: [postgis-users] Odd st_buffer behaviour
Thanks for the suggestions and feedback everyone. On 26 November 2013 08:49, Rémi Cura remi.c...@gmail.com wrote: About sharp turns : you could use a small buffer then errosion or straight skeleton (out of the box with sfcgal). For the flat encapt I suggest you to use st_split afterward. Cheers, Rémi-C 2013/11/26 Mike Toews mwto...@gmail.com On 26 November 2013 06:04, James David Smith james.david.sm...@gmail.com wrote: 2) Now I buffer it: SELECT ST_Buffer( ST_GeomFromText( 'LINESTRING(555936.152 200920.58202,555938.31202 200908.10202,555943.11201 200883.14201,555953.19201 200839.702,555964.47199 200798.18198,555974.312 200764.34202,555983.912 200744.18202,555990.554 200733.72103,555993.512 200729.06205,555995.77802 200726.75601,556006.95201 200715.38201,556024.232 200698.82202,556036.59799 200687.931,556050.39201 200675.78202,556055.914 200671.26502,556071.512 200658.50202,556094.91501 200640.53702,556095.45101 200640.15201,556113.99201 200628.74201,556138.47201 200616.50204,556159.11202 200605.94202,556180.23201 200589.86202,556207.592 200568.02202,556217.91202 200558.182,556228.47201 200545.702,556240.472 200527.70203,556251.99201 200509.22199,556253.23701 200506.73203,556258.952 200495.30201,556268.1 200478.2,556279.592 200458.58202,556300 200431.2,556351.2 200364,556349.253 200366.23401)'), 1000, 'endcap=flat join=round'); Hi James, I just had a spin with this geometry in JTS TestBuilder, in Buffer BufferWithParams. This graphical tool has similar controls as ST_Buffer, but is slightly more interactive. I get pretty much the same result, with anomalies on both ends of the linestring. GEOS (used by PostGIS) is a C++ port of JTS, so this is no surprise to see the same results. Only buffers less than 200 look normal. The oddness at the bottom is explained by a small J-shaped kink at the end of the linestring, which has a short and very sharp angle (nearly 360 degrees or 0 degrees), which makes the last segment go upwards and nearly parallel to the second-to-last segment of the linestring. Removing the last coordinate fixes things on the lower part. This is most likely a digitization error. If you have heaps of these geometries that need cleaning up, you could write a function to return the maximum vertex angle in a linestring, and filter out the sharp ones, e.g. 350 degrees or 10 degrees, then check and fix these up manually. On the upper-right part of the buffer, the polygon is clearly buffered by the correct distance from the middle of the line, but the clip from the top cap carves it a bit funny. I've seen this before too, and I'm not sure if anything can be done about this part. -Mike ___ postgis-users mailing list postgis-users@lists.osgeo.org http://lists.osgeo.org/cgi-bin/mailman/listinfo/postgis-users ___ postgis-users mailing list postgis-users@lists.osgeo.org http://lists.osgeo.org/cgi-bin/mailman/listinfo/postgis-users ___ postgis-users mailing list postgis-users@lists.osgeo.org http://lists.osgeo.org/cgi-bin/mailman/listinfo/postgis-users
Re: [postgis-users] Odd st_buffer behaviour
Apologies. I think I've just answered this myself. It's the 'endcap=flat join=round' bit isn't it. It's not doing what I am expecting it to do. Though I'm not quite sure how to fix it yet. On 25 November 2013 17:04, James David Smith james.david.sm...@gmail.com wrote: Hi there, Some code to illustrate my problem: 1) A linestring (SRID: 27700) LINESTRING(555936.152 200920.58202,555938.31202 200908.10202,555943.11201 200883.14201,555953.19201 200839.702,555964.47199 200798.18198,555974.312 200764.34202,555983.912 200744.18202,555990.554 200733.72103,555993.512 200729.06205,555995.77802 200726.75601,556006.95201 200715.38201,556024.232 200698.82202,556036.59799 200687.931,556050.39201 200675.78202,556055.914 200671.26502,556071.512 200658.50202,556094.91501 200640.53702,556095.45101 200640.15201,556113.99201 200628.74201,556138.47201 200616.50204,556159.11202 200605.94202,556180.23201 200589.86202,556207.592 200568.02202,556217.91202 200558.182,556228.47201 200545.702,556240.472 200527.70203,556251.99201 200509.22199,556253.23701 200506.73203,556258.952 200495.30201,556268.1 200478.2,556279.592 200458.58202,556300 200431.2,556351.2 200364,556349.253 200366.23401) 2) Now I buffer it: SELECT ST_Buffer( ST_GeomFromText( 'LINESTRING(555936.152 200920.58202,555938.31202 200908.10202,555943.11201 200883.14201,555953.19201 200839.702,555964.47199 200798.18198,555974.312 200764.34202,555983.912 200744.18202,555990.554 200733.72103,555993.512 200729.06205,555995.77802 200726.75601,556006.95201 200715.38201,556024.232 200698.82202,556036.59799 200687.931,556050.39201 200675.78202,556055.914 200671.26502,556071.512 200658.50202,556094.91501 200640.53702,556095.45101 200640.15201,556113.99201 200628.74201,556138.47201 200616.50204,556159.11202 200605.94202,556180.23201 200589.86202,556207.592 200568.02202,556217.91202 200558.182,556228.47201 200545.702,556240.472 200527.70203,556251.99201 200509.22199,556253.23701 200506.73203,556258.952 200495.30201,556268.1 200478.2,556279.592 200458.58202,556300 200431.2,556351.2 200364,556349.253 200366.23401)'), 1000, 'endcap=flat join=round'); 3) The result is attached as a jpg (line thickness increased to aid viewing). Any ideas please? This is related to an ongoing discussion I was having with Remi a while ago. Basically I'm buffering loads of road centrelines to create polygons. But when I do it, a small number end up with really strange buffers like this attached example. I'm at a loss as to why. Thanks James ___ postgis-users mailing list postgis-users@lists.osgeo.org http://lists.osgeo.org/cgi-bin/mailman/listinfo/postgis-users
Re: [postgis-users] Odd st_buffer behaviour
Does offset curve gives the same result? (seems lile offsetting both side have same behavior) Maybe you can try several buffers with increasing size? (default appears wau before 1000) Also, can you try to simplify your line : each coordinates uses 15 digits, surely you don't need all of this ! (simplifying to 8 digits doesn't help). It seems like a bad design in algorithm ? Cheers, Rémi-C 2013/11/25 James David Smith james.david.sm...@gmail.com Hi there, Some code to illustrate my problem: 1) A linestring (SRID: 27700) LINESTRING(555936.152 200920.58202,555938.31202 200908.10202,555943.11201 200883.14201,555953.19201 200839.702,555964.47199 200798.18198,555974.312 200764.34202,555983.912 200744.18202,555990.554 200733.72103,555993.512 200729.06205,555995.77802 200726.75601,556006.95201 200715.38201,556024.232 200698.82202,556036.59799 200687.931,556050.39201 200675.78202,556055.914 200671.26502,556071.512 200658.50202,556094.91501 200640.53702,556095.45101 200640.15201,556113.99201 200628.74201,556138.47201 200616.50204,556159.11202 200605.94202,556180.23201 200589.86202,556207.592 200568.02202,556217.91202 200558.182,556228.47201 200545.702,556240.472 200527.70203,556251.99201 200509.22199,556253.23701 200506.73203,556258.952 200495.30201,556268.1 200478.2,556279.592 200458.58202,556300 200431.2,556351.2 200364,556349.253 200366.23401) 2) Now I buffer it: SELECT ST_Buffer( ST_GeomFromText( 'LINESTRING(555936.152 200920.58202,555938.31202 200908.10202,555943.11201 200883.14201,555953.19201 200839.702,555964.47199 200798.18198,555974.312 200764.34202,555983.912 200744.18202,555990.554 200733.72103,555993.512 200729.06205,555995.77802 200726.75601,556006.95201 200715.38201,556024.232 200698.82202,556036.59799 200687.931,556050.39201 200675.78202,556055.914 200671.26502,556071.512 200658.50202,556094.91501 200640.53702,556095.45101 200640.15201,556113.99201 200628.74201,556138.47201 200616.50204,556159.11202 200605.94202,556180.23201 200589.86202,556207.592 200568.02202,556217.91202 200558.182,556228.47201 200545.702,556240.472 200527.70203,556251.99201 200509.22199,556253.23701 200506.73203,556258.952 200495.30201,556268.1 200478.2,556279.592 200458.58202,556300 200431.2,556351.2 200364,556349.253 200366.23401)'), 1000, 'endcap=flat join=round'); 3) The result is attached as a jpg (line thickness increased to aid viewing). Any ideas please? This is related to an ongoing discussion I was having with Remi a while ago. Basically I'm buffering loads of road centrelines to create polygons. But when I do it, a small number end up with really strange buffers like this attached example. I'm at a loss as to why. Thanks James ___ postgis-users mailing list postgis-users@lists.osgeo.org http://lists.osgeo.org/cgi-bin/mailman/listinfo/postgis-users ___ postgis-users mailing list postgis-users@lists.osgeo.org http://lists.osgeo.org/cgi-bin/mailman/listinfo/postgis-users
Re: [postgis-users] Odd st_buffer behaviour
Steve, Thanks, you are of course right. I hadn't thought of that. Makes sense. James On 25 November 2013 17:58, Stephen Woodbridge wood...@swoodbridge.com wrote: This is because lines shaped like say an Omega character, will create an island inside the character at a certain offset and this can not be represented as a simple polygon. Well maybe it can but the algorithm probably does not try to reduce them to their most simple features. While the lines may not intersect, the offset lines may intersect and it is a function of how these are dealt with. -Steve On 11/25/2013 12:49 PM, James David Smith wrote: Hi Remi/all, I realise I'm digressing slightly from the point, but this seems related. This seems strange to me: I check the geometry type of a table of what I think are linestrings (roads): ukroads=# SELECT COUNT(*), geometrytype(geom) FROM ukrds GROUP BY geometrytype(geom); 395356 | LINESTRING Great. They are all linestrings. Now I check that none of them are self-intersecting: ukroads=# SELECT COUNT(*), st_issimple(geom) FROM ukrds GROUP BY st_issimple(geom); 395356 | t Ok. That's fine. They are all ok. Now I check that they are all valid: ukroads=# SELECT COUNT(*), st_isvalid(geom) FROM ukrds GROUP BY st_isvalid(geom); 395356 | t So now I buffer them all by 1000 metres wanting to make a polygon out of each line: ukroads=# SELECT COUNT(a.*), geometrytype(a.the_geom) FROM (SELECT st_buffer(geom,1000) as the_geom FROM ukrds) AS a GROUP BY geometrytype(a.the_geom); 392255 | POLYGON 3101 | MULTIPOLYGON However I am returned with 3101 multipolygons (and the rest polygons). Why is that? Should they not all be polygons? Why do some of them become a multipolygon? Thanks James On 25 November 2013 17:25, Rémi Cura remi.c...@gmail.com wrote: You could use the default ending (which is well defined), then split the resulting with the line like endcap=flat (easy to build, translate endpoint by radius and -radius in normal direction) I still fail to understand why you would need this kind of ending. Cheers, Rémi C 2013/11/25 Rémi Cura remi.c...@gmail.com Does offset curve gives the same result? (seems lile offsetting both side have same behavior) Maybe you can try several buffers with increasing size? (default appears wau before 1000) Also, can you try to simplify your line : each coordinates uses 15 digits, surely you don't need all of this ! (simplifying to 8 digits doesn't help). It seems like a bad design in algorithm ? Cheers, Rémi-C 2013/11/25 James David Smith james.david.sm...@gmail.com Hi there, Some code to illustrate my problem: 1) A linestring (SRID: 27700) LINESTRING(555936.152 200920.58202,555938.31202 200908.10202,555943.11201 200883.14201,555953.19201 200839.702,555964.47199 200798.18198,555974.312 200764.34202,555983.912 200744.18202,555990.554 200733.72103,555993.512 200729.06205,555995.77802 200726.75601,556006.95201 200715.38201,556024.232 200698.82202,556036.59799 200687.931,556050.39201 200675.78202,556055.914 200671.26502,556071.512 200658.50202,556094.91501 200640.53702,556095.45101 200640.15201,556113.99201 200628.74201,556138.47201 200616.50204,556159.11202 200605.94202,556180.23201 200589.86202,556207.592 200568.02202,556217.91202 200558.182,556228.47201 200545.702,556240.472 200527.70203,556251.99201 200509.22199,556253.23701 200506.73203,556258.952 200495.30201,556268.1 200478.2,556279.592 200458.58202,556300 200431.2,556351.2 200364,556349.253 200366.23401) 2) Now I buffer it: SELECT ST_Buffer( ST_GeomFromText( 'LINESTRING(555936.152 200920.58202,555938.31202 200908.10202,555943.11201 200883.14201,555953.19201 200839.702,555964.47199 200798.18198,555974.312 200764.34202,555983.912 200744.18202,555990.554 200733.72103,555993.512 200729.06205,555995.77802 200726.75601,556006.95201 200715.38201,556024.232 200698.82202,556036.59799 200687.931,556050.39201 200675.78202,556055.914 200671.26502,556071.512 200658.50202,556094.91501 200640.53702,556095.45101 200640.15201,556113.99201 200628.74201,556138.47201 200616.50204,556159.11202 200605.94202,556180.23201 200589.86202,556207.592 200568.02202,556217.91202 200558.182,556228.47201 200545.702,556240.472 200527.70203,556251.99201 200509.22199,556253.23701 200506.73203,556258.952 200495.30201,556268.1 200478.2,556279.592 200458.58202,556300 200431.2,556351.2 200364,556349.253 200366.23401)'), 1000, 'endcap=flat join=round'); 3) The result is attached as a jpg (line thickness