问题来源:
在最近的工作中,我们需要将微波链路改成光链路。为了找到最近的光缆站点,我们需要确定距离微波站点最近的光缆站点,并找到最近的路由以便进行改正。我们已经拥有微波站点的经纬度数据,但在谷歌地球上一个个打点来寻找最近的站点非常耗时费力。因此,我考虑采用一种更快速的方法,通过计算并筛选最小值,自动整理并汇总数据,以便快速找到离微波站点最近的光缆站点。
话不多说,直接上代码:
import math
import pandas as pd
import numpy as np
import xlwings as xw
import time
timeName=time.strftime("%y%m%d_%H%M%S")
fpath=r'D:\Desktop\最近文档\站点信息(微改光)20221224.xlsx'
wb = xw.Book(fpath)
# sht=xw.sheets.active
df=pd.read_excel(fpath,sheet_name='全部站点信息',header=0)
def distance(lat1, lon1, lat2, lon2):
radius = 6371 # 地球的半径(单位:千米)
dlat = math.radians(lat2-lat1)
dlon = math.radians(lon2-lon1)
a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(lat1)) \
* math.cos(math.radians(lat2)) * math.sin(dlon/2) * math.sin(dlon/2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
d = radius * c
return d
df['纬度']= pd.to_numeric(df['纬度'], errors="coerce")
df['经度']= pd.to_numeric(df['经度'], errors="coerce")
df_OSP = df.set_index("Site ID")
df_OSP=df_OSP[df_OSP['是否OSP']=='OSP']
df_微改光=pd.read_excel(fpath,sheet_name='微改光目标站点',header=0)
df_match_SiteID=df_微改光.merge(df,on='Site ID',how='left')
df_match_SiteID=df_match_SiteID.dropna(subset=["经度", "经度"],how='any')
df_tgt=df_match_SiteID[df_match_SiteID['是否OSP']!='OSP']
def 最近站点(SiteID,df_OSP):
lon=df_tgt[df_tgt['Site ID']==SiteID]['经度'].iloc[0]
lat=df_tgt[df_tgt['Site ID']==SiteID]['纬度'].iloc[0]
dis=df_OSP.apply(lambda row: distance(lat, lon, row['纬度'],row['经度']), axis=1)
目标值=[dis.idxmin(),str(dis.min())[0:5]]
return 目标值
def 第2站点(SiteID,df_OSP):
lon=df_tgt[df_tgt['Site ID']==SiteID]['经度'].iloc[0]
lat=df_tgt[df_tgt['Site ID']==SiteID]['纬度'].iloc[0]
dis=df_OSP.apply(lambda row: distance(lat, lon, row['纬度'],row['经度']), axis=1)
目标值=[dis.nsmallest(3).index[1],str(dis.nsmallest(3).iloc[1])[0:5]]
return 目标值
def 第3站点(SiteID,df_OSP):
lon=df_tgt[df_tgt['Site ID']==SiteID]['经度'].iloc[0]
lat=df_tgt[df_tgt['Site ID']==SiteID]['纬度'].iloc[0]
dis=df_OSP.apply(lambda row: distance(lat, lon, row['纬度'],row['经度']), axis=1)
目标值=[dis.nsmallest(3).index[2],str(dis.nsmallest(3).iloc[2])[0:5]]
return 目标值
df_tgt['最近OSP站点']=df_tgt['Site ID'].apply(lambda x:最近站点(x,df_OSP)[0])
df_tgt['最近站点球面距离']=df_tgt['Site ID'].apply(lambda x:最近站点(x,df_OSP)[1])
df_tgt['第2站点']=df_tgt['Site ID'].apply(lambda x:第2站点(x,df_OSP)[0])
df_tgt['第2站点球面距离']=df_tgt['Site ID'].apply(lambda x:第2站点(x,df_OSP)[1])
df_tgt['第3站点']=df_tgt['Site ID'].apply(lambda x:第3站点(x,df_OSP)[0])
df_tgt['第3站点球面距离']=df_tgt['Site ID'].apply(lambda x:第3站点(x,df_OSP)[1])
目标数据=wb.sheets.add('目标数据'+timeName,after=1)
目标数据.range('a1').options(index=False).value=df_tgt
wb.save()
最后得到的目标数据,写入当前excel