Cómo convertir en PostGIS líneas no simples a simples (How to convert non-simple to simple lines in PostGIS)

Jul
2018
23

posted by on Blog

No comments

Las líneas no simples son aquellas que pasan por un mismo punto dos veces, es decir, se autointersecan.

A los que trabajamos con cartografía esto no nos gusta nada, ya que puede originar comportamientos no deseados en análisis espaciales futuros.

PostGIS con ST_IsSimple permite saber si una línea contiene autointersecciones pero no permite eliminarlas.

El comando ST_Node calcula nuevas intersecciones convirtiendo una linestring en una multilinestring con 3 subelementos (en el ejemplo inferior), pero !sorpresa! esa nueva multilinestring sigue siendo no simple (* razón en la figura).

La sencilla función STX_NodeSimple que hemos desarrollado en plpgsql partirá dicho elemento cerrado de forma que la multilinestring resultante sea simple.

Non-simple lines are those that pass through the same point twice, that is, they are self-intersecting.

Those of us who work with cartography do not like this at all, since it can cause unwanted behavior in future spatial analysis.

PostGIS with ST_Issimple allows to know if a line contains self-intersections but does not allow to eliminate them.

The ST_Node command calculates new intersections by converting a linestring into a multilinestring with 3 subelements (in the example), but what a surprise to know that the new multilinestring is still not simple (* reason).

The STX_NodeSimple  in plpgsql will split said closed element so that the resulting multilinestring is simple.

nodesimple_code1

nodeexample

s1=# select st_astext(geom), st_issimple(geom),       st_numgeometries(geom),st_length(geom) from
(select st_node ('LINESTRING (6 3, 15 12, 26 16, 36 17, 26 7, 19 18, 22 22)'::geometry)) as foo(geom);

-[ RECORD 1 ]----+-------------------------------------------------------
st_astext | MULTILINESTRING((6 3,15 12,21.3489932885906 14.3087248322148),(21.3489932885906 14.3087248322148,26 16,36 17,26 7,21.3489932885906 14.3087248322148),(21.3489932885906 14.3087248322148,19 18,22 22))
st_issimple | f
st_numgeometries | 3
st_length | 66.6630380273346

s1=# select st_astext(geom), st_issimple(geom), st_numgeometries(geom),st_length(geom) from
(select stx_nodesimple ('LINESTRING (6 3, 15 12, 26 16, 36 17, 26 7, 19 18, 22 22)'::geometry)) as foo(geom);

-[ RECORD 1 ]----+-------------------------------------------------------
st_astext | MULTILINESTRING((6 3,15 12,21.3489932885906 14.3087248322148),(21.3489932885906 14.3087248322148,26 16),(26 16,36 17,26 7,21.3489932885906 14.3087248322148),(21.3489932885906 14.3087248322148,19 18,22 22))
st_issimple | t
st_numgeometries | 4
st_length | 66.6630380273346

Leave a Reply