Обчислення орієнтації кожної сторони багатокутника за допомогою ArcPy?


9

Я хочу вивчити орієнтацію кожної лінії в полігоні, щоб я міг обчислити їх сонячне випромінювання. Кожен багатокутник являє собою будівлю і має пов'язану висоту. На даний момент я просто хочу розглянути орієнтацію, а згодом розглянемо питання затінення.

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

Я знайомий з python і планував робити все це зі сценарію.


1
Чи є відповіді на це питання допомога: gis.stackexchange.com/questions/1886 / ...
Шон

@Sean - дякую, так, це взагалі допомагає. Мені не знайомі конкретні команди ArcGIS, які можна використовувати для цього. Крім того, питання про те, що всередині / зовні грані лінії в полігоні все ще залишається.
djq

Коли ви говорите "орієнтація", ви не досить чітко її визначили --- яка орієнтація ідеального шестикутника, наприклад?
Дан С.

@Dan S. Я щойно відредагував свою відповідь, щоб включити орієнтацію кожного рядка в полігоні.
djq

вибачте, відповідали - я не встиг привласнити призову належним чином.
djq

Відповіді:


6

Якщо ви просто хочете орієнтуватися на більшість, перегляньте відповідь @Mapperz вище.

Інакше, як ви кажете, ви могли розділити багатокутники на лінії за допомогою інструменту « Полігон до лінії ». Це додає ліве і праве поле FID, де поле дорівнює -1, якщо немає зовнішнього багатокутника - це може спричинити дещо затьмарення, хоча якщо ваші будівлі сусідні або перекриваються.

Звідти ви можете розділити рядки в кожній вершині (можливо, використовувати Спліт на лінії COGO ), а потім обчислити кути на кожному з рядків (можливо, оновивши атрибути COGO ).

Якщо припустити, що ваше кутове поле обчислюється з півночі, аспект буде правильним, де лівий_FID дорівнює -1, а для отримання аспекту, коли правий_FID -1, просто додайте 180 °. Тоді на основі оригінального FID ви можете об'єднати, отримати більшість аспектів на основі довжини тощо.

Інструмент «Полігон до лінії» - це сценарій, (наскільки я знаю) інструментів COGO немає, тож вам доведеться щось там придумати.

Сподіваюся, це допомагає!


2
Безсоромний штекер та коментар. По-перше, якщо у вас немає інформаційної ліцензії, code.google.com/p/boundary-generator робить більш-менш те саме, що інструмент "Полігон до лінії". По-друге - це дає вам набагато більше інформації, ніж просто дивитися на якусь загальну орієнтацію загального полігону ... наприклад, ви можете використовувати отриману таблицю, щоб зробити набагато точніші обчислення впливу сонячних променів, враховуючи аспект кожної окремої стіни. .
Дан С.


5

Пошук орієнтації

У рамках сценарію багатокутник буде доступний у вигляді набору кілець - одне зовнішнє кільце і нульове або більше внутрішніх кілець - з кожним кільцем, представленим циклічно впорядкованим набором векторів (v [0], v 1 , ... , v [m-1], v [m] = v [0]). Кожен вектор дає координати вершини (дві послідовні вершини не збігаються). З цього прямо, як вказували інші, отримати нормальні вектори (тобто вектори, перпендикулярні до напрямків ребер):

n [i] = t (v [i + 1] - v [i]).

Операція "t" обертає вектор на 90 градусів проти годинникової стрілки :

t ((x, y)) = (y, -x).

Мають значення лише напрямки цих нормальних векторів, тому їх масштабують так, щоб вони мали одиницю довжини: вектор (x, y) переносить масштаб до (x / s, y / s), де s = Sqrt (x ^ 2 + y ^ 2) (який - довжина відповідного краю). Відтепер припустимо, що це було зроблено. Запишіть компоненти отриманих одиниць звичайних векторів як

n [i] = (u [i], v [i]), i = 0, 1, ..., m-1.

Дискримінація зовні зсередини

