Przenoszenie przepływów (połączenia + wartości) między wielokątami


14

W QGIS istnieją dwa pliki kształtów reprezentujące ruchome dane między komórkami i jedną dodatkową warstwą, patrz zdjęcie poniżej

Przykład_plików_kształtów


Przenoszenie danych zdefiniowane przez:

  • Wielokąt "LayerA"(przezroczyste kwadraty z czerwonym konturem). Poza tym odnosi się również do kręgów reprezentujących ruchy w komórkach, wizualizowane na pozycji "LayerA"geocentroidów.

    Warstwa A_AT

  • Warstwa polilinii "Flows"(żółte / szare strzałki), przekazuje wartości poprzez połączenia między geocentroidami "LayerA"obiektów

    Flows_AT


Warstwa docelowa:

  • Wielokąt "LayerB"(jasny liliowy kolor z ciemnoszarym konturem).

    WarstwaB_AT

Dodatkowo, już przeniesione "FLUX"i wartości ruchu w komórkach od "LayerA"do "LayerB"wielokątów, patrz moje poprzednie pytanie: dziedziczone wartości pomiędzy wielokątów w QGIS? . Stało się to za pomocą %z $areaobliczeń.


Może istnieć sensowne rozwiązanie / podejście do przesyłania / przesyłania / przekształcania połączeń przepływowych reprezentowanych przez "Flows"i jego wartości z relacji "LayerA"do relacji "LayerB".

Jak mogę uzyskać te połączenia jako polilinie?

Ponadto nowe przepływy odziedziczą podobny styl "Flows".

Na żądanie mogę podać próbkę danych.

Przepływy będą istniały nie między cechami "LayerA", ale między cechami "LayerB" . Głównym celem jest uzyskanie atrybutu "FLUX"(tj. Z / do) dla połączeń między "LayerB"możliwymi jako tabela / matryca początkowa-docelowa.


Istnieje kilka wymagań / kryteriów, których należy przestrzegać:

1. Brak połączeń przepływowych między częściami elementów (zaznaczonymi na żółto) w tej samej komórce

warunek_1

2. Nie ma połączeń między tą samą funkcją, nawet jej części znajdują się w różnych komórkach

stan_2

3. Istnieją połączenia między częściami elementów "LayerB"(na podstawie "Union"danych wyjściowych), jeśli są one całkowicie w obrębie dwóch odrębnych "LayerA"elementów komórki

stan_3

4. Nowa "FLUX"wartość, która jest przenoszona, zostanie obliczona, jak pokazano na obrazku poniżej.

Na przykład istnieje połączenie między dwiema komórkami Ii II, gdzie "FLUX"jest 100. Zakładając inne wartości, "NEW_FLUX"pomiędzy A'i B''będą wokół 1.5625. 100to tylko jeden przykład.

warunek_4


Bibliografia:


1
Dzięki za edycję, zaczynam rozumieć, ale nie jestem pewien. Czy możesz edytować swój pierwotny post jeszcze raz, aby dodać oczekiwany wynik? (na przykład: Warstwa liniowa między centroidami polygon_b z tymi polami poniżej: - „field1”: wyjaśnienie, próby danych itd.)
J. Monticolo

1
Dla wyjaśnienia, czy możemy swobodniej dyskutować na tym czacie GSE: chat.stackexchange.com/rooms/92038/... ?
J. Monticolo,

1
Z technicznego punktu widzenia wszystko jest wykonalne, ale co tak naprawdę próbujesz osiągnąć? Wydaje mi się, że próbujesz interpolować dane z siatki uogólnionej do bardziej szczegółowej geografii. O ile się nie pomyliłem, może to prowadzić do bardzo mylących wyników. Jeśli nie masz danych o przepływach na poziomie „warstwy B”, żadne matematyczne sztuczki nie mogą ich odtworzyć. Jest to odpowiednik powiększania poniżej poziomu pikseli i wykonywania obrotu 3D przy użyciu obrazu o niskiej rozdzielczości w niedokładnym filmie gliniarzy.
MarHoff,

Odpowiedzi:


4

Z Wirtualnymi Warstwami teoretycznie jest to możliwe (w przypadku plików kształtów proces będzie wyjątkowo długi, ale jeśli warstwy znajdują się w Przestrzennej bazie danych, myślę, że jest to o wiele szybsze).

Oto kod:

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

Będzie wyglądać wyjście graficzne

Wynik

Wynik został przetestowany ręcznie. Różnica "FLUX"wartości jest pomijalna.

Ostateczne wyjście odziedziczy style "Flow"i będzie wyglądać

Output_Final

Polecam przetestować go z kilkoma danymi, a jeśli zajmuje to zbyt dużo czasu dla dużych zestawów danych, wykonaj krok po kroku zapytania ( "inter_ab", "new_flux") i zapisz wynik i wykonaj następne zapytanie.


1
Przepraszam, jestem Francuzem i używam otwartej bazy danych francuskiego miasteczka jako Polygon_bwarstwy, a jej kluczowym polem jest id_geofla. Dokonałem korekty.
J. Monticolo,

1
Dodałem wyjaśnienia, mam nadzieję, że to pomoże.
J. Monticolo,

1
Tak, poprawne jest mieć wielokąty. Wprowadziłem poprawki dla wszystkich warstw polygon_b i polygon_a . ** wartość **, jeśli przepływ tworzy połączenie. Dla mnie wynikiem nie jest warstwa liniowa, ale bezpośrednio warstwa polygon_b z wartością polygon_a importowaną przez warstwę przepływową .
J. Monticolo,

4

Możesz wykonać połączenie między trzema warstwami, a następnie agregować według layerB. Prawdopodobnie można zastosować warstwy wirtualne. Nie jestem pewien, czy ważne dane są w warstwie, layerAczy w flowwarstwie. Oto (niesprawdzona) możliwość:

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

Wypróbowałem to rozwiązanie, które działa. Ważne dane są w "Flows".
Taras,

@Taras Świetnie! Możesz także użyć agregatów takich jak sum(f.flow_var)lub nawetsum(fl.flow_var * a.poly_var)
JGH
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.