20231123更新部分代码、说明
下载最新【免费】检查面多边形图斑内角角度(arcgis工具箱-开源)资源-CSDN文库
打开角度检查工具使用说明.pdf,按要求使用即可,工具箱中有具体说明(注意是平面坐标,地理坐标请投影后运行)
特别地:现阶段工具不特别区分内外角,譬如下面截图中红框内角还是统计为锐角
(PS:如有需求可联系Q:775915005,定制修改为统计内角、统计特定角度的数量、统计各内角的角度等)
附工具箱完整代码:
# -*- coding:utf-8 -*-
# ---------------------------------------------------------------------------
# Author: LGZ
# Created on: 2023/02
# Contact: QQ775915005
# Reference:
# ---------------------------------------------------------------------------
import arcpy,math
def ruijiao_number(input_feature,minjiao):
if "jiaodu" not in [i.name for i in arcpy.ListFields(input_feature)]:
arcpy.AddMessage(str([i.name for i in arcpy.ListFields(input_feature)]))
arcpy.AddField_management(input_feature, "jiaodu", "TEXT",field_length= 254)
with arcpy.da.UpdateCursor(input_feature, ["SHAPE@", "jiaodu"]) as cursor:
for row in cursor:
pc = row[0].partCount
n = 0
for i0 in range(pc): # 处理多对象
p = row[0].getPart(i0) # 返回Array (arcpy)
count0 = p.count # 计算点对象数目
arcpy.AddMessage(str(count0))
ls = list()
list2 = [[]]
r = 0
# n = 0
for i1 in range(count0): # 根据None点划分制作二维列表
ls.append(p.getObject(i1))
for i2 in ls:
if i2:
list2[r].append(i2)
else:
if list2[r] == []:
continue
else:
list2.append([])
r += 1
arcpy.AddMessage(str(list2))
# n = 0
for i3 in list2: # [点1, 点2, 点3,点1]
for i4 in range(len(i3)): # 点1
p0x = round(i3[i4].X, 3) # 点1的X坐标,下同
p0y = round(i3[i4].Y, 3)
p1x = round(i3[i4 + 1].X, 3)
p1y = round(i3[i4 + 1].Y, 3)
if i4 == len(i3) - 2:
p2x = round(i3[1].X, 3)
p2y = round(i3[1].Y, 3)
else:
p2x = round(i3[i4 + 2].X, 3)
p2y = round(i3[i4 + 2].Y, 3)
l1x = p0x - p1x
l1y = p0y - p1y
l2x = p2x - p1x
l2y = p2y - p1y
l1cd = math.sqrt(l1x * l1x + l1y * l1y)
l2cd = math.sqrt(l2x * l2x + l2y * l2y)
xljchucd = (l1x * l2x + l1y * l2y) / (l1cd * l2cd) # cos
jiao = math.acos(round(xljchucd,3)) * 180.0 / (math.pi)
if jiao < float(minjiao): # 统计小于输入角度的点数
n += 1
if i4 == len(i3) - 2: # 倒数第2点退出本循环
break
arcpy.AddMessage(str(n))
row[1] = str(n)
cursor.updateRow(row) # 更新行
# del row
# del cursor
arcpy.RefreshActiveView()
arcpy.RefreshTOC()
if __name__ == '__main__':
try:
# arcpy.env.overwriteOutput = True
# 注意arcpy.GetParameterAsText获取是文本格式,注意中文注释下面空一行
argv = tuple(arcpy.GetParameterAsText(i)
for i in range(arcpy.GetArgumentCount()))
arcpy.AddMessage(str(argv))
ruijiao_number(*argv)
except arcpy.ExecuteError:
print(arcpy.GetMessages())
else:
arcpy.AddMessage("program success,Q:775915005")
附字段计算器函数式计算代码(实现思路与工具箱一致,结果一致,须在文本类型字段下运行):
import math
def shiftCoordinate(shape,minjiao):
n = 0
pc = shape.partCount # 多少部分
for i0 in range(pc):
p = shape.getPart(i0) # Array (arcpy)
count0 = p.count
ls = list()
list2 = [[]]
r = 0
for i1 in range(count0):
ls.append(p.getObject(i1))
for i2 in ls:
if i2:
list2[r].append(i2)
else:
if list2[r] == []:
continue
else:
list2.append([])
r += 1
for i3 in list2: # [1323, 1312, 345,1323]
for i4 in range(len(i3)):
p0x = round(i3[i4].X, 3)
p0y = round(i3[i4].Y, 3)
p1x = round(i3[i4+1].X, 3)
p1y = round(i3[i4+1].Y, 3)
if i4 == len(i3)-2:
p2x = round(i3[1].X, 3)
p2y = round(i3[1].Y, 3)
else:
p2x = round(i3[i4+2].X,3)
p2y = round(i3[i4+2].Y,3)
l1x = p0x - p1x
l1y = p0y - p1y
l2x = p2x - p1x
l2y = p2y - p1y
l1cd = math.sqrt(l1x * l1x + l1y * l1y)
l2cd = math.sqrt(l2x * l2x + l2y * l2y)
xljchucd = (l1x * l2x + l1y * l2y) / (l1cd * l2cd) # cos
jiao = math.acos(round(xljchucd,3)) * 180.0 / (math.pi)
if jiao < minjiao:
n += 1
if i4 == len(i3)-2:
break
return str(n)