Як ви зауважуєте, це залишає неоднозначну спрямованість: чи слід використовувати n [i] чи -n [i]? Який із них вказує назовні? Це питання еквівалентний знаходженню ступеня від гауссова відображення . Для його обчислення потрібно підсумовувати кути, на які змінюються нормальні напрямки, коли ви йдете навколо кільця. Оскільки нормальні вектори мають одиничну довжину, косинус кута між двома послідовними ребрами є

Cos (q_i) = n [i]. n [i + 1] = u [i] * u [i + 1] + v [i] * v [i + 1], i = 0, 1, ..., m-1.

(Визначте n [m] = n [0].)

Синус кута між двома послідовними ребрами дорівнює

Sin (q_i) = n [i]. t (n [i + 1]) = u [i] * v [i + 1] - v [i] * u [i + 1].

(Зауважте, що для цих розрахунків поки що потрібні лише суми, різниці та продукти.) Застосування основної зворотної дотичної функції (ATan2) до будь-якої такої пари (косинуса, синуса) дає кут q_i від -180 до 180 градусів. Підсумовуючи ці кути за i = 0, 1, ..., n-1, утворюється (до помилки з плаваючою комою) загальна кривизна кільця, яка повинна бути кратною 360 градусів; для замкнутого непересічного кільця воно буде або +360, або -360. У першому випадку ступінь дорівнює 1, а в другому - ступінь -1. Усі норми орієнтовані назовні, коли ступінь зовнішнього кільця дорівнює +1, а градуси внутрішніх кілець - -1. Переорієнтуйте їх по кільцю за потребою, відповідно до цього правила. Тобто, якщо ступінь будь-якого кільця протилежна тій, яка потрібна, заперечуйте всі норми для цього кільця. Тепер ви можете приступити до своїх розрахунків інсоляції.


Дякую за дуже вичерпну відповідь. Коли ви говорите: "У рамках сценарію багатокутник буде доступний як набір кілець", як доступний полігон? Хоча знайомий з деякими сценаріями пітона, я не знаю, як інтерпретувати полігон таким чином. Я читаю це повільно і намагаюся зрозуміти це, але мені важко перекласти деякі пояснення в псевдокод, який я можу написати.
djq

Кілька зауважень щодо цієї відповіді: Типові GIS API завжди представлятимуть зовнішню сторону багатокутника в порядку, проти годинникової стрілки, IIRC, а це означає, що вам не потрібно робити цього вигадливого розрізнення зсередини - просто використовуйте обертання за годинниковою стрілкою на зовнішніх кільцях і проти отворів за годинниковою стрілкою на отворах. Пояснення для celenius: біт "безлічі кілець" полягає в тому, як більшість API, включаючи пітон ArcGIS, дозволяють розкласти багатокутник на складові його сегменти лінії - кільце - це закрита крива їх. Оскільки багатокутники можуть підтримувати острови і нори, у вас може бути кілька кілець ...
Dan S.

@Dan Я хотів би, щоб це було так, щоб GISs підтримували такі послідовні уявлення. Протягом багатьох років програмне забезпечення ESRI коливалося вперед і назад серед негативно-позитивно орієнтованих полігонів і просто залишало їх не орієнтованими. На даний момент я не впевнений, що буду покладатися навіть на документально підтверджені заяви щодо їхнього нинішнього підходу: я був би обережним. Перевірити орієнтацію мало коштує після того, як ви вже обробили всі краї кільцем.
whuber

.. ну, я вдячив цю маленьку відмову від IIRC, на щастя. ;) Це не все так, що часто я вже роблю речі на рівні геометрії на стеку ESRI.
Дан С.

@Dan S. - Мені все ще незрозуміло, як це можна запрограмувати в python. Чи є для цього якісь вказівки?
djq

1

Чи може це допомогти?


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

1

/ * Можливо, це допомагає:

Азимут - pi / 2 - орієнтація, спрямована зовні сторонами полігону RHR:

Ось приклад PostGIS, ви можете створити таблицю bldg117862, використовуючи оператор у кінці. SRID - EPSG 2271 (штат штату Пенсіль Північ), а геометрія - багатополігон. Щоб візуалізувати в ArcGIS 10, вставте запит / підзапити у з'єднання рівня запитів до postgis після створення таблиці bldg117862. * /

