python 判断点在随机多边形内_python之 判断点是否在多边形范围内

本文介绍了如何使用Python判断一个点是否位于多边形内部,包括点在多边形外包矩形内的判断,以及射线与边交点的计算,通过这些方法实现了对简单多边形和复杂多边形中点的判断。
摘要由CSDN通过智能技术生成

#coding=UTF-8

importcsvimportjson#点是否在外包矩形内

def isPoiWithinBox(poi, sbox, toler=0.0001):#sbox=[[x1,y1],[x2,y2]]

#不考虑在边界上,需要考虑就加等号

if poi[0] > sbox[0][0] and poi[0] < sbox[1][0] and poi[1] > sbox[0][1] and poi[1] < sbox[1][1]:returnTrueif toler >0:pass

returnFalse#射线与边是否有交点

def isRayIntersectsSegment(poi, s_poi, e_poi): #[x,y] [lng,lat]

if s_poi[1] == e_poi[1]: #排除与射线平行、重合,线段首尾端点重合的情况

returnFalseif s_poi[1] > poi[1] and e_poi[1] > poi[1]:returnFalseif s_poi[1] < poi[1] and e_poi[1] < poi[1]:returnFalseif s_poi[1] == poi[1] and e_poi[1] > poi[1]:returnFalseif e_poi[1] == poi[1] and s_poi[1] > poi[1]:returnFalseif s_poi[0] < poi[0] and e_poi[1] < poi[1]:returnFalse

xseg= e_poi[0] - (e_poi[0] - s_poi[0]) * (e_poi[1] - poi[1]) / (e_poi[1] - s_poi[1]) #求交

if xseg

def isPoiWithinSimplePoly(poi, simPoly, tolerance=0.0001):#点;多边形数组;容限

#simPoly=[[x1,y1],[x2,y2],……,[xn,yn],[x1,y1]]

#如果simPoly=[[x1,y1],[x2,y2],……,[xn,yn]] i循环到终点后还需要判断[xn,yx]和[x1,y1]

#先判断点是否在外包矩形内

if not isPoiWithinBox(poi, [[0, 0], [180, 90]], tolerance):returnFalse

polylen=len(simPoly)

sinsc= 0 #交点个数

for i in range(polylen - 1):

s_poi=simPoly[i]

e_poi= simPoly[i + 1]ifisRayIntersectsSegment(poi, s_poi, e_poi):

sinsc+= 1

return True if sinsc % 2 == 1 elseFalsedef isPoiWithinPoly(poi, poly, tolerance=0.0001):#点;多边形三维数组;容限

#poly=[[[x1,y1],[x2,y2],……,[xn,yn],[x1,y1]],[[w1,t1],……[wk,tk]]] 三维数组

#先判断点是否在外包矩形内

if not isPoiWithinBox(poi, [[0, 0], [180, 90]], tolerance):returnFalse

sinsc= 0 #交点个数

for epoly in poly: #逐个二维数组进行判断

for i in range(len(epoly) - 1): #[0,len-1]

s_poi =epoly[i]

e_poi= epoly[i + 1]ifisRayIntersectsSegment(poi, s_poi, e_poi):

sinsc+= 1

return sinse %2 !=0 #这样更简洁些

#return True if sinsc % 2 == 1 else False

### 比较完备的版本

def pointInPolygon(cin_path,out_path,gfile,t=0):

pindex= [2,3] #wgslng,wgslat 2,3

with open(out_path, 'w', newline='') as cut_file:

fin= open(cin_path, 'r', encoding='gbk')

gfn= open(gfile, 'r', encoding='utf-8')

gjson=json.load(gfn)if gjson["features"][0]["geometry"]['type']=="MultiPolygon":

plist=gjson["features"][0]["geometry"]['coordinates'] #四维

filewriter = csv.writer(cut_file, delimiter=',')

w=0for line in csv.reader(fin, delimiter=','):if w ==0:

filewriter.writerow(line)

