#1 Thu 25 September 2008 12:58
- NyPon
- Participant actif
- Date d'inscription: 3 Nov 2008
- Messages: 111
Boucle WHILE/FOR Postgresql
Bonjour,
j'arrive à insérer des données d'une table d'origine à une table de destination avec une requête qui regroupe les géométries en fonction d'un champs.
TABLE D'ORIGINE
[img]http://www.developpez.net/forums/attachment.php?attachmentid=36097&stc=1&d=1222263495[/img]
TABLE DE DESTINATION
[img]http://www.developpez.net/forums/attachment.php?attachmentid=36098&stc=1&d=1222263506[/img]
cette requête fait une union de géométrie des lignes qui ont le même numéro pacage.
est-il possible d'automatiser cette insertion des données en sql avec une boucle FOR ou une boucle WHILE ? ou une autre solution...
mes numéros pacages sont compris entre "76000105" et "80157753" mais ne se suivent pas forcement.
j'ai essayé cette requête :
Code:
SELECT pacage, geomunion (the_geom) as the_geom FROM rpg76 GROUP BY pacage;
qui me renvoi cette erreur :
Code:
NOTICE: TopologyException: found non-noded intersection between 527822 2.56006e+006, 528042 2.55985e+006 and 527363 2.55994e+006, 527824 2.56006e+006 527823 2.56006e+006 ERROR: GEOS union() threw an error! ********** Erreur ********** ERROR: GEOS union() threw an error! État SQL :XX000
ce qui me fait dire qu'il y a un problème de géometrie dans mes polygones.
quelqu'un peut-il m'aider s'il vous plait ?
merci d'avance.
cordialement,
nicolas
Dernière modification par nponzo (Thu 25 September 2008 12:58)
Hors ligne
#2 Fri 26 September 2008 20:37
- NyPon
- Participant actif
- Date d'inscription: 3 Nov 2008
- Messages: 111
Re: Boucle WHILE/FOR Postgresql
Bon,
visiblement je mélange deux choses,
j'ai pensé que je pourrais faire une boucle car ma requête ne fonctionnait pas en me renvoyant l'erreur précédente.
il se trouve que la requête fonctionne, donc c'est bien un problème de géométrie.
dans l'erreur précédente : Code:
Code:
NOTICE: TopologyException: found non-noded intersection between 527822 2.56006e+006, 528042 2.55985e+006 and 527363 2.55994e+006, 527824 2.56006e+006 527823 2.56006e+006 ERROR: GEOS union() threw an error! ********** Erreur ********** ERROR: GEOS union() threw an error! État SQL :XX000
527822 2.56006e+006 sont des coordonnées lambert.
je suis allé voir et il y a effectivement une erreur à cet endroit. j'en ai aussi plein d'autre que j'ai découvertes avec la requête :
Code:
SELECT pacage, geomunion (the_geom) AS the_geom FROM rpg76 WHERE isvalid(the_geom) GROUP BY pacage;
merci à Xavier-Pierre sur Développez.com.
voilà où ça en est, si ça intéresse quelqu'un, n'hésitez pas à vous manifester.
PS: je ne sais pas s'il est possible de déplacer cette discussion car elle n'a plus rien a faire dans les boucles.
merci à tous,
cordialement,
nicolas.
Hors ligne
#3 Wed 01 October 2008 18:00
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1544
Re: Boucle WHILE/FOR Postgresql
Bonjour,
les geometries sont-elles valides ( st_isvalid() ) ?
Si non, "nettoyer" les geometries invalides en tentant un buffer nul
st_buffer(the_geom, 0.0) et eventuellement en reduisant la precision
des données en utilisant snaptogrid() (ce sont des données metriques
je suppose, inutile de garder les decimales).
Si cela ne marche pas, il faut tenter de reperer les points en erreur
et les nettoyer a la main avec un SIG bureautique (jump, gvSig, uDig,
etc...)
Nicolas
Hors ligne
#4 Thu 02 October 2008 07:50
- NyPon
- Participant actif
- Date d'inscription: 3 Nov 2008
- Messages: 111
Re: Boucle WHILE/FOR Postgresql
Bonjour Nicolas,
en effet, j'ai fait la requête isvalid (the_geom) et il m'a renvoyé une quinzaine d'erreur que je suis allé corrigé "ala mano" dans mon logiciel d'information géographique.
mais vous proposez st_isvalid(). quelle est la différence entre st_isvalid et isvalid.
merci pour les ressources, je savais pas que la fonciton st_buffer(the_geom, 0.0) corrigeait les géométrie.
merci pour votre aide, ça m'a été très utile.
Hors ligne
#5 Thu 02 October 2008 19:29
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1544
Re: Boucle WHILE/FOR Postgresql
La validité des geometries est une condition necessaire mais helas pas
encore suffisante pour que les algos de postgis puissent traiter sans
erreur tous les cas.
mais vous proposez st_isvalid(). quelle est la différence entre st_isvalid et isvalid.
aucune. Les fonctions de postgis suivent desormais la regle de nommage
definie par la norme ISO SQL-MM, dans laquelle les fonctions sont
prefixées par "st_" (buffer() devient ainsi st_buffer()). Les anciens
noms sont gardés pour des raisons de compatibilité mais devraient
disparaitre a terme.
merci pour les ressources, je savais pas que la fonciton st_buffer(the_geom, 0.0) corrigeait les géométrie.
merci pour votre aide, ça m'a été très utile.
Effectivement, il existe quelques "tricks" dans postgis pour nettoyer
les geometries ou tenter de faire en sorte que les algos GEOS ne
produisent pas d'erreurs.
Typiquement, le code de buffer() est tel que bien souvent il arrive a
rendre valide des geometries qui ne l'etaient pas. De meme avec la
fonction st_snaptogrid(), qui fixe une certaine precision pour les
geometries, et qui permet souvent de s'affranchir des erreurs geos
("side location conflict" par exemple).
Lorsqu'on travaille avec des données projetées, dans des systemes
metriques comme c'est le cas en France, il n'est pas forcement
necessaire de garder toute une floppée de decimales, qui representent
une precision sub-metrique.
les nouvelles versions de PostGIS vont se concentrer sur ces points
(nettoyage de couches, validation, etc) en ajoutant des fonctions
specifiques
Nicolas
Hors ligne
#6 Fri 03 October 2008 09:46
- NyPon
- Participant actif
- Date d'inscription: 3 Nov 2008
- Messages: 111
Re: Boucle WHILE/FOR Postgresql
Bonjour,
et bien merci pour les explications,
c'est enrichissant.
comment savoir ça sur les fonctions ?
peut-être ai-je survolé de trop haut la doc.
encore merci,
cordialement,
nicolas
Hors ligne
#7 Fri 03 October 2008 12:28
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1544
Re: Boucle WHILE/FOR Postgresql
Le forum officiel PostGIS est une bonne source d'information pour
suivre les derniers développements et connaître un peu les meilleures
façons de résoudre les problèmes rencontrés lors de l'utilisation de PG
Les auteurs de PostGIS y sont très (re)actifs.
Les blogs et/ou posts de ces personnes sont également tres intéressants:
Paul Ramsey: http://lin-ear-th-inking.blogspot.com/
Martin Davis ("papa" de JTS et donc GEOS)
Regina Obe: http://www.bostongis.com/
Le wiki de PostGIS contient également de nombreuses informations utiles:
http://postgis.refractions.net/support/wiki/
Nicolas
Hors ligne
#8 Fri 03 October 2008 18:33
Re: Boucle WHILE/FOR Postgresql
et la doc en français sur postgis.fr !!
Y.
Yves Jacolin, bénévole de l'association GeoRezo.net, agit au nom et pour le compte de l'association - Partageons ce qui nous départage !! - GeoRezo vous aide ? Aidez GeoRezo !
Hors ligne
#9 Wed 08 October 2008 14:24
- NyPon
- Participant actif
- Date d'inscription: 3 Nov 2008
- Messages: 111
Re: Boucle WHILE/FOR Postgresql
Bonjour,
désolé de ne répondre que maintenant, je n'avais pas accès à la toile.
merci pour toutes ces infos à bientôt sur le forum de postgis
Hors ligne
#10 Tue 20 January 2009 17:27
- NyPon
- Participant actif
- Date d'inscription: 3 Nov 2008
- Messages: 111
Re: Boucle WHILE/FOR Postgresql
Bonjour à tous,
je reprend ce post pour illustrer par image et pourquoi pas relancer la discussion
récemment, j'ai fusionner toutes les parcelles d'une section afin de récupérer le polygone de la section.
Code:
SELECT section.insee, geomunion(section.the_geom) FROM section WHERE isvalid(section.the_geom) group by section.insee, section.the_geom;
j'avais cependant un polygone invalide (venant pourtant d'une section vectorisée par le cadastre):
j'ai essayé st_buffer(the_geom,0.0) et rien ne fonctionnait
[img]http://www.atelier-cuesta.fr/polygone_a_corriger.gif[/img]
j'ai fait st_snaptogrid(the_geom,1.0) et mon polygone à trou n'en avait plus.
[img]http://www.atelier-cuesta.fr/polygone_corrige.gif[/img]
je me disais que je pouvais peut-être faire les deux en même temps dans une même requête j'ai essayé :
Code:
SELECT section.insee, st_snaptogrid((geomunion(section_yd.the_geom)),1.0) FROM section WHERE isvalid(section.the_geom) group by section.insee, section.the_geom;
mais je suis peut-être un peu optimiste ! ou un peu niais ?!
voilà, pour illustrer par image et vous remercier par la même occasion pour toutes vos interventions.
cordialement,
Nicolas
Hors ligne
#11 Fri 23 January 2009 13:08
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1544
Re: Boucle WHILE/FOR Postgresql
Code:
SELECT section.insee, st_snaptogrid((geomunion(section_yd.the_geom)),1.0) FROM section WHERE isvalid(section.the_geom) group by section.insee, section.the_geom;mais je suis peut-être un peu optimiste ! ou un peu niais ?!
voilà, pour illustrer par image et vous remercier par la même occasion pour toutes vos interventions.
cordialement,
Nicolas
Salut,
La requete precedente ne marche pas ?
Et essayer un snapToGrid sur les geometries AVANT de faire leur union, ca ne marche pas non plus ?
Nico
Hors ligne
#12 Mon 26 January 2009 10:54
- NyPon
- Participant actif
- Date d'inscription: 3 Nov 2008
- Messages: 111
Re: Boucle WHILE/FOR Postgresql
bonjour Nicolas,
En fait, la requête précédente fonctionne, mais ne me fait pas l'union des géométries,
j'ai essayé de faire le snaptogrid tout seul et le résultat n'est pas convaincant (le 'trous' sont plus grands)
j'ai essayé geomunion tout seul et rien à faire.
Et puis finalement, j'ai fait le geomunion suivi du st_buffer(the_geom,1.0)
cela fonctionne et à comblé les trous alors que st_buffer(the_geom,0.0) ne faisait rien.
j'ai du me trompé la première fois. je n'arrives pas à obtenir le même résultat en faisant d'abord l'union et puis le snaptogrid.
j'ai un peu du mal à m'y retrouver avec tous les tests que j'ai fait. il faut que je reprenne.
par contre la requête suivante :
Code:
SELECT section_yd.commune, st_buffer((geomunion(section_yd.the_geom)),1.0) FROM section_yd WHERE isvalid(section_yd.the_geom) group by section_yd.commune, section_yd.the_geom;
ne fait pas l'union.
pour l'instant j'arrive à avoir ce que je veux en plusieurs étapes.
je ne sais pas si je fais vraiment évoluer le post là, je suis désolé.
en tout cas merci pour les infos,
à bientôt j'espère,
cordialement,
Hors ligne