Аналіз ребер полігону PostGIS (орієнтація, довжина ребра)


9

Я досить новачок у світі ГІС і особливо PostGIS, тому, вибачте, якщо відповідь здасться очевидною ...

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

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

Таблиця результатів може виглядати приблизно так:

building_id | edge_id | orientation | edge_length
-------------------------------------------------
      1     |    1    |     315     |    10.0
      1     |    2    |      45     |     7.0
      1     |   ...   |     ...     |     ...

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

  1. Чи є ефективна функція PostGIS, яка може аналізувати краї полігону? У випадку, якщо немає вбудованої функції PostGIS, я також зацікавився б підходом на основі Python.
  2. Що було б розумним способом зберігання результату в таблиці PostGIS, оскільки полігони можуть мати різну кількість ребер?

2
Спочатку створіть відрізки багатокутника: stackoverflow.com/questions/7595635/… Потім координати початкової точки та кінцевої точки повинні перейти до стовпців, таких як x1, y1 та x2, y2 та ніж ST_Azimuth (ST_Startpoint (геометрії), ST_Endpoint (геометрії)) . ( postgis.org/docs/ST_Azimuth.html )
Тамас Коса

1
@TamasKosa: у вас суть хорошої відповіді. Чому б не розширити її в одну? Також для нормалів азимути потребують +/- pi / 2.
Мартін Ф

1
@TamasKosa Це такий підхід, про який я також думав. Використовуйте ST_ExteriorRing, а потім отримайте азимути, як ви говорите. Як я б в ідеалі зберігав результати, оскільки будівлі можуть мати різну кількість країв? У таблиці, як я описав вище? Я згоден з MartinF, це майже відповідь;)
n1000

Просто цікаво, чому ви хочете нормалізуватись ... опромінення сонця?
Мартін Ф

1
Перша частина вашого питання отримала відповідь - ви можете використовувати ST_Dumppoints та ST_Azimuth. У другій частині, оскільки немає просторових елементів до виводу, я б подумав, що буде знайдено посилання на polygonID та edge_id.
Джон Пауелл

Відповіді:


10

Вчора у мене не було часу створити його детально ... Дивіться своє рішення в 4 кроки:

CREATE OR REPLACE VIEW bd_segment AS
SELECT
      ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) AS sp,
      ST_PointN(geom, generate_series(2, ST_NPoints(geom)  )) AS ep
    FROM
       -- extract the individual linestrings
       (SELECT (ST_Dump(ST_Boundary(the_geom))).geom
       FROM bd) AS linestrings;

CREATE OR REPLACE VIEW bd_segment_geom AS
SELECT sp, ep, st_makeline(sp, ep) 
FROM bd_segment;

CREATE OR REPLACE view bd_segment_id AS 
SELECT bd.gid, row_number() 
    OVER (order by bd.gid), degrees(st_azimuth(ff.sp, ff.ep)-1.57079633) AS az_deg,
    ST_LENGTH(ff.st_makeline) , ff.st_makeline FROM bd_segment_geom ff
JOIN bd ON st_touches(ff.st_makeline, bd.the_geom)
GROUP BY bd.gid, ff.sp, ff.ep, ff.st_makeline;

UPDATE bd_segment_id
SET az_deg = az_deg + 360
WHERE az_deg < 0;

Останній запит дає вам ідентифікатори будівельних конструкцій з просторовим з'єднанням за допомогою st_touches. Сподіваюся, це допомагає. Оновлення - у qgis рішення виглядає так: введіть тут опис зображення


1
Вражає! Я змусив його працювати. Дуже дякую! Це стає трохи повільним при великій кількості будівель. Азимути зараз не нормальні. Чи маєте ви також ідею, як вирішити це? Я не впевнений, як знайти «зовнішню» сторону багатокутника.
n1000

1
додати 90 градусів до азимуту в радіані так: градуси (st_azimuth (ff.sp, ff.ep) +1.57079633). Він іноді генеруватиме значення, що перевищують 360. але за допомогою запиту на оновлення ви можете замінити їх. Якщо ви хочете використовувати як статичний вигляд, створіть "СТВОРИТИ МАТЕРІАЛІЗОВАНИЙ ПОГЛЯД", і це буде не повільно лише в перший раз.
Тамас Коса

2
Не зовсім. Якщо припустити, що на півночі 0 °, це дасть нормальну сторону внутрішньої частини полігону / будівлі (як це також видно на екрані екрана). Але ви праві - простий UPDATEповинен зробити трюк. Ще раз дякую за це чудове рішення. Я зачекаю ще кілька днів, якщо з’являться інші відповіді, перш ніж приймати.
n1000

1
Про що ST_ForceRHR? Ця відповідь насправді здається нормальною.
Якуб Каня

@JakubKania Я намагався знайти ST_ForceRHRрішення, але не було успіху. Буду вдячний за підказки ... Я спробувавST_Dump(ST_Boundary(ST_ForceRHR(the_geom)))
n1000
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.