[Gfoss] Postgres e View incompatibili con Qgis - vecchio problema

Ciao a tutti,
stamane sono andato a riprendere in mano un mio vecchio problema di visualizzazioni di view tra Qgis e Postgres, memore di una discussione aperta daAndrea Peri un po' di tempo fa [0].
Tuttavia non ho trovato il modo di far funzionare tale soluzione con il mio caso che ora vi spiego, utilizzando nel concreto il mio caso in archeologia:
in postgres ho:
US: layer "strati" con campi gid, sito, area, us e the_geom
US_table: tabella alfanumerica con dati relativi agli strati e i campi che la identificano: sito, area, us
Reperti_table: tabella alfanumerica reperti con dentro i reperti di ogni strato e i dati relativi agli strati: sito, area, us

```

```

```
US 1:1 US_table
```


```
US_table 1:N Reperti_table
```

```

```

A questo punto ho una view US_+_US_table_view per visualizare i dati degli strati facendo un join sui campi sito, area, us tra US e US_table
e tutto fila liscio.
Ma se provo a fondere la US_+_US_table_view con Reperti_table, dove per 1 record di US_+_US_table_view ho N record di Reperti_table, Qgis non ha piùun id univoco per caricare le geometrie.
Ho provato il metodo di cui sotto [1], ma oltre ad id e geometria, devo portare nella view altri campi come sito, area, us per fare le analisi su Qgis, e ovviamente sono obbligato a inserirle nel group_by (e questo non lo capisco), quindi non posso più avere id univoco.

Quindi, nella sostanza, non capisco come fare un join tra 2 tabelle, quando sono in rapporto N:N e fare in modo che la vista sia valida per Qgis.

Ci può essere una strada percorribile?

ciao e grazie

luca

