18 votos

¿Cómo se utiliza ST_Intersection?

Este es un resumen rápido de lo que intento hacer: Tengo 3 tablas en Postgres, 'a' y 'b', cada una tiene una columna Polígono, y 'c' tiene una columna Punto. Lo que estoy tratando de hacer es obtener las intersecciones de geometrías entre 'a', 'b' y 'c', y mostrar dichas geometrías en una capa vectorial de OpenLayers.

Ya sé cómo mostrar cualquier tipo de geometría a partir de un String en OpenLayers, pero estoy teniendo problemas con la función ST_Intersection de PostGIS, estoy haciendo esto:

SELECT ST_Intersection(a.geom, b.geom) as inter from a, b;

donde a.geom y b.geom son las dos columnas de geometría, y recibo este mensaje de error:

NOTICE:  TopologyException: found non-noded intersection between 515172 2.14408e+06, 497067 2.13373e+06 and 501321 2.13546e+06, 471202 2.14843e+06 500621 2.13576e+06 
ERROR:  GEOS Intersection() threw an error!

También intenté expresar la geometría resultante como texto usando ST_AsText así:

SELECT ST_AsText(ST_Intersection(a.geom, b.geom)) as inter from a, b;

pero me envía este mensaje de error:

HINT: No function matches the given name and argument types. You might need to add explicit type casts.

No sé lo que estoy haciendo mal, sólo quiero obtener el WKT de Polygons para mostrarlo en OpenLayers, aquí es cómo mostrar una geometría de un WKT:

                    var in_options = {
                        'internalProjection': new OpenLayers.Projection("EPSG:4326"),
                        'externalProjection': new OpenLayers.Projection("EPSG:4326")
                    }; 

                    var fea= new OpenLayers.Format.WKT(in_options).read(data); //data is the string with the WKT
                    vectorLayer.addFeatures([fea]); //this piece of code works great
                    map.zoomToExtent(bounds);

ACTUALIZACIÓN: He probado el siguiente:

SELECT ST_Intersection(a.geom, b.geom) as intersect_ab FROM a INNER JOIN b ON 
ST_Intersection(a,b) WHERE ST_Overlaps(a.geom, b.geom) 
AND ST_isvalid(a.geom)='t' AND ST_isvalid(b.geom)='t';

pero me aparece el siguiente mensaje de error:

ERROR: Function st_intersection(a,b) does not exist.
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

He añadido el isvalid para verificar que sólo se evalúan los polígonos válidos, pero me dice que el error está en la ST_Intersection(a,b), tanto a, como b y c tienen el mismo SRID así que estoy muy confundido, perdón si estoy preguntando demasiado, pero soy bastante nuevo con PostGIS así que espero no molestar mucho. Gracias.

10voto

tobes Puntos 19

Mi opinión es que falla si la intersección devuelve NULL. Así que deberías añadir una cláusula where que compruebe si realmente hay una intersección antes de intentar crear el WKT.

8voto

Xavier Nodet Puntos 2498

La pista es

ERROR: Function st_intersection(a,b) does not exist.
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

Como dice el mensaje de error no se puede utilizar st_intersection de esa manera. Resumiendo las otras respuestas deberías usar algo así:

SELECT ST_Intersection(a.geom, b.geom) as intersect_ab 
FROM a INNER JOIN b ON ST_Intersects(a.geom,b.geom)
WHERE ST_isvalid(a.geom)='t' AND ST_isvalid(b.geom)='t';

AFAIK no tiene sentido utilizar st_overlaps y st_intersects en la misma frase que son bastante similares .

4voto

Fabien Ancelin Puntos 431

Hago una prueba entre diferentes capas de polígonos y falla si hay al menos una geometría no válida en una de las capas. ¿Comprobó la validez de sus polígonos utilizando ST_isvalid(the_geom)? Puede ser la clave.

2voto

Vasu Puntos 11

Prueba algo así:

SELECT  ST_Intersection(a.geom, b.geom) As intersect_ab
    FROM a INNER JOIN b ON ST_Intersection(a,b)
    WHERE ST_Overlaps(a.geom, b.geom)
    ;

Fuente

1voto

rmmh Puntos 4361

Intenté excluir las geometrías no válidas pero no funcionó, así que al final tuve que borrar todas las geometrías no válidas y luego usar esto:

SELECT ST_AsText(ST_Intersection(a.geom, b.geom)) as intersect_ab FROM a,b 
WHERE ST_Overlaps(a.geom, b.geom) AND ST_isvalid(a.geom)='t' AND ST_isvalid(b.geom)='t';

Como puedes ver omití la parte ST_Intersection(a,b), y esto funcionó muy bien, estoy un poco triste porque no pude encontrar una manera de excluir cualquier geometría inválida de mi selección, de todos modos gracias a todos por ayudarme aquí.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X