Transferindo fluxos (conexões + valores) entre polígonos

14

No QGIS, existem dois shapefiles que representam os dados em movimento entre as células e uma camada adicional, veja a imagem abaixo

Example_of_shapefiles


Movendo dados definidos por:

  • Polígono "LayerA"(quadrados transparentes com contorno vermelho). Além disso, também se refere a círculos que representam os movimentos dentro das células, visualizados na posição dos "LayerA"geocentróides.

    LayerA_AT

  • Camada de polilinha "Flows"(setas amarelas / cinza), transmite valores por meio de conexões entre geocentróides de "LayerA"recursos

    Flows_AT


Camada alvo:

  • Polígono "LayerB"(recursos lilás claros com contorno cinza escuro).

    LayerB_AT

Além disso, já transferi "FLUX"e mova valores dentro das células "LayerA"para "LayerB"polígonos. Veja minha pergunta anterior: Valores herdados entre polígonos no QGIS? . Foi feita usando o %de $areacálculo.


Pode haver uma solução / abordagem significativa de transferência / transmissão / transformação de conexões de fluxo representadas por "Flows"e seus valores de relações de "LayerA"em relações de "LayerB".

Como posso conseguir essas conexões como polilinhas?

Além disso, novos fluxos herdarão um estilo semelhante ao "Flows".

A pedido, posso fornecer uma amostra dos dados.

Os fluxos existirão não entre os recursos de "LayerA", mas entre os recursos de "LayerB" . O objetivo principal é obter o atributo "FLUX"(isto é, de / para) para conexões entre "LayerB"possíveis como tabela / matriz de origem e destino.


Existem alguns requisitos / critérios que devem ser respeitados:

1. Não há conexões de fluxo entre as partes dos recursos (selecionadas em amarelo) na mesma célula

condição_1

2. Não há conexões entre o mesmo recurso, mesmo que suas partes estejam em células diferentes

condição_2

3. As conexões existem entre partes dos recursos "LayerB"(com base na "Union"saída) se estiverem inteiramente dentro de dois "LayerA"recursos de célula distintos

condição_3

4. O novo "FLUX"valor que está sendo transportado será calculado conforme mostrado na imagem abaixo.

Por exemplo, há uma conexão entre duas células Ie II, onde "FLUX"está 100. Assumindo outros valores, o "NEW_FLUX"entre A'e B''estará ao redor 1.5625. 100é apenas um exemplo.

condição_4


Referências:

Taras
fonte
1
Obrigado pela edição, começo a entender, mas não tenho muita certeza. Você pode editar sua postagem original mais uma vez para adicionar o resultado esperado? (por exemplo: linha de camada entre centroides polygon_b com esta campos abaixo: - "campo1": explicação, tentativas de Dados, etc.)
J. Monticolo
1
Para esclarecer, podemos discutir mais livremente nesta sala de bate-papo com IGE: chat.stackexchange.com/rooms/92038/… ?
J. Monticolo
1
Do ponto de vista técnico, tudo é factível, mas o que você realmente está tentando alcançar? Parece-me que você está tentando interpolar dados de uma grade generalizada para uma geografia mais refinada. A menos que eu entenda errado, isso pode levar a resultados muito enganosos. Se você não tiver dados sobre fluxos no nível "camada B", nenhum truque matemático poderá recriá-los. É o equivalente a aplicar zoom no nível de pixel e fazer uma rotação 3D usando uma imagem de baixa resolução em um filme de policiais impreciso.
MarHoff 09/04/19

Respostas:

4

Com as Camadas Virtuais, teoricamente, é possível (com shapefiles, o processo será muito longo, mas se as camadas estiverem em um Banco de Dados Espaciais, acho que é muito mais rápido).

Aqui o código:

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

A saída gráfica será semelhante a

Resultado

O resultado foi testado manualmente. A diferença de "FLUX"valores é negligenciável.

A saída final herdará estilos "Flow"e se parecerá com

Output_Final

Recomendo testá-lo com alguns dados e, se levar muito tempo para conjuntos de dados grandes, execute as consultas passo a passo ( "inter_ab", "new_flux") e salve o resultado e execute a próxima consulta.

J. Monticolo
fonte
1
Desculpe, eu sou francês e uso um banco de dados de município francês aberto como Polygon_bcamada, e é o campo principal id_geofla. Eu fiz a correção.
J. Monticolo
1
Eu adicionei explicações, espero que ajude.
J. Monticolo
1
Sim, é correto ter polígonos. Fiz correções para ter todas as camadas polygon_b e polygon_a . ** value ** se um fluxo fizer uma conexão. Para mim, o resultado não é uma camada de linha, mas diretamente a camada polygon_b com o valor polygon_a importado pela camada de fluxo .
J. Monticolo
4

Você pode fazer uma junção entre as três camadas e agregar por layerB. Camadas virtuais provavelmente podem ser usadas. Não tenho certeza se os dados importantes estão na layerAou na flowcamada. Aqui está uma possibilidade (não testada):

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
JGH
fonte
Eu tentei esta solução que funciona. Os dados importantes estão em "Flows".
Taras
@Taras Great! Você também pode usar agregados tais como sum(f.flow_var), ou mesmosum(fl.flow_var * a.poly_var)
JGH