Я хочу проверить ориентацию каждой линии в многоугольнике, чтобы я мог рассчитать их солнечную экспозицию. Каждый многоугольник представляет собой здание и имеет соответствующую высоту. На данный момент я просто хочу рассмотреть ориентацию, а позже рассмотрю вопросы затенения.
Один из подходов, который я подумал, состоял в том, чтобы разбить многоугольник на линии и вычислить ориентацию каждой линии, но сложность заключается в том, что мне затем нужно определить внешнюю грань этой линии. Хотя большинство полигонов представляют собой простые четырехсторонние фигуры с прямыми линиями, есть небольшое число, где это не так (вопрос, который я просто хочу рассмотреть, но пока не должен решать).
Я знаком с Python и планировал делать все это из сценария.
источник
Ответы:
Если вам нужна ориентация на большинство, посмотрите ответ @Mapperz выше.
В противном случае, как вы говорите, вы можете разбить полигоны на линии, используя инструмент Polygon To Line . Это добавляет левое и правое поле FID, где поле равно -1, если нет внешнего многоугольника - это может привести к небольшому разбросу, хотя, если ваши здания находятся рядом или перекрываются.
Оттуда вы можете разделить свои линии в каждой вершине (возможно, использовать разделение на линии COGO ), а затем вычислить углы на каждой из линий (возможно, путем обновления атрибутов COGO ).
Предполагая, что ваше угловое поле рассчитано с севера, аспект будет правильным, где left_FID равен -1, а чтобы получить аспект, когда right_FID равен -1, просто добавьте 180 °. Затем на основе исходного FID вы можете агрегировать, получать мажоритарный аспект на основе длины и т. Д.
Инструмент Polygon to line предназначен для сценариев (насколько я знаю), а инструменты COGO - нет, поэтому вам придется придумывать что-то там самостоятельно.
Надеюсь это поможет!
источник
Рассчитать главный угол многоугольника (картография)
Вычисляет доминантные углы входных многоугольников и присваивает значения указанному полю в классе пространственных объектов.
http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//007000000028000000.htm
источник
Нахождение ориентации
Внутри сценария многоугольник будет доступен в виде набора колец - одно внешнее кольцо и ноль или более внутренних колец - причем каждое кольцо представлено циклически упорядоченным набором векторов (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].)
Синус угла между двумя последовательными ребрами
Грех (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. При необходимости переориентируйте их кольцо за кольцом в соответствии с этим правилом. То есть, если степень любого кольца противоположна той, которая необходима, отрицайте все нормали для этого кольца. Теперь вы можете приступить к расчетам инсоляции.
источник
Может ли это помочь?
источник
/ * Может быть, это поможет:
Азимут - pi / 2 - это ориентация наружу сторон многоугольника RHR:
Вот пример PostGIS, вы можете создать таблицу bldg117862, используя оператор в конце. SRID - EPSG 2271 (PA StatePlane North Feet), а геометрия - мультиполигон. Для визуализации в ArcGIS 10 вставьте запрос / подзапросы в соединение уровня запросов с postgis после создания таблицы bldg117862. * /
- === НАЧАЛО ЗАПРОСА ===
/ * Внешний запрос обеспечивает ориентацию внешних ортогональных элементов и создает внешние ортогональные линии, равные по длине линиям сторон от средней точки сторон.
Доминирующим направлением (ями) будет сумма длин, сгруппированных по ориентации в порядке убывания *
ВЫБЕРИТЕ line_id в качестве side_id, длину, градусы (orthoaz) в качестве ориентации, 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)) как геом из
--next внешний подзапрос создает линии из пар точек сторон, вычисляет азимут (orthoaz) наружу, ортогональный для каждого сегмента
(ВЫБЕРИТЕ bldg2009gid, line_id, st_length (st_makeline (начальная точка, конечная точка)) :: numeric (10,2) как длина, азимут (начальная точка, конечная точка), азимут (начальная точка, конечная точка) - pi () / 2 как orthoaz, st_makeline ( начальная точка, конечная точка) как геом из
/ * самый внутренний подзапрос - используйте generate_series (), чтобы разложить строительные полигоны на пары начальная / конечная точки сторон - note1 - применить правило правой руки для обеспечения общей ориентации всех сторон многоугольника note2 - в примере используется многоугольник, для многоугольника geometryn () могут быть удалены * /
(ВЫБЕРИТЬ generate_series (1, npoints (externalring (geometryn (st_forceRHR (geom), 1))) - 1) как line_id, gid как bldg2009gid, pointn (externalring (geometryn (st_forceRHR (geom), 1))), generate_series (1, npoints (externalring (geometryn (st_forceRHR (geom), 1))) - 1)) в качестве начальной точки, pointn (externalring (geometryn (st_forceRHR (geom), 1)), generate_series (2, npoints (externalring (geometryn (st_forceRHR (geom) ), 1))))) как конечная точка от bldg117862) как t1) как t2
- === КОНЕЦ ЗАПРОСА ===
- операторы создания / вставки таблицы bldg117862
SET STANDARD_CONFORMING_STRINGS TO ON; SELECT DropGeometryColumn ('', 'bldg117862', 'geom'); DROP TABLE "bldg117862"; НАЧАТЬ; CREATE TABLE "bldg117862" (gid serial PRIMARY KEY, "motherpin" varchar (14), "taxpin" varchar (14), "status" varchar (15), "area" числовой, "prev_area" числовой, "pct_change" числовой, «picture» varchar (133), «mappage» varchar (6), «sref_gid» int4, «e_address» varchar (19), «a_address» varchar (19), «perim» числовой, «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); КОНЕЦ;
источник
Предполагая, что ориентация сегментов линии постоянна в многоугольнике, вы можете рассчитать направление (направление) вектора, перпендикулярного каждому сегменту линии. Сейчас у меня нет времени разбираться с кодом, но если вам нужна математика, ее можно легко получить :-)
источник