- === НАЧАЛО ПИТАННЯ ===

/ * Зовнішній запит забезпечує орієнтацію зовнішніх ортогоналів і створює зовнішні ортогональні лінії однакової довжини, як і сторони від середини сторін.

Домінуючим напрямком (напрямками) облицювання буде сума довжини, згрупована за орієнтацією, у порядку зменшення * /

SELECT line_id як side_id, довжина, градуси (ортоаз) як орієнтація, st_makeline (st_setsrid (st_line_interpolate_point (geom, .5), 2271), st_setsrid (st_makepoint (st_x (st_line_interpolate_point (geom, .5)) + (довжина * (sin) orthoaz))), st_y (st_line_interpolate_point (geom, .5)) + (довжина * (cos (orthoaz)))), 2271)) як geom від

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

(SELECT bldg2009gid, line_id, st_length (st_makeline (початкова точка, кінцева точка)) :: числовий (10,2) як довжина, азимут (початкова точка, кінцева точка), азимут (початкова точка, кінцева точка) - pi () / 2 як ортоаз, st_makeline ( початкова точка, кінцева точка) як geom від

/ * внутрішній підзапит - використовуйте create_series () для розкладання будівельних багатокутників на пари початкових / кінцевих точок сторін - note1 - правило праворуч для забезпечення загальної орієнтації всіх сторін багатокутника note2 - приклад використовує мультиполігон, для багатокутника геометрія () можна видалити * /

(SELECT generator_series (1, npoints (зовнішність (geometryn (st_forceRHR (geom), 1)))) - 1) як line_id, gid як bldg2009gid, pointn (exteriorring (geometryn (st_forceRHR (geom), 1)), 1)), generator_series (1, npoints (зовнішність (geometryn (st_forceRHR (geom), 1))) - 1)) як початкова точка, pointn (зовнішня частина (geometryn (st_forceRHR (geom), 1)), generator_series (2, npoints (external) (geometryn (st_forceRHR (geom) ), 1))))) як кінцева точка від bldg117862) як t1) як t2

- === КІНЦЯ ПИТАННЯ ===

- таблиця bldg117862 створює / вставляє заяви

ВКЛЮЧИТИ STANDARD_CONFORMING_STRINGS ON SELECT DropGeometryColumn ('', 'bldg117862', 'geom'); КОРОТКА ТАБЛИЦЯ "bldg117862"; ПОЧАТОК; СТВОРИТИ ТАБЛИЦЮ "bldg117862" (gid serial PRIMARY KEY, "motherpin" varchar (14), "taxpin" varchar (14), "status" varchar (15), "область" числовий, "prev_area" числовий, "pct_change" числовий, "картинка" varchar (133), "mappage" varchar (6), "sref_gid" int4, "e_adress" varchar (19), "a_adress" varchar (19), "perim" numeric, "card" int4, "a_addnum" int4, "e_street" varchar (50), "a_street" varchar (50), "e_hsnum" varchar (10)); SELECT AddGeometryColumn ('', 'bldg117862', 'geom', '2271', 'MULTIPOLYGON', 2); 0106000020DF080000010000000103000020DF080000010000000B0000008C721D6C98AC34415E2C5BB9D3E32541AE56DE17BEAC34410613E5A0A0E325411AB6C794AEAC3441BA392FE372E32541C89C38429DAC3441643857628AE325418C299A9095AC3441F66C29B573E32541983F02087EAC34413080AA9F93E325419BAC3C0A86AC3441AC1F3B3DABE32541803A40B974AC3441E8CF3DB9C2E325413E3758C186AC3441D0AAB0E7F7E325410AAAA5429BAC3441BA971217DCE325418C721D6C98AC34415E2C5BB9D3E32541 '); CREATE INDEX "bldg117862_geom_gist" ON "bldg117862" за допомогою gist ("geom" gist_geometry_ops); КІНЧ;


0

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

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