[0]: [http://www.mail-archive.com/gfoss@faunalia.it/msg02284.html](http://www.mail-archive.com/gfoss@faunalia.it/msg02284.html)

[1]:
create view1 as
select id as new_id, ST_Union(geometry) as new_geom from table group by id

create view2 as
select new_id, new_geom from view1;

Ciao Luca,

dipende da come vuoi rappresentare i dati dei reperti avendo come
geometria quella degli strati:

1. Se vuoi mappare i singoli reperti, fai un Join tra strati e reperti
senza group by; logicamente l'ID di questa view è l'ID univoco dei
reperti e tutti i reperti appartenenti allo stesso strato avranno la
stessa geometria poligonale dello strato, che è poco pratico per
l'interrogazione e inutile per la tematizzazione

2. Se vuoi rappresentare dati di sintesi sui reperti agganciati agli
strati, crei prima una view facendo una select su reperti con group by
sulla chiave esterna verso strati, quindi l'id della view sarà quello
degli strati, e aggiungerai degli aggregati sui dati dei reperti (min
max med su datazione, conteggio reperti etc); poi una seconda view che
unisce in un join 1:1 la prima view con la tabella strati

Ma hai una chiave primaria composta da sito, area e us?

Un giorno in cui sarò in buona aprirò una discussione sul perché i
nostri amati software ci debbano costringere a usare chiavi primarie
intere e a singolo campo :slight_smile:

Sig

Il giorno mer, 01/06/2011 alle 13.56 +0200, Luca Mandolesi ha scritto:

Ciao a tutti,
stamane sono andato a riprendere in mano un mio vecchio problema di visualizzazioni di view tra Qgis e Postgres, memore di una discussione aperta daAndrea Peri un po' di tempo fa [0].
Tuttavia non ho trovato il modo di far funzionare tale soluzione con il mio caso che ora vi spiego, utilizzando nel concreto il mio caso in archeologia:
in postgres ho:
US: layer "strati" con campi gid, sito, area, us e the_geom
US_table: tabella alfanumerica con dati relativi agli strati e i campi che la identificano: sito, area, us
Reperti_table: tabella alfanumerica reperti con dentro i reperti di ogni strato e i dati relativi agli strati: sito, area, us

US 1:1 US_table
US_table 1:N Reperti_table

A questo punto ho una view US_+_US_table_view per visualizare i dati degli strati facendo un join sui campi sito, area, us tra US e US_table
e tutto fila liscio.
Ma se provo a fondere la US_+_US_table_view con Reperti_table, dove per 1 record di US_+_US_table_view ho N record di Reperti_table, Qgis non ha piùun id univoco per caricare le geometrie.
Ho provato il metodo di cui sotto [1], ma oltre ad id e geometria, devo portare nella view altri campi come sito, area, us per fare le analisi su Qgis, e ovviamente sono obbligato a inserirle nel group_by (e questo non lo capisco), quindi non posso più avere id univoco.

Quindi, nella sostanza, non capisco come fare un join tra 2 tabelle, quando sono in rapporto N:N e fare in modo che la vista sia valida per Qgis.

Ci può essere una strada percorribile?

ciao e grazie

luca

[0]: http://www.mail-archive.com/gfoss@faunalia.it/msg02284.html

[1]:
create view1 as
select id as new_id, ST_Union(geometry) as new_geom from table group by id

create view2 as
select new_id, new_geom from view1;

_______________________________________________
Iscriviti all'associazione GFOSS.it: http://www.gfoss.it/drupal/iscrizione
Gfoss@lists.gfoss.it
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e' una lista di discussione pubblica aperta a tutti.
Non inviate messaggi commerciali.
I messaggi di questa lista non rispecchiano necessariamente
le posizioni dell'Associazione GFOSS.it.
502 iscritti all'11.2.2011

Grazie Luca, per la risposta altamente esaustiva ma dal mio basso punto di vista moooolto complessa.
Farò un po’ di prove per vedere fino dove arrivo e se ho dubbi. Poi magari riposto qua i miei dubbi.

Grazie ancora.

2011/6/1 Luca Sigfrido Percich <sigfrido@tiscali.it>

Ciao Luca,

dipende da come vuoi rappresentare i dati dei reperti avendo come
geometria quella degli strati:

  1. Se vuoi mappare i singoli reperti, fai un Join tra strati e reperti
    senza group by; logicamente l’ID di questa view è l’ID univoco dei
    reperti e tutti i reperti appartenenti allo stesso strato avranno la
    stessa geometria poligonale dello strato, che è poco pratico per
    l’interrogazione e inutile per la tematizzazione

  2. Se vuoi rappresentare dati di sintesi sui reperti agganciati agli
    strati, crei prima una view facendo una select su reperti con group by
    sulla chiave esterna verso strati, quindi l’id della view sarà quello
    degli strati, e aggiungerai degli aggregati sui dati dei reperti (min
    max med su datazione, conteggio reperti etc); poi una seconda view che
    unisce in un join 1:1 la prima view con la tabella strati

Ma hai una chiave primaria composta da sito, area e us?

Un giorno in cui sarò in buona aprirò una discussione sul perché i
nostri amati software ci debbano costringere a usare chiavi primarie
intere e a singolo campo :slight_smile:

Sig

Il giorno mer, 01/06/2011 alle 13.56 +0200, Luca Mandolesi ha scritto:

Ciao a tutti,
stamane sono andato a riprendere in mano un mio vecchio problema di visualizzazioni di view tra Qgis e Postgres, memore di una discussione aperta daAndrea Peri un po’ di tempo fa 0.
Tuttavia non ho trovato il modo di far funzionare tale soluzione con il mio caso che ora vi spiego, utilizzando nel concreto il mio caso in archeologia:
in postgres ho:
US: layer “strati” con campi gid, sito, area, us e the_geom
US_table: tabella alfanumerica con dati relativi agli strati e i campi che la identificano: sito, area, us
Reperti_table: tabella alfanumerica reperti con dentro i reperti di ogni strato e i dati relativi agli strati: sito, area, us

US 1:1 US_table
US_table 1:N Reperti_table

A questo punto ho una view US_+US_table_view per visualizare i dati degli strati facendo un join sui campi sito, area, us tra US e US_table
e tutto fila liscio.
Ma se provo a fondere la US
+US_table_view con Reperti_table, dove per 1 record di US+_US_table_view ho N record di Reperti_table, Qgis non ha piùun id univoco per caricare le geometrie.
Ho provato il metodo di cui sotto [1], ma oltre ad id e geometria, devo portare nella view altri campi come sito, area, us per fare le analisi su Qgis, e ovviamente sono obbligato a inserirle nel group_by (e questo non lo capisco), quindi non posso più avere id univoco.

Quindi, nella sostanza, non capisco come fare un join tra 2 tabelle, quando sono in rapporto N:N e fare in modo che la vista sia valida per Qgis.

Ci può essere una strada percorribile?

ciao e grazie

luca

[1]:
create view1 as
select id as new_id, ST_Union(geometry) as new_geom from table group by id

create view2 as
select new_id, new_geom from view1;


Iscriviti all’associazione GFOSS.it: http://www.gfoss.it/drupal/iscrizione
Gfoss@lists.gfoss.it
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e’ una lista di discussione pubblica aperta a tutti.
Non inviate messaggi commerciali.
I messaggi di questa lista non rispecchiano necessariamente
le posizioni dell’Associazione GFOSS.it.
502 iscritti all’11.2.2011

Ma hai una chiave primaria composta da sito, area e us?

Come chiave primaria uso un numero progressivo nel caso delle tabelle alfanumeriche, mentre sito, area e us li uso per l’univocità.

Assumendo che le tabelle strato e reperto abbiano ciascuna una sua PK
integer, il ragionamento fatto prima dovrebbe portarti in entrambi i
casi ad avere view visibili in QGIS.

Quando pensi ai JOIN e ai GROUP BY, pensa sempre a qual'è l'oggetto in
uscita, ovvero: la singola riga della query che ottengo cosa mi
rappresenta? Uno strato o un reperto? In base a quello capisci quali
campi portar fuori ed eventualmente come raggruppare.

Buon lavoro

Sig

Il giorno mer, 01/06/2011 alle 15.05 +0200, Luca Mandolesi ha scritto:

                Ma hai una chiave primaria composta da sito, area e
                us?

Come chiave primaria uso un numero progressivo nel caso delle tabelle
alfanumeriche, mentre sito, area e us li uso per l'univocità.

Oh, grazie a tutti, ho aggirato il problema ed ho ottenuto quello che volevo e almeno con un set limitato di record mi pare che giri.
Questo quanto ho fatto:

tre tabelle:

us: contiene i dati solo alfanumerici dei miei strati archeologici, ha un id_us integer serial e come univocità campi sito, area, us
reperti: contiene i dati solo alfanumerici contenuti nei singoli strati N:1 con US, ha un id_reperto integer serial e come univocita campi sito, area, us
unita_stratigrafiche_poligoni: contiene le geometrie degli strati, dove 1 us può avere più geometrie associate in base ai campi sito, area, us, + un gid integer serial

view

reperti_+_us_view: da reperti join con us sui campi sito, area, us

reperti_+us+poligoni_view: da reperti+_us join con us sui campi sito, area, us: a questo punto ho gli id_reperti e i gid duplicati perchè a N geometrie corrispondono N reperti.

qui ho seguito Andrea Peri [0]:

view1: ho preso tutti i campi di reperti_+us+_poligoni_view e gli ho raggruppati in base all’id_reperti riottenendo valori univoci legati al campo geometrico
view2: dalla view1 riprende tutti i campi e fa il join su reperti in base all’id_reperto e prendendone tutti i campi

poi io ho aggiunto
view3: prende tutti i campi della view2 e fa il join con us, basandosi sui campi sito, area, us

In questo modo ho tutti i campi delle tabelle us, reperti riferiti alle gometrie delle us in un’unica view caricabile su qgis grazie all’id univoco e numerico id_reperto

Ho fatto un piccolo db in postgres di prova con pochi dati e spero che funzioni anche con il mio DB più grande. Se per caso qualcuno lo volesse per spaciugare sono ben lieto di redistribuirlo, sopratutto perchè sono sicuro di essere andato da Roma a Milano passando per il polo Sud…

Questo è il risultato a schermo 1:
le geometrie colorate sono le mie fosse da grano di XV secolo, che contengono dei reperti .
Ho provato il nuovo sistema di etichette, ed ho notato che per far apparire tutte e quattro le etichette, dandogli libero come setting è difficile trovare lo zoom giusto perchè appaiano tutte.
Però per me è un gran risultato. Per la prima volta, spero con il mio DB ufficiale, potrò vedere fase per fase di uno scavo divise in base alla successione fisica, le datazioni dei reperti distribuite e capire di che epoca sono gli strati.

Grazie a tutti.

Luca

[0]: [http://www.mail-archive.com/gfoss@faunalia.it/msg02284.html](http://www.mail-archive.com/gfoss@faunalia.it/msg02284.html)

2011/6/3 Luca Sigfrido Percich <luca.percich@alice.it>

Ciao Luca,

felice che tu abbia risolto.

Grazie

Ho fatto un po’ fatica a capire il tuo problema. Ti consiglio di usare
il più possibile nomi autoesplicativi per le tabelle ed i campi,
soprattutto quando si riferiscono a chiavi esterne, e di chiarire in che
modo le diverse tabelle si collegano tra di loro, ad esempio:

us (meglio unita_stratigrafiche)
id_us integer PK
sito
area
us

(Immagino che tu possa avere più siti, ogni sito più aree, e ogni area
diverse unità stratigrafiche. Sito e area hanno a loro volta le loro
tabelle?)

unita_stratigrafiche_geom
geom POLYGON
id integer PK
(sito, area, us) => us.(sito, area, us)

Esatto, proprio così

Quindi nel tuo modello non hai un legame

reperto => poligono => us

ma

reperto => us
e
poligono => us

e quindi non sai ogni reperto in quale poligono cada, ho capito bene?

reperto(sito, area, us => us(sito,area,us) => poligono(sito, area, us)

e le relazioni sono

reperto N:1 us 1:N poligono

Quindi 1 reperto cade in N poligoni appartenenti alla medesima unità stratigrafica, così si verifica l’N a N che fa perdere la presenza di una chiave primaria univoca.

…bel casotto vero? Si capisce un po’ di più?

Quello che ho capito come regola per poter risolvere il problema è avere un doppio sistema di id nelle tre tabelle per poter fare il join dopo il passaggio del group by. Provo a scrivere un esempietto generale da sottoporre a tutti.

PS: Luca, mi arrivano le tua mail in privato e non sulla lista…ciao

Ciao Luca,

Il giorno ven, 03/06/2011 alle 09.14 +0200, Luca Mandolesi ha scritto:

Quindi 1 reperto cade in N poligoni appartenenti alla medesima unità
stratigrafica, così si verifica l'N a N che fa perdere la presenza di
una chiave primaria univoca.

....bel casotto vero? Si capisce un po' di più?

Per chi non è archeologo la cosa è effettivamente poco chiara... da
estraneo alla materia sarei portato a credere che per ogni reperto si
sappia dove è stato trovato (x,y), quindi anche in quale poligono cada.
O forse i diversi poligoni possono essere sovrapposti nello spazio
bidimensionale ma non nel tempo o nella profondità di scavo?

PS: Luca, mi arrivano le tua mail in privato e non sulla lista...ciao

Talvolta faccio reply anziché reply to all per sbaglio, ma nel tuo caso
erano osservazioni/chiarimenti che ritenevo di interesse solo tuo, salvo
poi il tuo obbligo morale di farci un bel riassunto a fine lavoro! :)))

