基本原理:想要为某个线状要素类中的所有线要素生成等距离节点,可以按照以下步骤实现:
读取要素折点;结合折点间距离大小以及直线上点与距离关系(通过相似三角形)求得可满足预期距离的点的坐标位置,将所得点坐标信息保存为xls文件;应用ArcGIS读取xls,生成点状要素类。以下为生成等距离节点xls文件得代码,由于xls最多可存储65535行,本代码会将多余的部分存到同一份xls文件的下一个表中。
# -*- coding: utf-8 -*- import sys, math import arcpy import xlwt reload(sys) sys.setdefaultencoding('utf8') fc_path = unicode("./xxx.mdb/line", "utf-8") # 根据两点坐标和由一点出发的距离,求第三点坐标 def calPosition(p1, p2, d): p1_x = p1[0] p1_y = p1[1] p2_x = p2[0] p2_y = p2[1] d_12 = math.sqrt(math.pow((p2_x - p1_x), 2) + math.pow((p2_y - p1_y), 2)) d_x = (d * (p2_x - p1_x)) / d_12 d_y = (d * (p2_y - p1_y)) / d_12 x = p1_x + d_x y = p1_y + d_y return (x, y) # 计算一条折线总长度及刨除最后一部分的折线长度 def calLength(points): length_total = 0 length_exclude_last_segment = 0 for i in range(0, len(points)-1): p1 = points[i] p2 = points[i+1] p1_x = p1[0] p1_y = p1[1] p2_x = p2[0] p2_y = p2[1] d_12 = math.sqrt(math.pow((p2_x - p1_x), 2) + math.pow((p2_y - p1_y), 2)) length_total += d_12 if i!= (len(points)-2): length_exclude_last_segment += d_12 return length_total, length_exclude_last_segment # 根据切分距离生成折点 def splitLine(points, d): vertex_generated = [points[0]] point_index = 1 # 点集中即将访问的下一个点 # 未遍历完折线所有折点时 while point_index < len(points): points_sub = [] points_sub.append(vertex_generated[-1]) # 新生成折点作为起点 d_balance = 0 point_index_copy = point_index # 从当前位置向后遍历,在总长度未满足条件前不断添加折点 for i in range(point_index_copy, len(points)): points_sub.append(points[i]) length_total, length_exclude_last_segment = calLength(points_sub) # print point_index, length_total, length_exclude_last_segment if length_total >= d: d_balance = d - length_exclude_last_segment point_index = i break else: point_index = i + 1 # 如果最后一段折线长度大于0,可以排除遍历到最后折点不足情况 if d_balance > 0: p1 = points_sub[-2] p2 = points_sub[-1] vertex = calPosition(p1, p2, d_balance) vertex_generated.append(vertex) vertex_generated.append((points[-1][0], points[-1][1])) # print vertex_generated return vertex_generated def addSheet(workbook, n): sheet_name = "Sheet" + str(n) worksheet = workbook.add_sheet(sheet_name) worksheet.write(0, 0, "x") worksheet.write(0, 1, "y") return worksheet def saveVertex(wooksheet, vertex_generated, vertex_num): for i in range(vertex_num, vertex_num + len(vertex_generated)): worksheet.write(i, 0, vertex_generated[i-vertex_num][0]) worksheet.write(i, 1, vertex_generated[i-vertex_num][1]) workbook = xlwt.Workbook(encoding='utf-8') worksheet = addSheet(workbook, 1) vertex_num = 1 sheet_index = 1 with arcpy.da.SearchCursor(fc_path, ("OID@", "SHAPE@")) as cursor: for row in cursor: print "------next row------" for part in row[1]: points = [] for point in part: points.append((point.X, point.Y)) vertex_generated = splitLine(points, 10) if (vertex_num + len(vertex_generated)) > 65500: vertex_num = 1 sheet_index += 1 worksheet = addSheet(workbook, sheet_index) saveVertex(worksheet, vertex_generated, vertex_num) vertex_num += len(vertex_generated) break workbook.save('vertex_generated.xls') print "------done------"