Transfert de flux (connexions + valeurs) entre polygones

14

Dans QGIS, il y a deux fichiers de formes représentant les données en mouvement entre les cellules et une couche supplémentaire, voir l'image ci-dessous

Example_of_shapefiles


Déplacement de données défini par:

  • Polygone "LayerA"(carrés transparents avec contour rouge). En outre, il concerne également les cercles représentant les mouvements à l'intérieur des cellules, visualisés sur la position des "LayerA"géocentroïdes.

    LayerA_AT

  • Couche de polyligne "Flows"(flèches jaunes / grises), transmet des valeurs via des connexions entre géocentroïdes d' "LayerA"entités

    Flows_AT


Couche cible:

  • Polygone "LayerB"(traits lilas clair avec contour gris foncé).

    LayerB_AT

De plus, j'ai déjà transféré "FLUX"et déplacé des valeurs dans des cellules de "LayerA"vers des "LayerB"polygones, voir ma question précédente: valeurs héritées entre polygones dans QGIS? . Il a été fait en utilisant le %de $areacalcul.


Il pourrait y avoir une solution / approche significative de transfert / transmission / transformation des connexions de flux représentées par "Flows"et ses valeurs de relations de "LayerA"en relations de "LayerB".

Comment puis-je réaliser ces connexions en tant que polylignes?

De plus, les nouveaux flux hériteront d'un style similaire à "Flows".

À la demande, je peux fournir un échantillon des données.

Les flux n'existeront pas entre les caractéristiques de "LayerA", mais entre les caractéristiques de "LayerB" . L'objectif principal est d'obtenir l'attribut "FLUX"(c'est-à-dire de / à) pour les connexions entre "LayerB"possible comme table / matrice origine-destination.


Certaines exigences / certains critères doivent être respectés:

1. Il n'y a pas de connexions de flux entre les pièces des entités (sélectionnées en jaune) dans la même cellule

condition_1

2. Il n'y a pas de connexions entre la même fonction, même si ses parties sont dans des cellules différentes

condition_2

3. Des connexions existent entre des parties d'entités "LayerB"(basées sur la "Union"sortie) si elles se trouvent entièrement dans deux "LayerA"entités de cellule distinctes

condition_3

4. La nouvelle valeur "FLUX"transmise sera calculée comme indiqué sur l'image ci-dessous.

Par exemple, il existe une connexion entre deux cellules Iet II, où "FLUX"est 100. En supposant d'autres valeurs, l' "NEW_FLUX"entre A'et B''sera autour 1.5625. 100n'est qu'un seul exemple.

condition_4


Les références:

Taras
la source
1
Merci pour le montage, je commence à comprendre mais pas très sûr. Pouvez-vous modifier votre message d'origine une fois de plus pour ajouter le résultat attendu? (par exemple: Couche de ligne entre les centroïdes polygon_b avec les champs ci-dessous: - "champ1": explication, tentatives de données, etc.)
J. Monticolo
1
Pour clarifier, pouvons-nous discuter plus librement sur cette salle de chat GSE: chat.stackexchange.com/rooms/92038/… ?
J.Monticolo
1
D'un point de vue technique, tout est faisable, mais qu'essayez-vous réellement d'atteindre? Il me semble que vous essayez d'interpoler des données d'une grille généralisée à une géographie plus fine. À moins que je ne me trompe, cela peut conduire à des résultats très trompeurs. Si vous ne disposez pas de données sur les flux au niveau de la "couche B", aucune ruse mathématique ne peut les recréer. C'est l'équivalent d'un zoom sous le niveau des pixels et d'une rotation 3D en utilisant une image basse résolution dans un film de flics inexact.
MarHoff

Réponses:

4

Avec les couches virtuelles, théoriquement, c'est possible (avec les fichiers de formes, le processus sera très long, mais si les couches sont dans une base de données spatiale, je pense que c'est beaucoup plus rapide).

Voici le code:

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

La sortie graphique ressemblera à

Production

Le résultat a été testé manuellement. La différence de "FLUX"valeurs est négligeable.

La sortie finale héritera des styles "Flow"et ressemblera à

Output_Final

Je recommande de le tester avec quelques données, et si cela prend trop de temps pour les grands ensembles de données, exécutez pas à pas les requêtes ( "inter_ab", "new_flux") et enregistrez le résultat et exécutez la requête suivante.

J. Monticolo
la source
1
Désolé, je suis français et j'utilise une base de données de cantons français ouverte comme Polygon_bcouche, et son champ clé est id_geofla. J'ai fait la correction.
J. Monticolo
1
J'ai ajouté des explications, j'espère que ça aide.
J. Monticolo
1
Oui, c'est correct d'avoir des polygones. J'ai fait des corrections pour avoir l'ensemble des couches polygon_b et polygon_a . ** valeur ** si un flux établit une connexion. Pour moi, le résultat n'est pas une couche linéaire, mais directement une couche polygon_b avec la valeur polygon_a importée par la couche de flux .
J. Monticolo
4

Vous pouvez faire une jointure entre les trois couches, puis agréger par layerB. Les couches virtuelles peuvent probablement être utilisées. Je ne sais pas si les données importantes sont dans layerAou dans la flowcouche .. Voici une possibilité (non testée):

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
la source
J'ai essayé cette solution ça marche. Les données importantes sont là "Flows".
Taras
@Taras Great! Vous pouvez également utiliser des agrégats tels que sum(f.flow_var)ou mêmesum(fl.flow_var * a.poly_var)
JGH