Ich versuche, ST_Difference zu verwenden, um mit PostGis 2.1 (und Postgres SQL 9.3) einen Satz von Polygonen (process.trimmedparcelsnew) zu erstellen, die keinen der Bereiche enthalten, die von einem anderen Satz von Polygonen (test.single_geometry_1) abgedeckt werden. Hier ist meine Frage:
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;
Die resultierenden Polygone wurden jedoch nicht zugeschnitten, sondern scheinen dort geteilt worden zu sein, wo sie sich mit der anderen Schicht schneiden. Ich habe versucht, nur die Auswahl auszuführen, ohne das Ergebnis in eine Tabelle und alles andere, was mir einfällt, einzutragen, aber ich kann diese Funktion anscheinend nicht zum Laufen bringen.
Ich habe ein Bild des Ergebnisses angehängt
Nach Kommentaren habe ich versucht, eine WHERE-Klausel hinzuzufügen. Ich möchte, dass die Pakete, die keine Schnittpunkte haben, und die Schnittbereiche der anderen Pakete entfernt werden (die Ebene test.single_geometry repräsentiert die Kontamination, die ich von meinen Paketen entfernen möchte). Ich habe eine Kreuzung versucht, aber natürlich möchte ich eigentlich die Nicht-Kreuzungen, also versuche ich jetzt eine Disjunktion. Ich habe auch versucht, das orig zu meiner Tabelle hinzuzufügen, aber die Dokumentation für ST_Difference ( http://postgis.net/docs/ST_Difference.html ) besagt, dass es genau die Geometrie zurückgibt, die ich brauche (eine Geometrie, die den Teil der Geometrie A darstellt, der schneidet sich nicht mit der Geometrie B), daher bin ich verwirrt, warum ich stattdessen das ursprüngliche Polygon in meiner Tabelle haben möchte. Wie auch immer, hier ist mein geänderter Code:
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);
Nach der Antwort von dbaston habe ich jetzt versucht:
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;
Das Ergebnis ist nur eine Kopie von test.multi_geometry_1. Obwohl jetzt die Aufteilung nicht mehr stattfindet.
Ich habe die frühere Version ausprobiert, erhalte aber erneut eine Kopie von 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;
Ich frage mich, ob ich noch etwas falsch mache. Die folgende Erklärung lautet:
DROP TABLE IF EXISTS processing.parcels_trimmed_no_coalesce;
Und ich führe die Abfragen aus dem PostgreSQL SQL-Abfragefenster und Openjump aus.
Die Aussage, mit der ich die Tabelle sehe, lautet:
SELECT * FROM processing.parcels_trimmed_no_coalesce;
Im Interesse der Vereinfachung habe ich diese Abfrage jetzt auf nur Folgendes reduziert:
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;
Dies führt immer noch nur zu den ursprünglichen Polygonen (test.geometriestocut), wenn das gewünschte Ergebnis das Original ist, das gegen test.geometriestocut gegen getrimmt wurde.
WHERE
Klausel angegeben, sodass die resultierende Tabelle möglicherweise eine Polynomerweiterung enthält. Wie viele Zeilen sind intrimmedparcelsnew
?Antworten:
Mit einem Self-Join können Sie die Beziehung zwischen Paaren zweier Features bearbeiten. Ich glaube jedoch nicht, dass Sie an Paaren interessiert sind: Für jedes Feature möchten Sie die Beziehung zwischen diesem Feature und allen anderen Features in Ihrem Datensatz bearbeiten. Sie können dies mit einem Unterabfrageausdruck erreichen:
Möglicherweise sehen Sie jedoch etwas Seltsames in den Ergebnissen. Pakete ohne Überlappungen werden vollständig verworfen! Das liegt daran, dass das
ST_Union
Aggregat in einem leeren Recordset seinNULL
wird undST_Difference(geom, NULL)
istNULL
. Um dies zu glätten, müssen Sie IhrenST_Difference
Anruf in Folgendes einschließenCOALESCE
:Dies bedeutet , dass , wenn das Ergebnis
ST_Difference
istNULL
, der zusammengefügte Ausdruck auf die ursprüngliche Geometrie bewerten wird.Mit der obigen Abfrage werden überlappende Bereiche vollständig aus Ihrer Domain entfernt. Wenn Sie stattdessen einen Gewinner auswählen möchten, können Sie dies
a.id < b.id
anstelle eines anderen Kriteriums tuna.id != b.id
.quelle
Ich hatte das gleiche Problem wie du. Ich weiß nicht, ob Sie bereits eine Lösung für Ihr Problem gefunden haben, aber ich habe die oben akzeptierte Antwort geändert und das bekommen, was ich wollte.
quelle
Ich verwende ST_DifferenceAgg () aus den PostGIS-Addons . Sie müssen die beiden Tabellen zusammenführen, einen eindeutigen Bezeichner und einen Index für die Geometriespalte haben. Hier ist ein kurzes Beispiel:
Dadurch werden die überlappenden Teile mit dem größten überlappenden Polygon zusammengeführt. Wenn Sie den überlappenden Teil getrennt halten möchten, sehen Sie sich das Beispiel ST_splitAgg () an.
quelle