Errori: ERRORE: 1 modifica al valore attributo non applicato.
Errori della sorgente dati:
La modifica dell'identificativo elemento dell'elemento 2460 non è consentita.
Grazie a tutti
--
Hai ricevuto questo messaggio perché sei iscritto al gruppo "QGIS_Utenti_FVG" di Google Gruppi.
Per annullare l'iscrizione a questo gruppo e non ricevere più le sue email, invia un'email a qgis_utenti_f...@googlegroups.com.
Per visualizzare questa discussione sul Web, visita https://groups.google.com/d/msgid/qgis_utenti_fvg/c3843f9a-63d3-42c6-89a1-40d01c281f3an%40googlegroups.com.
l'attributo "fid": Valore "Genera automaticamente" non è un numero
Impossibile scrivere l'elemento
Per visualizzare questa discussione sul Web, visita https://groups.google.com/d/msgid/qgis_utenti_fvg/9268395a-ab54-48a8-b73b-d696bb340149n%40googlegroups.com.
Ciao
Postgis è uno strumento molto potente, il linguaggio è un dialetto SQL (postgresql) con funzioni tipiche introdotte da postgis.
A me ha completamente cambiato il modo di lavorare in GIS, velocizzando brutalmente alcune attività di codifica che prima potevano essere macchinose e spesso portavano a crash di qgis soprattutto se lavoravo su grosse moli dati..
Le “Topological Relationships” di Postgis sono l’omologo delle funzioni del “seleziona per posizione” di qgis, solo che dal mio punto di vista sono molto più customizzabili, ti permettono di lavorare su moli enormi di dati in un colpo e ti evitano di generare una pletora di file temporanei che sono error-prone.
Ti faccio un esempio che potrebbe adattarsi ai “fid” del tuo caso.
Hai una serie di poligoni in una tabella di geodb postgis (per comodità postgis dato che è quello che conosco di più) ed una serie di altri poligoni in una tabella sempre postgis.
La prima serie è una tabella “nuova” del geodb con la colonna geom (geometria) ed un campo vuoto, chiamiamolo “fid_nuovo”, la seconda “vecchia” è sempre una tabella di geometrie, con colonna geom (diversa da quella della tabella nuova) e campo “fid_vecchio”. Mettiamo per comodità che le geometrie delle due tabelle siano con lo stesso SRID.
Tu vuoi popolare il campo “fid_nuovo” coi valori presi dal campo “fid_vecchio” usando una funzione topologica di contenimento, meglio se fatta su centroide della geometria “vecchia”, ma puoi fare viceversa, vedi tu.
In postgis la funzione che ti lega spazialmente per contenimento le due tabelle è st_contains(geom-a, geom-b)
https://postgis.net/docs/ST_Contains.html
ovvero la condizione topologica che verifica il legame è “geometria-a contiene geometria-b”
la funzione che data una geometria ti ritorna il relativo centroide è st_centroid(geom)
https://postgis.net/docs/ST_Centroid.html
una possibile sintassi in postgis (ve ne sono tante differenti) che mette in relazione le due tabelle rispetto alle posizioni reciproche delle geometrie è
SELECT vecchia. fid_vecchio, nuova. fid_nuovo
FROM
vecchia, nuova
WHERE
St_contains(nuova.geom, st_centroid(vecchia.geom))
Ovvero
Seleziona il campo fid_vecchio dalla tabella vecchia, seleziona il campo fid_nuovo dalla tabella nuova
Nei casi in cui
La geometria nella tabella vecchia contiene la geometria della tabella nuova (trasformata al volo in centroide).
Ti uscirà un listato di fid_nuovi senza valore con di fianco i corrispettivi fid_vecchi (si spera in rapporto 1:1 ma non è detto, dato che un centroide di una feature non necessariamente cade dentro la feature omologa/adiacente… puoi provare a ricorrere ad altre funzioni di trasformazione, come
https://postgis.net/docs/ST_PointOnSurface.html
https://postgis.net/docs/ST_GeometricMedian.html
ecc ecc)
A questo punto se il rapporto è 1:1 puoi fare
UPDATE nuova
SET
fid_nuovo= fid_vecchio
FROM
vecchia
WHERE
St_contains(nuova.geom, st_centroid(vecchia.geom))
Ovvero
Aggiorna la tabella nuova
Popola il campo fid_nuovo di modo che sia uguale a fid_vecchio
Preso dalla tabella vecchia
Solo nel caso in cui la geometria della tabella nuova contiene il centroide della geometria della tabella vecchia.
Naturalmente il tipo di dati del campo fid_nuovo deve poter contenere i dati del campo fid_vecchio
Esempio
Fid_nuovo è integer (intero), fid_vecchio ti sembra sia integer (contiene numeri interi) ma è memorizzato in un campo testo.
Postgis non ti permette di fare il travaso e darà errore (integer non può contenere testo)
In questo caso farò un “cast”
UPDATE nuova
SET
fid_nuovo= fid_vecchio::integer
FROM
vecchia
WHERE
St_contains(nuova.geom, st_centroid(vecchia.geom))
:: vuol dire “cosideralo come”
fid_vecchio::integer considera fid_vecchio come intero, anche se è in una colonna testo
https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-cast/
Metti il caso in cui gli SRID differiscano e che la tua tabella vecchia sia in 4326 (WGS84 lat/long) e la tua tabella nuova sia in 32633 (UTM33N/WGS84),
si possono riproiettare al volo le geometrie con la funzione st_transform(geom, srid)
https://postgis.net/docs/ST_Transform.html
la sintassi sarà
UPDATE nuova
SET
fid_nuovo= fid_vecchio::integer
FROM
vecchia
WHERE
St_contains(nuova.geom, st_transform(st_centroid(vecchia.geom),32633))
Ovvero
Aggiorna la tabella nuova
Fai sì che fid_nuovo sia uguale a fid_vecchio (considerato come intero)
Preso da vecchia
Nel caso in cui
La geometria nuova (32633) contiene il centroide della geometria vecchia (4326) riproiettato al volo in 32633
Conviene riproiettare il centroide e non il poligono per questioni di uso di risorse computazionali (riproiettare 1 punto “costa meno” che riproiettare n vertici)
Puoi lavorare per sottoinsiemi.
Metti che un centroide della tabella vecchia sia contenuto in più di un poligono della nuova, il fid_vecchio sarà presente “n” volte nel primo listato
Puoi fare una sottoquery (o query annidata) che seleziona solamente i fid_vecchi che sono presenti una sola volta (rapporto 1:1)
Select fid_vecchio FROM (
SELECT vecchia. fid_vecchio, count(vecchia. fid_vecchio) as conteggio_vecchi
FROM
vecchia, nuova
WHERE
St_contains(nuova.geom, st_centroid(vecchia.geom))
GROUP BY vecchia. fid_vecchio
) as sottoquery
Where conteggio_vecchi=1
Ovvero seleziona la lista dei fid_vecchi contati una sola volta quando rapportati alle geometrie nuove.
Questa la usi come sottoquery nella query di aggiornamento
UPDATE nuova
SET
fid_nuovo= fid_vecchio::integer
FROM
vecchia
WHERE
-- condizione 1, sottoquery
fid_vecchio in(
Select fid_vecchio FROM (
SELECT vecchia. fid_vecchio, count(vecchia. fid_vecchio) as conteggio_vecchi
FROM
vecchia, nuova
WHERE
St_contains(nuova.geom, st_centroid(vecchia.geom))
GROUP BY vecchia. fid_vecchio
) as sottoquery
Where conteggio_vecchi=1
)
AND
-- Condizione 2, contenimento
St_contains(nuova.geom, st_centroid(vecchia.geom))
Ovvero mi aggiorni come sopra usando due condizioni:
1: I fid_vecchi sono compresi in un insieme di fid_vecchi contati una sola volta (sottoquery)
E
2: le geometrie vecchie (intese come centroide) sono contenute nei poligoni delle geometrie nuove
Fatto l’update ti potranno rimanere tot geometrie nuove senza fid_nuovo popolato, ti concentrerai solo su queste per vedere come fare a ricavare i corrispettivi fid_vecchi.
Potrai ad esempio traslare i centroidi delle geometrie vecchie di tot se vedi che lo spostamento del centroide del vecchio è costante rispetto ai poligoni nuovi.
Ad esempio con ST_Translate(geometry g1, float deltax, float deltay)
https://postgis.net/docs/ST_Translate.html
Metti che le differenze siano di 50m in x e 100 in Y costanti
UPDATE nuova
SET
fid_nuovo= fid_vecchio
FROM
vecchia
WHERE
fid_nuovo is NULL
AND
St_contains(nuova.geom, st_translate(st_centroid(vecchia.geom)), 50, 100)
Ovvero
Aggiorna fid_nuovo della tabella nuova copiando i valori del fid_vecchio della tabella vecchia
Solo nel caso in cui fid_nuovo non sia già stato popolato precedentemente (fid_nuovo is NULL)
E
La geometria del nuovo contiene il centroide della geometria vecchia spostato di 50m in X e 100 in Y
Anyway, questi sono esempi base sulle potenzialità dello strumento, le ho messe lì per far venire un po’ di gola ;)
Due tabelle postgis, nuova e vecchia, nessun passaggio intermedio, fine delle tabelle/shp file temporanei in giro per i dischi.
Aggiornamento di N campi al volo, nell’esempio uno solo ma puoi usarne quanti vuoi
SET nuovo_1= vecchio_1, nuovo_2= vecchio_2, nuovo_n= vecchio_n
Eseguibili su moli di dati enormi
Stratificabili per area (metti ad esempio di introdurre un’ulteriore sottoquery che restringe le operazioni a singoli comuni, presenti in una terza tabella postgis) o per tipologia di copertura del suolo (sottoquery sul Corine Land Cover) ecc ecc
Query di testo salvabili e ripetibili secondo necessità..
Per me Game Changer
Buon corso ;)
Pietro
P.S.
L’SQL qui sopra può aver errori, non l’ho eseguito quindi non so se c’è qualche refuso, ma indicativamente dovrebbe essere corretto
Da: qgis_ut...@googlegroups.com <qgis_ut...@googlegroups.com>
Per conto di Francesco Carbone
Inviato: venerdì 22 settembre 2023 07:59
A: QGIS_Utenti_FVG <qgis_ut...@googlegroups.com>
Oggetto: Re: [qgis_utenti_fvg:578] Re: problema con fid durante "fusione attributi elemento" tra diverse geometrie
Per visualizzare questa discussione sul Web, visita https://groups.google.com/d/msgid/qgis_utenti_fvg/2c7ec47c-f610-4b35-b32f-8591bc3609f6n%40googlegroups.com.