A parte la sua specificità, trovo il tuo problema molto interessante,
penso sia così per altri nella lista.

Buon lavoro

Sig

_____________
PRIVACY
Le informazioni contenute in questo messaggio sono riservate e confidenziali. Il loro utilizzo e' consentito esclusivamente al destinatario del messaggio, per le finalità indicate nel messaggio stesso. Qualora Lei non fosse la persona a cui il presente messaggio è destinato, La invitiamo ad eliminarlo dal Suo Sistema e a distruggere le varie copie o stampe, dandone gentilmente comunicazione all’indirizzo mail del mittente. Ogni utilizzo improprio e' contrario ai principi del D.lgs 196/03 e alla legislazione europea (Direttiva 2002/58/CE).

PRIVACY
Le informazioni contenute in questo messaggio sono riservate e confidenziali. Il loro utilizzo e' consentito esclusivamente al destinatario del messaggio, per le finalità indicate nel messaggio stesso. Qualora Lei non fosse la persona a cui il presente messaggio è destinato, La invitiamo ad eliminarlo dal Suo Sistema e a distruggere le varie copie o stampe, dandone gentilmente comunicazione all’indirizzo mail del mittente. Ogni utilizzo improprio e' contrario ai principi del D.lgs 196/03 e alla legislazione europea (Direttiva 2002/58/CE).

