【arcpy】线状要素等距离生成点

基本原理:想要为某个线状要素类中的所有线要素生成等距离节点,可以按照以下步骤实现:

  1. 读取要素折点;
  2. 结合折点间距离大小以及直线上点与距离关系(通过相似三角形)求得可满足预期距离的点的坐标位置,将所得点坐标信息保存为xls文件;
  3. 应用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------"




  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值