J'essaie d'utiliser ST_Difference pour créer un ensemble de polygones (processing.trimmedparcelsnew) qui ne contiennent aucune des zones couvertes par un autre ensemble de polygones (test.single_geometry_1) à l'aide de PostGis 2.1 (et Postgres SQL 9.3). Voici ma requête:
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;
Mais les polygones résultants n'ont pas été rognés, mais semblent avoir été séparés à leur intersection avec l'autre couche. J'ai essayé d'exécuter la sélection sans mettre le résultat dans un tableau et tout ce à quoi je peux penser, mais je n'arrive pas à faire fonctionner cette fonction.
J'ai joint une photo du résultat
Après les commentaires, j'ai essayé d'ajouter une clause WHERE. Je veux que les parcelles qui n'ont pas d'intersections et les zones d'intersection des autres parcelles soient supprimées (la couche test.single_geometry représente la contamination que je veux supprimer de mes parcelles). J'ai essayé une intersection mais bien sûr je veux en fait les non intersections donc j'essaye maintenant une disjonction. J'ai également essayé d'ajouter l'orig à ma table, mais la documentation de ST_Difference ( http://postgis.net/docs/ST_Difference.html ) dit qu'elle renvoie la géométrie exacte dont j'ai besoin (une géométrie qui représente la partie de la géométrie A qui n'intersecte pas la géométrie B), je ne comprends donc pas pourquoi je voudrais plutôt le polygone d'origine dans ma table. Quoi qu'il en soit, voici mon code modifié:
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);
Suite à la réponse de dbaston, j'ai maintenant essayé:
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;
Le résultat est juste une copie de test.multi_geometry_1. Bien que maintenant le fractionnement ne se produise plus.
J'ai essayé la version précédente, mais encore une fois, obtenez une copie 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;
Je commence à me demander s'il y a autre chose que je fais mal? L'énoncé de procédure est le suivant:
DROP TABLE IF EXISTS processing.parcels_trimmed_no_coalesce;
Et j'exécute les requêtes depuis la fenêtre de requête SQL PostgreSQL et Openjump.
La déclaration que j'utilise pour voir le tableau est:
SELECT * FROM processing.parcels_trimmed_no_coalesce;
Dans un souci de simplification, j'ai maintenant réduit cette requête à:
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;
Il en résulte toujours uniquement les polygones d'origine (test.geometriestocut) lorsque le résultat souhaité est l'original ajusté par rapport à test.geometriestocutagainst.
WHERE
clause, vous pouvez donc avoir une expansion polynomiale dans la table résultante. Combien de lignes y a-trimmedparcelsnew
t-il?Réponses:
Une auto-jointure vous permet d'opérer sur la relation entre des paires de deux fonctionnalités. Mais je ne pense pas que les paires vous intéressent: pour chaque entité, vous voulez opérer sur la relation entre cette entité et toutes les autres entités de votre jeu de données. Vous pouvez accomplir cela avec une expression de sous-requête:
Vous pourriez cependant voir quelque chose d'étrange dans les résultats. Les colis qui n'ont pas de chevauchement sont entièrement abandonnés! C'est parce que l'
ST_Union
agrégat sur un jeu d'enregistrements vide va êtreNULL
, etST_Difference(geom, NULL)
estNULL
. Pour faciliter cela, vous devez encapsuler votreST_Difference
appel dans unCOALESCE
:Cela signifie que si le résultat de
ST_Difference
estNULL
, l'expression fusionnée sera évaluée selon la géométrie d'origine.La requête ci-dessus supprimera entièrement les zones qui se chevauchent de votre domaine. Si vous souhaitez plutôt choisir un gagnant, vous pouvez le faire
a.id < b.id
, ou un autre critère, au lieu dea.id != b.id
.la source
J'ai eu le même problème que toi. Je ne sais pas si vous avez déjà trouvé une solution à votre problème, mais j'ai modifié la réponse acceptée ci-dessus et j'ai obtenu ce que je voulais.
la source
J'utilise ST_DifferenceAgg () des extensions PostGIS . Vous devez fusionner les deux tables ensemble, avoir un identifiant unique et un index sur la colonne de géométrie. Voici un petit exemple:
Cela fusionnera les parties qui se chevauchent avec le plus grand polygone qui se chevauchent. Si vous souhaitez conserver la partie se chevauchant, regardez l'exemple de ST_splitAgg ().
la source