Nous utilisons des cookies pour vous garantir la meilleure expérience sur notre site. Si vous continuez à utiliser ce dernier, nous considèrerons que vous acceptez l'utilisation des cookies. J'ai compris ! ou En savoir plus !.
banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

Printemps des cartes 2024

#1 Mon 23 September 2013 14:46

Razorbak
Participant assidu
Lieu: Clermont Ferrand
Date d'inscription: 7 Oct 2007
Messages: 505

[PostGis] Vue avec une sélection sur la superficie max

Bonjour,

Je dispose d'une couche présentant des doublons.
J'aimerai créer une vue permettant d'afficher uniquement un seul objet (et non retourner les objets en doublons) en affichant en priorité les objets ayant la plus grande superficie.
Je comprends bien qu'il va falloir utiliser ST_AREA mais comment spécifier que je veux récupérer l'objet ayant la plus grande superficie en cas de doublon ?
Est-ce possible ?

Je vous remercie.
Bonne journée

Dernière modification par Razorbak (Mon 23 September 2013 14:46)

Hors ligne

 

#2 Mon 23 September 2013 15:13

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1536

Re: [PostGis] Vue avec une sélection sur la superficie max

Bonjour,

Plusieurs solutions:

• Utiliser GROUP BY pour grouper les objets les doublons et ne former qu'un seul objet, puis afficher par surface croissante

Code:

-- id est l'identifiant en double pour les doublons
select id, st_area(geom)
from matable
group by id, st_area(geom)
order by st_area(geom);

• Utiliser DISTINCT ON, clause propre a Postgresql, permettant d'eleminer des lignes ayant une ou plusieurs colonnes identiques (et pas toute les colonnes, comme avec la clause DISTINCT:

Code:

with order as (
     select id, st_area(geom) as area
     from matable
     order by 2
) select distinct on (id) id, area
from order;

Le choix va dépendre de vos données et des attributs que vous voulez afficher au final.

Nicolas

Hors ligne

 

#3 Mon 23 September 2013 16:07

SANTANNA
Moderateur
Lieu: Angers
Date d'inscription: 18 Jan 2008
Messages: 3807

Re: [PostGis] Vue avec une sélection sur la superficie max

Bonjour,
Nicolas, il ne manquerait pas la notion de sélection du max dans tes exemples?

Une proposition (selon ce que j'ai compris de la question). On suppose que col1 et col2 sont les champs communs entre les entités. Ce code devrait permettre de sélectionner pour chaque couple (col1, col2) la plus grande surface et la géométrie de l'entité correspondante (+ d'autres champs).

Code:

Select col1, col2, col3,  geom, st_area(geom)
from matable
where (col1, col2, st_area(geom)) in 
(select col1, col2, max(st_area(geom)) from matable
group by col1, col2)

EDIT: Attention par contre si un des champs de comparaison contient une valeur nulle.... pas de correspondance pour lui...

Dernière modification par SANTANNA (Mon 23 September 2013 16:28)

Hors ligne

 

#4 Mon 23 September 2013 17:08

JP LLORENS
Participant assidu
Date d'inscription: 12 Nov 2008
Messages: 231

Re: [PostGis] Vue avec une sélection sur la superficie max

Bonjour .
Autre solution, dans le premier code proposé par Nicolas, remplacer "order by st_area(geom)" par "order  by st_area(geom) desc limit 1". Les résultats sont triés du plus grand au plus petit et on limite nombre d'entités renvoyées à 1 (la plus grande) => ça évite d'utiliser la fonction max()
Cordialement
JPL

Hors ligne

 

#5 Mon 23 September 2013 17:45

Razorbak
Participant assidu
Lieu: Clermont Ferrand
Date d'inscription: 7 Oct 2007
Messages: 505

Re: [PostGis] Vue avec une sélection sur la superficie max

Bonjour,

Merci pour ces quelques pistes. Par contre, je ne veux pas récupérer un seul enregistrement mais bien tous les enregistrements et dans le cas où il y a un doublon, je veux récupérer l'objet ayant la plus grande superficie.
La proposition de JP LLORENS ne peut donc convenir, étant donné qu'on se limite à un seul objet en résultat.
Je vous tiens au courant si ça fonctionne.

Merci

Bonne fin de journée

Hors ligne

 

#6 Mon 23 September 2013 18:05

JP LLORENS
Participant assidu
Date d'inscription: 12 Nov 2008
Messages: 231

Re: [PostGis] Vue avec une sélection sur la superficie max

Oops autant pour moi !
Ma solution ne présente aucun intérêt dans le cadre d'un group by.
Désolé.
JPL

Hors ligne

 

#7 Mon 23 September 2013 19:46

ppluvinet
Participant assidu
Lieu: LYON
Date d'inscription: 6 Aug 2007
Messages: 608

Re: [PostGis] Vue avec une sélection sur la superficie max

on convient que col1 et col2 sont les champs communs des doublons.
Sans tester, mon exemple consiste à rajouter une colonne et mettre un 'oui' lorsque le doublon est le + grand :

Code:

alter table matable add column maxarea text;
update matable as a set maxarea = 'oui' from 
(select col1, col2, max(st_area2d(geom)) as maxarea from matable group by col1, col2) as b
where st_area2d(a.geom) = b.maxarea  and a.col1 = b.col1 and a.col2 = b.col2;

Dernière modification par ppluvinet (Mon 23 September 2013 20:59)


Pascal PLUVINET

Hors ligne

 

#8 Mon 23 September 2013 20:51

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1536

Re: [PostGis] Vue avec une sélection sur la superficie max

S'il faut tous les enregistrements et juste les aires les plus grandes pour les doublons, le DISTINCT ON devrait le faire wink

Il manquait une sous requete dans mon exemple, pour permettre le classement sur l'aire:

Code:

drop table if exists test;
create table test (uniq_id serial, id int, area double precision);

insert into test (id, area) values 
    (1, 3.34),
    (1, 19.34),
    (1, 123.34),
    (2, 34.34),
    (3, 6123.34),
    (4, 12),
    (4, 12311.34),
    (5, 23123.34),
    (6, 14),
    (7, 12334),
    (7, 123345),
    (7, 5466),
    (7, 9999),
    (8, 1.34),
    (9, 0.12334);

select * from test;

with ordered as (
    select uniq_id, id, area
    from test
    order by 3 desc
), dist as (
    select distinct on (id) id, uniq_id, area
    from test
) select * from dist order by 3 desc;

-- ou, avec une construction SQL classique et une jointure sur elle-meme (sous requete au lieu d'une clause WITH ...)
SELECT t.*
FROM test t
INNER JOIN
    (
        SELECT id, MAX(area) AS max_area
        FROM test
        GROUP BY id
    ) groupedt ON t.id = groupedt.id AND t.area = groupedt.max_area
order by area desc;

Nicolas

Hors ligne

 

Pied de page des forums

Powered by FluxBB