Provo a splittare l’argomento:

archeologia

i reperti non sono posizionati x,y per motivi di praticità (anche se in alcune branche si fa o per casi eccezionali), ma sono semplicemente legati per identificatore di unità stratigrafica al poligono che la rappresenta.

In archeologia la regola sarebbe che 1 US → 1 poligono.

Tuttavia per praticità se una fossa è stata divisa in 2 dal passaggio al cento di un muro, al riempimento della fossa viene dato il medesimo numero di US che però saranno 2 poligoni distinti, divisi dal muro.

Il modo corretto sarebbe quello di dare 2 numeri differenti al riempimento della fossa e poi uguagliarli a livello di singola scheda US, così avremmo sempre N reperti x 1 poligono.


dal punto di vista postgres

Sono arrivato ad usare 2 serie parallele di identificatori, semplicemente perchè quando arrivo allo step in cui raggruppo le geometrie in base all’id_reperto [0], se inserisco nel select anche gli altri campi appartenenti alle us e ai reperti che mi servono per le ricerche che avevo già inserito nelle view precedenti, lui mi obbliga ad inserire tutti i campi nel Group by e quindi ritorno ad avere il problema iniziale.

Mi sorge un dubbio, non si può fare una query così?

CREATE OR REPLACE VIEW view1 AS
SELECT id_reperti AS new_id_reperti, st_union(the_geom) AS new_geom, campo1, campo2, campo3, campo4
FROM reperti_e_us_e_poligoni_view
GROUP BY new_id_reperti

