Trasferimento di flussi (connessioni + valori) tra poligoni


14

In QGIS ci sono due shapefile che rappresentano i dati in movimento tra le celle e un livello aggiuntivo, vedi immagine sotto

Example_of_shapefiles


Spostamento dei dati definito da:

  • Poligono "LayerA"(quadrati trasparenti con contorno rosso). Inoltre si riferisce anche ai cerchi che rappresentano i movimenti all'interno delle cellule, visualizzati sulla posizione dei "LayerA"geocentroidi.

    LayerA_AT

  • Lo strato di polilinea "Flows"(frecce gialle / grigie) trasmette valori tramite connessioni tra geocentroidi di "LayerA"caratteristiche

    Flows_AT


Livello target:

  • Poligono "LayerB"(lineamenti lilla chiaro con contorno grigio scuro).

    LayerB_AT

Inoltre, ho già trasferito "FLUX"e valori di movimento all'interno delle cellule da "LayerA"in "LayerB"poligoni, vedere la mia domanda precedente: Ereditato valori compresi tra i poligoni in QGIS? . È stato fatto usando il %di$area calcolo.


Potrebbe esserci una soluzione / approccio significativo per trasferire / trasmettere / trasformare connessioni di flusso rappresentate da "Flows"e i suoi valori da relazioni di "LayerA"a relazioni di"LayerB" .

Come posso ottenere tali connessioni come polilinee?

Inoltre, i nuovi flussi erediteranno uno stile simile a "Flows" .

Su richiesta, posso fornire un campione di dati.

I flussi non esistono tra le funzionalità di "LayerA", ma tra le funzionalità di "LayerB" . L'obiettivo principale è quello di ottenere l'attributo "FLUX"(cioè da / a) per le connessioni tra "LayerB"possibili come tabella / matrice origine-destinazione.


Ci sono alcuni requisiti / criteri che dovrebbero essere rispettati:

1. Non ci sono connessioni di flusso tra le parti delle caratteristiche (selezionate in giallo) nella stessa cella

Condition_1

2. Non ci sono connessioni tra la stessa funzione anche se le sue parti sono in celle diverse

condition_2

3. Esistono connessioni tra parti di funzioni "LayerB"(basate "Union"sull'output) se si trovano interamente in due "LayerA"funzioni di celle distinte

condition_3

4. Nuovo"FLUX" valore trasmesso verrà calcolato come mostrato nell'immagine seguente.

Ad esempio, v'è una connessione tra due celle Ie II, dove "FLUX"è 100. Supponendo altri valori, "NEW_FLUX"tra A'e B''sarà in giro 1.5625. 100è solo un singolo esempio.

condition_4


Riferimenti:


1
Grazie per la modifica, comincio a capire ma non sono molto sicuro. Puoi modificare il tuo post originale ancora una volta per aggiungere il risultato previsto? (ad esempio: strato di linea tra i centroidi polygon_b con i campi seguenti: - "field1": spiegazione, dati tentati, ecc.)
J. Monticolo

1
Per chiarimenti, possiamo discutere più liberamente su questa chat room di GSE: chat.stackexchange.com/rooms/92038/… ?
J. Monticolo,

1
Da un punto di vista tecnico tutto è fattibile, ma cosa stai effettivamente cercando di ottenere? Mi sembra che tu stia cercando di interpolare i dati da una griglia generalizzata a una geografia più finemente dettagliata. A meno che non ti sbagli, questo può portare a risultati molto fuorvianti. Se non disponi di dati sui flussi a livello di "livello B", nessun trucco matematico può ricrearli. È l'equivalente dello zoom sotto il livello dei pixel e fai una rotazione 3D usando un'immagine a bassa risoluzione in un film di poliziotti impreciso.
MarHoff

Risposte:


4

Con i livelli virtuali, in teoria, è possibile (con gli shapefile, il processo sarà molto lungo, ma se i livelli si trovano in un database spaziale, penso che sia molto più veloce).

Ecco il codice:

WITH inter_ab AS ( 
--create intersection between LayerA and LayerB 
SELECT LayerA.id || '_' || LayerB.FLAECHEID AS id, 
LayerA.id AS id_a, 
ST_AREA(LayerA.geometry) AS area_a, 
LayerB.FLAECHEID AS id_b, 
ST_INTERSECTION(LayerB.geometry, LayerA.geometry) AS geom 
FROM LayerA, LayerB 
WHERE ST_INTERSECTION(layerB.geometry, layerA.geometry) IS NOT NULL 
),

--calculation of the new flux value 
new_flux AS (SELECT t1.id_b AS origine, 
t2.id_b AS dest, 
SUM(Flows.flux * ST_AREA(t1.geom) / t1.area_a * ST_AREA(t2.geom) / t2.area_a) AS value  
FROM inter_ab t1, inter_ab t2, flows 
-- no connection between the same feature 
WHERE t1.id <> t2.id 
-- rule 1 
AND t1.id_a <> t2.id_a 
-- rule 2 
AND t1.id_b <> t2.id_b 
-- get flow data 
AND flows.origine = t1.id_a 
AND flows.dest = t2.id_a 
GROUP BY t1.id_b, t2.id_b
)

--create flows between original layerB features
SELECT new_flux.origine,
new_flux.dest,
new_flux.value AS flux,
make_line(ST_CENTROID(t3.geometry), ST_CENTROID(t4.geometry)) AS geom --ST_MakeLine under postGIS
FROM LayerB t3,
LayerB t4,
new_flux
WHERE t3.FLAECHEID = new_flux.origine
AND t4.FLAECHEID = new_flux.dest

L'output grafico sarà simile

Produzione

Il risultato è stato testato manualmente. La differenza di "FLUX"valori è trascurabile.

L'output finale erediterà "Flow"e assomiglierà agli stili

Output_Final

Consiglio di testarlo con pochi dati e, se impiega troppo tempo per set di dati di grandi dimensioni, esegui le query passo dopo passo ("inter_ab" , "new_flux") e salvi il risultato ed esegui la query successiva.


1
Siamo spiacenti, sono francese e utilizzo un database di borgata francese aperto come Polygon_blayer, ed è il campo chiave id_geofla. Ho fatto la correzione.
J. Monticolo

1
Ho aggiunto spiegazioni, spero che aiuti.
J. Monticolo,

1
Sì, è corretto avere poligoni. Ho fatto le correzioni per avere l'intera polygon_b strati e polygon_a . ** ** valore se un flusso di stabilire una connessione. Per me, il risultato non è un livello di linea, ma direttamente un livello polygon_b con il valore polygon_a importato dal livello flusso .
J. Monticolo,

4

È possibile eseguire un join tra i tre livelli, quindi aggregare per layerB. È possibile utilizzare probabilmente i livelli virtuali. Non sono sicuro che i dati importanti si trovino nel layerAo nel flowlayer. Ecco una possibilità (non testata):

SELECT b.id, b.geometry, sum(a.myVar)
FROM layerB b
LEFT JOIN flow f
   ON ST_Intersects(ST_EndPoint(f.geometry),b.geometry)
 JOIN layerA a
   ON ST_Intersects(ST_StartPoint(f.geometry),a.geometry)
GROUP BY b.id

Ho provato questa soluzione che funziona. I dati importanti sono presenti "Flows".
Taras,

@Taras Great! Puoi anche usare aggregati come sum(f.flow_var)o anchesum(fl.flow_var * a.poly_var)
JGH
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.