Перенесення потоків (з'єднання + значення) між багатокутниками


14

У QGIS є два файли форми, що представляють рухомі дані між клітинками та одним додатковим шаром, див. Зображення нижче

Example_of_shapefiles


Переміщення даних, визначених:

  • Багатокутник "LayerA"(прозорі квадрати з червоним контуром). Крім того, він також відноситься до кіл, що представляють рухи всередині клітин, візуалізовані на позиції "LayerA"геоцентроїдів.

    ШарA_AT

  • Полілінійний шар "Flows"(жовті / сірі стрілки) передають значення за допомогою з'єднань між геоцентроїдами "LayerA"ознак

    Flows_AT


Цільовий шар:

  • Багатокутник "LayerB"(світло-бузкові риси з темно-сірими обрисами).

    ШарB_AT

Крім того, я вже передав "FLUX"і значення руху в клітинах з "LayerA"в "LayerB"багатокутники, см моїх попередніх питання: успадковані значень між полігонами в QGIS? . Це було зроблено з допомогою %з $areaрозрахунку.


Можливо, може бути осмислене рішення / підхід передачі / передачі / перетворення потокових з'єднань, представлених "Flows"та його значеннями з відносин "LayerA"у відносини "LayerB".

Як я можу досягти таких з'єднань як поліліній?

Крім того, нові потоки успадкують подібний стиль "Flows".

За запитом я можу надати зразок даних.

Потоки існуватимуть не між ознаками "LayerA", а між ознаками "LayerB" . Основна мета полягає у досягненні атрибуту "FLUX"(тобто від / до) для з'єднань між "LayerB"можливими як таблиця / Origin-Destination Matrix.


Є деякі вимоги / критерії, яких слід дотримуватися:

1. Немає потокових з'єднань між частинами функцій (вибраними жовтим кольором) в одній клітині

умова_1

2. Немає зв’язків між однією і тією ж особливістю, навіть її частини знаходяться в різних клітинках

умова_2

3. З'єднання існують між частинами ознак "LayerB"(на основі "Union"результату), якщо вони повністю знаходяться в двох різних "LayerA"елементах комірок

умова_3

4. Нове "FLUX"значення, яке передається, буде обчислено, як показано на зображенні нижче.

Наприклад, існує зв'язок між двома клітинками Iі II, де "FLUX"є 100. Припускаючи інші значення, "NEW_FLUX"між A'і B''буде навколо 1.5625. 100є лише окремим прикладом.

умова_4


Список літератури:


1
Дякую за редагування, я починаю розуміти, але не дуже впевнений. Чи можете ви відредагувати своє початкове повідомлення ще раз, щоб додати очікуваний результат? (наприклад: Рівень ліній між центроїдами polygon_b з цими полями нижче: - "field1": пояснення, спроби даних тощо)
J. Monticolo

1
Для уточнення, чи можемо ми більш вільно обговорювати цей чат GSE: chat.stackexchange.com/rooms/92038/… ?
Дж. Монтіколо

1
З технічної точки зору все можливе, але чого ви насправді намагаєтесь досягти? Мені здається, ви намагаєтесь інтерполювати дані з узагальненої сітки в більш дрібнозернисту географію. Якщо я не помилився, це може призвести до дуже оманливих результатів. Якщо у вас немає даних про потоки на рівні "рівня B", жодна математична хитрість не зможе їх відтворити. Це еквівалент масштабування під піксельним рівнем і обертання 3D, використовуючи зображення з низькою роздільною здатністю у неточному кінофільмі.
MarHoff

Відповіді:


4

З віртуальними шарами теоретично це можливо (із формними файлами процес буде дуже довгим, але якщо шари знаходяться в просторовій базі даних, я думаю, це набагато швидше).

Ось код:

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

Графічний вихід буде виглядати так

Вихідні дані

Результат тестували вручну. Різниця у "FLUX"значеннях нехтує.

Кінцевий висновок успадкує стилі від "Flow"та буде схожий

Вихідна_Конечна

Я рекомендую протестувати його з кількома даними, і якщо для великих наборів даних це займе багато часу, виконайте покрокові запити ( "inter_ab", "new_flux") і збережіть результат та виконайте наступний запит.


1
Вибачте, я французький, і я використовую відкриту базу даних французьких містечок як Polygon_bшар, і ключовим полем є id_geofla. Я зробив виправлення.
Дж. Монтіколо

1
Я додав пояснення, сподіваюся, що це допомагає.
Дж. Монтіколо

1
Так правильно мати багатокутники. Я вніс виправлення на цілі шари polygon_b та polygon_a . ** значення **, якщо потік здійснює з'єднання. Для мене результат - це не лінійний шар, а безпосередньо polygon_b шар зі значенням polygon_a, імпортованим потоковим шаром.
Дж. Монтіколо

4

Ви можете зробити з'єднання між трьома шарами, а потім об'єднати layerB. Віртуальні шари, ймовірно, можуть бути використані. Я не впевнений, чи важливі дані знаходяться в layerAабо в flowшарі. Ось така (неперевірена) можливість:

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

Я спробував це рішення, воно працює. Важливі дані є в "Flows".
Тарас

@Taras Чудово! Ви також можете використовувати такі агрегати, як, sum(f.flow_var)або навіть,sum(fl.flow_var * a.poly_var)
JGH
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.