In QGIS there are two shapefiles representing the moving data between cells and one additional layer, see image below
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.Polyline layer
"Flows"
(yellow/grey arrows), convey values via connections between geocentroids of"LayerA"
features
Target layer:
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
2. There are no connections between the same feature even its parts are in different cells
3. Connections exist between parts of features "LayerB"
(based on "Union"
output) if they are entirely within two distinct "LayerA"
cell features
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.
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
The result was tested manually. The difference in "FLUX"
values is neglectable.
The final output will inherit styles from "Flow"
and look like
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