Estoy tratando de usar ST_Difference para crear un conjunto de polígonos (processing.trimmedparcelsnew) que no contienen ninguna parte del área cubierta por otro conjunto de polígonos (test.single_geometry_1) usando PostGis 2.1 (y Postgres SQL 9.3). Aquí está mi consulta:
CREATE TABLE processing.trimmedparcelsnew AS
SELECT
orig.id, ST_Difference(orig.geom, cont.geom) AS difference
FROM
test.single_geometry_1 cont,
test.multi_geometry_1 orig;
Pero los polígonos resultantes no se han recortado, sino que parecen haberse dividido donde se cruzan con la otra capa. He intentado ejecutar el select sin poner el resultado en una tabla y todo lo demás que se me ocurre, pero parece que no puedo hacer que esta función funcione.
He adjuntado una foto del resultado
Después de los comentarios, he intentado agregar una cláusula WHERE. Quiero las parcelas que no tienen intersecciones, y las áreas de intersección de las otras parcelas eliminadas (la prueba de capa. Single_geometry representa la contaminación que quiero eliminar de mis parcelas). Intenté una intersección pero, por supuesto, realmente quiero las no intersecciones, así que ahora estoy intentando una disyunción. También intenté agregar el origen a mi tabla, pero la documentación de ST_Difference ( http://postgis.net/docs/ST_Difference.html ) dice que devuelve la geometría exacta que necesito (una geometría que representa esa parte de la geometría A que no se cruza con la geometría B), por lo que estoy confundido sobre por qué querría el polígono original en mi tabla. De todos modos, aquí está mi código modificado:
CREATE TABLE processing.trimmedparcelsnew AS
SELECT
orig.id, ST_Difference(orig.geom, cont.geom) AS difference, orig.geom AS geom
FROM
test.single_geometry_1 cont,
test.multi_geometry_1 orig
WHERE ST_Disjoint(orig.geom, cont.geom);
Siguiendo la respuesta de Dbaston, ahora he intentado:
CREATE TABLE processing.parcels_trimmed AS
SELECT id, COALESCE(ST_Difference(geom, (SELECT ST_Union(b.geom)
FROM test.single_geometry_1 b
WHERE ST_Intersects(a.geom, b.geom)
AND a.id != b.id)), a.geom)
FROM test.multi_geometry_1 a;
El resultado de esto es solo una copia de test.multi_geometry_1. Aunque ahora la división ya no se produce.
Probé la versión anterior, pero nuevamente recibí una copia de test.multi_geometry_1:
CREATE TABLE processing.parcels_trimmed_no_coalesce AS
SELECT id, COALESCE(ST_Difference(geom, (SELECT ST_Union(b.geom)
FROM test.single_geometry_1 b
WHERE ST_Intersects(a.geom, b.geom)
AND a.id != b.id)), a.geom)
FROM test.multi_geometry_1 a;
Estoy empezando a preguntarme si hay algo más que estoy haciendo mal. La declaración que sigue es:
DROP TABLE IF EXISTS processing.parcels_trimmed_no_coalesce;
Y estoy ejecutando las consultas desde la ventana de consulta SQL de PostgreSQL y Openjump.
La declaración que uso para ver la tabla es:
SELECT * FROM processing.parcels_trimmed_no_coalesce;
En aras de la simplificación, ahora he reducido esta consulta a solo:
SELECT id, COALESCE(ST_Difference(geom, (SELECT ST_Union(b.geom)
FROM test.geometriestocutagainst b
WHERE ST_Intersects(a.geom, b.geom)
AND a.id != b.id)), a.geom)
FROM test.geometriestocut a;
Esto todavía da como resultado los polígonos originales (test.geometriestocut) cuando el resultado deseado es el original recortado contra test.geometriestocuta contra.
fuente
WHERE
cláusula, por lo que puede tener una expansión polinómica en la tabla resultante. ¿Cuántas filas haytrimmedparcelsnew
?Respuestas:
Una autounión le permite operar en la relación entre pares de dos características. Pero no creo que le interesen los pares: para cada característica, desea operar en la relación entre esa característica y todas las demás características en su conjunto de datos. Puede lograr esto con una expresión de subconsulta:
Sin embargo, es posible que vea algo extraño en los resultados. ¡Las parcelas que no tienen superposiciones se están eliminando por completo! Esto se debe a que el
ST_Union
agregado en un conjunto de registros vacío seráNULL
, yST_Difference(geom, NULL)
esNULL
. Para suavizar esto, debe completar suST_Difference
llamada enCOALESCE
:Esto significa que si el resultado de
ST_Difference
esNULL
, la expresión fusionada se evaluará a la geometría original.La consulta anterior eliminará las áreas superpuestas de su dominio por completo. Si en su lugar desea elegir un ganador, puede hacerlo
a.id < b.id
, o algún otro criterio, en lugar dea.id != b.id
.fuente
Yo tenía el mismo problema que tú. No sé si ya encontró una solución a su problema, pero modifiqué la respuesta aceptada arriba y obtuve lo que quería.
fuente
Yo uso ST_DifferenceAgg () de los complementos PostGIS . Debe fusionar las dos tablas juntas, tener un identificador único y un índice en la columna de geometría. Aquí hay un breve ejemplo:
Esto fusionará las partes superpuestas con el polígono superpuesto más grande. Si desea mantener la parte superpuesta separada, mire el ejemplo ST_splitAgg ().
fuente