Рекурсивний запит PostGIS на основі підключення рядків


9

У мене виникають труднощі із запитом. У мене є мережа рядків рядків, кожна зі значенням у колонці n_type. Це може бути одним із кількох варіантів. Я хотів би створити нову таблицю, яка групує будь-які рядки рядків одного типу і утворюють суцільну лінію.

Перед:

введіть тут опис зображення

Після:

введіть тут опис зображення

Ось що я отримав досі. Він повертає результати, але вони не мають ніякого сенсу - типи не збігаються, і він повертає занадто багато функцій.

Зауважте також, що я визначив "безперервну" будь-яку лінію в межах 5 футів від її сусіда і зустрічається під кутом менше 30 градусів.

WITH RECURSIVE all_links (i, pk_uid, n_type, geom) AS (
    SELECT  1 AS i,
            pk_uid,
            n_type,
            geom
    FROM    network
    WHERE   n_type != 'none'

    UNION ALL

    SELECT  a.i + 1,
            b.pk_uid,
            b.n_type,
            b.geom
    FROM    network b, all_links a
    WHERE   b.n_type = a.n_type
    AND     b.geom <#> a.geom <= 5  --lines are continuous if within 5 feet of neighbor
    AND     ABS( DEGREES( 3*pi() - st_azimuth(st_startpoint(a.geom),st_endpoint(a.geom)) + st_azimuth(st_startpoint(b.geom),st_endpoint(b.geom)))::int % 360 - 180) <= 30 )  --only take links within 30 degrees of the same angle

SELECT i, n_type, ST_Union(the_geom) FROM all_links GROUP BY i, n_type

Я припустив, що рекурсивний запит - це дорога, але я радий, що я помилявся на цьому. Рекурсиви трохи важко впорядкувати.

Редагувати: Я також повинен додати, що я вже спробував агрегувати за допомогою ST_Union та ST_Linemerge, а потім демпінгував результат. Цей вид працює, але не враховує> 30 градусів перехрестя, а також не може вшанувати толерантність п’яти футів для підключення.


Не заглиблюючись до цього, пара спостережень. Вам потрібно буде об'єднати a.geom і b.geom у виберіть пункт. Напевно, ви повинні переконатися, що ви також не спробуєте приєднатись до лінії, а такожa.pk_uid != b.pk_uid
MickyT

@MickyT спасибі Я мав би зазначити, що я можу зробити об'єднання в останньому пункті SELECT, але поки що тільки вибрав *, щоб я міг бачити всі результати. Я зміню фрагмент коду, щоб показати, яким він повинен виглядати в кінцевому підсумку.
spencerrecneps

Рекурсивні запити важко застосувати. Лол і +1
Джон Пауелл

Швидкий огляд підказує, що у вас можуть виникнути проблеми з базовим / якірним запитом. Вам потрібно вибрати початкову точку для кожного рядка - A, B, C тощо, яку ви потім збираєте в рекурсивній частині. Можливо, вам потрібно додати якісь замовлення до запиту якоря (можливо, у x чи y, напрямок - важко пізнати, не бачачи даних). Я би розбив це і переконався, що спочатку отримую розумні стартові точки, перш ніж продовжувати рекурсивну частину. Нещодавно я використовував рекурсивний запит, щоб знайти смуги у часових рядах, і як тільки я правильно визначив опорні точки, все було легко (іш)
Джон Пауелл

@dbaston Хороший момент, але ви можете це зробити і за допомогою рекурсивного запиту, і ще не у кожного встановлений такий.
Джон Пауелл

Відповіді:


1

Принаймні, у вашому рішенні відсутнє попереднє замовлення компонентів лінії, як сказав Джон Барса.

Я б сказала, що рекурсивні запити дуже і дуже важкі.

Ви повинні спробувати повторити поведінку ST_Linemerge в новій функції бази даних. Спершу я спробую переглянути джерело реалізації ST_Linemerge та повторити його, змінивши його для отримання кутового посмикування 30 градусів.

Щоб відкинути від агрегування відрізки, які не знаходяться під кутом <30 град., Необхідно порівняти їх ВНУТРІ петлі агрегації.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.