w= 1

continuepoint= [float(line[pindex[0]]), float(line[pindex[1]])]for polygon in plist: # ifisPoiWithinPoly(point, polygon):

filewriter.writerow(line)breakfin.close()

gfn.close()elif gjson["features"][0]["geometry"]['type']=="Polygon":

polygon=gjson["features"][0]["geometry"]['coordinates'] #三维

filewriter = csv.writer(cut_file, delimiter=',')

w=0for line in csv.reader(fin, delimiter=','):if w ==0:

filewriter.writerow(line)

w= 1

continuepoint= [float(line[pindex[0]]), float(line[pindex[1]])]ifisPoiWithinPoly(point, polygon):

filewriter.writerow(line)

fin.close()

gfn.close()else:print('check',gfile)print('end')#调用

defbaTch():importosimportglob

wpath="D:/DigitalC_data/coordConvert" #文件路径

sname="D:/DigitalC_data/coordConvertOut"gpath='D:/cityBoundaryJson/guangzhou_wgs84.json'

for input_file in glob.glob(os.path.join(wpath, '*.csv')):

fname=input_file.split('\\')

pointInPolygon(input_file,os.path.join(sname,fname[1]),gpath)print(fname[1])## 应用

### 应用3

'''对一个csv数据,如果点在多边形内,给某一列(tag)(或者加一列)加上这个多边形的属性(有多个多边形)'''

defgivePolyTag():pass

### 应用方式1

defpointInPolygon1():

gfile= 'E:/ComputerGraphicsProj/Geojson2kml/J2K_data/深圳poly_bd09.geojson'cin_path= 'L:/OtherSys/DigitalCityData/深圳特征图层/city_site_poi_sec_shenzhen.csv'out_path= 'L:/OtherSys/DigitalCityData/深圳特征图层/city_site_poi_sec_shenzhen_out1.csv'pindex= [4, 5] #wgslng,wgslat 2,3

with open(out_path,'w', newline='') as cut_file:

fin= open(cin_path, 'r', encoding='gbk')

gfn= open(gfile, 'r', encoding='utf-8')

gjson=json.load(gfn)

polygon= gjson["features"][0]["geometry"]['coordinates'][0]

filewriter= csv.writer(cut_file, delimiter=',')

w=0for line in csv.reader(fin, delimiter=','):if w ==0:

filewriter.writerow(line)

w= 1

continuepoint= [float(line[pindex[0]]), float(line[pindex[1]])]ifisPoiWithinSimplePoly(point, polygon):

filewriter.writerow(line)

fin.close()

gfn.close()print('done')#pointInPolygon1()

def csvToDArrary(csvpath):#csv文件转二维数组

cdata =[]

with open(csvpath,'r', encoding='gbk') as rfile:for line in csv.reader(rfile, delimiter=','):

cdata.append(line)returncdata### 应用方式2

defpointInPolygon2():

gfile= 'E:/ComputerGraphicsProj/Geojson2kml/J2K_data/深圳poly_bd09.geojson'cin_path= 'L:/OtherSys/DigitalCityData/深圳特征图层/shenzhen_tAllNotIn.csv'out_path= 'L:/OtherSys/DigitalCityData/深圳特征图层/shenzhen_tAllNotIn_out2.csv'pindex= [4, 5] #wgslng,wgslat 2,3

with open(out_path,'w', newline='') as cut_file:

gfn= open(gfile, 'r', encoding='utf-8')

gjson=json.load(gfn)

polygon= gjson["features"][0]["geometry"]['coordinates'][0]

filewriter= csv.writer(cut_file, delimiter=',')

w=0

cdata=csvToDArrary(cin_path)for line incdata:if w ==0:

filewriter.writerow(line)

w= 1

continuepoint= [float(line[pindex[0]]), float(line[pindex][1])]ifisPoiWithinSimplePoly(point, polygon):

filewriter.writerow(line)

gfn.close()print('done')

pointInPolygon()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值