使用ArcPy计算多边形各边的方向?


9

我想检查多边形中每条线的方向,以便可以计算它们的日照量。每个多边形代表一栋建筑物,并具有关联的高度。目前,我只想考虑方向,以后再考虑遮光问题。

我认为一种方法是将多边形分割成线,并计算每条线的方向,但是困难是我必须识别该线的外表面。尽管大多数多边形是带有直线的简单四边形图形,但在少数情况下并非如此(我只是想考虑但不必解决这个问题)。

我熟悉python,并计划通过脚本执行所有操作。


1
做这个问题的答案有帮助:gis.stackexchange.com/questions/1886/…–
Sean

@Sean-谢谢,是的,这确实有帮助。我不熟悉可用于执行此操作的特定ArcGIS命令。同样,仍然存在知道多边形中线的内/外面的问题。
djq 2010年

当您说“方向”时,您对我的定义还不够好-例如,理想六角形的方向是什么?
Dan S.

@DanS。我刚刚编辑了答案,以包括多边形中每条线的方向。
djq 2010年

抱歉的答复者-昨天我没有设法正确分配赏金。
djq 2010年

Answers:


6

如果您只想要多数取向,请查看上面的@Mapperz答案。

否则,如您所说,您可以使用“ 多边形转线”工具将多边形分成线。这将添加一个左右FID字段,如果没有外部多边形,则该字段为-1-如果建筑物相邻或重叠,则可能会造成一些混乱。

从那里,您可以在每个顶点处分割线(可以使用Split into COGO lines),然后计算每条线上的角度(可能通过更新COGO属性计算)。

假设您已从North计算出角度场,则在left_FID为-1的情况下该宽高比是正确的,而在right_FID为-1的情况下获得该宽高比仅需增加180°。然后,您可以基于原始FID进行汇总,并根据长度获取多数票等。

多边形到线工具是可编写脚本的,(据我所知)COGO工具不是可编写脚本的,因此您必须自己准备一些东西。

希望这可以帮助!


2
无耻的插件和评论:首先,如果您没有Info许可证,code.google.com / p / boundary-generator的作用与Polygon to Line工具大致相同。其次-这不仅给您提供了更多信息,而不仅仅是查看整个多边形的某种一般方向...例如,您可以使用结果表来进行更精确的日光照射计算,同时考虑到每面墙的外观。
Dan S.


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时,法线都朝外。 根据此规则,根据需要将它们重新定位。也就是说,如果任何环的度数与所需度数相反,则取反该环的所有法线。现在,您可以继续进行日照计算。


感谢您提供非常全面的答案。当您说“在脚本中,面将作为一组环可用”时,面如何可用?尽管熟悉某些python脚本,但我不知道如何以这种方式解释多边形。我正在慢慢阅读并试图理解它,但是我很难将某些解释翻译成我可以编写的伪代码。
djq 2010年

关于此答案的一些注意事项:典型的GIS API始终会以逆时针的顺序IIRC呈现多边形的外部,这意味着您不必从内部区分花哨的外部-只需在外圈上使用顺时针旋转,在孔上逆时针旋转。澄清摄氏度:“套环”位是大多数API(包括ArcGIS的python)如何将多边形分解成其组成线段的方法-环是它们的闭合曲线。由于多边形可能支撑岛和孔,因此您可能会有多个环...
Dan S.

@Dan我希望GIS保持这种一致的表示形式。多年以来,ESRI软件一直在负向和正向多边形之间来回波动,而使它们处于未定向状态。在这一点上,我不确定我是否会依赖于有关其当前方法的书面声明:我会保持谨慎。在处理完环中的所有边缘后,只需花费很少的时间即可检查方向。
ub

好吧,谢天谢地,我确实放了一点IIRC免责声明。;)我不再经常在ESRI堆栈上进行几何级的工作了。
Dan S.

@Dan S.-我仍然不清楚如何在python中进行编程。有什么指导方针吗?
djq 2010年

1

可以这样帮助?


那是您挖出的有趣的论文。但是,此处描述的方法均与日照量计算无关(除非该计算旨在粗略地近似,此处似乎不是这种情况)。
ub

1

/ *也许有帮助:

方位角-pi / 2是RHR多边形侧面的朝外方向:

这是一个PostGIS示例,您可以使用末尾的语句创建bldg117862表。SRID为EPSG 2271(PA StatePlane北脚),几何图形为Multipolygon。要在ArcGIS 10中可视化,请在创建表bldg117862。* /后将查询/子查询粘贴到PostgreSQL的查询层连接中。

-===查询开始===

/ *外部查询提供向外正交的方向,并从侧面的中点创建与侧面长度相等的向外的正交线。

主导方向是长度的总和,按方向分组,降序为* /

选择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外部子查询从两边的点对制作线,为每个线段计算向外正交的方位角(正交)

(SELECT bldg2009gid,line_id,st_length(st_makeline(startpoint,endpoint)):: numeric(10,2)作为长度,方位角(startpoint,endpoint),azimuth(startpoint,endpoint)-pi()/ 2作为orthoaz,st_makeline(起点,终点)作为来自的geom

/ *最里面的子查询-使用generate_series()将建筑物多边形分解成边的起点/终点对-注意1-强制使用右手规则以确保所有边的共同方向注意2-示例使用多面多边形,对于多边形geometryn()可以删除* /

(SELECT generate_series(1,npoints(exteriorring(geometryn(st_forceRHR(geom),1)))-1)as line_id,gid as bldg2009gid,pointn(exteriorring(geometryn(st_forceRHR(geom),1)),generate_series(1, npoints(exteriorring(geometryn(st_forceRHR(geom),1)))-1))作为起点,pointn(exteriorring(geometryn(st_forceRHR(geom),1)),generate_series(2,npoints(exteriorring(geometryn(st_forceRHR(geom),1))-1))作为起点),1)))))作为bldg117862)的端点作为t1)的t2

-===查询结束===

-bldg117862表创建/插入语句

将STANDARD_CONFORMING_STRINGS设置为ON;SELECT DropGeometryColumn('','bldg117862','geom'); 删除表“ bldg117862”;开始; 创建表“ bldg117862”(gid串行主键,“ motherpin” varchar(14),“ taxpin” varchar(14),“ status” varchar(15),“ area”数字,“ prev_area”数字,“ pct_change”数字, “图片” varchar(133),“地图页” 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' ); 使用gist(“ geom” gist_geometry_ops)在“ bldg117862”上创建索引“ bldg117862_geom_gist”;结束;


0

假设线段的方向在多边形中是恒定的,则可以计算垂直于每个线段的矢量的方位(航向)。我现在没有时间练习代码,但是如果您需要数学,可以轻松提供它:-)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.