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 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 InsertGeoTable(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(): for num in range(len(dic[key])): # sequence代表每条路中node的排序号 coor = MapNavigation.Get_Coordinate( dic[key][num]) #有的点没有坐标 if coor: sql_insert = 'insert into {}(WayId,NodeId,GeoCode) values({},{},{});'.format( tablename, key, dic[key][num], repr(Coor_GeoHash.encode(coor[1], coor[0]))) try: cursor.execute(sql_insert) # 执行sql语句 connection.commit() # 提交 except Exception as e: print(e) connection.rollback() cursor.close() else: 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 Judge_Route_connectivity(waylists:list): """ 判断一条路的连通性,如果不连通,则将其拆分为连通的几个部分 :param waylists: :return: """ All_routes = [] #存储所有的子连通路线 subRoute = [] #存储子路线 for index in range(len(waylists)): if index == len(waylists)-1: break intersection = MapNavigation.TwoWay_intersection(waylists[index], waylists[index + 1]) #此两个路段的连通性 if intersection: subRoute.extend([waylists[index], waylists[index + 1]]) else: if len(subRoute)==0: #此情况是子连通路线中只有一个路段,但是subRoute会为空,所以这里要加入waylists[index] subRoute.append(waylists[index]) #new_list = list(set(subRoute)) #subRoute.sort(key=subRoute.index) del_adjacent(subRoute) All_routes.append(subRoute) #print(All_routes) subRoute = [] if len(subRoute)!=0: #new_list = list(set(subRoute)) #new_list.sort(key=subRoute.index) del_adjacent(subRoute) All_routes.append(subRoute) return All_routes
def Getway_startendnode_coordi(wayid, flag=0): """ 得到路段的网格编号 flag=0 代表获取路段起点的编号 flag = 1代表获取路段末尾点的网格编号 :return: """ wayids = MapNavigation.Get_way_NodesSequenceId(wayid) if wayids: if flag == 0: processnodeid = wayids[0][0] else: processnodeid = wayids[-1][0] coor = MapNavigation.Get_Coordinate(processnodeid) return coor else: return [0, 0]
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 GetAllLines(route_list:list): """ 通过每个轨迹点的归属路段找出完整轨迹,如果出现断路,先不处理 :param route_list: 轨迹点的归属路段列表 :return: """ All_Lines = [] del_adjacent(route_list) #去重相邻重复元素 for index in range(len(route_list)): if index == len(route_list) - 1: break else: temwaylist = MapNavigation.waytoway(route_list[index], route_list[index + 1]) if temwaylist: # and len(temwaylist)<5: #加入相邻两个轨迹点不能够超过五个路段,但是对于相邻两个轨迹处于远距离可能会有问题 All_Lines.extend(temwaylist) else: All_Lines.extend([route_list[index], route_list[index + 1]]) del_adjacent(All_Lines) return All_Lines
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 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 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()