功能描述
本Arcpy脚本实现了在线Shapefile中生成指定数量线上点的功能,且具体数据由线Shapefile相应字段来指定,实现思想借鉴了类似配额的概念。
代码
from __future__ import division
import arcpy
import math
import random
# out dir
dir = "F:\\tmp\\tmp\\"
# line shapefile
line = "F:\\tmp\\line.shp"
# unique identify field name
fid = "FID"
# the field name which stored point number
cnt = "c"
# define a Point Object, referenced from web
class Point:
def __init__(self,x=0,y=0):
self.x=x
self.y=y
def getx(self):
return self.x
def gety(self):
return self.y
# cal the length of tow Point, referenced from web
class Getlen:
def __init__(self,p1,p2):
self.x=p1.getx()-p2.getx()
self.y=p1.gety()-p2.gety()
self.len= math.sqrt((self.x**2)+(self.y**2))
def getlen(self):
return self.len
# cal the lenght of a line shapefile from its points
class GetLineLen:
def __init__(self, pnts):
self.pnts = pnts;
def getlen(self):
ln = 0.0;
for s in range(1, len(pnts)):
ln += (Getlen(Point(pnts[s].X, pnts[s].Y), Point(pnts[s-1].X, pnts[s-1].Y)).getlen())
return ln;
# create result point shapefile
output_name = "point_"+str(random.randint(10000, 99999))+".shp"
output = dir + output_name
arcpy.CreateFeatureclass_management(dir, output_name, "POINT")
with arcpy.da.InsertCursor(output, ["SHAPE@"]) as oic:
with arcpy.da.SearchCursor(line, [fid, cnt, "SHAPE@"]) as cursor:
for row in cursor:
# print start log
print "---------------- start:",fid,"=",row[0]
rd = str(random.randint(1000, 9999))
print "rd:",rd
# result point array : [arcpy.Point]
rp = []
for pnts in row[2]:
f = pnts[0]
l = pnts[len(pnts)-1]
s = int(row[1])
line_pnt_cnt = len(pnts)
if s==1:
# select a probably middle position
p1 = pnts[int(line_pnt_cnt/2)]
p2 = pnts[int(line_pnt_cnt/2)-1]
rp.append(arcpy.Point((p1.X+p2.X)*0.5, (p1.Y+p2.Y)*0.5))
elif s==2:
# select start point and end point
rp.append(arcpy.Point(f.X, f.Y))
rp.append(arcpy.Point(l.X, l.Y))
elif s>2:
# select start point
rp.append(arcpy.Point(f.X, f.Y))
line_len = GetLineLen(pnts).getlen()
step_len = line_len/(s-1)
last_retain = 0.0
for pt in range(1, line_pnt_cnt):
this_line_len = Getlen(Point(pnts[pt-1].X, pnts[pt-1].Y), Point(pnts[pt].X,pnts[pt].Y)).getlen()
# cal pei e
pe = this_line_len/step_len
if last_retain + pe >= 1:
# has
z = int((last_retain + pe)/1)
# calc
for zz in range(0, z):
tx = pnts[pt-1].X + (pnts[pt].X - pnts[pt-1].X)*(zz+1-last_retain)/pe
ty = pnts[pt-1].Y + (pnts[pt].Y - pnts[pt-1].Y)*(zz+1-last_retain)/pe
rp.append(arcpy.Point(tx, ty))
# loop
last_retain = last_retain + pe -z
else:
last_retain = (last_retain + pe)
for pp in rp:
oic.insertRow([pp])
print "----------------"
print "complete, result:", output