def FinalLines(txtpath,kmlsavepath,txtfile): """ 批量处理每辆车的完成路网匹配 :param txtpath: txt文件路径,txt文件是最终确定的轨迹点所属路段的存储文件 :param kmlsavepath: kml文件的保存路径 txtfile kml路线对应的txt文档 :return: """ if not os.path.isdir(kmlsavepath): os.mkdir(kmlsavepath) with open(txtpath,'r') as file: lines = file.readlines() linesnum = len(lines) finalconnways = [] #最终能走通的路线 count = 0 for i in range(linesnum): if lines[i].strip("\n")=="New_Road": continue waylists = GetAllLines(eval(lines[i].strip("\n"))) if len(waylists)>=3: if MapNavigation.JudgeLines(waylists): finalconnways.append(waylists) elif len(waylists)==2: if MapNavigation.JudgeTwoWay(waylists[0],waylists[1]): finalconnways.append(waylists) else:pass #print(finalconnways) finalconnways = Common_Functions.Double_layer_list(finalconnways) file = open(txtfile,'a') for sub in finalconnways: file.write(str(sub)+"\n") count += 1 nodes = Fill_coordinate_By_Routes(sub) Common_Functions.list2kml(nodes, str(count),kmlsavepath) file.close()
def JudgeTwoWay(wayid1,wayid2): """ 判断两个相邻有交点路段是否能够互通,即从way1 是否能到达way2 注意:此部分只判断有交点的两个路段 没有交点的两个路段会直接判断为不能互通 思路: 1、无交点,判定为不通,两个路段ID相同,判定为相通 2、 :param wayid1: :param wayid2: :return: """ if wayid1==wayid2: Common_Functions.SaveRoutesConn("connects", wayid1, wayid2, 1) return True node_id = TwoWay_intersection(wayid1, wayid2) # 两条路段交点 if not node_id: #两个路段没有交点 return False try: wayid1_oneway_flag = Getway_Direction(wayid1) # 标记wayid1是否为单向 wayid2_oneway_flag = Getway_Direction(wayid2) # 标记wayid2是否为单向 wayslist1 = Get_way_NodeID(wayid1) wayslist2 = Get_way_NodeID(wayid2) # 示例:[320524866, 2207731964, 320524867] index = wayslist2.index(node_id[0][0]) # node_id[0][0]为取出交点 node_id为嵌套元组 if wayid1_oneway_flag == 0 and wayid2_oneway_flag == 0: # 两个路段均为双向 Common_Functions.SaveRoutesConn("connects", wayid1, wayid2, 1) return True elif wayid1_oneway_flag == 1 and wayid2_oneway_flag == 0: # wayid1 为单向 wayid2 为双向 # wayid1为单向 wayid2为双向 if wayslist1.index(node_id[0][0]) == 0: # 交点为wayid1的第一个点 Common_Functions.SaveRoutesConn("connects", wayid1, wayid2, 0) return False else: Common_Functions.SaveRoutesConn("connects", wayid1, wayid2, 1) return True elif wayid1_oneway_flag == 0 and wayid2_oneway_flag == 1: # wayid1 为双向 wayid2 为单向 if index == len(wayslist2) - 1: # 交点是way2的最后一个点,那么即使way1 way2有交点,则way1也是无法到达way2的 Common_Functions.SaveRoutesConn("connects", wayid1, wayid2, 0) return False else: Common_Functions.SaveRoutesConn("connects", wayid1, wayid2, 1) return True else: # 两个路段均为单向 if index == len(wayslist2) - 1: # 交点是way2的最后一个点,那么即使way1 way2有交点,则way1也是无法到达way2的 Common_Functions.SaveRoutesConn("connects", wayid1, wayid2, 0) return False elif wayslist1.index(node_id[0][0]) == 0 and wayslist2.index(node_id[0][0]) == 0: # 交点同时是way1 way2的第一个点 Common_Functions.SaveRoutesConn("connects", wayid1, wayid2, 1) return True elif wayslist1.index(node_id[0][0]) == 0: # 交点是way1的第一个点 Common_Functions.SaveRoutesConn("connects", wayid1, wayid2, 0) return False else: Common_Functions.SaveRoutesConn("connects", wayid1, wayid2, 1) return True except: return False
def FindPointCandidateWay_Grid(csvfilepath, candidatewaypath, candidatewayname): """ :param csvfilepath: csv文件路径 例:H:\TrunksArea\\334e4763-f125-425f-ae42-8028245764fe.csv" :param candidatewaypath: 轨迹点候选路段保存路径 :param candidatewayname: 候选路段保存的文件名 :return: """ if not os.path.isdir(candidatewaypath): os.mkdir(candidatewaypath) # 读时间 经纬度 网格编号 #df = pd.read_csv("H:\GPS_Data\Road_Network\BYQBridge\TrunksArea\\334e4763-f125-425f-ae42-8028245764fe.csv",header=None, usecols=[1, 2, 3, 4, 5]) df = pd.read_csv(csvfilepath, header=None, usecols=[1, 2, 3, 4, 5]) points_num = df.shape[0] # 坐标数量 pd.set_option('display.max_columns', None) pd.set_option('display.max_rows', None) # print(df.iloc[:,1:4]) drop_list = [] # 要删除的索引列表 for row in range(1, points_num): if row == points_num: break points_dis = Common_Functions.haversine(df.iloc[row, 1], df.iloc[row, 2], df.iloc[row - 1, 1], df.iloc[row - 1, 2]) # 相邻坐标点之间的距离 if points_dis < 0.01: # 距离小于10米 drop_list.append(row) newdf = df.drop(drop_list) # 删除相邻点在10米之内的点 newdf = newdf.reset_index(drop=True) txtname = candidatewayname + ".txt" file = open(os.path.join(candidatewaypath, txtname), 'a') print("本轨迹段共查找坐标点数为:{}".format(newdf.shape[0])) for row in range(newdf.shape[0]): dic = {} #candidatacode = BigGridCode.Neighbor(newdf.iloc[row, 1], newdf.iloc[row, 2]) # 查找附近八个区域 # for subcode in candidatacode: # if subcode: # waysets = list(Common_Functions.GetWay_ByGridCode(subcode[1])) # for subway in waysets: # dic[subway[0]] = subcode[1] pointCode = BigGridCode.Encode(newdf.iloc[row, 1], newdf.iloc[row, 2]) waysets = list(Common_Functions.GetWay_ByGridCode(pointCode[1])) if waysets: for subway in waysets: dic[subway[0]] = pointCode[1] #print(f"{newdf.iloc[row, 1]},{newdf.iloc[row, 2]}CandidateWay>>>{str(dic)}") if dic: file.write("PointID-" + str(row + 1) + "CandidateWay>>>" + str(dic) + "\n") file.close()
def InsertGridTable(waylistpath, dbname, tablename): connection = pymysql.connect(host='localhost', user='******', passwd='123456', charset='utf8') cursor = connection.cursor() cursor.execute("use {};".format(dbname)) print("ways信息开始导入数据库...") with open(waylistpath, 'r') as file: dic = json.loads(file.read()) with tqdm(total=len(dic)) as pbar: for key in dic.keys(): Isflag = 1 #标记该路段是否有轨迹点没有坐标 completeLineCode = [] #存储一条线路的完整编号 for num in range(1, len(dic[key])): # sequence代表每条路中node的排序号 coor1 = MapNavigation.Get_Coordinate(dic[key][num - 1]) #有的点没有坐标 coor2 = MapNavigation.Get_Coordinate(dic[key][num]) if coor1 and coor2: #print(coor1[0],coor1[1],coor2[0],coor2[1]) temcodelist = BigGridCode.GetGridCodes( coor1[0], coor1[1], coor2[0], coor2[1]) completeLineCode.extend(temcodelist) else: Isflag = 0 continue if Isflag == 1: #`FirstLevelTable`(`WayID`, `GridCode`, `SequenceID`) sequenceid = 0 Common_Functions.del_adjacent(completeLineCode) # li = list(set(completeLineCode)) # li.sort(key=completeLineCode.index) #with open("H:\GPS_Data\Road_Network\Beijing\\BJGrid.txt",'a') as file: #file.write(key +">>>" + str(completeLineCode)+"\n") for sub in completeLineCode: sequenceid += 1 sql_insert = 'insert into {}(WayID,GridCode,SequenceID) values({},{},{});'.format( tablename, key, repr(sub[1]), sequenceid) try: cursor.execute(sql_insert) # 执行sql语句 connection.commit() # 提交 except Exception as e: print(e) connection.rollback() cursor.close() else: print(f"未导入:{key}") pass pbar.update(1) connection.close()
def AllwayConn(waysjsonpath): """ 对左右的路段进行连通性判断 permutations(Allwayset,2) 二二组合,(A,B,C)->AB AC BA BC CA CB :param waysjsonpath:所有路段json文件路径 :return: """ AllwaysLists = [] with open(waysjsonpath, 'r') as file: dic = json.loads(file.read()) for key in dic.keys(): AllwaysLists.append(key) Allwaysset = set(AllwaysLists) for twowaytuple in permutations(Allwaysset, 2): print(f"正在查看路段:{twowaytuple[0]}与路段:{twowaytuple[1]}的连通性......") connectroute = Common_Functions.InquireConn(twowaytuple[0], twowaytuple[1], "connects") # 先查表 # connectroute = -1 if connectroute != 0 and connectroute != 1: # 表中没有记录 再用简易导航 connectroute = MapNavigation.waytoway(twowaytuple[0], twowaytuple[1]) # 为列表 if connectroute: print( f"路段{twowaytuple[0]}---->{twowaytuple[1]}的路线:{connectroute}" ) else: print(f"路段{twowaytuple[0]}不能到达路段{twowaytuple[1]}") else: print("数据库中已存在,跳过")
def AllwayConn(waysjsonpath): """ 对左右的路段进行连通性判断 permutations(Allwayset,2) 二二组合,(A,B,C)->AB AC BA BC CA CB :param waysjsonpath:所有路段json文件路径 :return: """ AllwaysLists = [] with open(waysjsonpath, 'r') as file: dic = json.loads(file.read()) for key in dic.keys(): AllwaysLists.append(key) Allwaysset = set(AllwaysLists) for twowaytuple in permutations(Allwaysset, 2): try: print(f"正在查看路段:{twowaytuple[0]}与路段:{twowaytuple[1]}的连通性......") way1_x, way1_y = Getway_startendnode_coordi( twowaytuple[0]) # 路段1的起点坐标 way2_x, way2_y = Getway_startendnode_coordi( twowaytuple[1]) # 路段2的起始坐标 print(way1_x, way1_y, way2_x, way2_y) if way1_x != 0 and way1_y != 0 and way2_x != 0 and way2_y != 0: waydis = Common_Functions.haversine(way1_x, way1_y, way2_x, way2_y) print(waydis) if waydis < 3: connectroute = Common_Functions.InquireConn( twowaytuple[0], twowaytuple[1], "connects") # 先查表 # connectroute = -1 if connectroute != 0 and connectroute != 1: # 表中没有记录 再用简易导航 connectroute = MapNavigation.waytoway( twowaytuple[0], twowaytuple[1]) # 为列表 if connectroute: print( f"路段{twowaytuple[0]}---->{twowaytuple[1]}的路线:{connectroute}" ) else: print(f"路段{twowaytuple[0]}不能到达路段{twowaytuple[1]}") else: print("数据库中已存在,跳过") else: pass except Exception as e: print(e)
def Fill_coordinate_By_Routes(waylists:list): """ 根据最终的waylist求出路网坐标点 传入的列表是要是已经连通好的路线 :param waylists 路线中路段列表,以车辆"003b5b7e-e72c-4fc5-ac6d-bcc248ac7a16"经过北野场桥为例 [437527026, 466289459, 466289461, 466289460, 606768166, 152616724] :return: """ AllNodeLists = [] #道路坐标列表 AllNodeIDLists = [] #道路坐标点编号列表 First_intersection = 0 #第一个交点 if len(waylists)==0: return None if len(waylists) == 1: nodelist = Common_Functions.Get_way_Nodes(waylists[0]) AllNodeIDLists.extend(nodelist[:]) for node in AllNodeIDLists: node_coordinate = Common_Functions.Get_Coordinate(node) AllNodeLists.append(node_coordinate) return AllNodeLists for index in range(len(waylists)): if index == len(waylists)-1: nodelist = Common_Functions.Get_way_Nodes(waylists[index]) First_intersection_index = nodelist.index(First_intersection) AllNodeIDLists.extend(nodelist[First_intersection_index:]) break else: Second_intersection = MapNavigation.TwoWay_intersection(waylists[index],waylists[index+1])[0][0] #两条路交点,TwoWay_intersection返回的为元组,如((1213),) nodelist = Common_Functions.Get_way_Nodes(waylists[index]) #获得该路段的所有坐标点 if index==0: First_intersection_index = 0 #路段第一个交点在路段中的索引号,此时First_intersection_index还是None else: First_intersection_index = nodelist.index(First_intersection) Second_intersection_index = nodelist.index(Second_intersection) #第二个坐标交点 AllNodeIDLists.extend(nodelist[First_intersection_index:Second_intersection_index+1]) First_intersection = Second_intersection for node in AllNodeIDLists: node_coordinate = Common_Functions.Get_Coordinate(node) AllNodeLists.append(node_coordinate) return AllNodeLists
def Batchprocess(sourcecsvpath,splitsavepath,candidatewaypath): if not os.path.isdir(splitsavepath): os.mkdir(splitsavepath) sourcecsvfilelist = Common_Functions.findcsvpath(sourcecsvpath) #找出所有的网格化之后的单车文件路径 # for singlefile in sourcecsvfilelist: # RoadMatching.TrajectorySplit(singlefile,splitsavepath) #完整轨迹分段 folderlist = os.listdir(splitsavepath) #文件夹列表 print(folderlist) #dicflag = {00000000:"BreakPoint"} for folder in folderlist: tempath = os.path.join(splitsavepath,folder) if os.path.isdir(tempath): print(f"正在处理车辆{folder}") if folder =="10706a7b-3d56-4551-9a09-debda7d2c032": continue partcsvlists = Common_Functions.findcsvpath(tempath) #每个文件夹中的分段轨迹csv文件 for index in range(len(partcsvlists)): RoadMatching.FindPointCandidateWays(partcsvlists[index],candidatewaypath,folder) txtname = folder + ".txt" if index!=len(partcsvlists)-1: with open(os.path.join(candidatewaypath, txtname), 'a') as file: file.write("PointIDCandidateWay>>>BreakPoint\n") else: pass
def BatchSelectLines(Candidatewaypath,savepath): """ 批量选出最终匹配的轨迹 :param Candidatewaypath: 所有候选路线的txt路径 :param savepath: kml保存路径 :return: """ txtlist = Common_Functions.findtxtpath(Candidatewaypath) for singletxt in txtlist: print(singletxt) (tempath, tempfilename) = os.path.split(singletxt) # tempfilename为txt文件名(包含后缀) (trunkname, extension) = os.path.splitext(tempfilename) # filename 为传入的txt文件名 extension为后缀 kmlsavepath = os.path.join(savepath,trunkname) txtkmllinename = trunkname +".txt" if not os.path.isdir(kmlsavepath): os.mkdir(kmlsavepath) FinalLines(singletxt,kmlsavepath,os.path.join(kmlsavepath,txtkmllinename))
file.close() def BatchSelectLines(Candidatewaypath,savepath): """ 批量选出最终匹配的轨迹 :param Candidatewaypath: 所有候选路线的txt路径 :param savepath: kml保存路径 :return: """ txtlist = Common_Functions.findtxtpath(Candidatewaypath) for singletxt in txtlist: print(singletxt) (tempath, tempfilename) = os.path.split(singletxt) # tempfilename为txt文件名(包含后缀) (trunkname, extension) = os.path.splitext(tempfilename) # filename 为传入的txt文件名 extension为后缀 kmlsavepath = os.path.join(savepath,trunkname) txtkmllinename = trunkname +".txt" if not os.path.isdir(kmlsavepath): os.mkdir(kmlsavepath) FinalLines(singletxt,kmlsavepath,os.path.join(kmlsavepath,txtkmllinename)) #FinalLines("H:\GPS_Data\Road_Network\BYQBridge\FinalRoutes\\10706a7b-3d56-4551-9a09-debda7d2c032.txt","H:\GPS_Data\Road_Network\BYQBridge\KML\PartTrunksAreaKml") #BatchSelectLines("H:\GPS_Data\Road_Network\BYQBridge\FinalRoutes\Test","H:\GPS_Data\Road_Network\BYQBridge\KML\PartTrunksAreaKml\Batch") # FinalLines("H:\GPS_Data\Road_Network\BYQBridge\FinalRoutes\FullTrack\\10706a7b-3d56-4551-9a09-debda7d2c032.txt", # "H:\GPS_Data\Road_Network\BYQBridge\KML\PartTrunksAreaKml\FullTrack\\10706a7b-3d56-4551-9a09-debda7d2c032", # "H:\GPS_Data\Road_Network\BYQBridge\KML\PartTrunksAreaKml\FullTrack\\10706a7b-3d56-4551-9a09-debda7d2c032\\10706a7b.txt") Common_Functions.list2kml(Fill_coordinate_By_Routes([242945739, 242945750, 242945771, 47574802, 680002283, 47574807]), "se","H:\GPS_Data\Road_Network\BYQBridge\KML\PartTrunksAreaKml\Grid\BYC") #print(GetAllLines([318909305, 317886767, 407991264, 51997674, 317916355, 391813868, 29135445, 317916344, 29135795, 391813830, 210697668, 317916290, 29135960, 47574189, 242945770, 47574191, 229521327, 258296019, 317889645, 317913828, 29136270, 606768167, 606768159, 508147677, 508312926, 466839062, 466839044, 466839045, 332203310, 332203325, 398538985]))
def SelectFinalRoutes(candidatewaypath, savefinalroutespath): """ 本函数与SelectFinalRoute功能相同,只是本函数处理完整的轨迹时,如果大于50.会重新开始计算最大连通性 根据坐标点的候选路段选出路网的匹配路线 保存格式为:车辆名:路线(如果不确定,可能为多条),车辆名为txt文件名 :param candidatewaypath: 坐标点候选路段的txt文件路径,如H:\\CandidateWay\\NewStrategy\\334e4763-f125-425f-ae42-8028245764fe.txt :param savefinalroutespath: 最终路线保存路径 :return: """ #file = open("H:\GPS_Data\Road_Network\BYQBridge\FinalRoutes\\334e4763-f125-425f-ae42-8028245764fe.txt", 'a') max_connect = 0 #记录计算最大连通的轨迹点数 (tempath, tempfilename) = os.path.split( candidatewaypath) # tempfilename为txt文件名(包含后缀) (trunkname, extension) = os.path.splitext( tempfilename) # filename 为传入的csv文件名 extension为后缀 savetxtfilename = trunkname + '.txt' Resetflag = 0 #标记最终路段是否重新开始计算 file = open(os.path.join(savefinalroutespath, savetxtfilename), 'a') with open(candidatewaypath) as candidatewayfile: filelines = candidatewayfile.readlines() linesnum = len(filelines) finalline = [] #存储最终路线,可能为多条,随着坐标点的迭代,会变化,直到处理完最有一个坐标点 for key in eval(filelines[0].strip('\n').split(">>>")[-1]).keys(): finalline.append([key]) #print(finalline) # 遍历每个坐标点的候选路段 print("需要处理坐标数为:{}".format(linesnum)) for lineindex in range(1, linesnum): print(f"正在处理第{lineindex+1}个坐标") if filelines[lineindex].strip('\n').split( ">>>")[-1] == "BreakPoint": #轨迹分段,分开计算 file.write("New_Road\n") for sub in finalline: file.write(str(sub) + "\n") file.flush() Resetflag = 1 #标记从下一个点要重新开始匹配轨迹了 max_connect = 0 continue if max_connect == 100: file.write("New_Road\n") for sub in finalline: file.write(str(sub) + "\n") file.flush() Resetflag = 1 #标记从下一个点要重新开始匹配轨迹了 max_connect = 0 continue if Resetflag == 1: finalline.clear() for key in eval(filelines[lineindex].strip('\n').split(">>>") [-1]).keys(): finalline.append([key]) Resetflag = 0 continue templine = [] #存储临时路线 #print("处理坐标{}:{}".format(lineindex,eval(filelines[lineindex].strip('\n').split(">>>")[-1]))) #print("处理路段{}".format(eval(filelines[lineindex].strip('\n').split(">>>")[-1]))) connect_next_flag = 0 #记录下一步是否能有能走通的路段 for subline in finalline: #遍历每一条的候选路线 for key in eval(filelines[lineindex].strip('\n').split(">>>") [-1]).keys(): #遍历每个轨迹点的候选路段 #此代码块只加入key,不加入完整路线 print("路段:{}匹配key:{}".format(subline[-1], key)) # 只需要查看subline的最后一个路段与路段key是否连通即可,因为subline的连通性是通过测试的 connectroute = Common_Functions.InquireConn( subline[-1], key, "connects") #先查表 #connectroute = -1 if connectroute != 0 and connectroute != 1: #表中没有记录 再用简易导航 connectroute = MapNavigation.waytoway( subline[-1], key) # 为列表 if connectroute: connect_next_flag = 1 temsubline = copy.deepcopy(subline) temsubline.append(key) # 只加入轨迹点所属路段,而不加入这两个路段走通的路线 templine.append(temsubline) else: # 此路线不连通,舍弃当前路段key pass """ #此代码块是加入完整路线 #connectroute = Common_Functions.InquireConn(subline[-1], key,"connects") #先查表 #connectroute = -1 connectroute = MapNavigation.Nodirectionwaytoway(subline[-1], key) # 为列表 if subline[-1] == key: temsubline = copy.deepcopy(subline) templine.append(temsubline) #elif connectroute !=0 and connectroute!= 1: #表中没有记录 再用简易导航 #connectroute = MapNavigation.Nodirectionwaytoway(subline[-1], key) # 为列表 elif connectroute: #路段可连通 temsubline = copy.deepcopy(subline) temsubline.extend(connectroute[1:]) #将走通的路线加入到子路线,扩展当前路线 templine.append(temsubline) else:pass """ if connect_next_flag == 0: #所有的候选路线与当前轨迹点的候选路段均不能相通,跳过此轨迹点 pass else: finalline.clear() # print(templine) finalline = Common_Functions.DoubleDel(templine) # 去相邻重复 再去重 finalline = Common_Functions.Main_Auxiliary_road( finalline) # 去除头尾路段一样的候选路线,路线只有一个路段 不会处理 # print(finalline) #finalline = Common_Functions.Start_End(finalline) # 对于[wayid1,wayid2,wayid3] [wayid1,wayid4,wayid5,wayid3] 去除路段多的,如果包含路段数量一致 暂不处理 finalline = Common_Functions.Sequential_subset( finalline) # 最后去路线(至少两个及以上的其他路线是其前缀) max_connect += 1 file.write("New_Road\n") for sub in finalline: file.write(str(sub) + "\n") file.flush() file.close()
def SelectFinalRoutes(candidatewaypath, savefinalroutespath): """ 本函数与SelectFinalRoute功能相同,只是本函数处理完整的轨迹时,如果大于50.会重新开始计算最大连通性 根据坐标点的候选路段选出路网的匹配路线 保存格式为:车辆名:路线(如果不确定,可能为多条),车辆名为txt文件名 :param candidatewaypath: 坐标点候选路段的txt文件路径,如H:\\CandidateWay\\NewStrategy\\334e4763-f125-425f-ae42-8028245764fe.txt :param savefinalroutespath: 最终路线保存路径 :return: """ #file = open("H:\GPS_Data\Road_Network\BYQBridge\FinalRoutes\\334e4763-f125-425f-ae42-8028245764fe.txt", 'a') max_connect = 0 (tempath, tempfilename) = os.path.split( candidatewaypath) # tempfilename为txt文件名(包含后缀) (trunkname, extension) = os.path.splitext( tempfilename) # filename 为传入的csv文件名 extension为后缀 savetxtfilename = trunkname + '.txt' file = open(os.path.join(savefinalroutespath, savetxtfilename), 'a') with open(candidatewaypath) as candidatewayfile: filelines = candidatewayfile.readlines() linesnum = len(filelines) finalline = [] #存储最终路线,可能为多条,随着坐标点的迭代,会变化,直到处理完最有一个坐标点 for key in eval(filelines[0].strip('\n').split(">>>")[-1]).keys(): finalline.append([key]) predict = eval(filelines[0].strip('\n').split(">>>")[-1]) # 遍历每个坐标点的候选路段 print(f"需要处理坐标数为:{linesnum}") for lineindex in range(1, linesnum): templine = [] #存储临时路线 curdict = eval(filelines[lineindex].strip('\n').split(">>>")[-1]) flag = 0 #标记之前的路线与当前轨迹点的所有候选路段是否能连通,不能连通,舍弃该轨迹点 newdic = {} for subline in finalline: #遍历每一条的候选路线 #print(f"ID{lineindex-1}:{predict},{curdict}") for key in curdict.keys(): #遍历每个轨迹点的候选路段 connectroute = Common_Functions.InquireConn( subline[-1], key, "connects") #先查表 if connectroute != 0: #print(subline[-1], predict[subline[-1]], key, curdict[key]) connectroute = GridMapNavigation.CandidateWay_Connect( subline[-1], predict[subline[-1]], key, curdict[key]) # 双重列表 #print(f"next:{connectroute}") if connectroute: flag = 1 for line in connectroute: temsubline = copy.deepcopy(subline) temsubline.extend(line) # 将走通的路线加入到子路线,扩展当前路线 templine.append(temsubline) #newdic[line[-1]] = curdict[line[-1]] else: pass else: pass if flag == 1: finalline.clear() predict = curdict templine = Common_Functions.DoubleDel(templine) templine = Common_Functions.Main_Auxiliary_road( templine) #去除头尾路段一样的候选路线,路线只有一个路段 不会处理 templine = Common_Functions.Start_End( templine ) # 对于[wayid1,wayid2,wayid3] [wayid1,wayid4,wayid5,wayid3] 去除路段多的,如果包含路段数量一致 暂不处理 Common_Functions.Sequential_subset( finalline) # 最后去路线(至少两个及以上的其他路线是其前缀) for sub in templine: finalline.append(Common_Functions.del_adjacent(sub)) else: pass #print(f"final:{finalline}") print("共选出{}条路".format(len(finalline))) for sub in finalline: print(sub) file.write(str(sub) + "\n") file.close()
dic[subway[0]] = pointCode[1] #print(f"{newdf.iloc[row, 1]},{newdf.iloc[row, 2]}CandidateWay>>>{str(dic)}") if dic: file.write("PointID-" + str(row + 1) + "CandidateWay>>>" + str(dic) + "\n") file.close() import time start = time.time() #FindPointCandidateWay_Grid("H:\GPS_Data\Road_Network\BYQBridge\TrunksArea\\b79a4749-6228-4e47-8c1e-4e5c5dce8a53.csv","H:\GPS_Data\Road_Network\BYQBridge\CandidateWay\Grid\BYC","b79a4749-6228-4e47-8c1e-4e5c5dce8a53") #SelectFinalRoutes("H:\GPS_Data\Road_Network\BYQBridge\CandidateWay\Grid\BYC\\10706a7b-3d56-4551-9a09-debda7d2c032.txt","H:\GPS_Data\Road_Network\BYQBridge\FinalRoutes\Grid\BYC") # for subpath in Common_Functions.findtxtpath("H:\GPS_Data\Road_Network\BYQBridge\CandidateWay\\NewStrategy"): # (tempath, tempfilename) = os.path.split(subpath) # tempfilename为txt文件名(包含后缀) # (trunkname, extension) = os.path.splitext(tempfilename) # filename 为文件名 extension为后缀 # csvfile = trunkname + ".csv" # FindPointCandidateWay_Grid( # os.path.join("H:\GPS_Data\Road_Network\BYQBridge\TrunksArea",csvfile), # "H:\GPS_Data\Road_Network\BYQBridge\CandidateWay\Grid\BYC", trunkname) #最终路线 for subpath in Common_Functions.findtxtpath( "H:\GPS_Data\Road_Network\BYQBridge\CandidateWay\Grid\BYC"): print(subpath) SelectFinalRoutes( subpath, "H:\GPS_Data\Road_Network\BYQBridge\FinalRoutes\Grid\BYC") #FindPointCandidateWay_Grid("H:\GPS_Data\Road_Network\BYQBridge\TrunksArea\\334e4763-f125-425f-ae42-8028245764fe.csv","H:\GPS_Data\Road_Network\BYQBridge\CandidateWay\Grid\BYC","334e4763-f125-425f-ae42-8028245764fe") #SelectFinalRoutes("H:\GPS_Data\Road_Network\BYQBridge\CandidateWay\Grid\BYC\\99b9e495-22f3-4dd2-81e1-a946b3805229.txt","H:\GPS_Data\Road_Network\BYQBridge\FinalRoutes\Grid\BYC") print(time.time() - start)
def TrajectorySplit(csvfilepath, processpath): """ :param csvfilepath: 原始轨迹csv文件 :param processpath: 存储原轨迹分段之后的csv文件 :return: """ (path, file) = os.path.split(csvfilepath) (filename, extension) = os.path.splitext(file) filesavepath = os.path.join(processpath, filename) #文件分段之后保存的路径 if not os.path.isdir(filesavepath): os.mkdir(filesavepath) df = pd.read_csv(csvfilepath, header=None, usecols=[1, 2, 3, 4, 5], names=[0, 1, 2, 3, 4]) df = df.sort_values(by=0) # 时间排序 points_num = df.shape[0] # 坐标数量 pd.set_option('display.max_columns', None) pd.set_option('display.max_rows', None) drop_list = [] # 要删除的索引列表 df.iloc[:, 0] = pd.to_datetime(df.iloc[:, 0], format="%Y%m%d ") for row in range(1, points_num): if row == points_num: break points_dis = Common_Functions.haversine(df.iloc[row, 1], df.iloc[row, 2], df.iloc[row - 1, 1], df.iloc[row - 1, 2]) # 相邻坐标点之间的距离 Time_difference = (df.iloc[row, 0] - df.iloc[row - 1, 0]).seconds #相邻两个坐标点的时间差,单位:秒 if points_dis < 0.01: # 距离小于10米 drop_list.append(row) if Time_difference != 0: speed = points_dis / Time_difference #速度 秒 else: speed = 0 if speed >= 0.034: drop_list.append(row) #时速大于120 ,0.034时速为122 newdf = df.drop(drop_list) # 删除相邻点在10米之内的点和时速大于120的异常点 newdf = newdf.reset_index(drop=True) #Candidate_pointName = filename + ".csv" #newdf.to_csv(os.path.join(filesavepath, os.path.join()), index=0,header=0, encoding='utf_8_sig') #筛选出的被匹配的轨迹点 #以上为处理所有的相邻点距离小于10米的坐标 #以下循环为分段 start_row = 0 #文件分割的起始行数 endrow = 0 #结束行数 part_num = 1 part_name = "part" + str(part_num) + ".csv" #tem_df = pd.DataFrame(None) Is_Save_flag = 0 #记录该轨迹段是否保存 for row in range(1, newdf.shape[0]): #Time_difference = (newdf.iloc[row, 0] - newdf.iloc[row - 1, 0]).seconds # 相邻两个坐标点的时间差,单位:秒 Adjacent_two_points_dis = Common_Functions.haversine( newdf.iloc[row, 1], newdf.iloc[row, 2], newdf.iloc[row - 1, 1], newdf.iloc[row - 1, 2]) # 相邻坐标点之间的距离 if Adjacent_two_points_dis > 5: endrow = row - 1 Is_Save_flag = 1 if row == newdf.shape[0] - 1: #tem_df = newdf.loc[start_row:row+1, :] endrow = row Is_Save_flag = 1 if Is_Save_flag == 1: newdf.loc[start_row:endrow, :].to_csv(os.path.join( filesavepath, part_name), index=0, header=0, encoding='utf_8_sig') start_row = endrow + 1 Is_Save_flag = 0 #tem_df.drop(tem_df.index, inplace=True) part_num += 1 part_name = "part" + str(part_num) + ".csv"
def BatchSelectFinalRoute(Candidatewaypath, finalroutepath): candidatetxts = Common_Functions.findtxtpath(Candidatewaypath) for subway in candidatetxts: print(subway) SelectFinalRoute(subway, finalroutepath)
def SelectFinalRoute(candidatewaypath, savefinalroutespath): """ 根据坐标点的候选路段选出路网的匹配路线 保存格式为:车辆名:路线(如果不确定,可能为多条),车辆名为txt文件名 :param candidatewaypath: 坐标点候选路段的txt文件路径,如H:\\CandidateWay\\NewStrategy\\334e4763-f125-425f-ae42-8028245764fe.txt :param savefinalroutespath: 最终路线保存路径 :return: """ #file = open("H:\GPS_Data\Road_Network\BYQBridge\FinalRoutes\\334e4763-f125-425f-ae42-8028245764fe.txt", 'a') (tempath, tempfilename) = os.path.split( candidatewaypath) # tempfilename为txt文件名(包含后缀) (trunkname, extension) = os.path.splitext( tempfilename) # filename 为传入的csv文件名 extension为后缀 savetxtfilename = trunkname + '.txt' file = open(os.path.join(savefinalroutespath, savetxtfilename), 'a') with open(candidatewaypath) as candidatewayfile: filelines = candidatewayfile.readlines() linesnum = len(filelines) finalline = [] #存储最终路线,可能为多条,随着坐标点的迭代,会变化,直到处理完最有一个坐标点 for key in eval(filelines[0].strip('\n').split(">>>")[-1]).keys(): finalline.append([key]) #print(finalline) # 遍历每个坐标点的候选路段 print("需要处理坐标数为:{}".format(linesnum)) for lineindex in range(1, linesnum): templine = [] #存储临时路线 # 遍历到最后一行 print(len(finalline)) print(finalline) print("处理坐标{}:{}".format( lineindex, eval(filelines[lineindex].strip('\n').split(">>>")[-1]))) #print("处理路段{}".format(eval(filelines[lineindex].strip('\n').split(">>>")[-1]))) for subline in finalline: for key in eval(filelines[lineindex].strip('\n').split(">>>") [-1]).keys(): temsubline = [] #此代码块只加入key,不加入完整路线 print("路段:{}匹配key:{}".format(subline[-1], key)) # 只需要查看subline的最后一个路段与路段key是否连通即可,因为subline的连通性是通过测试的 connectroute = Common_Functions.InquireConn( subline[-1], key, "connects") #先查表 #connectroute = -1 if connectroute != 0 and connectroute != 1: #表中没有记录 再用简易导航 connectroute = MapNavigation.waytoway( subline[-1], key) # 为列表 if connectroute: temsubline = copy.deepcopy(subline) temsubline.append(key) # 只加入轨迹点所属路段,而不加入这两个路段走通的路线 templine.append(temsubline) else: # 此路线不连通,舍弃当前路段key pass """ #此代码块是加入完整路线 #connectroute = Common_Functions.InquireConn(subline[-1], key,"connects") #先查表 #connectroute = -1 connectroute = MapNavigation.Nodirectionwaytoway(subline[-1], key) # 为列表 if subline[-1] == key: temsubline = copy.deepcopy(subline) templine.append(temsubline) #elif connectroute !=0 and connectroute!= 1: #表中没有记录 再用简易导航 #connectroute = MapNavigation.Nodirectionwaytoway(subline[-1], key) # 为列表 elif connectroute: #路段可连通 temsubline = copy.deepcopy(subline) temsubline.extend(connectroute[1:]) #将走通的路线加入到子路线,扩展当前路线 templine.append(temsubline) else:pass """ # print(temsubline) # print(templine) finalline.clear() #print(templine) finalline = Common_Functions.DoubleDel(templine) #去相邻重复 再去重 finalline = Common_Functions.Main_Auxiliary_road( finalline) #去除头尾路段一样的候选路线,路线只有一个路段 不会处理 #print(finalline) finalline = Common_Functions.Start_End( finalline ) # 对于[wayid1,wayid2,wayid3] [wayid1,wayid4,wayid5,wayid3] 去除路段多的,如果包含路段数量一致 暂不处理 finalline = Common_Functions.Sequential_subset( finalline) # 最后去路线(至少两个及以上的其他路线是其前缀) print("共选出{}条路".format(len(finalline))) for sub in finalline: file.write(str(sub) + "\n") file.flush() print(finalline) file.close()
def FindPointCandidateWay(csvfilepath, candidatewaypath, candidatewayname): """ 处理北野场桥 找出坐标点的候选路段,此部分已经通过角度(大于90)、距离(大于30米)筛除一部分候选路段 :param csvfilepath: csv文件路径 例:H:\TrunksArea\\334e4763-f125-425f-ae42-8028245764fe.csv" :param candidatewaypath: 轨迹点候选路段保存路径 :param candidatewayname: 候选路段保存的文件名 :return: """ if not os.path.isdir(candidatewaypath): os.mkdir(candidatewaypath) # 读时间 经纬度 网格编号 #df = pd.read_csv("H:\GPS_Data\Road_Network\BYQBridge\TrunksArea\\334e4763-f125-425f-ae42-8028245764fe.csv",header=None, usecols=[1, 2, 3, 4, 5]) df = pd.read_csv(csvfilepath, header=None, usecols=[1, 2, 3, 4, 5]) points_num = df.shape[0] # 坐标数量 pd.set_option('display.max_columns', None) pd.set_option('display.max_rows', None) # print(df.iloc[:,1:4]) drop_list = [] # 要删除的索引列表 for row in range(1, points_num): if row == points_num: break points_dis = Common_Functions.haversine(df.iloc[row, 1], df.iloc[row, 2], df.iloc[row - 1, 1], df.iloc[row - 1, 2]) # 相邻坐标点之间的距离 if points_dis < 0.01: # 距离小于10米 drop_list.append(row) # print(drop_list) newdf = df.drop(drop_list) # 删除相邻点在10米之内的点 # print(newdf.iloc[:,1:3]) newdf = newdf.reset_index(drop=True) #file = open("H:\GPS_Data\Road_Network\BYQBridge\CandidateWay\\NewStrategy\\334e4763-f125-425f-ae42-8028245764fe.txt", 'a') txtname = candidatewayname + ".txt" file = open(os.path.join(candidatewaypath, txtname), 'a') print("本轨迹段共查找坐标点数为:{}".format(newdf.shape[0])) for row in range(newdf.shape[0]): if row == 0: #print("处理起始坐标点{}".format([newdf.iloc[row, 1], newdf.iloc[row, 2], newdf.iloc[row, 3], newdf.iloc[row, 4]])) dic = Common_Functions.Find_Candidate_Route([ newdf.iloc[row, 1], newdf.iloc[row, 2], newdf.iloc[row, 3], newdf.iloc[row, 4] ], [ newdf.iloc[row + 1, 1], newdf.iloc[row + 1, 2], newdf.iloc[row + 1, 3], newdf.iloc[row + 1, 4] ], flag=1) if dic: # 有候选路段才保存 file.write("PointID-" + str(row + 1) + "CandidateWay>>>" + str(dic) + "\n") elif row == newdf.shape[0] - 1: #print("处理终点坐标点{}".format([df.iloc[row - 1, 2], df.iloc[row - 1, 3], df.iloc[row, 2], df.iloc[row, 3]])) dic = Common_Functions.Find_Candidate_Route([ newdf.iloc[row - 1, 1], newdf.iloc[row - 1, 2], newdf.iloc[row - 1, 3], newdf.iloc[row - 1, 4] ], [ newdf.iloc[row, 1], newdf.iloc[row, 2], newdf.iloc[row, 3], newdf.iloc[row, 4] ], flag=2) if dic: file.write("PointID-" + str(row + 1) + "CandidateWay>>>" + str(dic) + "\n") else: dis1 = Common_Functions.haversine(newdf.iloc[row, 1], newdf.iloc[row, 2], newdf.iloc[row - 1, 1], newdf.iloc[row - 1, 2]) dis2 = Common_Functions.haversine(newdf.iloc[row, 1], newdf.iloc[row, 2], newdf.iloc[row + 1, 1], newdf.iloc[row + 1, 2]) # 找相邻最近的点做为轨迹方向 if dis2 > dis1: #print("处理终点坐标点{}".format([newdf.iloc[row - 1, 1], newdf.iloc[row - 1, 2], newdf.iloc[row - 1, 3], newdf.iloc[row - 1, 4]])) dic = Common_Functions.Find_Candidate_Route([ newdf.iloc[row - 1, 1], newdf.iloc[row - 1, 2], newdf.iloc[row - 1, 3], newdf.iloc[row - 1, 4] ], [ newdf.iloc[row, 1], newdf.iloc[row, 2], newdf.iloc[row, 3], newdf.iloc[row, 4] ], flag=2) else: #print("处理起始坐标点{}".format([newdf.iloc[row, 1], newdf.iloc[row, 2], newdf.iloc[row, 3], newdf.iloc[row, 4]])) dic = Common_Functions.Find_Candidate_Route([ newdf.iloc[row, 1], newdf.iloc[row, 2], newdf.iloc[row, 3], newdf.iloc[row, 4] ], [ newdf.iloc[row + 1, 1], newdf.iloc[row + 1, 2], newdf.iloc[row + 1, 3], newdf.iloc[row + 1, 4] ], flag=1) if dic: file.write("PointID-" + str(row + 1) + "CandidateWay>>>" + str(dic) + "\n") file.close()
def Nodirectionwaytoway(way_id1,way_id2,max_sum=8): """ 无方向 有交点就会认为通行 :param way_id1: :param way_id2: :param max_sum: :return: """ if way_id1 == way_id2: return [way_id1,way_id2] finalroute = [] node_id = TwoWay_intersection(way_id1, way_id2) #两条路段交点 if node_id: if JudgeTwoWay(way_id1,way_id2): finalroute.extend([way_id1, way_id2]) Common_Functions.SaveRoutesConn("connects", way_id1, way_id2, 1) return finalroute else: Common_Functions.SaveRoutesConn("connects", way_id1, way_id2, 0) return False else: #两条路段没有直接交点 Candidate_Routes = [[way_id1]] # 候选路线 flag = 0 count = 0 #迭代多少次之后仍然没有找到可行路线,则认为不可走 exitflag = 0 #标记是否是通过找到满足条件的路线而退出的 grid1 = Getway_startendnode_grid(way_id1,flag=0) startx = grid1[0] starty = grid1[1] grid2 = Getway_startendnode_grid(way_id1, flag=0) Endx = grid2[0] Endy = grid2[1] while True: temCandidate_Routes = [] # 存储当前这一轮新的候选路线 AllNextways = [] MaxDel = [] #存因路段数目大于阈值,而筛除的路线 for sub in Candidate_Routes: if way_id2 in sub: flag = 1 break if len(sub) > max_sum: #防止寻找时间过长,如果目的是为了查找路线,可将此条件删除 MaxDel.append(sub) for sub in MaxDel: Candidate_Routes.remove(sub) if len(Candidate_Routes)==0: flag = 1 exitflag = 1 if count==8: flag=1 exitflag = 1 if flag == 1: break for subroute in Candidate_Routes: # subroute 表示正在处理的路线 preways = subroute #表示当前路线已有的路段 processingway = subroute[-1] # 表示要处理的路段 nextway = NodirectionFindNextWay(processingway,preways) # 下一步的可选路段 if len(nextway)==0: #当前路线下一步没有能走的路 pass else: AllNextways.extend(nextway) for next in nextway: temroute = copy.deepcopy(subroute) temroute.append(next) temCandidate_Routes.append(temroute) count += 1 Candidate_Routes.clear() Candidate_Routes = temCandidate_Routes Candidate_Routes = Common_Functions.Double_layer_list(Candidate_Routes) Candidate_Routes = Common_Functions.Main_Auxiliary_road(Candidate_Routes) # 去除头尾路段一样的候选路线 Candidate_Routes = Common_Functions.Start_End(Candidate_Routes) # 对于[wayid1,wayid2,wayid3] [wayid1,wayid4,wayid5,wayid3] 去除路段多的,如果包含路段数量一致 暂不处理 Candidate_Routes = Common_Functions.Sequential_subset(Candidate_Routes) # 最后去前缀 #print(len(Candidate_Routes)) delsub = [] for sub in Candidate_Routes: #判断行驶方向 secondgrid = Getway_startendnode_grid(sub[-1], flag=0) if secondgrid: curx = secondgrid[0] cury = secondgrid[1] if Endx > startx and Endy>starty: #路段way_id2 在way_id1 的右上部 if curx < startx and cury < starty: delsub.append(sub) #此路线方向向左下部走 删除此路线 if Endx > startx and Endy < starty: # 路段way_id2 在way_id1 的右下部 if curx < startx and cury > starty: delsub.append(sub) # 此路线方向向左上部走 删除此路线 if Endx <startx and Endy < starty: # 路段way_id2 在way_id1 的左下部 if curx > startx and cury > starty: delsub.append(sub) # 此路线方向向右上部走 删除此路线 if Endx < startx and Endy > starty: # 路段way_id2 在way_id1 的左上部 if curx > startx and cury < starty: delsub.append(sub) # 此路线方向向右上部走 删除此路线 else: delsub.append(sub) for sub in Common_Functions.Double_layer_list(delsub): Candidate_Routes.remove(sub) #print(len(Candidate_Routes)) if len(AllNextways)==0: #所有的候选路线都没有下一步路可走 flag=1 exitflag = 1 minnum = float("inf") if exitflag==1: #证明是循环跳出不是因为找到路径跳出的 Common_Functions.SaveRoutesConn("connects", way_id1, way_id2, 0) return False Deleteways = [] #print(Candidate_Routes) for sub in Candidate_Routes: #由于以上为没有方向的判断,所以在此循环中要加入方向的判断 if way_id2 in sub: if len(sub)==1: return sub elif len(sub)==2 and JudgeTwoWay(sub[0],sub[1]): pass elif len(sub) >= 3 and JudgeLines(sub): pass else: Deleteways.append(sub) else: Deleteways.append(sub) if len(Deleteways)!=0: for delsub in Common_Functions.Double_layer_list(Deleteways): Candidate_Routes.remove(delsub) if len(Candidate_Routes)==0: Common_Functions.SaveRoutesConn("connects", way_id1, way_id2, 0) return False for sub in Candidate_Routes: if way_id2 in sub: if len(sub) < minnum: finalroute = sub minnum = len(sub) else: pass if len(finalroute)==0: Common_Functions.SaveRoutesConn("connects", way_id1, way_id2,0) return False else: Common_Functions.SaveRoutesConn("connects", way_id1, way_id2, 1) return finalroute
def waytoway(way_id1,way_id2,max_num=8): """ 实现从way_id1到way_id2的路线规划,当此函数完全用作简易导航,可设置max_num为无穷 设置 max_num 与Count 的原因为防止查找完全不通的两个路段而耗费过长的时间 有方向通行 问题:即使很近的两个路段(实际短距离不能通行),但是会花费较多的时间去判断是否能通行 47574526,403874395两个路段不能互通 但是只在北野场桥一部分就花费了5分钟去判断可行性 :param way_id1: :param way_id2: :return: 首先判断两个路段是否有交集,有交集则这两条路不需要经过其他路线的连接 """ if way_id1 == way_id2: return [way_id1,way_id2] finalroute = [] node_id = TwoWay_intersection(way_id1, way_id2) #两条路段交点 if node_id: if JudgeTwoWay(way_id1,way_id2): finalroute.extend([way_id1, way_id2]) Common_Functions.SaveRoutesConn("connects", way_id1, way_id2, 1) return finalroute else: Common_Functions.SaveRoutesConn("connects", way_id1, way_id2, 0) return False else: #两条路段没有直接交点 Candidate_Routes = [[way_id1]] # 候选路线 flag = 0 count = 0 # 迭代多少次之后仍然没有找到可行路线,则认为不可走 exitflag = 0 #标记是否是通过找到满足条件的路线而退出的 grid1 = Getway_startendnode_grid(way_id1, flag=0) startx = grid1[0] starty = grid1[1] grid2 = Getway_startendnode_grid(way_id1, flag=0) Endx = grid2[0] Endy = grid2[1] startendwaydis = twoway_distance(way_id1, way_id2)+ 0.01 # 加1000米弹性范围,0.0003为30米 while True: print(Candidate_Routes) temCandidate_Routes = [] # 存储当前这一轮新的候选路线 AllNextways = [] print(count) for subroute in Candidate_Routes: # subroute 表示正在处理的路线 processingway = subroute[-1] # 表示要处理的路段 wayflag,nextway = FindNextWay(processingway,subroute,way_id2) # 下一步的可选路段 #wayflag为FALSE 标记wayid2在nextway,但是由于方向问题,被删除,所以直接判定为不通 if not wayflag: Common_Functions.SaveRoutesConn("connects", way_id1, way_id2, 0) return False if len(nextway) == 0: # 当前路线下一步没有能走的路 pass else: AllNextways.extend(nextway) for next in nextway: temroute = copy.deepcopy(subroute) temroute.append(next) temCandidate_Routes.append(temroute) if len(AllNextways)==0: #所有的候选路线都没有下一步路可走 flag=1 exitflag = 1 count += 1 Candidate_Routes.clear() Candidate_Routes = temCandidate_Routes Candidate_Routes = Common_Functions.Double_layer_list(Candidate_Routes) Candidate_Routes = Common_Functions.Main_Auxiliary_road(Candidate_Routes) # 去除头尾路段一样的候选路线 Candidate_Routes = Common_Functions.Start_End(Candidate_Routes) # 对于[wayid1,wayid2,wayid3] [wayid1,wayid4,wayid5,wayid3] 去除路段多的,如果包含路段数量一致 暂不处理 Candidate_Routes = Common_Functions.Sequential_subset(Candidate_Routes) # 最后去前缀 delsub = [] for sub in Candidate_Routes: if way_id2 in sub: flag = 1 break if len(Candidate_Routes) == 0: flag = 1 exitflag = 1 if count == max_num: flag = 1 exitflag = 1 if flag == 1: break for sub in Candidate_Routes: if len(sub) >= 3: if JudgeLines(sub): # 判断当前路线是否能通 for i in combinations(sub,2): Common_Functions.SaveRoutesConn("connects", i[0],i[1], 1) elif not JudgeLines(sub) and way_id2 in sub: # 目标路段在子路线中 但是不能走通 Common_Functions.SaveRoutesConn("connects", way_id1, way_id2, 0) return False else: delsub.append(sub) continue elif len(sub) == 2: if JudgeTwoWay(sub[0], sub[1]): Common_Functions.SaveRoutesConn("connects", sub[0], sub[1], 1) pass elif JudgeTwoWay(sub[0], sub[1]) and way_id2 in sub: # 目标路段在子路线中 但是不能走通 Common_Functions.SaveRoutesConn("connects", way_id1, way_id2, 0) return False else: delsub.append(sub) continue else: pass for sub in Candidate_Routes: # 判断行驶方向 secondgrid = Getway_startendnode_grid(sub[-1], flag=0) if secondgrid: curx = secondgrid[0] cury = secondgrid[1] if Endx > startx and Endy > starty: # 路段way_id2 在way_id1 的右上部 if abs(startx - curx) <= 5 or abs(starty - cury) <= 5: # 防止道路过近,出现偏差,方向加500米偏差 pass elif curx <= startx and cury <= starty: delsub.append(sub) # 此路线方向向左下部走 删除此路线 if Endx > startx and Endy < starty: # 路段way_id2 在way_id1 的右下部 if abs(startx - curx) <= 5 or abs(starty - cury) <= 5: # 防止道路过近,出现偏差,方向加500米偏差 pass elif curx < startx and cury > starty: delsub.append(sub) # 此路线方向向左上部走 删除此路线 if Endx < startx and Endy < starty: # 路段way_id2 在way_id1 的左下部 if abs(startx - curx) <= 5 or abs(starty - cury) <= 5: # 防止道路过近,出现偏差,方向加500米偏差 pass elif curx > startx and cury > starty: delsub.append(sub) # 此路线方向向右上部走 删除此路线 if Endx < startx and Endy > starty: # 路段way_id2 在way_id1 的左上部 if abs(startx - curx) <= 5 or abs(starty - cury) <= 5: # 防止道路过近,出现偏差,方向加500米偏差 pass elif curx > startx and cury < starty: delsub.append(sub) # 此路线方向向右上部走 删除此路线 else: pass temstaryendwaydis = twoway_distance(way_id1, sub[-1]) if temstaryendwaydis > startendwaydis: delsub.append(sub) for sub in Common_Functions.Double_layer_list(delsub): Candidate_Routes.remove(sub) if exitflag==1: #证明是循环跳出不是因为找到路径跳出的 Common_Functions.SaveRoutesConn("connects", way_id1, way_id2, 0) return False Deleteways = [] for sub in Candidate_Routes: if way_id2 in sub: if len(sub) == 1: return sub elif len(sub) == 2 and JudgeTwoWay(sub[0], sub[1]): pass elif len(sub) >= 3 and JudgeLines(sub): for i in combinations(sub, 2): Common_Functions.SaveRoutesConn("connects", i[0], i[1], 1) pass else: Deleteways.append(sub) else: Deleteways.append(sub) if len(Deleteways)!=0: for delsub in Common_Functions.Double_layer_list(Deleteways): Candidate_Routes.remove(delsub) if len(Candidate_Routes)==0: Common_Functions.SaveRoutesConn("connects", way_id1, way_id2, 0) return False minnum = float("inf") for sub in Candidate_Routes: if way_id2 in sub: if len(sub) < minnum: finalroute = sub minnum = len(sub) else: pass if len(finalroute)==0: Common_Functions.SaveRoutesConn("connects", way_id1, way_id2, 0) return False else: Common_Functions.SaveRoutesConn("connects", way_id1, way_id2, 1) return finalroute