Pages: 1
- Sujet précédent - Récupération d'un champ par jointure spatiale dans postgis - Sujet suivant
#1 Sun 14 March 2010 17:59
Récupération d'un champ par jointure spatiale dans postgis
Bonjour,
Je débute avec postgis.
Je voudrais savoir s'il est possible de récupérer un champ d'une couche qui se trouve dans un autre schéma ?
J'ai une couche mobilier (ponctuel) qui se trouve dans le schéma Reseau
Je voudrais récupérer le champ insee_commune qui se trouve dans la couche commune qui se trouve dans le schéma cadastre.
Merci pour votre aide
Hors ligne
#2 Sun 14 March 2010 19:00
Re: Récupération d'un champ par jointure spatiale dans postgis
Salut,
C'est tout à fait possible, il suffit de préfixer le nom de la table par le nom du schema :
Par exemple, pour joindre tes deux tables si elles sont en relation par le champ clef :
Code:
select t1.insee_commune , t2.* from cadastre.commune as t1 join reseau.mobilier as t2 on t1.clef = t2.clef
Le lien vers la doc :
http://docs.postgresql.fr/8.4/sql-createschema.html
vincent
Hors ligne
#3 Sun 14 March 2010 20:06
Re: Récupération d'un champ par jointure spatiale dans postgis
Merci Vincent,
En fait, ce que je voudrais faire est plus compliqué :
En lançant la requête, je m'aperçois que les tables sont dans 2 bases différentes.
J'obtiens une ERROR: schema "reseau" does not exist
commune se trouve dans la base cadastre et mobilier dans la base reseau.
La notion de schéma n'est pas la même que dans oracle.
En final, je voudrais créer un trigger qui se déclenche après l'insertion du point.
Il faudrait que je récupère le numéro insee de la commune dans laquelle est situé le point.
C'est pour cela que j'essaie de récupérer le champ par une jointure spatiale.
Hors ligne
#4 Sun 14 March 2010 20:34
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Récupération d'un champ par jointure spatiale dans postgis
Merci Vincent,
En fait, ce que je voudrais faire est plus compliqué :
En lançant la requête, je m'aperçois que les tables sont dans 2 bases différentes.
J'obtiens une ERROR: schema "reseau" does not exist
commune se trouve dans la base cadastre et mobilier dans la base reseau.
La notion de schéma n'est pas la même que dans oracle.
En final, je voudrais créer un trigger qui se déclenche après l'insertion du point.
Il faudrait que je récupère le numéro insee de la commune dans laquelle est situé le point.
C'est pour cela que j'essaie de récupérer le champ par une jointure spatiale.
Bonsoir,
PostgreSQL ne permet pas encore de faire de requetes entre bases de données différentes.
Dans votre cas, le plus simple serait sans doute de migrer les différentes bases dans une seule, en gardant cette notion de schéma.
Avec pg_dump et psql, il est assez facile de realiser cette migration.
Il est egalement possible de realiser des operations entre base au niveau client, mais on perd un peu l'intéret de la base de données dans ce cas.
Nicolas
En ligne
#5 Sun 14 March 2010 22:47
Re: Récupération d'un champ par jointure spatiale dans postgis
Merci Vincent,
En fait, ce que je voudrais faire est plus compliqué :
En lançant la requête, je m'aperçois que les tables sont dans 2 bases différentes.
En final, je voudrais créer un trigger qui se déclenche après l'insertion du point.
PostgreSQL ne permet pas encore de faire de requetes entre bases de données différentes
En fait on peut le faire avec le module dblink :
http://www.postgresql.org/docs/current/ … blink.html
Ceci étant c'est rarement la meilleure solution au problème posé : en termes de perf, d'intégrité, on soulève d'autres soucis.
Dans votre cas, le plus simple serait sans doute de migrer les différentes bases dans une seule, en gardant cette notion de schéma.
Avec pg_dump et psql, il est assez facile de realiser cette migration.
Oui effectivement. C'est plutot un problème de flux de données entre vos différents composants (et bases) de l'infrastructure.
Si une fusion totale des bases dans une seule n'est pas envisageable, la solution la plus simple est souvent de faire une copie partielle des tables nécessaires dans la base de destination, que l'on garde en synchro avec des scripts maison, un ETL, ou des systèmes de synchro spécifiques (slony & co). Ça dépend des contraintes de l'infrastructure et de l'utilisation des données principalement (lecture seule ou rw par exemple).
Hors ligne
#6 Mon 15 March 2010 02:02
- pedro
- Juste Inscrit !
- Lieu: nou
- Date d'inscription: 23 Jul 2009
- Messages: 5
Re: Récupération d'un champ par jointure spatiale dans postgis
Attention, l'erreur peut aussi provenir d'un problème de droit.
Les schémas cadastre et réseau sont-ils dans 2 bases différentes ou bien dans la même base ?
S'ils sont dans la même base, il suffit alors de donner les droits adéquats avec la commande GRANT, cf http://docs.postgresql.fr/8.4/sql-grant.html.
Et dans ce cas là, pas besoin de copier des données.
Je pense que ça vaut le coup de clarifier ce point, avant d'envisager toute autre solution....
Hors ligne
#7 Mon 15 March 2010 20:13
- cmonrocq
- Juste Inscrit !
- Date d'inscription: 14 Mar 2010
- Messages: 2
Re: Récupération d'un champ par jointure spatiale dans postgis
Bonjour
une solution possible est le dblink du package contrib
voir :
http://www.postgresql.org/docs/8.3/stat … blink.html
http://mat.oxyg3n.org/index.php?post/20 … ec-db_link
attention : si tu es sur Linux, il ne suffit de l'installer via un
apt-get ou autre installeur, il faut explicitement charger le package :
psql -d testgis -f /usr/share/postgresql/8.3/contrib/dblink.sql
Christophe
Hors ligne
#8 Mon 15 March 2010 22:30
Re: Récupération d'un champ par jointure spatiale dans postgis
Bonsoir,
vu vos réponses, il vaut mieux que je rappatrie la couche commune dans la base réseau.
Dans ce cas quelle est la syntaxe pour récuperer le code commune d'un objet inclu dans la commune.
Je pensais à une commande :
select a.nom from commune a, mobilier b where within(a.geometrie=b.geometrie)
mais cela ne fonctionne pas
Avez vous une syntaxe plus adaptée ?
Ensuite,,
je voudrais que cette requete devienne une fonction intégrée à un trigger.
Merci beaucoup pour vos précieux conseils
Hors ligne
#9 Mon 15 March 2010 22:37
- ppluvinet
- Participant assidu
- Lieu: VALENCE
- Date d'inscription: 6 Aug 2007
- Messages: 617
Re: Récupération d'un champ par jointure spatiale dans postgis
bonsoir,
replacer le = par une virgule ...?
Pascal PLUVINET
Hors ligne
#10 Sun 21 March 2010 15:36
Re: Récupération d'un champ par jointure spatiale dans postgis
Bonjour,
Je n'avance pas beaucoup
la requête fonctionne bien en select, mais lorsque je veux mettre à jour la table, j'obtiens un message d'erreur :
update mob_urbain b set planche=(select a.planche from commune a , mob_urbain b where within(b.geometrie,a.geometrie));
ERROR: more than one row returned by a subquery used as an expression
********** Erreur **********
ERROR: more than one row returned by a subquery used as an expression
État SQL :21000
J'ai essayé la syntaxe suivante :
update mob_urbain b set b.planche= commune.planche where within(b.geometrie, commune.geometrie);
ça ne fonctionne pas non plus.
Avez-vous une solution pour faire fonctionner cette mise à jour ?
Merci beaucoup
Hors ligne
#11 Sun 21 March 2010 18:06
Re: Récupération d'un champ par jointure spatiale dans postgis
Bonjour,
Un UPDATE signifie met moi à jour chaque ligne de la base, c'est c'est à dire met à jour la colonne commune pour chaque mobilier urbain.
Or, votre select renvoie plusieurs valeurs de communes pour un mobilier urbain (car vos mobiliers urbains appartiennent à plusieurs communes vraisemblablement)
C'est donc normal qu'il refuse de faire la MAJ.
Deux possibilités pour résoudre votre problème :
-découper votre mobilier urbain par commune mais le souci c'est que vos clés sur le mobilier urbain ne seront plus uniques et là votre maj marchera mais vous "casserez" votre modèle actuel (et je ne connais pas le contexte d'utilisation de votre travail...)
-rajouter un table de croisement pour améliorer votre modèle qui ne correspond pas à la réalité rencontrée
Vous vous attendiez à ce qu'un mobilier urbain appartienne à une seule commune avec une relation 1,1 (là votre update aurait pu fonctionné) mais vous êtes dans le cas où vous avez une relation 1,n
http://cerig.efpg.inpg.fr/tutoriel/base … chap06.htm pour un rappel sur les relations.
Cordialement
ThomasG
Hors ligne
#12 Sun 21 March 2010 20:44
Re: Récupération d'un champ par jointure spatiale dans postgis
Merci pour ces précisions.
En fait, la table mobilier est une table géographique constituée de points.
Ces points sont contenus dans une commune. La table commune de type polygone contient un champ planche (insee) et un champ nom.
Je voudrais récupérer à l'aide d'un trigger, les informations planche et nom lors de la création d'un point ou de sa modification.
Enfin, je voudrais mettre à jour le champ date lors de la création ou de modification.
Merci pour votre aide
Hors ligne
#13 Sun 21 March 2010 23:47
Re: Récupération d'un champ par jointure spatiale dans postgis
Bonjour,
Le code de cette page http://www.grappa.univ-lille3.fr/polys/ … ux062.html semble se rapprocher de votre besoin au moins sur
mettre à jour le champ date lors de la création ou de la modification
Cordialement
ThomasG
Hors ligne
#14 Mon 22 March 2010 11:54
- ppluvinet
- Participant assidu
- Lieu: VALENCE
- Date d'inscription: 6 Aug 2007
- Messages: 617
Re: Récupération d'un champ par jointure spatiale dans postgis
a essayer:
Code:
update mob_urbaina a set planche= b.planche from commune b where within(a.geometrie, b.geometrie);
Dernière modification par ppluvinet (Mon 22 March 2010 12:32)
Pascal PLUVINET
Hors ligne
#15 Mon 22 March 2010 21:23
Re: Récupération d'un champ par jointure spatiale dans postgis
Bonsoir Pascal,
Cela fonctionne parfaitement, merci beaucoup.
Je continue donc pour créer la fonction et le trigger.
Là encore j'ai un message d'erreur : ERROR: syntax error at or near "BEGIN"
État SQL :42601
Caractère : 70
et la fonction :
CREATE OR REPLACE FUNCTION maj_planche()
RETURNS "trigger" AS $$
BEGIN
update mob_urbain a set planche = b.planche from commune b where within(a.geometrie, b.geometrie);
END;
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION maj_planche() OWNER TO postgres;
$$
CREATE TRIGGER trig_mob_urbain AFTER INSERT or UPDATE
ON mob_urbain FOR EACH ROW
EXECUTE PROCEDURE public.maj_planche();
J'ai beau chercher dans les forums, j'obtiens toujours le même message.
Hors ligne
#16 Fri 26 March 2010 11:29
Re: Récupération d'un champ par jointure spatiale dans postgis
Voici la fonction qui réalise ce que je voulais faire. Merci à toutes les personnes qui m'ont aidé à réaliser ce bout de code qui sera très utile.
CREATE OR REPLACE FUNCTION maj_planche()
RETURNS "trigger" AS
$BODY$
begin
select into NEW.planche planche from commune where within(NEW.geometrie, geometrie);
return NEW ;
end;$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION maj_planche() OWNER TO postgres;
CREATE TRIGGER trig_mob_urbain BEFORE INSERT or UPDATE
ON mob_urbain FOR EACH ROW
EXECUTE PROCEDURE public.maj_planche();
Hors ligne
Pages: 1
- Sujet précédent - Récupération d'un champ par jointure spatiale dans postgis - Sujet suivant