Pages: 1
- Sujet précédent - Requête sur une table PostgreSQL/Postgis et sur une autre requête - Sujet suivant
#1 Fri 07 November 2014 12:48
- Bertrand DORNER
- Participant actif
- Lieu: COLMAR
- Date d'inscription: 5 Sep 2005
- Messages: 90
Requête sur une table PostgreSQL/Postgis et sur une autre requête
Bonjour,
Essayant d'appliquer une formation de première initiation à Postgis, j'ai cherché à adapter les exercices proposés à des données et des besoins locaux de ma structure, qui n'utilise encore que partiellement PostgreSQL et Postgis, en lien avec QGIS. Le plus gros du travail cartographique est toujours fait avec MapInfo et des fichiers dits plats.
J'ai cherché, dans la manipulation de données vectorielles, à obtenir une sélection d'une table de points présente sur Postgis (importation initiale depuis l'utilitaire shp2pgsql-gui.exe, livré avec l'installation de Postgis 2.1, elle-même associée à l'installation de postgresql-9.3.4-4-windows.exe) par rapport au résultat d'une requête SQL sur une autre table Postgis. Le tout devant à chaque fois être affiché via QGIS.
Je commence par rechercher des captages aep distants de 40m ou moins d'une sélection de tronçons de cours d'eau, répondant aux conditions : cours d'eau nommés (BD Topo hydro de l'IGN) et permanents, sans récupération d'informations des cours d'eau.
La requête est
SELECT DISTINCT n_prelev_aep_p_068_echange.*
FROM n_prelev_aep_p_068_echange, (SELECT* from n_troncon_cours_eau_bdt_068
where not nom='NR' and not regime='Intermittent'
) as cours_eau_permanents_nommes
WHERE ST_DWithin(n_prelev_aep_p_068_echange.geom, cours_eau_permanents_nommes.geom, 40)
J'obtiens 54 enregistrements, affichables dans mon projet QGIS, dans lequel ma requête est enregistrée mais avec le seules informations attributaires de la table des captages
Je cherche ensuite à associer à ces captages le nom du tronçon de cours d'eau associé, via la requête
SELECT DISTINCT n_prelev_aep_p_068_echange.gid, n_prelev_aep_p_068_echange.geom, n_prelev_aep_p_068_echange.indice_nat, n_prelev_aep_p_068_echange.date_dup_i, n_prelev_aep_p_068_echange.date_derni, n_prelev_aep_p_068_echange.uge_nom, n_prelev_aep_p_068_echange.identperi_, n_prelev_aep_p_068_echange.nom as captage_nom, cours_eau_permanents_nommes.nom as cours_eau_nom
FROM n_prelev_aep_p_068_echange, (SELECT* from n_troncon_cours_eau_bdt_068 where not nom='NR' and not regime='Intermittent') as cours_eau_permanents_nommes
WHERE ST_DWithin(n_prelev_aep_p_068_echange.geom, cours_eau_permanents_nommes.geom, 40)
ORDER BY n_prelev_aep_p_068_echange.indice_nat - pour vérifier l'absence de doublons
Je suis étonné de trouver 55 enregistrements, certes associant les identifiants des captages et les noms de cours d'eau, mais impossible d'obtenir l'affichage dans Qgis.
Quelles pourraient être les explications ?
Merci d'avance
Bertrand
Hors ligne
#2 Fri 07 November 2014 14:21
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Requête sur une table PostgreSQL/Postgis et sur une autre requête
Bonjour,
Des messages d'erreurs ?
La couche est bien listée dans la liste des tables de la bd ?
Nico
Hors ligne
#3 Fri 07 November 2014 14:35
- SANTANNA
- Moderateur
- Lieu: Angers
- Date d'inscription: 18 Jan 2008
- Messages: 3941
Re: Requête sur une table PostgreSQL/Postgis et sur une autre requête
Bonjour,
QGIS n'autorise l'affichage de couches PG que s'il détecte un champ clé primaire (pour lui, il faut que ce soit un integer non dupliqué).
Cette condition semble être respectée dans la première situation (le gid). Mais l'est-elle dans la seconde? En récupérant des valeurs de la seconde table (cours_eau_permanents_nommes), n'y a-t-il pas le risque de se retrouver, pour un même gid de captage, avec deux valeurs cours_eau_nom? Auquel cas, le gid n'est plus unique... (ce qui expliquerait le 55ème individu)
Hors ligne
#4 Fri 07 November 2014 14:53
- Bertrand DORNER
- Participant actif
- Lieu: COLMAR
- Date d'inscription: 5 Sep 2005
- Messages: 90
Re: Requête sur une table PostgreSQL/Postgis et sur une autre requête
Je découvre le message de Santanna, et c'est bien ce que je constate (cf la capture d'écran).
Dans la première requête, je ne fais remonter aucun renseignement de la requête sur les cours d'eau nommés (soit une interrogation indirecte de la table en dur des cours d'eau).
A noter que les requêtes sont écrites et exécutées depuis l'interface de gestion des bases de données de Qgis (version 2.2), et ne sont pas stockées dans Pgadmin. Dans l'hypothèse où cela aurait une importance
Deux valeurs de cours d'eau ? C'est vrai que le risque n'est pas nul, pour peu qu'un captage se trouve à moins de 40m de distance de deux cours d'eau à la fois. Mais j'imagine que, dans un tel cas, le ou les captages concernés apparaîtraient en doublon : une entrée avec le premier cours d'eau, une entrée avec le second.
Je n'ai pas trouvé de doublon sur les captages (55 enregistrements réellement différents sur la seconde requête, et en faisant attention)
Sur la capture jpeg, les deux messages au bas correspondent aux deux tentatives successives d'afficher la requête
Hors ligne
#5 Fri 07 November 2014 15:00
- Bertrand DORNER
- Participant actif
- Lieu: COLMAR
- Date d'inscription: 5 Sep 2005
- Messages: 90
Re: Requête sur une table PostgreSQL/Postgis et sur une autre requête
Rebonjour,
J'ai fait une seconde capture dans la foulée, qui vous montre
- la requête visant à récupérer les noms des cours d'eau associés aux captages
- une partie des données remontées
- les messages d'échec d'affichage des données graphiques
- la gestion, comme une couche Qgis entière de la première requête portant sur les seuls attributs des captages
En espérant que l'exposé de la situation soit suffisamment clair, même si cela ne vaut pas l'examen des données en direct
Cordialement
Hors ligne
#6 Fri 07 November 2014 15:16
- SANTANNA
- Moderateur
- Lieu: Angers
- Date d'inscription: 18 Jan 2008
- Messages: 3941
Re: Requête sur une table PostgreSQL/Postgis et sur une autre requête
En faisant un order by gid, vous n'en trouvez pas un en double?
Parce que QGIS affiche effectivement un message d'erreur stipulant : "couche sans clé primaire".
Essayez ceci
Code:
SELECT row_number() over ()::integer as num_unique, liste.* FROM (SELECT DISTINCT n_prelev_aep_p_068_echange.gid, n_prelev_aep_p_068_echange.geom, n_prelev_aep_p_068_echange.indice_nat, n_prelev_aep_p_068_echange.date_dup_i, n_prelev_aep_p_068_echange.date_derni, n_prelev_aep_p_068_echange.uge_nom, n_prelev_aep_p_068_echange.identperi_, n_prelev_aep_p_068_echange.nom as captage_nom, cours_eau_permanents_nommes.nom as cours_eau_nom FROM n_prelev_aep_p_068_echange, (SELECT* from n_troncon_cours_eau_bdt_068 where not nom='NR' and not regime='Intermittent') as cours_eau_permanents_nommes WHERE ST_DWithin(n_prelev_aep_p_068_echange.geom, cours_eau_permanents_nommes.geom, 40) ORDER BY n_prelev_aep_p_068_echange.indice_nat) liste
et choisissez num_unique comme clé primaire pour voir
Hors ligne
#7 Fri 07 November 2014 16:55
- Bertrand DORNER
- Participant actif
- Lieu: COLMAR
- Date d'inscription: 5 Sep 2005
- Messages: 90
Re: Requête sur une table PostgreSQL/Postgis et sur une autre requête
Pour le order by n_prelev_aep_p_068_echange.gid, j'ai bien vérifié, j'ai 55 gid différents. Sur une série réduite comme celle-ci, que j'ai pu examiner lentement, un doublon m'aurait vite interpellé.
J'ai essayé la requête, que je n'ai pas très bien comprise. En tout cas le message d'erreur de Echec_requete se rapporte à un élément du code qui fonctionnait sans problème avec la requête initiale (celle des 55 enregistrements)
"SELECT row_number() over ()::integer as num_unique, liste.* FROM" a-t-il pour objet de forcer, si elle ne se fait pas, la création d'un identifiant unique dans la requête ? A quel ensemble d'objets (captages de la table postgis, ou cours d'eau de la requête enregistrée dans le projet qgs) se rapporterait num_unique ?
"(SELECT DISTINCT n_prelev_aep_p_068_echange.gid, n_prelev_aep_p_068_echange.geom, n_prelev_aep_p_068_echange.indice_nat, n_prelev_aep_p_068_echange.date_dup_i, n_prelev_aep_p_068_echange.date_derni, n_prelev_aep_p_068_echange.uge_nom, n_prelev_aep_p_068_echange.identperi_, n_prelev_aep_p_068_echange.nom as captage_nom, cours_eau_permanents_nommes.nom as cours_eau_nom
FROM n_prelev_aep_p_068_echange, (SELECT* from n_troncon_cours_eau_bdt_068 where not nom='NR' and not regime='Intermittent') as cours_eau_permanents_nommes)" : j'ai du mal à comprendre où est l'erreur. Faudrait-il mettre un alias à l'extérieur de cet ensemble ? J'ai fait un essai, non concluant, cf la capture alias_inoperant.jpg
Et où cette requête serait-elle stockée ?
Dernière modification par Bertrand DORNER (Fri 07 November 2014 16:56)
Hors ligne
#8 Fri 07 November 2014 17:37
- Bertrand DORNER
- Participant actif
- Lieu: COLMAR
- Date d'inscription: 5 Sep 2005
- Messages: 90
Re: Requête sur une table PostgreSQL/Postgis et sur une autre requête
Bonsoir,
Avant de m'absenter pour le we et la semaine qui vient, j'en suis venu à la bonne vieille méthode du pointage manuel sur impression, pour comparer la liste de la requête sans noms de cours d'eau (imprimable car exportable depuis Qgis), et la liste avec des noms de cours d'eau (ni exportable ni imprimable) : il y a tout simplement un captage qui se trouve à moins de 40 mètres de distance, de deux objets cours d'eau, nommés et permanents, en même temps. L'un des identifiants de captages apparaît deux fois dans la seconde liste, puisqu'il ne peut y avoir deux noms de cours d'eau dans le même champ
Le SQL spatial permet bien de découvrir son territoire.
Bon we à tous et merci pour vos contributions
Cordialement
Bertrand
Hors ligne
#9 Wed 14 January 2015 15:38
- Bertrand DORNER
- Participant actif
- Lieu: COLMAR
- Date d'inscription: 5 Sep 2005
- Messages: 90
Re: Requête sur une table PostgreSQL/Postgis et sur une autre requête
Bonjour, et bonne année à tous,
J'ai finalement, étant revenu sur cette recherche, trouvé comment répondre à la série de questions :
trouver et cartographier les captages d'eau potable situés à moins de 40m de distance des tronçons de cours d'eau permanents et nommés de la BD Topo, en affichant les identifiants des captages, les noms des gestionnaires des captages, et les noms des tronçons de cours d'eau.
Voici déjà la requête, brute de commentaires
SELECT DISTINCT row_number() over() as myid, n_prelev_aep_p_068_echange.indice_nat, n_prelev_aep_p_068_echange.gid, n_prelev_aep_p_068_echange.uge_nom, n_prelev_aep_p_068_echange.geom, cours_eau_permanents_nommes.nom
FROM n_prelev_aep_p_068_echange, (SELECT* from n_troncon_cours_eau_bdt_068
where not nom='NR' and not regime='Intermittent'
) as cours_eau_permanents_nommes
WHERE ST_DWithin(n_prelev_aep_p_068_echange.geom, cours_eau_permanents_nommes.geom, 40)
ORDER BY n_prelev_aep_p_068_echange.indice_nat
Essayons de procéder par étapes successives
- Sélection des tronçons de cours d'eau permanents et nommés :
SELECT* (sélection de la clé primaire gid et de la géométrie pour un affichage cartographique)
FROM n_troncon_cours_eau_bdt_068
WHERE not nom='NR' and not regime='Intermittent' (absence de valeur 'NULL' dans le champ nom)
- Sélection des captages à l'intérieur d'une distance de 40m autour des cours d'eau recherchés au départ :
SELECT DISTINCT n_prelev_aep_p_068_echange.indice_nat, n_prelev_aep_p_068_echange.gid, n_prelev_aep_p_068_echange.uge_nom, n_prelev_aep_p_068_echange.geom (sélection de la clé primaire des captages et de la géométrie pour un affichage cartographique)
FROM n_prelev_aep_p_068_echange, (SELECT* from n_troncon_cours_eau_bdt_068
where not nom='NR' and not regime='Intermittent'
) as cours_eau_permanents_nommes (renommer en alias la première requête permet qu'elle soit considérée comme une table)
WHERE ST_DWithin(n_prelev_aep_p_068_echange.geom, cours_eau_permanents_nommes.geom, 40)
On obtient 54 enregistrements, cartographiables, sans relation attributaire avec les cours d'eau
- Question supplémentaire, les points de captages répondant à ces conditions doivent afficher le nom du tronçon de cours d'eau
Dans la clause SELECT DISTINCT, ajout de "row_number() over() as myid" (histoire d'avoir un identifiant unique pour les enregistrements de captages présents en doublons, car à moins de 40m de plusieurs cours d'eau, ou tronçons différents de mêmes cours d'eau) et "cours_eau_permanents_nommes.nom" (noms des tronçons de cours d'eau de la BD Topo)
La clause ORDER BY n'apparaît pas comme indispensable à la cartographie
En rajoutant les noms de cours d'eau j'obtiens 55 enregistrements, non cartographiables (un captage en doublon car à moins de 40m de deux cours d'eau nommés)
En rajoutant le champ myid, j'obtiens 60 enregistrements, cartographiables. Les enregistrements supplémentaires correspondent à deux tronçons d'un cours d'eau de part et d'autre d'un affluent lui aussi nommé et permanent, et à un/des captages situés à cheval de deux tronçons d'un même cours d'eau nommé et permanent, peut-être au confluent de cours d'eau temporaires et sans nom.
En espérant que cette démarche soit utile
Cordialement
Hors ligne
Pages: 1
- Sujet précédent - Requête sur une table PostgreSQL/Postgis et sur une autre requête - Sujet suivant