Monday 29 June 2015

qgis - Transferring flows (connections + values) between polygons


In QGIS there are two shapefiles representing the moving data between cells and one additional layer, see image below


Example_of_shapefiles






Moving data defined by:





  • Polygon "LayerA" (transparent squares with red outline). Besides it also relates to circles representing the movements within cells, visualized on the position of "LayerA" geocentroids.


    LayerA_AT





  • Polyline layer "Flows" (yellow/grey arrows), convey values via connections between geocentroids of "LayerA" features


    Flows_AT







Target layer:






  • Polygon "LayerB" (light lilac features with dark grey outline).


    LayerB_AT




Additionally, I have already transferred "FLUX" and movement values within cells from "LayerA" into "LayerB" polygons, see my previous question: Inherited values between polygons in QGIS?. It was done using the % of $area calculation.




There might be a meaningful solution/approach of transferring/transmitting/transforming flow connections represented by "Flows" and its values from relations of "LayerA" into relations of "LayerB".


How can I achieve those connections as polylines?


Additionally, new flows will inherit a similar style to "Flows".


By the request, I can provide a sample of the data.



Flows will exist not between features of "LayerA", but between features of "LayerB". The main aim is to achieve the attribute "FLUX" (i.e. from/to) for connections between"LayerB" possible as table/Origin-Destination Matrix.




There are some requirements/criteria that should be adhered:


1. There are no flow connections between features' parts (selected in yellow) in the same cell


condition_1


2. There are no connections between the same feature even its parts are in different cells


condition_2


3. Connections exist between parts of features "LayerB" (based on "Union" output) if they are entirely within two distinct "LayerA" cell features


condition_3


4. New "FLUX"-value that is conveying, will be calculated as shown on the image below.



For instance, there is a connection between two cells I and II, where "FLUX" is 100. Assuming other values, the "NEW_FLUX" between A' and B'' will be around 1.5625. 100 is only a single example.


condition_4




References:




Answer



With the Virtual Layers, theoretically, it's possible (with shapefiles, the process will be extra long, but if the layers are in a Spatial Database, I think it is a lot faster).


Here the 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

The graphical output will look like


Output


The result was tested manually. The difference in "FLUX" values is neglectable.



The final output will inherit styles from "Flow" and look like


Output_Final


I recommend to test it with a few data, and if it takes too long for large data sets, execute step by step the queries ("inter_ab", "new_flux") and save the result and execute the next query.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...