{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import pandas as pd\n",
|
|
"import numpy as np\n",
|
|
"import os, sys, copy, argparse, json, pickle\n",
|
|
"import sumolib, traci\n",
|
|
"from tqdm import tqdm\n",
|
|
"from datetime import datetime\n",
|
|
"path_root = os.path.dirname(os.path.dirname(os.path.abspath('.')))\n",
|
|
"# path_scr = os.path.join(path_root, 'scripts')\n",
|
|
"# sys.path.append(path_scr)\n",
|
|
"# from preprocess_daily import DailyPreprocessor\n",
|
|
"# from generate_signals import SignalGenerator"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class DailyPreprocessor:\n",
|
|
" pass\n",
|
|
"self = DailyPreprocessor()\n",
|
|
"self.config_name = 'test_0729'\n",
|
|
"self.file_net = 'new_sungnam_network_internal_target_0721.net.xml'"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# 루트폴더 지정\n",
|
|
"self.path_root = path_root\n",
|
|
"with open(os.path.join(self.path_root, 'configs', f'config_{self.config_name}.json'), 'r') as config_file:\n",
|
|
" config = json.load(config_file)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# 주요 폴더 경로 지정\n",
|
|
"self.paths = config['paths']\n",
|
|
"self.path_data = os.path.join(self.path_root, *self.paths['data'])\n",
|
|
"self.path_intermediates = os.path.join(self.path_root, *self.paths['intermediates'])\n",
|
|
"self.path_results = os.path.join(self.path_root, *self.paths['results'])\n",
|
|
"self.path_tables = os.path.join(self.path_root, *self.paths['tables'])\n",
|
|
"self.path_networks = os.path.join(self.path_root, *self.paths['networks'])\n",
|
|
"self.path_scripts = os.path.join(self.path_root, *self.paths['scripts'])\n",
|
|
"\n",
|
|
"# 이슈사항 목록\n",
|
|
"self.issues = []"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# 1-1. 네트워크 불러오기\n",
|
|
"self.net = sumolib.net.readNet(os.path.join(self.path_networks, self.file_net))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"['angle.csv',\n",
|
|
" 'coord.csv',\n",
|
|
" 'inter_info.csv',\n",
|
|
" 'inter_node.csv',\n",
|
|
" 'nema.csv',\n",
|
|
" 'plan.csv',\n",
|
|
" 'TC_IF_TOD_DAY_PLAN.csv',\n",
|
|
" 'TC_IF_TOD_HOLIDAY_PLAN.csv',\n",
|
|
" 'TC_IF_TOD_RED_YELLO.csv',\n",
|
|
" 'TC_IF_TOD_WEEK_PLAN.csv',\n",
|
|
" 'TL_IF_SIGL_CYCL.csv',\n",
|
|
" 'turn_type.csv',\n",
|
|
" 'turn_type_modified.csv',\n",
|
|
" 'uturn.csv',\n",
|
|
" 'u_condition.csv']"
|
|
]
|
|
},
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"os.listdir(self.path_tables)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# cnames = []\n",
|
|
"# csv_names = list(os.listdir(self.path_tables))\n",
|
|
"# for csv_name in csv_names:\n",
|
|
"# print(csv_name)\n",
|
|
"# try:\n",
|
|
"# df = pd.read_csv(os.path.join(self.path_tables, csv_name))\n",
|
|
"# except UnicodeDecodeError as e:\n",
|
|
"# df = pd.read_csv(os.path.join(self.path_tables, csv_name), encoding='cp949')\n",
|
|
"# cnames.extend(list(df.columns))\n",
|
|
"# print(list(df.columns))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# 1-2. 테이블 불러오기\n",
|
|
"self.alphs = ['A', 'B']\n",
|
|
"\n",
|
|
"loading_dtype_1 = {'CRSRD_ID':int, 'CYCL':int, 'DAY':int,\n",
|
|
" 'FRI_PLAN_NO':int, 'HOUR':int, 'LAST_MDFCN_DT':str,\n",
|
|
" 'MIN':int, 'MNTH':int, 'MON_PLAN_NO':int,\n",
|
|
" 'OFFSET':int, 'PHASE':int, 'PLAN_NO':int,\n",
|
|
" 'RINGA_FLOW':int, 'RINGA_MIN_SEC':int, 'RINGA_RED_SEC':int,\n",
|
|
" 'RINGA_YELLO_SEC':int, 'RINGB_FLOW':int, 'RINGB_MIN_SEC':int,\n",
|
|
" 'RINGB_RED_SEC':int, 'RINGB_YELLO_SEC':int, 'SAT_PLAN_NO':int,\n",
|
|
" 'SUN_PLAN_NO':int, 'THU_PLAN_NO':int, 'TUE_PLAN_NO':int,\n",
|
|
" 'WED_PLAN_NO':int, 'adj_inc_edge_id':str, 'adj_out_edge_id':str,\n",
|
|
" 'angle_code':str, 'child_id':str, 'condition':str,\n",
|
|
" 'group_no':str, 'inc_dire':str, 'inc_edge_id':str,\n",
|
|
" 'inter_lat':float, 'inter_lon':float, 'inter_name':str,\n",
|
|
" 'inter_no':int, 'inter_type':str, 'main_phase_no':str,\n",
|
|
" 'move_no':int, 'node_id':str, 'out_dire':str,\n",
|
|
" 'out_edge_id':str, 'parent_id':str, 'phase_no':int,\n",
|
|
" 'ring_type':str, 'turn_type':str}\n",
|
|
"\n",
|
|
"loading_dtype_2 = {f'RING{alph}_PHASE{i}':int for alph in self.alphs for i in range(1,9)}\n",
|
|
"loading_dtype = {**loading_dtype_1, **loading_dtype_2}\n",
|
|
"\n",
|
|
"# 수작업으로 만든 테이블 불러오기\n",
|
|
"self.inter_node = pd.read_csv(os.path.join(self.path_tables, 'inter_node.csv'), dtype=loading_dtype)\n",
|
|
"self.inter_info = pd.read_csv(os.path.join(self.path_tables, 'inter_info.csv'), dtype=loading_dtype)\n",
|
|
"self.turn_type = pd.read_csv(os.path.join(self.path_tables, 'turn_type.csv'), dtype=loading_dtype)\n",
|
|
"self.uturn = pd.read_csv(os.path.join(self.path_tables, 'uturn.csv'), dtype=loading_dtype)\n",
|
|
"self.u_condition= pd.read_csv(os.path.join(self.path_tables, 'u_condition.csv'), dtype=loading_dtype)\n",
|
|
"self.coord = pd.read_csv(os.path.join(self.path_tables, 'coord.csv'), dtype=loading_dtype)\n",
|
|
"self.nema = pd.read_csv(os.path.join(self.path_tables, 'nema.csv'), dtype=loading_dtype, encoding='cp949')\n",
|
|
"self.angle = pd.read_csv(os.path.join(self.path_tables, 'angle.csv'), dtype=loading_dtype)\n",
|
|
"\n",
|
|
"# DB에서 fetch하는 테이블 불러오기\n",
|
|
"self.dayplan = pd.read_csv(os.path.join(self.path_tables, 'TC_IF_TOD_DAY_PLAN.csv'), dtype=loading_dtype)\n",
|
|
"self.holyplan = pd.read_csv(os.path.join(self.path_tables, 'TC_IF_TOD_HOLIDAY_PLAN.csv'), dtype=loading_dtype)\n",
|
|
"self.weekplan = pd.read_csv(os.path.join(self.path_tables, 'TC_IF_TOD_WEEK_PLAN.csv'), dtype=loading_dtype)\n",
|
|
"self.red_yel = pd.read_csv(os.path.join(self.path_tables, 'TC_IF_TOD_RED_YELLO.csv'), dtype=loading_dtype)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# 교차로목록, 노드목록 정의\n",
|
|
"self.inter_nos = [int(x) for x in sorted(self.inter_info.inter_no.unique())]\n",
|
|
"self.node_ids = sorted(self.inter_node.node_id.unique())"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# cnames = []\n",
|
|
"# csv_names = list(os.listdir(self.path_tables))\n",
|
|
"# for csv_name in csv_names:\n",
|
|
"# print(csv_name)\n",
|
|
"# try:\n",
|
|
"# df = pd.read_csv(os.path.join(self.path_tables, csv_name))\n",
|
|
"# except UnicodeDecodeError as e:\n",
|
|
"# df = pd.read_csv(os.path.join(self.path_tables, csv_name), encoding='cp949')\n",
|
|
"# cnames.extend(list(df.columns))\n",
|
|
"# print(list(df.columns))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"['CRSRD_ID', 'PLAN_NO', 'HOUR', 'MIN', 'CYCL', 'OFFSET', 'RINGA_PHASE1', 'RINGA_PHASE2', 'RINGA_PHASE3', 'RINGA_PHASE4', 'RINGA_PHASE5', 'RINGA_PHASE6', 'RINGA_PHASE7', 'RINGA_PHASE8', 'RINGB_PHASE1', 'RINGB_PHASE2', 'RINGB_PHASE3', 'RINGB_PHASE4', 'RINGB_PHASE5', 'RINGB_PHASE6', 'RINGB_PHASE7', 'RINGB_PHASE8', 'LAST_MDFCN_DT']\n",
|
|
"['CRSRD_ID', 'MNTH', 'DAY', 'PLAN_NO', 'LAST_MDFCN_DT']\n",
|
|
"['CRSRD_ID', 'SUN_PLAN_NO', 'MON_PLAN_NO', 'TUE_PLAN_NO', 'WED_PLAN_NO', 'THU_PLAN_NO', 'FRI_PLAN_NO', 'SAT_PLAN_NO', 'LAST_MDFCN_DT']\n",
|
|
"['CRSRD_ID', 'PLAN_NO', 'PHASE', 'RINGA_FLOW', 'RINGA_RED_SEC', 'RINGA_YELLO_SEC', 'RINGA_MIN_SEC', 'RINGB_FLOW', 'RINGB_RED_SEC', 'RINGB_YELLO_SEC', 'RINGB_MIN_SEC', 'LAST_MDFCN_DT']\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"cnames = []\n",
|
|
"tods = [self.dayplan, self.holyplan, self.weekplan, self.red_yel]\n",
|
|
"for tod in tods:\n",
|
|
" cnames.extend(list(tod.columns))\n",
|
|
" print(list(tod.columns))\n",
|
|
"cnames = sorted(set(cnames))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# 1-5. 테이블 표준화\n",
|
|
"\n",
|
|
"# 컬럼명 변경\n",
|
|
"rename_cname_1 = {'CRSRD_ID':'inter_no', 'CYCL':'cycle', 'DAY':'DD',\n",
|
|
" 'HOUR':'hh', 'MIN':'mm', 'MNTH':'MM',\n",
|
|
" 'OFFSET':'offset', 'PHASE':'phase_no', 'PLAN_NO':'plan_no',\n",
|
|
" 'RINGA_RED_SEC':'red_A', 'RINGA_YELLO_SEC':'yel_A', 'RINGB_RED_SEC':'red_B',\n",
|
|
" 'RINGB_YELLO_SEC':'yel_B'}\n",
|
|
"\n",
|
|
"rename_cname_2 = {f'RING{alph}_PHASE{i}':f'dura_{alph}{i}' for alph in self.alphs for i in range(1,9)}\n",
|
|
"rename_cname = {**rename_cname_1, **rename_cname_2}\n",
|
|
"\n",
|
|
"# 컬럼명 변경 적용\n",
|
|
"self.dayplan = self.dayplan.rename(columns=rename_cname)\n",
|
|
"self.holyplan = self.holyplan.rename(columns=rename_cname)\n",
|
|
"self.weekplan = self.weekplan.rename(columns=rename_cname)\n",
|
|
"self.red_yel = self.red_yel.rename(columns=rename_cname)\n",
|
|
"\n",
|
|
"# 날짜 지정\n",
|
|
"DT = datetime(2024, 7, 25)\n",
|
|
"MM, DD = DT.month, DT.day # 월, 일\n",
|
|
"hplan = self.holyplan[(self.holyplan.MM==MM) & (self.holyplan.DD==DD)]\n",
|
|
"dow_number = DT.weekday() # 요일\n",
|
|
"dows = [dow for dow in self.weekplan.columns if dow.endswith('PLAN_NO')]\n",
|
|
"dows = dows[1:] + dows[0:1]\n",
|
|
"dow = dows[dow_number]\n",
|
|
"\n",
|
|
"# (신호교차로, 신호계획번호) 목록\n",
|
|
"if len(hplan):\n",
|
|
" inter_pnos = list(zip(hplan['inter_no'], hplan['plan_no']))\n",
|
|
"else:\n",
|
|
" inter_pnos = list(zip(self.weekplan.inter_no, self.weekplan[dow]))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# 신호테이블 통합\n",
|
|
"self.plan = self.dayplan.copy()\n",
|
|
"self.plan['inter_pno'] = list(zip(self.plan['inter_no'], self.plan['plan_no']))\n",
|
|
"self.plan = self.plan[(self.plan.inter_pno.isin(inter_pnos))]\n",
|
|
"self.plan = self.plan.drop(columns='inter_pno')\n",
|
|
"max_phase_no = int(self.red_yel.phase_no.max())\n",
|
|
"for j in range(1,max_phase_no+1):\n",
|
|
" RY = self.red_yel[self.red_yel.phase_no==j].iloc[0]\n",
|
|
" red_A = RY.red_A\n",
|
|
" red_B = RY.red_B\n",
|
|
" yel_A = RY.yel_A\n",
|
|
" yel_B = RY.yel_B\n",
|
|
" self.plan[f'red_A{j}'] = red_A\n",
|
|
" self.plan[f'red_B{j}'] = red_B\n",
|
|
" self.plan[f'yellow_A{j}'] = yel_A\n",
|
|
" self.plan[f'yellow_B{j}'] = yel_B"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# 1-6. 주요 객체 (리스트, 딕셔너리) 저장\n",
|
|
"self.parent_ids = sorted(self.inter_node[self.inter_node.inter_type=='parent'].node_id.unique())\n",
|
|
"self.child_ids = sorted(self.inter_node[self.inter_node.inter_type=='child'].node_id.unique())\n",
|
|
"self.uturn_ids = sorted(self.uturn.child_id.unique())\n",
|
|
"self.coord_ids = sorted(self.coord.child_id.unique())\n",
|
|
"\n",
|
|
"# node2inter : node_id to inter_no\n",
|
|
"self.node2inter = dict(zip(self.inter_node['node_id'], self.inter_node['inter_no']))\n",
|
|
"\n",
|
|
"# inter2node : inter_no to node_id\n",
|
|
"inter_node1 = self.inter_node[self.inter_node.inter_type == 'parent'].drop('inter_type', axis=1)\n",
|
|
"inter_info1 = self.inter_info[['inter_no', 'inter_lat', 'inter_lon']]\n",
|
|
"inter = pd.merge(inter_node1, inter_info1, how='left', left_on=['inter_no'],\n",
|
|
" right_on=['inter_no']).drop_duplicates()\n",
|
|
"\n",
|
|
"self.inter2node = dict(zip(inter['inter_no'], inter['node_id']))\n",
|
|
"\n",
|
|
"# ch2pa : child to parent\n",
|
|
"self.ch2pa = {}\n",
|
|
"for child_id in self.child_ids:\n",
|
|
" parent_no = self.inter_node[self.inter_node.node_id==child_id].inter_no.iloc[0]\n",
|
|
" sub_inter_node = self.inter_node[self.inter_node.inter_no==parent_no]\n",
|
|
" self.ch2pa[child_id] = sub_inter_node[sub_inter_node.inter_type=='parent'].iloc[0].node_id\n",
|
|
"self.dires = ['북', '북동', '동', '남동', '남', '남서', '서', '북서'] # 정북기준 시계방향으로 8방향\n",
|
|
"\n",
|
|
"# ids\n",
|
|
"self.ids = {'node_ids' : self.node_ids,\n",
|
|
" 'parent_ids': self.parent_ids,\n",
|
|
" 'child_ids' : self.child_ids,\n",
|
|
" 'uturn_ids' : self.uturn_ids,\n",
|
|
" 'coord_ids' : self.coord_ids,\n",
|
|
" 'inter_nos' : self.inter_nos}\n",
|
|
"with open(os.path.join(self.path_intermediates, 'ids.json'), 'w') as file:\n",
|
|
" json.dump(self.ids, file)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>inter_no</th>\n",
|
|
" <th>phas_A</th>\n",
|
|
" <th>phas_B</th>\n",
|
|
" <th>move_A</th>\n",
|
|
" <th>move_B</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>2</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>3</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>2</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>4</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>3</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>1</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>4</th>\n",
|
|
" <td>437</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>2</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" inter_no phas_A phas_B move_A move_B\n",
|
|
"0 436 1 1 5 2\n",
|
|
"1 436 2 2 8 3\n",
|
|
"2 436 3 3 7 4\n",
|
|
"3 436 4 4 6 1\n",
|
|
"4 437 1 1 6 2"
|
|
]
|
|
},
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# 2. 중간산출물 만들기\n",
|
|
"# 2-1 매칭테이블 생성\n",
|
|
"# 2-1-1\n",
|
|
"self.match1 = pd.read_csv(os.path.join(self.path_intermediates, 'match1.csv'))\n",
|
|
"self.match1.head()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>inter_no</th>\n",
|
|
" <th>phase_no</th>\n",
|
|
" <th>ring_type</th>\n",
|
|
" <th>move_no</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>5</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>8</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>3</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>2</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>7</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" inter_no phase_no ring_type move_no\n",
|
|
"0 436 1 A 5\n",
|
|
"0 436 1 B 2\n",
|
|
"1 436 2 A 8\n",
|
|
"1 436 2 B 3\n",
|
|
"2 436 3 A 7"
|
|
]
|
|
},
|
|
"execution_count": 16,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# 2-1-2\n",
|
|
"matchA = self.match1[['inter_no', 'phas_A', 'move_A']].copy()\n",
|
|
"matchA.columns = ['inter_no', 'phase_no', 'move_no']\n",
|
|
"matchA['ring_type'] = 'A'\n",
|
|
"matchB = self.match1[['inter_no', 'phas_B', 'move_B']].copy()\n",
|
|
"matchB.columns = ['inter_no', 'phase_no', 'move_no']\n",
|
|
"matchB['ring_type'] = 'B'\n",
|
|
"self.match2 = pd.concat([matchA, matchB]).drop_duplicates()\n",
|
|
"self.match2 = self.match2[['inter_no', 'phase_no', 'ring_type', 'move_no']]\n",
|
|
"self.match2 = self.match2.sort_values(by=list(self.match2.columns))\n",
|
|
"self.match2.head()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>inter_no</th>\n",
|
|
" <th>phase_no</th>\n",
|
|
" <th>ring_type</th>\n",
|
|
" <th>move_no</th>\n",
|
|
" <th>inc_dire</th>\n",
|
|
" <th>out_dire</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>북</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>2</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>북</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>3</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>서</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>4</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>동</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" inter_no phase_no ring_type move_no inc_dire out_dire\n",
|
|
"0 436 1 A 5 서 북\n",
|
|
"1 436 1 B 2 서 동\n",
|
|
"2 436 2 A 8 남 북\n",
|
|
"3 436 2 B 3 남 서\n",
|
|
"4 436 3 A 7 북 동"
|
|
]
|
|
},
|
|
"execution_count": 17,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# 2-1-3\n",
|
|
"# nema 정보 불러오기 및 병합\n",
|
|
"self.match3 = pd.merge(self.match2, self.nema, how='left', on='move_no').drop_duplicates()\n",
|
|
"self.match3.head()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>inter_no</th>\n",
|
|
" <th>move_no</th>\n",
|
|
" <th>angle_code</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>16</th>\n",
|
|
" <td>438</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>100277</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>17</th>\n",
|
|
" <td>438</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>276098</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>18</th>\n",
|
|
" <td>438</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>274342</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>19</th>\n",
|
|
" <td>438</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>101181</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>20</th>\n",
|
|
" <td>438</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>183340</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>21</th>\n",
|
|
" <td>438</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>182276</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>22</th>\n",
|
|
" <td>438</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>347099</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>23</th>\n",
|
|
" <td>438</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>348186</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" inter_no move_no angle_code\n",
|
|
"16 438 6 100277\n",
|
|
"17 438 2 276098\n",
|
|
"18 438 5 274342\n",
|
|
"19 438 1 101181\n",
|
|
"20 438 8 183340\n",
|
|
"21 438 3 182276\n",
|
|
"22 438 7 347099\n",
|
|
"23 438 4 348186"
|
|
]
|
|
},
|
|
"execution_count": 18,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"node_id = '106350'\n",
|
|
"inter_no = self.node2inter[node_id]\n",
|
|
"self.angle[self.angle.inter_no==inter_no]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 19,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>inter_no</th>\n",
|
|
" <th>phase_no</th>\n",
|
|
" <th>ring_type</th>\n",
|
|
" <th>move_no</th>\n",
|
|
" <th>inc_dire</th>\n",
|
|
" <th>out_dire</th>\n",
|
|
" <th>inc_angle</th>\n",
|
|
" <th>out_angle</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>262</td>\n",
|
|
" <td>358</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>262</td>\n",
|
|
" <td>074</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>2</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>174</td>\n",
|
|
" <td>355</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>3</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>172</td>\n",
|
|
" <td>263</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>4</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>356</td>\n",
|
|
" <td>074</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" inter_no phase_no ring_type move_no inc_dire out_dire inc_angle out_angle\n",
|
|
"0 436 1 A 5 서 북 262 358\n",
|
|
"1 436 1 B 2 서 동 262 074\n",
|
|
"2 436 2 A 8 남 북 174 355\n",
|
|
"3 436 2 B 3 남 서 172 263\n",
|
|
"4 436 3 A 7 북 동 356 074"
|
|
]
|
|
},
|
|
"execution_count": 19,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# 2-1-4\n",
|
|
"# helper dictionaries\n",
|
|
"im2inc_angle = dict() # a dictionary that maps (inter_no, move_no) to inc_angle\n",
|
|
"im2out_angle = dict() # a dictionary that maps (inter_no, move_no) to out_angle\n",
|
|
"self.angle = self.angle.dropna(subset=['move_no'])\n",
|
|
"self.angle['move_no'] = self.angle['move_no'].astype(int)\n",
|
|
"for row in self.angle.itertuples():\n",
|
|
" inter_no = row.inter_no\n",
|
|
" move_no = row.move_no\n",
|
|
" angle_code = row.angle_code\n",
|
|
" if isinstance(angle_code, str) and len(angle_code) == 6:\n",
|
|
" im2inc_angle[(inter_no, move_no)] = angle_code[:3]\n",
|
|
" im2out_angle[(inter_no, move_no)] = angle_code[3:]\n",
|
|
" else:\n",
|
|
" im2inc_angle[(inter_no, move_no)] = np.nan\n",
|
|
" im2out_angle[(inter_no, move_no)] = np.nan\n",
|
|
"for inter_no in self.inter_nos:\n",
|
|
" im2inc_angle[(inter_no, 17)] = np.nan\n",
|
|
" im2out_angle[(inter_no, 17)] = np.nan\n",
|
|
" im2inc_angle[(inter_no, 18)] = np.nan\n",
|
|
" im2out_angle[(inter_no, 18)] = np.nan\n",
|
|
"\n",
|
|
"# 진입, 진출 방위각 매칭\n",
|
|
"self.match4 = self.match3.copy()\n",
|
|
"for i, row in self.match4.iterrows():\n",
|
|
" inter_no = row.inter_no\n",
|
|
" move_no = row.move_no\n",
|
|
" self.match4.at[i, 'inc_angle'] = im2inc_angle[(inter_no, move_no)]\n",
|
|
" self.match4.at[i, 'out_angle'] = im2out_angle[(inter_no, move_no)]\n",
|
|
"self.match4.head()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 20,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# 2-1-5\n",
|
|
"self.match5 = self.match4.copy()\n",
|
|
"# 진입진출ID 매칭\n",
|
|
"for index, row in self.match5.iterrows():\n",
|
|
" node_id = self.inter2node[row.inter_no]\n",
|
|
" node = self.net.getNode(node_id)\n",
|
|
" # 교차로의 모든 (from / to) edges\n",
|
|
" inc_edges = [edge for edge in node.getIncoming() if edge.getFunction() == ''] # incoming edges\n",
|
|
" out_edges = [edge for edge in node.getOutgoing() if edge.getFunction() == ''] # outgoing edges\n",
|
|
" # 교차로의 모든 (from / to) unit vector\n",
|
|
" inc_vecs = []\n",
|
|
" for inc_edge in inc_edges:\n",
|
|
" start = inc_edge.getShape()[-1]\n",
|
|
" end = inc_edge.getShape()[-2]\n",
|
|
" inc_vec = np.array(end) - np.array(start)\n",
|
|
" inc_vec = inc_vec / (inc_vec ** 2).sum() ** 0.5\n",
|
|
" inc_vecs.append(inc_vec)\n",
|
|
" out_vecs = []\n",
|
|
" for out_edge in out_edges:\n",
|
|
" start = out_edge.getShape()[0]\n",
|
|
" end = out_edge.getShape()[1]\n",
|
|
" out_vec = np.array(end) - np.array(start)\n",
|
|
" out_vec = out_vec / (out_vec ** 2).sum() ** 0.5\n",
|
|
" out_vecs.append(out_vec)\n",
|
|
" # 진입각, 진출각 불러오기\n",
|
|
" if not pd.isna(row.inc_angle):\n",
|
|
" inc_angle = int(row.inc_angle)\n",
|
|
" out_angle = int(row.out_angle)\n",
|
|
" # 방위각을 일반각으로 가공, 라디안 변환, 단위벡터로 변환\n",
|
|
" inc_angle = (90 - inc_angle) % 360\n",
|
|
" inc_angle = inc_angle * np.pi / 180.\n",
|
|
" inc_vec_true = np.array([np.cos(inc_angle), np.sin(inc_angle)])\n",
|
|
" out_angle = (90 - out_angle) % 360\n",
|
|
" out_angle = out_angle * np.pi / 180.\n",
|
|
" out_vec_true = np.array([np.cos(out_angle), np.sin(out_angle)])\n",
|
|
" # 매칭 엣지 반환\n",
|
|
" inc_index = np.array([np.dot(inc_vec, inc_vec_true) for inc_vec in inc_vecs]).argmax()\n",
|
|
" out_index = np.array([np.dot(out_vec, out_vec_true) for out_vec in out_vecs]).argmax()\n",
|
|
" inc_edge_id = inc_edges[inc_index].getID()\n",
|
|
" out_edge_id = out_edges[out_index].getID()\n",
|
|
" self.match5.at[index, 'inc_edge_id'] = inc_edge_id\n",
|
|
" self.match5.at[index, 'out_edge_id'] = out_edge_id\n",
|
|
"\n",
|
|
"self.match5['node_id'] = self.match5['inter_no'].map(self.inter2node)\n",
|
|
"self.match5['node_type'] = 'normal'\n",
|
|
"self.match5 = self.match5.sort_values(by=['inter_no','phase_no','ring_type']).reset_index(drop=True)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 21,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# n2io2turn : dictionary that maps node_id to io2turn\n",
|
|
"self.n2io2turn = dict()\n",
|
|
"for node_id in self.parent_ids:\n",
|
|
" turn = self.turn_type[self.turn_type.node_id==node_id]\n",
|
|
" io = list(zip(turn.inc_edge_id, turn.out_edge_id))\n",
|
|
" # io2turn : dictionary that maps (inc_edge_id, out_edge_id) to turn_type\n",
|
|
" io2turn = dict(zip(io, turn.turn_type))\n",
|
|
" self.n2io2turn[node_id] = io2turn"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 22,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# turn_type 지정\n",
|
|
"for i, row in self.match5.iterrows():\n",
|
|
" node_id = row.node_id\n",
|
|
" inc_edge_id = row.inc_edge_id\n",
|
|
" out_edge_id = row.out_edge_id\n",
|
|
" if not (pd.isna(inc_edge_id) and pd.isna(out_edge_id)):\n",
|
|
" io2turn = self.n2io2turn[node_id]\n",
|
|
" if (inc_edge_id, out_edge_id) in io2turn:\n",
|
|
" turn_type = io2turn[(inc_edge_id, out_edge_id)]\n",
|
|
" self.match5.at[i, 'turn_type'] = turn_type"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 23,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# 2-1-6\n",
|
|
"self.uturn = pd.merge(self.uturn, self.u_condition, on='child_id')\n",
|
|
"\n",
|
|
"# p2inc_edge2angle : node_id to inc_edge2angle\n",
|
|
"p2inc_edge2angle = dict()\n",
|
|
"# p2out_edge2angle : node_id to out_edge2angle\n",
|
|
"p2out_edge2angle = dict()\n",
|
|
"# p2inc_angle2edge : node_id to inc_angle2edge\n",
|
|
"p2inc_angle2edge = dict()\n",
|
|
"# p2out_angle2edge : node_id to out_angle2edge\n",
|
|
"p2out_angle2edge = dict()\n",
|
|
"for node_id in self.parent_ids:\n",
|
|
" m5 = self.match5[self.match5.node_id==node_id]\n",
|
|
" m5 = m5.dropna(subset=['inc_edge_id', 'out_edge_id'])\n",
|
|
" # inc_edge2angle : inc_edge_id to inc_angle\n",
|
|
" inc_edge2angle = dict(zip(m5.inc_edge_id, m5.inc_angle.astype(int)))\n",
|
|
" p2inc_edge2angle[node_id] = inc_edge2angle\n",
|
|
" # out_edge2angle : out_edge_id to out_angle\n",
|
|
" out_edge2angle = dict(zip(m5.out_edge_id, m5.out_angle.astype(int)))\n",
|
|
" p2out_edge2angle[node_id] = out_edge2angle\n",
|
|
" # inc_angle2edge : inc_angle to inc_edge_id\n",
|
|
" inc_angle2edge = dict(zip(m5.inc_angle.astype(int), m5.inc_edge_id))\n",
|
|
" p2inc_angle2edge[node_id] = inc_angle2edge\n",
|
|
" # out_angle2edge : out_angle to out_edge_id\n",
|
|
" out_angle2edge = dict(zip(m5.out_angle.astype(int), m5.out_edge_id))\n",
|
|
" p2out_angle2edge[node_id] = out_angle2edge"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 24,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"C:\\Users\\Uinetworks\\AppData\\Local\\Temp\\ipykernel_17420\\1413052539.py:73: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '519797' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n",
|
|
" cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
"C:\\Users\\Uinetworks\\AppData\\Local\\Temp\\ipykernel_17420\\1413052539.py:73: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '519796' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n",
|
|
" cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
"C:\\Users\\Uinetworks\\AppData\\Local\\Temp\\ipykernel_17420\\1413052539.py:73: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '519799' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n",
|
|
" cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
"C:\\Users\\Uinetworks\\AppData\\Local\\Temp\\ipykernel_17420\\1413052539.py:73: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '519798' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n",
|
|
" cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
"C:\\Users\\Uinetworks\\AppData\\Local\\Temp\\ipykernel_17420\\1413052539.py:73: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '519801' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n",
|
|
" cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
"C:\\Users\\Uinetworks\\AppData\\Local\\Temp\\ipykernel_17420\\1413052539.py:73: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '519800' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n",
|
|
" cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
"C:\\Users\\Uinetworks\\AppData\\Local\\Temp\\ipykernel_17420\\1413052539.py:73: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '519873' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n",
|
|
" cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
"C:\\Users\\Uinetworks\\AppData\\Local\\Temp\\ipykernel_17420\\1413052539.py:73: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '519874' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n",
|
|
" cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
"C:\\Users\\Uinetworks\\AppData\\Local\\Temp\\ipykernel_17420\\1413052539.py:73: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '516929' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n",
|
|
" cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
"C:\\Users\\Uinetworks\\AppData\\Local\\Temp\\ipykernel_17420\\1413052539.py:73: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '517055' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n",
|
|
" cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
"C:\\Users\\Uinetworks\\AppData\\Local\\Temp\\ipykernel_17420\\1413052539.py:73: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '519834' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n",
|
|
" cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
"C:\\Users\\Uinetworks\\AppData\\Local\\Temp\\ipykernel_17420\\1413052539.py:73: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '519833' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n",
|
|
" cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# 각 uturn node에 대하여 (inc_edge_id, out_edge_id) 부여\n",
|
|
"cmatches = []\n",
|
|
"for row in self.uturn.itertuples():\n",
|
|
" parent_id = row.parent_id\n",
|
|
" child_id = row.child_id\n",
|
|
" condition = row.condition\n",
|
|
" inc_edge_id = row.inc_edge_id\n",
|
|
" out_edge_id = row.out_edge_id\n",
|
|
" adj_inc_edge_id = row.adj_inc_edge_id\n",
|
|
" adj_out_edge_id = row.adj_out_edge_id\n",
|
|
" \n",
|
|
" # match5에서 부모노드id에 해당하는 행들을 가져옴 (cmatch)\n",
|
|
" cmatch = self.match5.copy()[self.match5.node_id==parent_id] # match dataframe for a child node\n",
|
|
" cmatch = cmatch.sort_values(by=['phase_no', 'ring_type']).reset_index(drop=True)\n",
|
|
" cmatch['node_id'] = child_id\n",
|
|
" cmatch['node_type'] = 'u_turn'\n",
|
|
"\n",
|
|
" # 진입엣지 각도\n",
|
|
" inc_angle = p2inc_edge2angle[parent_id][adj_inc_edge_id]\n",
|
|
"\n",
|
|
" # 이격각도\n",
|
|
" self.angle_separation = 10\n",
|
|
"\n",
|
|
" # 진입로 각도 목록\n",
|
|
" inc_angles = cmatch.dropna(subset=['inc_angle', 'out_angle']).inc_angle.astype(int).unique()\n",
|
|
" inc_angles = np.sort(inc_angles)\n",
|
|
" inc_angles = list(inc_angles - 360) + list(inc_angles) + list(inc_angles + 360)\n",
|
|
" inc_angles = np.array(inc_angles)\n",
|
|
"\n",
|
|
" # 보행신호시의 진입로 각도\n",
|
|
" inc_angles_left = inc_angles[inc_angles >= inc_angle + self.angle_separation]\n",
|
|
" inc_angle_pedes = np.sort(inc_angles_left)[0] % 360\n",
|
|
"\n",
|
|
" # 보행신호시의 진입로 엣지id\n",
|
|
" inc_angle2edge = p2inc_angle2edge[parent_id]\n",
|
|
" inc_edge_id_pedes = inc_angle2edge[inc_angle_pedes]\n",
|
|
"\n",
|
|
" # 진출로 각도 목록\n",
|
|
" out_angles = cmatch.dropna(subset=['inc_angle', 'out_angle']).out_angle.astype(int).unique()\n",
|
|
" out_angles = np.sort(out_angles)\n",
|
|
" out_angles = list(out_angles - 360) + list(out_angles) + list(out_angles + 360)\n",
|
|
" out_angles = np.array(out_angles)\n",
|
|
"\n",
|
|
" # 보행신호시의 진출로 각도\n",
|
|
" out_angles_right = out_angles[out_angles <= inc_angle - self.angle_separation]\n",
|
|
" out_angle_pedes = np.sort(out_angles_right)[-1] % 360\n",
|
|
"\n",
|
|
" # 보행신호시의 진출로 엣지id\n",
|
|
" out_angle2edge = p2out_angle2edge[parent_id]\n",
|
|
" out_edge_id_pedes = out_angle2edge[out_angle_pedes]\n",
|
|
"\n",
|
|
" # 진입엣지/진출엣지 포함 조건\n",
|
|
" inc_true = (cmatch.inc_edge_id==adj_inc_edge_id)\n",
|
|
" out_true = (cmatch.out_edge_id==adj_out_edge_id)\n",
|
|
"\n",
|
|
" # 보행신호시 조건\n",
|
|
" pedes_flag = (cmatch.inc_edge_id==inc_edge_id_pedes) & (cmatch.out_edge_id==out_edge_id_pedes)\n",
|
|
"\n",
|
|
" # 좌회전시 조건\n",
|
|
" right_flag = inc_true & (cmatch.turn_type=='left')\n",
|
|
"\n",
|
|
" # 보행신호이동류(17) 조건\n",
|
|
" crosswalk_on = (cmatch.move_no==17) & ~ out_true\n",
|
|
"\n",
|
|
" # 신호없음이동류(18) 조건\n",
|
|
" all_redsigns = (cmatch.move_no==18) & ~ out_true\n",
|
|
"\n",
|
|
" # 보행신호시/좌회전시 진입/진출 엣지id 배정\n",
|
|
" cmatch[['inc_edge_id', 'out_edge_id']] = np.nan\n",
|
|
" if condition == \"보행신호시\":\n",
|
|
" cmatch.loc[pedes_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
" elif condition == \"좌회전시\":\n",
|
|
" cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
"\n",
|
|
" uturn_not_assigned = cmatch[['inc_edge_id','out_edge_id']].isna().any(axis=1).all()\n",
|
|
"\n",
|
|
" if uturn_not_assigned:\n",
|
|
" # 좌회전시\n",
|
|
" if right_flag.any():\n",
|
|
" cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
" # 보행신호시\n",
|
|
" elif pedes_flag.any():\n",
|
|
" cmatch.loc[pedes_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
" # 보행신호이동류(17) 발생시\n",
|
|
" elif crosswalk_on.any():\n",
|
|
" cmatch.loc[crosswalk_on, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
" # 신호없음이동류(18) 발생시\n",
|
|
" elif all_redsigns.any():\n",
|
|
" cmatch.loc[all_redsigns, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
" # 진출엣지 미포함시\n",
|
|
" elif out_true.any():\n",
|
|
" cmatch.loc[~ out_true, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n",
|
|
" cmatches.append(cmatch)\n",
|
|
"\n",
|
|
"# 각 연등교차로(coordination node)에 대하여 (inc_edge_id, out_edge_id) 부여\n",
|
|
"self.coord['inter_no'] = self.coord['parent_id'].map(self.node2inter)\n",
|
|
"self.coord = self.coord.rename(columns={'child_id':'node_id'})\n",
|
|
"self.coord[['inc_dire', 'out_dire', 'inc_angle','out_angle']] = np.nan\n",
|
|
"self.coord['move_no'] = 20\n",
|
|
"self.coord = self.coord[['inter_no', 'phase_no', 'ring_type', 'move_no', 'inc_dire', 'out_dire', 'inc_angle','out_angle', 'inc_edge_id', 'out_edge_id', 'node_id']]\n",
|
|
"self.coord['node_type'] = 'coord'\n",
|
|
"\n",
|
|
"cmatches = pd.concat(cmatches)\n",
|
|
"self.match6 = pd.concat([self.match5, cmatches, self.coord]).drop_duplicates().sort_values(by=['inter_no', 'node_id', 'phase_no', 'ring_type'])\n",
|
|
"self.match6 = self.match6.reset_index(drop=True)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 25,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>inter_no</th>\n",
|
|
" <th>phase_no</th>\n",
|
|
" <th>ring_type</th>\n",
|
|
" <th>move_no</th>\n",
|
|
" <th>inc_dire</th>\n",
|
|
" <th>out_dire</th>\n",
|
|
" <th>inc_angle</th>\n",
|
|
" <th>out_angle</th>\n",
|
|
" <th>inc_edge_id</th>\n",
|
|
" <th>out_edge_id</th>\n",
|
|
" <th>node_id</th>\n",
|
|
" <th>node_type</th>\n",
|
|
" <th>turn_type</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>52</th>\n",
|
|
" <td>443</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>041</td>\n",
|
|
" <td>225</td>\n",
|
|
" <td>516916</td>\n",
|
|
" <td>513863</td>\n",
|
|
" <td>108769</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>53</th>\n",
|
|
" <td>443</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>221</td>\n",
|
|
" <td>043</td>\n",
|
|
" <td>513862</td>\n",
|
|
" <td>516917</td>\n",
|
|
" <td>108769</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>54</th>\n",
|
|
" <td>443</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>222</td>\n",
|
|
" <td>320</td>\n",
|
|
" <td>513862</td>\n",
|
|
" <td>518550</td>\n",
|
|
" <td>108769</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>55</th>\n",
|
|
" <td>443</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>221</td>\n",
|
|
" <td>043</td>\n",
|
|
" <td>513862</td>\n",
|
|
" <td>516917</td>\n",
|
|
" <td>108769</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>56</th>\n",
|
|
" <td>443</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>321</td>\n",
|
|
" <td>039</td>\n",
|
|
" <td>518549</td>\n",
|
|
" <td>516917</td>\n",
|
|
" <td>108769</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>57</th>\n",
|
|
" <td>443</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>18</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>108769</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>58</th>\n",
|
|
" <td>443</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>041</td>\n",
|
|
" <td>225</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109333</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>59</th>\n",
|
|
" <td>443</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>221</td>\n",
|
|
" <td>043</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109333</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>60</th>\n",
|
|
" <td>443</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>222</td>\n",
|
|
" <td>320</td>\n",
|
|
" <td>519873</td>\n",
|
|
" <td>519874</td>\n",
|
|
" <td>109333</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>61</th>\n",
|
|
" <td>443</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>221</td>\n",
|
|
" <td>043</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109333</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>62</th>\n",
|
|
" <td>443</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>321</td>\n",
|
|
" <td>039</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109333</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>63</th>\n",
|
|
" <td>443</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>18</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109333</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>64</th>\n",
|
|
" <td>455</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>073</td>\n",
|
|
" <td>257</td>\n",
|
|
" <td>513580</td>\n",
|
|
" <td>513581</td>\n",
|
|
" <td>109901</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>65</th>\n",
|
|
" <td>455</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>255</td>\n",
|
|
" <td>076</td>\n",
|
|
" <td>513582</td>\n",
|
|
" <td>513584</td>\n",
|
|
" <td>109901</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>66</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>257</td>\n",
|
|
" <td>043</td>\n",
|
|
" <td>513136</td>\n",
|
|
" <td>513139</td>\n",
|
|
" <td>106231</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>67</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>256</td>\n",
|
|
" <td>076</td>\n",
|
|
" <td>513136</td>\n",
|
|
" <td>513137</td>\n",
|
|
" <td>106231</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>68</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>074</td>\n",
|
|
" <td>258</td>\n",
|
|
" <td>513138</td>\n",
|
|
" <td>513135</td>\n",
|
|
" <td>106231</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>69</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>256</td>\n",
|
|
" <td>076</td>\n",
|
|
" <td>513136</td>\n",
|
|
" <td>513137</td>\n",
|
|
" <td>106231</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>70</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>040</td>\n",
|
|
" <td>077</td>\n",
|
|
" <td>513140</td>\n",
|
|
" <td>513137</td>\n",
|
|
" <td>106231</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>71</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>040</td>\n",
|
|
" <td>077</td>\n",
|
|
" <td>513140</td>\n",
|
|
" <td>513137</td>\n",
|
|
" <td>106231</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>72</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>106231</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>73</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>106231</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>74</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>257</td>\n",
|
|
" <td>043</td>\n",
|
|
" <td>519797</td>\n",
|
|
" <td>519796</td>\n",
|
|
" <td>109295</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>75</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>256</td>\n",
|
|
" <td>076</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109295</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>76</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>074</td>\n",
|
|
" <td>258</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109295</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>77</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>256</td>\n",
|
|
" <td>076</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109295</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>78</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>040</td>\n",
|
|
" <td>077</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109295</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>79</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>040</td>\n",
|
|
" <td>077</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109295</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>80</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109295</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>81</th>\n",
|
|
" <td>456</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109295</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>82</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>076</td>\n",
|
|
" <td>260</td>\n",
|
|
" <td>513152</td>\n",
|
|
" <td>513155</td>\n",
|
|
" <td>106234</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>83</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>257</td>\n",
|
|
" <td>075</td>\n",
|
|
" <td>513156</td>\n",
|
|
" <td>513151</td>\n",
|
|
" <td>106234</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>84</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>257</td>\n",
|
|
" <td>347</td>\n",
|
|
" <td>513156</td>\n",
|
|
" <td>513157</td>\n",
|
|
" <td>106234</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>85</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>075</td>\n",
|
|
" <td>166</td>\n",
|
|
" <td>513152</td>\n",
|
|
" <td>513153</td>\n",
|
|
" <td>106234</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>86</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>106234</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>87</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>106234</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>88</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>163</td>\n",
|
|
" <td>346</td>\n",
|
|
" <td>513154</td>\n",
|
|
" <td>513157</td>\n",
|
|
" <td>106234</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>89</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>162</td>\n",
|
|
" <td>258</td>\n",
|
|
" <td>513154</td>\n",
|
|
" <td>513155</td>\n",
|
|
" <td>106234</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>90</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>343</td>\n",
|
|
" <td>079</td>\n",
|
|
" <td>513158</td>\n",
|
|
" <td>513151</td>\n",
|
|
" <td>106234</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>91</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>344</td>\n",
|
|
" <td>164</td>\n",
|
|
" <td>513158</td>\n",
|
|
" <td>513153</td>\n",
|
|
" <td>106234</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>92</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>076</td>\n",
|
|
" <td>260</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109296</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>93</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>257</td>\n",
|
|
" <td>075</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109296</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>94</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>257</td>\n",
|
|
" <td>347</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109296</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>95</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>075</td>\n",
|
|
" <td>166</td>\n",
|
|
" <td>519799</td>\n",
|
|
" <td>519798</td>\n",
|
|
" <td>109296</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>96</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109296</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>97</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109296</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>98</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>163</td>\n",
|
|
" <td>346</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109296</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>99</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>162</td>\n",
|
|
" <td>258</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109296</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>100</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>343</td>\n",
|
|
" <td>079</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109296</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>101</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>344</td>\n",
|
|
" <td>164</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109296</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>102</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>6</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>076</td>\n",
|
|
" <td>260</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109297</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>103</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>257</td>\n",
|
|
" <td>075</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109297</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>104</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>257</td>\n",
|
|
" <td>347</td>\n",
|
|
" <td>519801</td>\n",
|
|
" <td>519800</td>\n",
|
|
" <td>109297</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>105</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>075</td>\n",
|
|
" <td>166</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109297</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>106</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109297</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>107</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109297</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>108</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>163</td>\n",
|
|
" <td>346</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109297</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>109</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>162</td>\n",
|
|
" <td>258</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109297</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>110</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>343</td>\n",
|
|
" <td>079</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109297</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>111</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>344</td>\n",
|
|
" <td>164</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109297</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" inter_no phase_no ring_type move_no inc_dire out_dire inc_angle \\\n",
|
|
"52 443 1 A 6 동 서 041 \n",
|
|
"53 443 1 B 2 서 동 221 \n",
|
|
"54 443 2 A 5 서 북 222 \n",
|
|
"55 443 2 B 2 서 동 221 \n",
|
|
"56 443 3 A 7 북 동 321 \n",
|
|
"57 443 3 B 18 NaN NaN NaN \n",
|
|
"58 443 1 A 6 동 서 041 \n",
|
|
"59 443 1 B 2 서 동 221 \n",
|
|
"60 443 2 A 5 서 북 222 \n",
|
|
"61 443 2 B 2 서 동 221 \n",
|
|
"62 443 3 A 7 북 동 321 \n",
|
|
"63 443 3 B 18 NaN NaN NaN \n",
|
|
"64 455 1 A 6 동 서 073 \n",
|
|
"65 455 1 B 2 서 동 255 \n",
|
|
"66 456 1 A 5 서 북 257 \n",
|
|
"67 456 1 B 2 서 동 256 \n",
|
|
"68 456 2 A 6 동 서 074 \n",
|
|
"69 456 2 B 2 서 동 256 \n",
|
|
"70 456 3 A 7 북 동 040 \n",
|
|
"71 456 3 B 7 북 동 040 \n",
|
|
"72 456 4 A 17 NaN NaN NaN \n",
|
|
"73 456 4 B 17 NaN NaN NaN \n",
|
|
"74 456 1 A 5 서 북 257 \n",
|
|
"75 456 1 B 2 서 동 256 \n",
|
|
"76 456 2 A 6 동 서 074 \n",
|
|
"77 456 2 B 2 서 동 256 \n",
|
|
"78 456 3 A 7 북 동 040 \n",
|
|
"79 456 3 B 7 북 동 040 \n",
|
|
"80 456 4 A 17 NaN NaN NaN \n",
|
|
"81 456 4 B 17 NaN NaN NaN \n",
|
|
"82 457 1 A 6 동 서 076 \n",
|
|
"83 457 1 B 2 서 동 257 \n",
|
|
"84 457 2 A 5 서 북 257 \n",
|
|
"85 457 2 B 1 동 남 075 \n",
|
|
"86 457 3 A 17 NaN NaN NaN \n",
|
|
"87 457 3 B 17 NaN NaN NaN \n",
|
|
"88 457 4 A 8 남 북 163 \n",
|
|
"89 457 4 B 3 남 서 162 \n",
|
|
"90 457 5 A 7 북 동 343 \n",
|
|
"91 457 5 B 4 북 남 344 \n",
|
|
"92 457 1 A 6 동 서 076 \n",
|
|
"93 457 1 B 2 서 동 257 \n",
|
|
"94 457 2 A 5 서 북 257 \n",
|
|
"95 457 2 B 1 동 남 075 \n",
|
|
"96 457 3 A 17 NaN NaN NaN \n",
|
|
"97 457 3 B 17 NaN NaN NaN \n",
|
|
"98 457 4 A 8 남 북 163 \n",
|
|
"99 457 4 B 3 남 서 162 \n",
|
|
"100 457 5 A 7 북 동 343 \n",
|
|
"101 457 5 B 4 북 남 344 \n",
|
|
"102 457 1 A 6 동 서 076 \n",
|
|
"103 457 1 B 2 서 동 257 \n",
|
|
"104 457 2 A 5 서 북 257 \n",
|
|
"105 457 2 B 1 동 남 075 \n",
|
|
"106 457 3 A 17 NaN NaN NaN \n",
|
|
"107 457 3 B 17 NaN NaN NaN \n",
|
|
"108 457 4 A 8 남 북 163 \n",
|
|
"109 457 4 B 3 남 서 162 \n",
|
|
"110 457 5 A 7 북 동 343 \n",
|
|
"111 457 5 B 4 북 남 344 \n",
|
|
"\n",
|
|
" out_angle inc_edge_id out_edge_id node_id node_type turn_type \n",
|
|
"52 225 516916 513863 108769 normal straight \n",
|
|
"53 043 513862 516917 108769 normal straight \n",
|
|
"54 320 513862 518550 108769 normal left \n",
|
|
"55 043 513862 516917 108769 normal straight \n",
|
|
"56 039 518549 516917 108769 normal left \n",
|
|
"57 NaN NaN NaN 108769 normal NaN \n",
|
|
"58 225 NaN NaN 109333 u_turn straight \n",
|
|
"59 043 NaN NaN 109333 u_turn straight \n",
|
|
"60 320 519873 519874 109333 u_turn left \n",
|
|
"61 043 NaN NaN 109333 u_turn straight \n",
|
|
"62 039 NaN NaN 109333 u_turn left \n",
|
|
"63 NaN NaN NaN 109333 u_turn NaN \n",
|
|
"64 257 513580 513581 109901 normal straight \n",
|
|
"65 076 513582 513584 109901 normal straight \n",
|
|
"66 043 513136 513139 106231 normal left \n",
|
|
"67 076 513136 513137 106231 normal straight \n",
|
|
"68 258 513138 513135 106231 normal straight \n",
|
|
"69 076 513136 513137 106231 normal straight \n",
|
|
"70 077 513140 513137 106231 normal left \n",
|
|
"71 077 513140 513137 106231 normal left \n",
|
|
"72 NaN NaN NaN 106231 normal NaN \n",
|
|
"73 NaN NaN NaN 106231 normal NaN \n",
|
|
"74 043 519797 519796 109295 u_turn left \n",
|
|
"75 076 NaN NaN 109295 u_turn straight \n",
|
|
"76 258 NaN NaN 109295 u_turn straight \n",
|
|
"77 076 NaN NaN 109295 u_turn straight \n",
|
|
"78 077 NaN NaN 109295 u_turn left \n",
|
|
"79 077 NaN NaN 109295 u_turn left \n",
|
|
"80 NaN NaN NaN 109295 u_turn NaN \n",
|
|
"81 NaN NaN NaN 109295 u_turn NaN \n",
|
|
"82 260 513152 513155 106234 normal straight \n",
|
|
"83 075 513156 513151 106234 normal straight \n",
|
|
"84 347 513156 513157 106234 normal left \n",
|
|
"85 166 513152 513153 106234 normal left \n",
|
|
"86 NaN NaN NaN 106234 normal NaN \n",
|
|
"87 NaN NaN NaN 106234 normal NaN \n",
|
|
"88 346 513154 513157 106234 normal straight \n",
|
|
"89 258 513154 513155 106234 normal left \n",
|
|
"90 079 513158 513151 106234 normal left \n",
|
|
"91 164 513158 513153 106234 normal straight \n",
|
|
"92 260 NaN NaN 109296 u_turn straight \n",
|
|
"93 075 NaN NaN 109296 u_turn straight \n",
|
|
"94 347 NaN NaN 109296 u_turn left \n",
|
|
"95 166 519799 519798 109296 u_turn left \n",
|
|
"96 NaN NaN NaN 109296 u_turn NaN \n",
|
|
"97 NaN NaN NaN 109296 u_turn NaN \n",
|
|
"98 346 NaN NaN 109296 u_turn straight \n",
|
|
"99 258 NaN NaN 109296 u_turn left \n",
|
|
"100 079 NaN NaN 109296 u_turn left \n",
|
|
"101 164 NaN NaN 109296 u_turn straight \n",
|
|
"102 260 NaN NaN 109297 u_turn straight \n",
|
|
"103 075 NaN NaN 109297 u_turn straight \n",
|
|
"104 347 519801 519800 109297 u_turn left \n",
|
|
"105 166 NaN NaN 109297 u_turn left \n",
|
|
"106 NaN NaN NaN 109297 u_turn NaN \n",
|
|
"107 NaN NaN NaN 109297 u_turn NaN \n",
|
|
"108 346 NaN NaN 109297 u_turn straight \n",
|
|
"109 258 NaN NaN 109297 u_turn left \n",
|
|
"110 079 NaN NaN 109297 u_turn left \n",
|
|
"111 164 NaN NaN 109297 u_turn straight "
|
|
]
|
|
},
|
|
"execution_count": 25,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"self.match6[52:52+60]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 26,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# 2-1-7\n",
|
|
"self.match7 = self.match6.copy()\n",
|
|
"self.match7 = self.match7[['inter_no', 'node_id', 'move_no', 'inc_angle', 'out_angle', 'inc_dire', 'out_dire', 'inc_edge_id', 'out_edge_id', 'node_type', 'turn_type']]\n",
|
|
"\n",
|
|
"# (1) 각 교차로별 방향 목록 : pdires (possible directions)\n",
|
|
"p2dires = {} # parent_id to directions\n",
|
|
"for parent_id in self.parent_ids:\n",
|
|
" dires = self.match7[self.match7.node_id == parent_id][['inc_dire','out_dire']].values.flatten()\n",
|
|
" dires = {dire for dire in dires if type(dire)==str}\n",
|
|
" p2dires[parent_id] = dires\n",
|
|
"\n",
|
|
"# (2) 각 (교차로, 진입방향) 별 진입id 목록 : inc2id (incoming direction to incoming edge_id)\n",
|
|
"inc2id = {}\n",
|
|
"for parent_id in self.parent_ids:\n",
|
|
" for inc_dire in p2dires[parent_id]:\n",
|
|
" df = self.match7[(self.match7.node_id==parent_id) & (self.match7.inc_dire==inc_dire)]\n",
|
|
" inc2id[(parent_id, inc_dire)] = df.inc_edge_id.iloc[0]\n",
|
|
"\n",
|
|
"# (3) 각 (교차로, 진출방향) 별 진출id 목록 : out2id (outgoing direction to outgoing edge_id)\n",
|
|
"out2id = {}\n",
|
|
"for parent_id in self.parent_ids:\n",
|
|
" for out_dire in p2dires[parent_id]:\n",
|
|
" df = self.match7[(self.match7.node_id==parent_id) & (self.match7.out_dire==out_dire)]\n",
|
|
" out2id[(parent_id, out_dire)] = df.out_edge_id.iloc[0]\n",
|
|
"\n",
|
|
"# (4) 각 parent_id별 이동류번호 목록\n",
|
|
"p2move = dict() # parent id to a list of aligned movement numbers\n",
|
|
"for parent_id in self.parent_ids:\n",
|
|
" pnema = self.nema[self.nema.inc_dire.isin(p2dires[parent_id]) & self.nema.out_dire.isin(p2dires[parent_id])]\n",
|
|
" p2move[parent_id] = list(pnema.move_no)\n",
|
|
"\n",
|
|
"# (5) 방위별 방향벡터\n",
|
|
"dire2vec = dict() # direction to unit vector\n",
|
|
"theta = np.pi/2\n",
|
|
"for dire in self.dires:\n",
|
|
" dire2vec[dire] = np.array([np.cos(theta), np.sin(theta)])\n",
|
|
" theta -= np.pi/4\n",
|
|
"\n",
|
|
"# (6) 각 parent_id별 : 각 이동류별 진입/진출 엣지 id\n",
|
|
"p2move2inc_edge_id = dict() # parent id to move2inc_edge_id\n",
|
|
"p2move2out_edge_id = dict() # parent id to move2out_edge_id\n",
|
|
"for parent_id in self.parent_ids:\n",
|
|
" move2inc_edge_id = dict() # plain movement to incoming edge id\n",
|
|
" move2out_edge_id = dict() # plain movement to outgoing edge id\n",
|
|
" for move_no in range(1,17):\n",
|
|
" row = self.nema[self.nema.move_no==move_no].iloc[0]\n",
|
|
" inc_dire = row.inc_dire\n",
|
|
" out_dire = row.out_dire\n",
|
|
" inc_vec_true = dire2vec[inc_dire]\n",
|
|
" out_vec_true = dire2vec[out_dire]\n",
|
|
"\n",
|
|
" node = self.net.getNode(parent_id)\n",
|
|
" # 교차로의 모든 (from / to) edges\n",
|
|
" inc_edges = [edge for edge in node.getIncoming() if edge.getFunction() == ''] # incoming edges\n",
|
|
" out_edges = [edge for edge in node.getOutgoing() if edge.getFunction() == ''] # outgoing edges\n",
|
|
" # 교차로의 모든 (from / to) unit vector\n",
|
|
" inc_vecs = []\n",
|
|
" for inc_edge in inc_edges:\n",
|
|
" start = inc_edge.getShape()[-1]\n",
|
|
" end = inc_edge.getShape()[-2]\n",
|
|
" inc_vec = np.array(end) - np.array(start)\n",
|
|
" inc_vec = inc_vec / (inc_vec ** 2).sum() ** 0.5\n",
|
|
" inc_vecs.append(inc_vec)\n",
|
|
" out_vecs = []\n",
|
|
" for out_edge in out_edges:\n",
|
|
" start = out_edge.getShape()[0]\n",
|
|
" end = out_edge.getShape()[1]\n",
|
|
" out_vec = np.array(end) - np.array(start)\n",
|
|
" out_vec = out_vec / (out_vec ** 2).sum() ** 0.5\n",
|
|
" out_vecs.append(out_vec)\n",
|
|
" # 매칭 엣지 반환\n",
|
|
" inc_index = np.array([np.dot(inc_vec, inc_vec_true) for inc_vec in inc_vecs]).argmax()\n",
|
|
" out_index = np.array([np.dot(out_vec, out_vec_true) for out_vec in out_vecs]).argmax()\n",
|
|
" inc_edge_id = inc_edges[inc_index].getID()\n",
|
|
" out_edge_id = out_edges[out_index].getID()\n",
|
|
" move2inc_edge_id[move_no] = inc_edge_id\n",
|
|
" move2out_edge_id[move_no] = out_edge_id\n",
|
|
" p2move2inc_edge_id[parent_id] = move2inc_edge_id\n",
|
|
" p2move2out_edge_id[parent_id] = move2out_edge_id\n",
|
|
"\n",
|
|
"# (7) 각 이동류별 진입/진출 방위\n",
|
|
"m2inc_dire = dict()\n",
|
|
"m2out_dire = dict()\n",
|
|
"for move_no in range(1,17):\n",
|
|
" row = self.nema[self.nema.move_no==move_no].iloc[0]\n",
|
|
" m2inc_dire[move_no] = row.inc_dire\n",
|
|
" m2out_dire[move_no] = row.out_dire\n",
|
|
"\n",
|
|
"# (8) 가능한 모든 이동류에 대하여 진입id, 진출id 배정 : matching\n",
|
|
"self.matching = []\n",
|
|
"for parent_id in self.parent_ids:\n",
|
|
" inter_no = self.node2inter[parent_id]\n",
|
|
" # 좌회전과 직진(1 ~ 16)\n",
|
|
" for move_no in range(1,17):\n",
|
|
" inc_dire = m2inc_dire[move_no]\n",
|
|
" out_dire = m2out_dire[move_no]\n",
|
|
" if move_no in p2move[parent_id]:\n",
|
|
" inc_edge_id = inc2id[(parent_id, inc_dire)]\n",
|
|
" out_edge_id = out2id[(parent_id, out_dire)]\n",
|
|
" else:\n",
|
|
" inc_edge_id = p2move2inc_edge_id[parent_id][move_no]\n",
|
|
" out_edge_id = p2move2out_edge_id[parent_id][move_no]\n",
|
|
" if (inc_edge_id, out_edge_id) in self.n2io2turn[parent_id]:\n",
|
|
" turn_type = self.n2io2turn[parent_id][inc_edge_id, out_edge_id]\n",
|
|
" else:\n",
|
|
" turn_type = 'left' if move_no % 2 else 'straight'\n",
|
|
" new_row = pd.DataFrame({'inter_no':[inter_no], 'node_id':[parent_id], 'move_no':[move_no],\n",
|
|
" 'inc_dire':[inc_dire], 'out_dire':[out_dire],\n",
|
|
" 'inc_edge_id':[inc_edge_id], 'out_edge_id':[out_edge_id],\n",
|
|
" 'turn_type': turn_type})\n",
|
|
" self.matching.append(new_row)\n",
|
|
"child_matching = self.match7[self.match7.node_id.isin(self.child_ids)]\n",
|
|
"child_matching = child_matching.drop(columns=['inc_angle', 'out_angle'])\n",
|
|
"self.matching = pd.concat(self.matching)\n",
|
|
"self.matching = self.matching.dropna(subset=['inc_edge_id', 'out_edge_id'])\\\n",
|
|
" .sort_values(by=['inter_no', 'node_id', 'move_no']).reset_index(drop=True)\n",
|
|
"self.matching['move_no'] = self.matching['move_no'].astype(int)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 27,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>inter_no</th>\n",
|
|
" <th>phase_no</th>\n",
|
|
" <th>ring_type</th>\n",
|
|
" <th>move_no</th>\n",
|
|
" <th>inc_dire</th>\n",
|
|
" <th>out_dire</th>\n",
|
|
" <th>inc_angle</th>\n",
|
|
" <th>out_angle</th>\n",
|
|
" <th>inc_edge_id</th>\n",
|
|
" <th>out_edge_id</th>\n",
|
|
" <th>node_id</th>\n",
|
|
" <th>node_type</th>\n",
|
|
" <th>turn_type</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>262</td>\n",
|
|
" <td>358</td>\n",
|
|
" <td>517505</td>\n",
|
|
" <td>517507</td>\n",
|
|
" <td>109836</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>262</td>\n",
|
|
" <td>074</td>\n",
|
|
" <td>517505</td>\n",
|
|
" <td>517004</td>\n",
|
|
" <td>109836</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>2</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>174</td>\n",
|
|
" <td>355</td>\n",
|
|
" <td>517509</td>\n",
|
|
" <td>517507</td>\n",
|
|
" <td>109836</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>3</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>172</td>\n",
|
|
" <td>263</td>\n",
|
|
" <td>517509</td>\n",
|
|
" <td>517504</td>\n",
|
|
" <td>109836</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>4</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>7</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>356</td>\n",
|
|
" <td>074</td>\n",
|
|
" <td>517002</td>\n",
|
|
" <td>517004</td>\n",
|
|
" <td>109836</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>...</th>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>111</th>\n",
|
|
" <td>457</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>344</td>\n",
|
|
" <td>164</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>109297</td>\n",
|
|
" <td>u_turn</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>112</th>\n",
|
|
" <td>458</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>8</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>073</td>\n",
|
|
" <td>250</td>\n",
|
|
" <td>513193</td>\n",
|
|
" <td>513188</td>\n",
|
|
" <td>106238</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>113</th>\n",
|
|
" <td>458</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>249</td>\n",
|
|
" <td>072</td>\n",
|
|
" <td>513189</td>\n",
|
|
" <td>513192</td>\n",
|
|
" <td>106238</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>114</th>\n",
|
|
" <td>458</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>A</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>106238</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>115</th>\n",
|
|
" <td>458</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>B</td>\n",
|
|
" <td>17</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" <td>106238</td>\n",
|
|
" <td>normal</td>\n",
|
|
" <td>NaN</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"<p>116 rows × 13 columns</p>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" inter_no phase_no ring_type move_no inc_dire out_dire inc_angle \\\n",
|
|
"0 436 1 A 5 서 북 262 \n",
|
|
"1 436 1 B 2 서 동 262 \n",
|
|
"2 436 2 A 8 남 북 174 \n",
|
|
"3 436 2 B 3 남 서 172 \n",
|
|
"4 436 3 A 7 북 동 356 \n",
|
|
".. ... ... ... ... ... ... ... \n",
|
|
"111 457 5 B 4 북 남 344 \n",
|
|
"112 458 1 A 8 남 북 073 \n",
|
|
"113 458 1 B 4 북 남 249 \n",
|
|
"114 458 2 A 17 NaN NaN NaN \n",
|
|
"115 458 2 B 17 NaN NaN NaN \n",
|
|
"\n",
|
|
" out_angle inc_edge_id out_edge_id node_id node_type turn_type \n",
|
|
"0 358 517505 517507 109836 normal left \n",
|
|
"1 074 517505 517004 109836 normal straight \n",
|
|
"2 355 517509 517507 109836 normal straight \n",
|
|
"3 263 517509 517504 109836 normal left \n",
|
|
"4 074 517002 517004 109836 normal left \n",
|
|
".. ... ... ... ... ... ... \n",
|
|
"111 164 NaN NaN 109297 u_turn straight \n",
|
|
"112 250 513193 513188 106238 normal straight \n",
|
|
"113 072 513189 513192 106238 normal straight \n",
|
|
"114 NaN NaN NaN 106238 normal NaN \n",
|
|
"115 NaN NaN NaN 106238 normal NaN \n",
|
|
"\n",
|
|
"[116 rows x 13 columns]"
|
|
]
|
|
},
|
|
"execution_count": 27,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"self.match6"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 28,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>inter_no</th>\n",
|
|
" <th>node_id</th>\n",
|
|
" <th>move_no</th>\n",
|
|
" <th>inc_dire</th>\n",
|
|
" <th>out_dire</th>\n",
|
|
" <th>inc_edge_id</th>\n",
|
|
" <th>out_edge_id</th>\n",
|
|
" <th>turn_type</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>109836</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>517003</td>\n",
|
|
" <td>517506</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>109836</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>동</td>\n",
|
|
" <td>517505</td>\n",
|
|
" <td>517004</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>2</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>109836</td>\n",
|
|
" <td>3</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>517509</td>\n",
|
|
" <td>517504</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>3</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>109836</td>\n",
|
|
" <td>4</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>남</td>\n",
|
|
" <td>517002</td>\n",
|
|
" <td>517506</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>4</th>\n",
|
|
" <td>436</td>\n",
|
|
" <td>109836</td>\n",
|
|
" <td>5</td>\n",
|
|
" <td>서</td>\n",
|
|
" <td>북</td>\n",
|
|
" <td>517505</td>\n",
|
|
" <td>517507</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>...</th>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" <td>...</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>139</th>\n",
|
|
" <td>458</td>\n",
|
|
" <td>106238</td>\n",
|
|
" <td>12</td>\n",
|
|
" <td>북서</td>\n",
|
|
" <td>남동</td>\n",
|
|
" <td>513195</td>\n",
|
|
" <td>513190</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>140</th>\n",
|
|
" <td>458</td>\n",
|
|
" <td>106238</td>\n",
|
|
" <td>13</td>\n",
|
|
" <td>남서</td>\n",
|
|
" <td>북서</td>\n",
|
|
" <td>513189</td>\n",
|
|
" <td>513194</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>141</th>\n",
|
|
" <td>458</td>\n",
|
|
" <td>106238</td>\n",
|
|
" <td>14</td>\n",
|
|
" <td>북동</td>\n",
|
|
" <td>남서</td>\n",
|
|
" <td>513193</td>\n",
|
|
" <td>513188</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>142</th>\n",
|
|
" <td>458</td>\n",
|
|
" <td>106238</td>\n",
|
|
" <td>15</td>\n",
|
|
" <td>북서</td>\n",
|
|
" <td>북동</td>\n",
|
|
" <td>513195</td>\n",
|
|
" <td>513192</td>\n",
|
|
" <td>left</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>143</th>\n",
|
|
" <td>458</td>\n",
|
|
" <td>106238</td>\n",
|
|
" <td>16</td>\n",
|
|
" <td>남동</td>\n",
|
|
" <td>북서</td>\n",
|
|
" <td>513191</td>\n",
|
|
" <td>513194</td>\n",
|
|
" <td>straight</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"<p>144 rows × 8 columns</p>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" inter_no node_id move_no inc_dire out_dire inc_edge_id out_edge_id \\\n",
|
|
"0 436 109836 1 동 남 517003 517506 \n",
|
|
"1 436 109836 2 서 동 517505 517004 \n",
|
|
"2 436 109836 3 남 서 517509 517504 \n",
|
|
"3 436 109836 4 북 남 517002 517506 \n",
|
|
"4 436 109836 5 서 북 517505 517507 \n",
|
|
".. ... ... ... ... ... ... ... \n",
|
|
"139 458 106238 12 북서 남동 513195 513190 \n",
|
|
"140 458 106238 13 남서 북서 513189 513194 \n",
|
|
"141 458 106238 14 북동 남서 513193 513188 \n",
|
|
"142 458 106238 15 북서 북동 513195 513192 \n",
|
|
"143 458 106238 16 남동 북서 513191 513194 \n",
|
|
"\n",
|
|
" turn_type \n",
|
|
"0 left \n",
|
|
"1 straight \n",
|
|
"2 left \n",
|
|
"3 straight \n",
|
|
"4 left \n",
|
|
".. ... \n",
|
|
"139 straight \n",
|
|
"140 left \n",
|
|
"141 straight \n",
|
|
"142 left \n",
|
|
"143 straight \n",
|
|
"\n",
|
|
"[144 rows x 8 columns]"
|
|
]
|
|
},
|
|
"execution_count": 28,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"self.matching"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 29,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[(0, <sumolib.net.connection.Connection at 0x248f3615940>),\n",
|
|
" (1, <sumolib.net.connection.Connection at 0x248f36159a0>),\n",
|
|
" (2, <sumolib.net.connection.Connection at 0x248f3615a60>),\n",
|
|
" (3, <sumolib.net.connection.Connection at 0x248f3615ac0>)]"
|
|
]
|
|
},
|
|
"execution_count": 29,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"node_id = '109901'\n",
|
|
"node = self.net.getNode(node_id)\n",
|
|
"conns = node.getConnections()\n",
|
|
"[(c.getJunctionIndex(), c) for c in node.getConnections()]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 30,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"2-2. 초기화 신호가 지정되었습니다. (우회전 : g)\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# 2-2 신호 초기화\n",
|
|
"self.nodes = [self.net.getNode(node_id) for node_id in self.node_ids]\n",
|
|
"self.node2init = {}\n",
|
|
"# 유턴노드를 제외한 모든 노드 (우회전, 삼지교차로직진 : g, 그외 : r)\n",
|
|
"for node_id in sorted(set(self.node_ids) - set(self.uturn_ids)):\n",
|
|
" node = self.net.getNode(node_id)\n",
|
|
" conns = [(c.getJunctionIndex(), c) for c in node.getConnections()]\n",
|
|
" conns = [c for c in conns if c[0] >= 0]\n",
|
|
" conns = sorted(conns, key=lambda x: x[0])\n",
|
|
" # print(node_id, len(conns),sep='\\n')\n",
|
|
" state = []\n",
|
|
" for i, ci in conns: # i번째 connection : ci\n",
|
|
" # print(ci.getTLLinkIndex())\n",
|
|
" if ci.getTLLinkIndex() < 0:\n",
|
|
" continue\n",
|
|
" are_foes = False\n",
|
|
" # 합류지점이 다르면서 상충되는 cj가 존재하면 r, 그외에는 g\n",
|
|
" for j, cj in conns: # j번째 connection : cj\n",
|
|
" # ci, cj의 합류지점이 같으면 통과\n",
|
|
" if ci.getTo() == cj.getTo():\n",
|
|
" continue\n",
|
|
" # ci, cj가 상충되면 are_foes를 True로 지정.\n",
|
|
" if node.areFoes(i, j):\n",
|
|
" are_foes = True\n",
|
|
" break\n",
|
|
" state.append('r' if are_foes else 'g')\n",
|
|
" self.node2init[node_id] = state\n",
|
|
"\n",
|
|
"# 유턴노드 (유턴x : G, 유턴 : G)\n",
|
|
"for node_id in self.uturn_ids:\n",
|
|
" node = self.net.getNode(node_id)\n",
|
|
" conns = [(c.getJunctionIndex(), c) for c in node.getConnections()]\n",
|
|
" conns = [c for c in conns if c[0] >= 0]\n",
|
|
" conns = sorted(conns, key=lambda x: x[0])\n",
|
|
" state = []\n",
|
|
" for i, ci in conns:\n",
|
|
" if ci.getTLLinkIndex() < 0:\n",
|
|
" continue\n",
|
|
" state.append('G')\n",
|
|
" self.node2init[node_id] = state\n",
|
|
"\n",
|
|
"# 신호가 부여되어 있는 경우에는 r을 부여 (우회전 : g, 그외 : r / 유턴x : G, 유턴 : r)\n",
|
|
"for _, row in self.match6.dropna(subset=['inc_edge_id', 'out_edge_id']).iterrows():\n",
|
|
" node_id = row.node_id\n",
|
|
" inc_edge_id = row.inc_edge_id\n",
|
|
" out_edge_id = row.out_edge_id\n",
|
|
" inc_edge = self.net.getEdge(inc_edge_id)\n",
|
|
" out_edge = self.net.getEdge(out_edge_id)\n",
|
|
" for conn in inc_edge.getConnections(out_edge):\n",
|
|
" index = conn.getTLLinkIndex()\n",
|
|
" if index >= 0:\n",
|
|
" self.node2init[node_id][index] = 'r'\n",
|
|
"\n",
|
|
"# json 파일로 저장\n",
|
|
"with open(os.path.join(self.path_intermediates, 'node2init.json'), 'w') as file:\n",
|
|
" json.dump(self.node2init, file, indent=4)\n",
|
|
"print('2-2. 초기화 신호가 지정되었습니다. (우회전 : g)')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 31,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# 2-3 유턴 인덱스 / 비보호좌회전 인덱스 지정\n",
|
|
"self.u2uindex = dict() # uturn node id to uturn index\n",
|
|
"for row in self.uturn.itertuples():\n",
|
|
" child_id = row.child_id\n",
|
|
" inc_edge_id = row.inc_edge_id\n",
|
|
" out_edge_id = row.out_edge_id\n",
|
|
" # self.u2uindex 지정\n",
|
|
" inc_edge = self.net.getEdge(inc_edge_id)\n",
|
|
" out_edge = self.net.getEdge(out_edge_id)\n",
|
|
" uturn_conn = inc_edge.getConnections(out_edge)[0]\n",
|
|
" self.u2uindex[child_id] = uturn_conn.getTLLinkIndex()\n",
|
|
"\n",
|
|
"self.p2UPLindices2inc_edge_ids = dict() # parent id to unprotected left index to incoming_edge_ids\n",
|
|
"for parent_id in self.parent_ids:\n",
|
|
" init_state = self.node2init[parent_id]\n",
|
|
" # 우회전 이동류 인덱스\n",
|
|
" indices_right = [i for i in range(len(init_state)) if init_state[i]=='g']\n",
|
|
" # from-to가 지정된 이동류 인덱스\n",
|
|
" indices_assigned = []\n",
|
|
" m5 = self.match5[(self.match5.node_id==parent_id)].dropna(subset=['inc_edge_id', 'out_edge_id'])\n",
|
|
" for row in m5.itertuples():\n",
|
|
" inc_edge = self.net.getEdge(row.inc_edge_id)\n",
|
|
" out_edge = self.net.getEdge(row.out_edge_id)\n",
|
|
" conns = inc_edge.getConnections(out_edge)\n",
|
|
" indices = [conn for conn in conns if conn.getTLLinkIndex()>=0]\n",
|
|
" indices = [conn for conn in conns if conn.getJunctionIndex()>=0]\n",
|
|
" indices = [conn.getTLLinkIndex() for conn in conns]\n",
|
|
" indices_assigned.extend(indices)\n",
|
|
" # 좌회전 이동류 인덱스\n",
|
|
" indices_left = []\n",
|
|
" for row in self.turn_type[self.turn_type.turn_type=='left'].itertuples():\n",
|
|
" inc_edge = self.net.getEdge(row.inc_edge_id)\n",
|
|
" out_edge = self.net.getEdge(row.out_edge_id)\n",
|
|
" conns = inc_edge.getConnections(out_edge)\n",
|
|
" indices = [conn for conn in conns if conn.getTLLinkIndex()>=0]\n",
|
|
" indices = [conn for conn in conns if conn.getJunctionIndex()>=0]\n",
|
|
" indices = [conn.getTLLinkIndex() for conn in conns]\n",
|
|
" indices_left.extend(indices)\n",
|
|
" # 비보호좌회전 인덱스 (unprotected left index)\n",
|
|
" UPLindices2inc_edge_ids = list((set(range(len(init_state))) - set(indices_right) - set(indices_assigned)).intersection(indices_left))\n",
|
|
" self.p2UPLindices2inc_edge_ids[parent_id] = dict()\n",
|
|
" for UPLindex in UPLindices2inc_edge_ids:\n",
|
|
" node = self.net.getNode(parent_id)\n",
|
|
" conns = node.getConnections()\n",
|
|
" conns = [conn for conn in conns if conn.getTLLinkIndex() == UPLindex]\n",
|
|
" inc_edge_ids = [conn.getFrom().getID() for conn in conns]\n",
|
|
" self.p2UPLindices2inc_edge_ids[parent_id][UPLindex] = inc_edge_ids\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 32,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# 2-4 신호배정\n",
|
|
"for i, row in self.matching.iterrows():\n",
|
|
" node_id = row.node_id\n",
|
|
" move_no = row.move_no\n",
|
|
" inc_edge_id = row.inc_edge_id\n",
|
|
" out_edge_id = row.out_edge_id\n",
|
|
" state_list = copy.deepcopy(self.node2init[node_id])\n",
|
|
" self.matching.at[i, 'state'] = ''.join(state_list)\n",
|
|
" if (pd.isna(inc_edge_id)) or (pd.isna(out_edge_id)):\n",
|
|
" continue\n",
|
|
" inc_edge = self.net.getEdge(inc_edge_id)\n",
|
|
" out_edge = self.net.getEdge(out_edge_id)\n",
|
|
" # 신호가 부여되어 있으면 (from, to가 존재하면) G 부여 (우회전 : g, 신호 : G, 그외 : r)\n",
|
|
" for conn in inc_edge.getConnections(out_edge):\n",
|
|
" index = conn.getTLLinkIndex()\n",
|
|
" if index >= 0:\n",
|
|
" state_list[index] = 'G'\n",
|
|
" self.matching.at[i, 'state'] = ''.join(state_list)\n",
|
|
"self.matching = self.matching.dropna(subset='state')\n",
|
|
"self.matching = self.matching.reset_index(drop=True)\n",
|
|
"self.matching = self.matching[['inter_no', 'node_id', 'move_no', 'inc_edge_id', 'out_edge_id', 'state', 'turn_type']]\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 33,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# match6 : 신호 배정\n",
|
|
"for i, row in self.match6.iterrows():\n",
|
|
" node_id = row.node_id\n",
|
|
" move_no = row.move_no\n",
|
|
" inc_edge_id = row.inc_edge_id\n",
|
|
" out_edge_id = row.out_edge_id\n",
|
|
" state_list = copy.deepcopy(self.node2init[node_id])\n",
|
|
" self.match6.at[i, 'state'] = ''.join(state_list)\n",
|
|
" if (pd.isna(inc_edge_id)) or (pd.isna(out_edge_id)):\n",
|
|
" continue\n",
|
|
" inc_edge = self.net.getEdge(inc_edge_id)\n",
|
|
" out_edge = self.net.getEdge(out_edge_id)\n",
|
|
" # 신호가 부여되어 있으면 (from, to가 존재하면) G 부여 (우회전 : g, 신호 : G, 그외 : r)\n",
|
|
" for conn in inc_edge.getConnections(out_edge):\n",
|
|
" index = conn.getTLLinkIndex()\n",
|
|
" if index >= 0:\n",
|
|
" state_list[index] = 'G'\n",
|
|
" self.match6.at[i, 'state'] = ''.join(state_list)\n",
|
|
"\n",
|
|
"# match6 : 비보호좌회전 신호 배정\n",
|
|
"for i, row in self.match6[self.match6.node_id.isin(self.parent_ids)].iterrows():\n",
|
|
" parent_id = row.node_id\n",
|
|
" state = row.state\n",
|
|
" UPLindices2inc_edge_ids = self.p2UPLindices2inc_edge_ids[parent_id]\n",
|
|
" for UPLindex in UPLindices2inc_edge_ids:\n",
|
|
" # 비보호좌회전 이동류에 대한 진입엣지에 신호가 부여되어 있으면\n",
|
|
" inc_edge_ids = UPLindices2inc_edge_ids[UPLindex]\n",
|
|
" if inc_edge_ids:\n",
|
|
" if inc_edge_id in inc_edge_ids:\n",
|
|
" # 해당 비보호좌회전 인덱스(UPLindex)에, 해당 진입엣지의 직진신호가 있을 때 g를 부여\n",
|
|
" state = state[:UPLindex] + 'g' + state[UPLindex+1:]\n",
|
|
" self.match6.at[i, 'state'] = state\n",
|
|
" else: # 직진신호가 없는 비보호좌회전 발생시 멈춤 및 오류메시지 출력\n",
|
|
" raise Exception(\n",
|
|
" f\"비보호좌회전 신호를 부여할 수 없습니다. \\\n",
|
|
" 신호가 부여되어 있지 않은 직진 또는 좌회전 연결이 존재하는데\\\n",
|
|
" (node_id : {parent_id}, index : {UPLindex})\\\n",
|
|
" 이 연결의 진입엣지(inc_edge_id : {inc_edge_id})에 부여된 신호가 없습니다.\")\n",
|
|
"\n",
|
|
"\n",
|
|
"# match6 : 유턴 신호가 한번도 배정되지 않은 경우에 대해서는 유턴이동류의 신호를 항상 g로 배정\n",
|
|
"for node_id in self.uturn_ids:\n",
|
|
" m6 = self.match6[self.match6.node_id==node_id]\n",
|
|
" if not len(m6):\n",
|
|
" continue\n",
|
|
" state_list = copy.deepcopy(self.node2init[node_id])\n",
|
|
" state = ''.join(state_list)\n",
|
|
" uindex = self.u2uindex[node_id]\n",
|
|
" values_at_uindex = [state[uindex] for state in m6.state]\n",
|
|
" # 유턴신호가 한번도 배정되지 않았으면\n",
|
|
" uturn_assigned = ('G' in values_at_uindex)\n",
|
|
" if not uturn_assigned:\n",
|
|
" # 해당 유턴 인덱스(uindex)에 g를 항상 부여\n",
|
|
" state = state[:uindex] + 'g' + state[uindex+1:]\n",
|
|
" self.match6.loc[self.match6.node_id==node_id, 'state'] = state\n",
|
|
"\n",
|
|
"self.match6 = self.match6.dropna(subset='state')\n",
|
|
"self.match6 = self.match6.reset_index(drop=True)\n",
|
|
"self.match6 = self.match6[['inter_no', 'node_id', 'phase_no', 'ring_type', 'move_no', 'inc_edge_id', 'out_edge_id', 'state', 'turn_type']]\n",
|
|
"self.match6.to_csv(os.path.join(self.path_intermediates, 'match6.csv'), index=0)\n",
|
|
"self.matching.to_csv(os.path.join(self.path_intermediates, 'matching.csv'), index=0)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 35,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# 신호계획 저장\n",
|
|
"self.plan.to_csv(os.path.join(self.path_tables, 'plan.csv'), index=0)\n",
|
|
"\n",
|
|
"# 노드별 주기 개수 저장\n",
|
|
"Aplan = self.plan.copy()[['inter_no'] + [f'dura_A{j}' for j in range(1,9)] + ['cycle']]\n",
|
|
"grouped = Aplan.groupby('inter_no')\n",
|
|
"df = grouped.agg({'cycle': 'min'}).reset_index()\n",
|
|
"df = df.rename(columns={'cycle': 'min_cycle'})\n",
|
|
"df['num_cycle'] = 300 // df['min_cycle'] + 2\n",
|
|
"inter2num_cycles = dict(zip(df['inter_no'], df['num_cycle']))\n",
|
|
"node2num_cycles = {node_id : inter2num_cycles[self.node2inter[node_id]] for node_id in self.node_ids}\n",
|
|
"with open(os.path.join(self.path_intermediates,'node2num_cycles.json'), 'w') as file:\n",
|
|
" json.dump(node2num_cycles, file, indent=4)"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "siggen_env",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.12.4"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|