Perchè si è costretti a inserire nel group by tutti i campi? Secondo me è qui che sbaglio…

Che ne dite?

[0]

CREATE OR REPLACE VIEW view1 AS
SELECT reperti_e_us_e_poligoni_view.id_reperti AS new_id_reperti, st_union(reperti_e_us_e_poligoni_view.the_geom) AS new_geom
FROM reperti_e_us_e_poligoni_view
GROUP BY reperti_e_us_e_poligoni_view.id_reperti;

Ciao Luca,

Il giorno ven, 03/06/2011 alle 11.12 +0200, Luca Mandolesi ha scritto:

Mi sorge un dubbio, non si può fare una query così?

CREATE OR REPLACE VIEW view1 AS
SELECT id_reperti AS new_id_reperti, st_union(the_geom) AS new_geom,
campo1, campo2, campo3, campo4
   FROM reperti_e_us_e_poligoni_view
  GROUP BY new_id_reperti

Perchè si è costretti a inserire nel group by tutti i campi? Secondo
me è qui che sbaglio...

Quando raggruppi, immagina la query in 2 tempi:

1. Applico le where e definisco i campi in uscita
2. Per ogni gruppo di record che presenta la stessa combinazione dei
campi indicati in GROUP BY, produco una sola riga in uscita

Quindi, un campo in uscita O appartiene al GROUP BY, O deve essere
associato ad un operatore che mi consenta di ottenere un solo valore da
molti record: min, max, avg, count etc.

Nel tuo caso, se sei sicuro che lo stesso ID_REPERTO si porti sempre
dietro gli stessi valori di sito, us e area, puoi semplicemente
indicare:

SELECT id_reperti AS new_id_reperti, st_union(the_geom) AS new_geom,
first(area), first(us), first(sito)

Con l'operatore di aggregazione first prendi semplicemente il primo
valore che trovi nel gruppo. Concettualmente è più corretto così che
inserendo us, sito e area nella group by, perché se vedo una query tipo:

select id, us, sito, area from... group by id, us, sito, area

mi aspetto che possano esistere diverse combinazioni di id, us, sito,
area.

Sig

_____________
PRIVACY
Le informazioni contenute in questo messaggio sono riservate e confidenziali. Il loro utilizzo e' consentito esclusivamente al destinatario del messaggio, per le finalità indicate nel messaggio stesso. Qualora Lei non fosse la persona a cui il presente messaggio è destinato, La invitiamo ad eliminarlo dal Suo Sistema e a distruggere le varie copie o stampe, dandone gentilmente comunicazione all’indirizzo mail del mittente. Ogni utilizzo improprio e' contrario ai principi del D.lgs 196/03 e alla legislazione europea (Direttiva 2002/58/CE).

PRIVACY
Le informazioni contenute in questo messaggio sono riservate e confidenziali. Il loro utilizzo e' consentito esclusivamente al destinatario del messaggio, per le finalità indicate nel messaggio stesso. Qualora Lei non fosse la persona a cui il presente messaggio è destinato, La invitiamo ad eliminarlo dal Suo Sistema e a distruggere le varie copie o stampe, dandone gentilmente comunicazione all’indirizzo mail del mittente. Ogni utilizzo improprio e' contrario ai principi del D.lgs 196/03 e alla legislazione europea (Direttiva 2002/58/CE).