13

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:

  • 1
    Thanks for the edit, I begin to understand but not very sure. Can you edit your original post one more time to add the expected result ? (for example : Line layer between polygon_b centroids with this fields below : - "field1" : explanation, attempted datas, etc.) – J. Monticolo Apr 5 at 11:27
  • 1
    For clarify, can we discuss more freely on this GSE chat room : chat.stackexchange.com/rooms/92038/… ? – J. Monticolo Apr 5 at 11:49
  • 1
    From a technical standpoint everything is doable, but what are you actually trying to achieve? Seems to me that you are trying to interpolate data from a generalize grid to a more finely grained geography. Unless i got you wrong, this can lead to very misleading results. If you don't have data about flows at the "layer B" level, no mathematic trickery can recreate them. It's the equivalent of zooming under pixel level and do a 3D rotation using a low resolution picture in an inaccurate cops movie. – MarHoff Apr 9 at 12:14
3
+200

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.

  • 1
    Sorry, I'm french and I use an open french township database as Polygon_b layer, and it's key field is id_geofla. I made the correction. – J. Monticolo Apr 4 at 11:31
  • 1
    I have added explanations, hope that helps. – J. Monticolo Apr 5 at 8:11
  • 1
    Yes its correct to have polygons. I've made corrections for have the whole polygon_b layers and polygon_a.**value** if a flow make a connection. For me, the result is not a line layer, but directly polygon_b layer with the polygon_a value imported by flow layer. – J. Monticolo Apr 5 at 9:04
4

You could do a join between the three layers, then aggregate by layerB. Virtual layers can likely be used. I am not sure if the important data is in layerA or in the flow layer.. Here is an (untested) possibility:

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
  • I have tried this solution it works. The important data is in "Flows". – Taras Apr 4 at 10:42
  • @Taras Great! You can also use aggregates such as sum(f.flow_var) or even sum(fl.flow_var * a.poly_var) – JGH Apr 4 at 12:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.