신호생성 repo (24. 1. 5 ~).
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

1687 lines
64 KiB

{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"import os\n",
"import json\n",
"import sumolib\n",
"from tqdm import tqdm"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"loading_dtype = {\n",
" 'inter_no':'int', 'start_hour':'int', 'start_minute':'int', 'cycle':'int','offset':'int',\n",
" 'node_id':'str', 'inter_type':'str', 'parent_id':'str','child_id':'str',\n",
" 'direction':'str', 'condition':'str', 'inc_edge':'str', 'out_edge':'str',\n",
" 'end_unix':'int', 'inter_name':'str', 'inter_lat':'float', 'inter_lon':'float',\n",
" 'group_no':'int', 'main_phase_no':'int', 'phase_no':'int','ring_type':'str'\n",
" }\n",
"for alph in ['A', 'B']:\n",
" for j in range(1,9):\n",
" loading_dtype[f'angle_{alph}{j}'] = 'str'\n",
" loading_dtype[f'dura_{alph}{j}'] = 'int'"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['match1.csv', 'match6.csv', 'matching.csv', 'movement', 'node2num_cycles.json']\n"
]
}
],
"source": [
"path_intermediates = '../../Intermediates'\n",
"files = os.listdir(path_intermediates)\n",
"print(files)\n",
"\n",
"match1 = pd.read_csv(os.path.join(path_intermediates, 'match1.csv'), index_col=0)\n",
"match6 = pd.read_csv(os.path.join(path_intermediates, 'match6.csv'), index_col=0)\n",
"matching = pd.read_csv(os.path.join(path_intermediates, 'matching.csv'), index_col=0)\n",
"nema = pd.read_csv(os.path.join('../../Data/tables', 'nema.csv'), encoding='cp949')\n",
"plan = pd.read_csv(os.path.join('../../Data/tables', 'plan.csv'), index_col=0)\n",
"angle = pd.read_csv(os.path.join('../../Data/tables', 'angle.csv'), index_col=0, dtype = loading_dtype)\n",
"inter_node = pd.read_csv(os.path.join('../../Data/tables', 'inter_node.csv'), index_col=0)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"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>inter_type</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>175</td>\n",
" <td>i0</td>\n",
" <td>parent</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>175</td>\n",
" <td>u00</td>\n",
" <td>child</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>176</td>\n",
" <td>i1</td>\n",
" <td>parent</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>177</td>\n",
" <td>i2</td>\n",
" <td>parent</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>177</td>\n",
" <td>u20</td>\n",
" <td>child</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>178</td>\n",
" <td>i3</td>\n",
" <td>parent</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>178</td>\n",
" <td>u30</td>\n",
" <td>child</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>178</td>\n",
" <td>u31</td>\n",
" <td>child</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>178</td>\n",
" <td>u32</td>\n",
" <td>child</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>201</td>\n",
" <td>i8</td>\n",
" <td>parent</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>202</td>\n",
" <td>i9</td>\n",
" <td>parent</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>206</td>\n",
" <td>i7</td>\n",
" <td>parent</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>210</td>\n",
" <td>i6</td>\n",
" <td>parent</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>210</td>\n",
" <td>u60</td>\n",
" <td>child</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>178</td>\n",
" <td>c30</td>\n",
" <td>child</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" inter_no node_id inter_type\n",
"0 175 i0 parent\n",
"1 175 u00 child\n",
"2 176 i1 parent\n",
"3 177 i2 parent\n",
"4 177 u20 child\n",
"5 178 i3 parent\n",
"6 178 u30 child\n",
"7 178 u31 child\n",
"8 178 u32 child\n",
"9 201 i8 parent\n",
"10 202 i9 parent\n",
"11 206 i7 parent\n",
"12 210 i6 parent\n",
"13 210 u60 child\n",
"14 178 c30 child"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"inter_node[]"
]
},
{
"cell_type": "code",
"execution_count": 7,
"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>move_no</th>\n",
" <th>inc_dir</th>\n",
" <th>out_dir</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1</td>\n",
" <td>동</td>\n",
" <td>남</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2</td>\n",
" <td>서</td>\n",
" <td>동</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>3</td>\n",
" <td>남</td>\n",
" <td>서</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>4</td>\n",
" <td>북</td>\n",
" <td>남</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>5</td>\n",
" <td>서</td>\n",
" <td>북</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>6</td>\n",
" <td>동</td>\n",
" <td>서</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>7</td>\n",
" <td>북</td>\n",
" <td>동</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>8</td>\n",
" <td>남</td>\n",
" <td>북</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>9</td>\n",
" <td>북동</td>\n",
" <td>남동</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>10</td>\n",
" <td>남서</td>\n",
" <td>북동</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>11</td>\n",
" <td>남동</td>\n",
" <td>남서</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>12</td>\n",
" <td>북서</td>\n",
" <td>남동</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>13</td>\n",
" <td>남서</td>\n",
" <td>북서</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>14</td>\n",
" <td>북동</td>\n",
" <td>남서</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>15</td>\n",
" <td>북서</td>\n",
" <td>북동</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>16</td>\n",
" <td>남동</td>\n",
" <td>북서</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>17</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>18</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>21</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" move_no inc_dir out_dir\n",
"0 1 동 남\n",
"1 2 서 동\n",
"2 3 남 서\n",
"3 4 북 남\n",
"4 5 서 북\n",
"5 6 동 서\n",
"6 7 북 동\n",
"7 8 남 북\n",
"8 9 북동 남동\n",
"9 10 남서 북동\n",
"10 11 남동 남서\n",
"11 12 북서 남동\n",
"12 13 남서 북서\n",
"13 14 북동 남서\n",
"14 15 북서 북동\n",
"15 16 남동 북서\n",
"16 17 NaN NaN\n",
"17 18 NaN NaN\n",
"18 21 NaN NaN"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"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>start_hour</th>\n",
" <th>start_minute</th>\n",
" <th>dura_A1</th>\n",
" <th>dura_A2</th>\n",
" <th>dura_A3</th>\n",
" <th>dura_A4</th>\n",
" <th>dura_A5</th>\n",
" <th>dura_A6</th>\n",
" <th>dura_A7</th>\n",
" <th>dura_A8</th>\n",
" <th>dura_B1</th>\n",
" <th>dura_B2</th>\n",
" <th>dura_B3</th>\n",
" <th>dura_B4</th>\n",
" <th>dura_B5</th>\n",
" <th>dura_B6</th>\n",
" <th>dura_B7</th>\n",
" <th>dura_B8</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>176</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>37</td>\n",
" <td>73</td>\n",
" <td>40</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>37</td>\n",
" <td>73</td>\n",
" <td>40</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>176</td>\n",
" <td>7</td>\n",
" <td>0</td>\n",
" <td>37</td>\n",
" <td>93</td>\n",
" <td>40</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>37</td>\n",
" <td>93</td>\n",
" <td>40</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>176</td>\n",
" <td>9</td>\n",
" <td>0</td>\n",
" <td>37</td>\n",
" <td>103</td>\n",
" <td>40</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>37</td>\n",
" <td>103</td>\n",
" <td>40</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>176</td>\n",
" <td>18</td>\n",
" <td>30</td>\n",
" <td>37</td>\n",
" <td>113</td>\n",
" <td>40</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>37</td>\n",
" <td>113</td>\n",
" <td>40</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" inter_no start_hour start_minute dura_A1 dura_A2 dura_A3 dura_A4 \\\n",
"4 176 0 0 37 73 40 0 \n",
"5 176 7 0 37 93 40 0 \n",
"6 176 9 0 37 103 40 0 \n",
"7 176 18 30 37 113 40 0 \n",
"\n",
" dura_A5 dura_A6 dura_A7 dura_A8 dura_B1 dura_B2 dura_B3 dura_B4 \\\n",
"4 0 0 0 0 37 73 40 0 \n",
"5 0 0 0 0 37 93 40 0 \n",
"6 0 0 0 0 37 103 40 0 \n",
"7 0 0 0 0 37 113 40 0 \n",
"\n",
" dura_B5 dura_B6 dura_B7 dura_B8 \n",
"4 0 0 0 0 \n",
"5 0 0 0 0 \n",
"6 0 0 0 0 \n",
"7 0 0 0 0 "
]
},
"metadata": {},
"output_type": "display_data"
},
{
"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>angle_A1</th>\n",
" <th>angle_A2</th>\n",
" <th>angle_A3</th>\n",
" <th>angle_A4</th>\n",
" <th>angle_A5</th>\n",
" <th>angle_A6</th>\n",
" <th>angle_A7</th>\n",
" <th>angle_A8</th>\n",
" <th>angle_B1</th>\n",
" <th>angle_B2</th>\n",
" <th>angle_B3</th>\n",
" <th>angle_B4</th>\n",
" <th>angle_B5</th>\n",
" <th>angle_B6</th>\n",
" <th>angle_B7</th>\n",
" <th>angle_B8</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>176</td>\n",
" <td>180000</td>\n",
" <td>180000</td>\n",
" <td>270356</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>359180</td>\n",
" <td>180270</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",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" inter_no angle_A1 angle_A2 angle_A3 angle_A4 angle_A5 angle_A6 angle_A7 \\\n",
"1 176 180000 180000 270356 NaN NaN NaN NaN \n",
"\n",
" angle_A8 angle_B1 angle_B2 angle_B3 angle_B4 angle_B5 angle_B6 angle_B7 \\\n",
"1 NaN 359180 180270 NaN NaN NaN NaN NaN \n",
"\n",
" angle_B8 \n",
"1 NaN "
]
},
"metadata": {},
"output_type": "display_data"
},
{
"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>inter_type</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>176</td>\n",
" <td>i1</td>\n",
" <td>parent</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" inter_no node_id inter_type\n",
"2 176 i1 parent"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"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>5</th>\n",
" <td>176</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>8</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>176</td>\n",
" <td>2</td>\n",
" <td>2</td>\n",
" <td>8</td>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>176</td>\n",
" <td>3</td>\n",
" <td>3</td>\n",
" <td>5</td>\n",
" <td>18</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" inter_no phas_A phas_B move_A move_B\n",
"5 176 1 1 8 4\n",
"6 176 2 2 8 3\n",
"7 176 3 3 5 18"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"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_dir</th>\n",
" <th>out_dir</th>\n",
" <th>inc_angle</th>\n",
" <th>out_angle</th>\n",
" <th>inc_edge</th>\n",
" <th>out_edge</th>\n",
" <th>node_id</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>176</td>\n",
" <td>1</td>\n",
" <td>A</td>\n",
" <td>8</td>\n",
" <td>남</td>\n",
" <td>북</td>\n",
" <td>180.0</td>\n",
" <td>0.0</td>\n",
" <td>-571542810_01</td>\n",
" <td>-571542797_02.99</td>\n",
" <td>i1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>176</td>\n",
" <td>1</td>\n",
" <td>B</td>\n",
" <td>4</td>\n",
" <td>북</td>\n",
" <td>남</td>\n",
" <td>359.0</td>\n",
" <td>180.0</td>\n",
" <td>571542797_02.99</td>\n",
" <td>571542810_01</td>\n",
" <td>i1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>176</td>\n",
" <td>2</td>\n",
" <td>A</td>\n",
" <td>8</td>\n",
" <td>남</td>\n",
" <td>북</td>\n",
" <td>180.0</td>\n",
" <td>0.0</td>\n",
" <td>-571542810_01</td>\n",
" <td>-571542797_02.99</td>\n",
" <td>i1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>176</td>\n",
" <td>2</td>\n",
" <td>B</td>\n",
" <td>3</td>\n",
" <td>남</td>\n",
" <td>서</td>\n",
" <td>180.0</td>\n",
" <td>270.0</td>\n",
" <td>-571542810_01</td>\n",
" <td>571543469_01</td>\n",
" <td>i1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>176</td>\n",
" <td>3</td>\n",
" <td>A</td>\n",
" <td>5</td>\n",
" <td>서</td>\n",
" <td>북</td>\n",
" <td>270.0</td>\n",
" <td>356.0</td>\n",
" <td>571543469_02</td>\n",
" <td>-571542797_02.99</td>\n",
" <td>i1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>176</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>i1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" inter_no phase_no ring_type move_no inc_dir out_dir inc_angle \\\n",
"8 176 1 A 8 남 북 180.0 \n",
"9 176 1 B 4 북 남 359.0 \n",
"10 176 2 A 8 남 북 180.0 \n",
"11 176 2 B 3 남 서 180.0 \n",
"12 176 3 A 5 서 북 270.0 \n",
"13 176 3 B 18 NaN NaN NaN \n",
"\n",
" out_angle inc_edge out_edge node_id \n",
"8 0.0 -571542810_01 -571542797_02.99 i1 \n",
"9 180.0 571542797_02.99 571542810_01 i1 \n",
"10 0.0 -571542810_01 -571542797_02.99 i1 \n",
"11 270.0 -571542810_01 571543469_01 i1 \n",
"12 356.0 571543469_02 -571542797_02.99 i1 \n",
"13 NaN NaN NaN i1 "
]
},
"metadata": {},
"output_type": "display_data"
},
{
"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>inc_dir</th>\n",
" <th>out_dir</th>\n",
" <th>inc_edge</th>\n",
" <th>out_edge</th>\n",
" <th>node_id</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>176</td>\n",
" <td>3</td>\n",
" <td>남</td>\n",
" <td>서</td>\n",
" <td>-571542810_01</td>\n",
" <td>571543469_01</td>\n",
" <td>i1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>176</td>\n",
" <td>4</td>\n",
" <td>북</td>\n",
" <td>남</td>\n",
" <td>571542797_02.99</td>\n",
" <td>571542810_01</td>\n",
" <td>i1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>176</td>\n",
" <td>5</td>\n",
" <td>서</td>\n",
" <td>북</td>\n",
" <td>571543469_02</td>\n",
" <td>-571542797_02.99</td>\n",
" <td>i1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>176</td>\n",
" <td>8</td>\n",
" <td>남</td>\n",
" <td>북</td>\n",
" <td>-571542810_01</td>\n",
" <td>-571542797_02.99</td>\n",
" <td>i1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>176</td>\n",
" <td>21</td>\n",
" <td>북</td>\n",
" <td>서</td>\n",
" <td>571542797_02.99</td>\n",
" <td>571543469_01</td>\n",
" <td>i1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>176</td>\n",
" <td>21</td>\n",
" <td>서</td>\n",
" <td>남</td>\n",
" <td>571543469_02</td>\n",
" <td>571542810_01</td>\n",
" <td>i1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" inter_no move_no inc_dir out_dir inc_edge out_edge \\\n",
"13 176 3 남 서 -571542810_01 571543469_01 \n",
"14 176 4 북 남 571542797_02.99 571542810_01 \n",
"15 176 5 서 북 571543469_02 -571542797_02.99 \n",
"16 176 8 남 북 -571542810_01 -571542797_02.99 \n",
"17 176 21 북 서 571542797_02.99 571543469_01 \n",
"18 176 21 서 남 571543469_02 571542810_01 \n",
"\n",
" node_id \n",
"13 i1 \n",
"14 i1 \n",
"15 i1 \n",
"16 i1 \n",
"17 i1 \n",
"18 i1 "
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"inter_no = 176\n",
"display(nema)\n",
"display(plan[plan.inter_no==inter_no].iloc[:,:-2])\n",
"display(angle[angle.inter_no==inter_no])\n",
"display(inter_node[inter_node.inter_no==inter_no])\n",
"display(match1[match1.inter_no==inter_no])\n",
"display(match6[match6.inter_no==inter_no])\n",
"display(matching[matching.inter_no==inter_no])"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"def make_match1(path_move):\n",
" '''\n",
" 신호 DB에는 매 초마다 이동류정보가 업데이트 된다. 그리고 이 이동류정보를 매 5초마다 불러와서 사용하게 된다.\n",
" '../Data/tables/move/'에는 5초마다의 이동류정보가 저장되어 있다.\n",
"\n",
" return : 통합된 이동류정보\n",
" - 모든 inter_no(교차로번호)에 대한 A, B링 현시별 이동류정보\n",
"\n",
" match1을 만드는 데 시간이 소요되므로 한 번 만들어서 저장해두고 저장해둔 것을 쓴다.\n",
" '''\n",
" # [이동류번호] 불러오기 (약 1분의 소요시간)\n",
" csv_moves = os.listdir(path_move)\n",
" moves = [pd.read_csv(path_move + csv_move, index_col=0) for csv_move in tqdm(csv_moves)]\n",
" match1 = pd.concat(moves).drop_duplicates().sort_values(by=['inter_no','phas_A','phas_B']).reset_index(drop=True)\n",
" match1.to_csv('../Intermediates/match1.csv')\n",
" return match1"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"def make_match2(match1):\n",
" '''\n",
" match1을 계층화함.\n",
" - match1의 컬럼 : inter_no, phas_A, phas_B, move_A, move_B\n",
" - match2의 컬럼 : inter_no, phase_no, ring_type, move_no\n",
" '''\n",
" # 계층화 (inter_no, phas_A, phas_B, move_A, move_B) -> ('inter_no', 'phase_no', 'ring_type', 'move_no')\n",
" matchA = match1[['inter_no', 'phas_A', 'move_A']].copy()\n",
" matchA.columns = ['inter_no', 'phase_no', 'move_no']\n",
" matchA['ring_type'] = 'A'\n",
" matchB = match1[['inter_no', 'phas_B', 'move_B']].copy()\n",
" matchB.columns = ['inter_no', 'phase_no', 'move_no']\n",
" matchB['ring_type'] = 'B'\n",
" match2 = pd.concat([matchA, matchB]).drop_duplicates()\n",
" match2 = match2[['inter_no', 'phase_no', 'ring_type', 'move_no']]\n",
" match2 = match2.sort_values(by=list(match2.columns))\n",
" return match2"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"def make_match3(match2, nema):\n",
" '''\n",
" 각 movement들에 방향(진입방향, 진출방향)을 매칭시켜 추가함.\n",
" - match2의 컬럼 : inter_no, phase_no, ring_type, move_no\n",
" - match3의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir\n",
"\n",
" nema : \n",
" - 컬럼 : move_no, inc_dir, out_dir\n",
" - 모든 종류의 이동류번호에 대하여 진입방향과 진출방향을 매칭시키는 테이블\n",
" - 이동류번호 : 1 ~ 16, 17, 18, 21\n",
" - 진입, 진출방향(8방위) : 동, 서, 남, 북, 북동, 북서, 남동, 남서\n",
" '''\n",
" # nema 정보 불러오기 및 병합\n",
" match3 = pd.merge(match2, nema, how='left', on='move_no').drop_duplicates()\n",
" return match3"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"def make_match4(match3, angle):\n",
" '''\n",
" 방위각 정보를 매칭시켜 추가함.\n",
" - match3의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir\n",
" - match4의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir, inc_angle, out_angle\n",
"\n",
" angle_original : \n",
" - 컬럼 : inter_no, angle_Aj, angle_Bj (j : 1 ~ 8)\n",
" - 모든 종류의 이동류번호에 대하여 진입방향과 진출방향을 매칭시키는 테이블\n",
" - 이동류번호 : 1 ~ 16, 17, 18, 21\n",
" - 진입, 진출방향(8방위) : 동, 서, 남, 북, 북동, 북서, 남동, 남서\n",
" '''\n",
"\n",
" # 계층화\n",
" angles = []\n",
" for i, row in angle.iterrows():\n",
" angle_codes = row[[f'angle_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]\n",
" new = pd.DataFrame({'inter_no':[row.inter_no] * 16, 'phase_no':list(range(1, 9))*2, 'ring_type':['A'] * 8 + ['B'] * 8, 'angle_code':angle_codes.to_list()})\n",
" angles.append(new)\n",
" angles = pd.concat(angles)\n",
" angles = angles.dropna().reset_index(drop=True)\n",
"\n",
" # 병합\n",
" six_chars = angles.angle_code.apply(lambda x:len(x)==6)\n",
" angles.loc[six_chars,'inc_angle'] = angles.angle_code.apply(lambda x:x[:3])\n",
" angles.loc[six_chars,'out_angle'] = angles.angle_code.apply(lambda x:x[3:])\n",
" angles = angles.drop('angle_code', axis=1)\n",
" match4 = pd.merge(match3, angles, how='left', left_on=['inter_no', 'phase_no', 'ring_type'],\n",
" right_on=['inter_no', 'phase_no', 'ring_type']).drop_duplicates()\n",
" return match4"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"def make_match5(match4, net, inter_node, inter_info):\n",
" '''\n",
" 진입엣지id, 진출엣지id, 노드id를 추가함 (주교차로).\n",
" - match4의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir, inc_angle, out_angle\n",
" - match5의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir, inc_angle, out_angle, inc_edge, out_edge, node_id\n",
" \n",
" 사용된 데이터 : \n",
" (1) net\n",
" - 성남시 정자동 부근의 샘플 네트워크\n",
" (2) inter_node\n",
" - 교차로번호와 노드id를 매칭시키는 테이블.\n",
" - parent/child 정보도 포함되어 있음\n",
" - 컬럼 : inter_no, node_id, inter_type\n",
" (3) inter_info\n",
" - 교차로 정보. 여기에서는 위도와 경도가 쓰임.\n",
" - 컬럼 : inter_no, inter_name, inter_lat, inter_lon, group_no, main_phase_no\n",
"\n",
" 진입엣지id, 진출엣지id를 얻는 과정 :\n",
" - match5 = match4.copy()의 각 열을 순회하면서 아래 과정을 반복함.\n",
" * 진입에 대해서만 서술하겠지만 진출도 마찬가지로 설명될 수 있음\n",
" - 해당 행의 교차로정보로부터 노드ID를 얻어내고, 해당 노드에 대한 모든 진출엣지id를 inc_edges에 저장.\n",
" * inc_edge(진입엣지) : incoming edge, out_edge(진출엣지) : outgoing_edge\n",
" - inc_edges의 모든 진입엣지에 대하여 진입방향(inc_dires, 2차원 단위벡터)을 얻어냄.\n",
" - 해당 행의 진입각으로부터 그에 대응되는 진입각방향(단위벡터)를 얻어냄.\n",
" - 주어진 진입각방향에 대하여 내적이 가장 작은 진입방향에 대한 진입엣지를 inc_edge_id로 지정함.\n",
" '''\n",
"\n",
" # parent node만 가져옴.\n",
" inter_node1 = inter_node[inter_node.inter_type == 'parent'].drop('inter_type', axis=1)\n",
" inter_info1 = 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",
" inter2node = dict(zip(inter['inter_no'], inter['node_id']))\n",
"\n",
" match5 = match4.copy()\n",
" # 진입진출ID 매칭\n",
" for index, row in match5.iterrows():\n",
" node_id = inter2node[row.inter_no]\n",
" node = 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) directions\n",
" inc_dirs = []\n",
" for inc_edge in inc_edges:\n",
" start = inc_edge.getShape()[-2]\n",
" end = inc_edge.getShape()[-1]\n",
" inc_dir = np.array(end) - np.array(start)\n",
" inc_dir = inc_dir / (inc_dir ** 2).sum() ** 0.5\n",
" inc_dirs.append(inc_dir)\n",
" out_dirs = []\n",
" for out_edge in out_edges:\n",
" start = out_edge.getShape()[0]\n",
" end = out_edge.getShape()[1]\n",
" out_dir = np.array(end) - np.array(start)\n",
" out_dir = out_dir / (out_dir ** 2).sum() ** 0.5\n",
" out_dirs.append(out_dir)\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_dir_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_dir_true = np.array([np.cos(out_angle), np.sin(out_angle)])\n",
" # 매칭 엣지 반환\n",
" inc_index = np.array([np.dot(inc_dir, inc_dir_true) for inc_dir in inc_dirs]).argmax()\n",
" out_index = np.array([np.dot(out_dir, out_dir_true) for out_dir in out_dirs]).argmax()\n",
" inc_edge_id = inc_edges[inc_index].getID()\n",
" out_edge_id = out_edges[out_index].getID()\n",
" match5.at[index, 'inc_edge'] = inc_edge_id\n",
" match5.at[index, 'out_edge'] = out_edge_id\n",
" match5['node_id'] = match5['inter_no'].map(inter2node)\n",
" match5 = match5.sort_values(by=['inter_no','phase_no','ring_type']).reset_index(drop=True)\n",
" return match5"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"def make_match6(match5, inter_node, uturn, coord):\n",
" '''\n",
" 진입엣지id, 진출엣지id, 노드id를 추가함 (부교차로).\n",
" - match6의 컬럼 : inter_no, phase_no, ring_type, move_no, inc_dir, out_dir, inc_angle, out_angle, inc_edge, out_edge, node_id\n",
" \n",
" 사용된 데이터 : \n",
" (1) inter_node\n",
" - 교차로번호와 노드id를 매칭시키는 테이블.\n",
" - parent/child 정보도 포함되어 있음\n",
" - 컬럼 : inter_no, node_id, inter_type\n",
" (2) uturn (유턴정보)\n",
" - 컬럼 : parent_id, child_id, direction, condition, inc_edge, out_edge\n",
" - parent_id, child_id : 주교차로id, 유턴교차로id\n",
" - direction : 주교차로에 대한 유턴노드의 상대적인 위치(방향)\n",
" - condition : 좌회전시, 직진시, 직좌시, 보행신호시 중 하나\n",
" - inc_edge, out_edge : 유턴에 대한 진입진출엣지\n",
" (3) coord (연동교차로정보)\n",
" - 컬럼 : parent_id, child_id, phase_no, ring_type, inc_edge, out_edge\n",
" - parent_id, child_id : 주교차로id, 연동교차로id\n",
" - 나머지 컬럼 : 각 (현시, 링)별 진입진출엣지\n",
"\n",
" 설명 :\n",
" - match5는 주교차로에 대해서만 진입엣지id, 진출엣지id, 노드id를 추가했었음.\n",
" 여기에서 uturn, coord를 사용해서 부교차로들(유턴교차로, 연동교차로)에 대해서도 해당 값들을 부여함.\n",
" 유턴교차로 :\n",
" - directions를 정북기준 시계방향의 8방위로 정함.\n",
" - 이를 통해 진입방향이 주어진 경우에 좌회전, 직진, 보행 등에 대한 (진입방향, 진출방향)을 얻어낼 수 있음.\n",
" - 예) 진입방향(direction)이 '북'일 때, \n",
" - 직진 : (북, 남)\n",
" * 남 : directions[(ind + 4) % len(directions)]\n",
" - 좌회전 : (북, 동)\n",
" * 동 : directions[(ind + 2) % len(directions)]\n",
" - 보행 : (서, 동)\n",
" * 서 : directions[(ind - 2) % len(directions)]\n",
" - uturn의 각 행을 순회하면서 아래 과정을 반복함\n",
" - match5에서 parent_id에 해당하는 행들을 가져옴(cmatch).\n",
" - condition 별로 진입방향, 진출방향A, 진출방향B 정함.\n",
" - 상술한 directions를 활용하여 정함.\n",
" - (진입방향, 진출방향A, 진출방향B)을 고려하여 (현시, 링) 별로 진입엣지id, 진출엣지id를 정함.\n",
" - ex) cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n",
" - 순회하면서 만든 cmatch를 cmatchs라는 리스트에 저장함.\n",
"\n",
" 연동교차로 :\n",
" - 연동교차로의 경우 coord에 (현시, 링)별 진입엣지ID, 진출엣지ID가 명시되어 있음.\n",
" - 'inc_dir', 'out_dir', 'inc_angle','out_angle'와 같은 열들은 np.nan을 지정해놓음.\n",
" - 이 열들은, 사실상 다음 스텝부터는 사용되지 않는 열들이기 때문에 np.nan으로 지정해놓아도 문제없음.\n",
"\n",
" match6 :\n",
" - 이렇게 얻은 match5, cmatchs, coord를 모두 pd.concat하여 match6을 얻어냄.\n",
" '''\n",
"\n",
" node2inter = dict(zip(inter_node['node_id'], inter_node['inter_no']))\n",
"\n",
" child_ids = inter_node[inter_node.inter_type=='child'].node_id.unique()\n",
" ch2pa = {} # child to parent\n",
" for child_id in child_ids:\n",
" parent_no = inter_node[inter_node.node_id==child_id].inter_no.iloc[0]\n",
" sub_inter_node = inter_node[inter_node.inter_no==parent_no]\n",
" ch2pa[child_id] = sub_inter_node[sub_inter_node.inter_type=='parent'].iloc[0].node_id\n",
" directions = ['북', '북동', '동', '남동', '남', '남서', '서', '북서'] # 정북기준 시계방향으로 8방향\n",
"\n",
" # 각 uturn node에 대하여 (inc_edge_id, out_edge_id) 부여\n",
" cmatches = []\n",
" for _, row in uturn.iterrows():\n",
" child_id = row.child_id\n",
" parent_id = row.parent_id\n",
" direction = row.direction\n",
" condition = row.condition\n",
" inc_edge_id = row.inc_edge\n",
" out_edge_id = row.out_edge\n",
" # match5에서 parent_id에 해당하는 행들을 가져옴\n",
" cmatch = match5.copy()[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[['inc_edge', 'out_edge']] = np.nan\n",
"\n",
" # condition 별로 inc_dire, out_dire_A, out_dire_B를 정함\n",
" ind = directions.index(direction)\n",
" if condition == \"좌회전시\":\n",
" inc_dire = direction\n",
" out_dire_A = out_dire_B = directions[(ind + 2) % len(directions)]\n",
" elif condition == \"직진시\":\n",
" inc_dire = direction\n",
" out_dire_A = out_dire_B = directions[(ind + 4) % len(directions)]\n",
" elif condition == \"보행신호시\":\n",
" inc_dire = directions[(ind + 2) % len(directions)]\n",
" out_dire_A = directions[(ind - 2) % len(directions)]\n",
" out_dire_B = directions[(ind - 2) % len(directions)]\n",
"\n",
" # (inc_dire, out_dire_A, out_dire_B) 별로 inc_edge_id, out_edge_id를 정함\n",
" if condition == '보행신호시':\n",
" cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n",
" cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n",
" # 이동류번호가 17(보행신호)이면서 유턴노드방향으로 가는 신호가 없으면 (inc_edge_id, out_edge_id)를 부여한다.\n",
" cmatch.loc[(cmatch.move_no==17) & (cmatch.out_dir!=direction), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n",
" else: # '직진시', '좌회전시'\n",
" cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n",
" cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), ['inc_edge', 'out_edge']] = [inc_edge_id, out_edge_id]\n",
" # 유턴신호의 이동류번호를 19로 부여한다.\n",
" cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_A), 'move_no'] = 19\n",
" cmatch.loc[(cmatch.inc_dir==inc_dire) & (cmatch.out_dir==out_dire_B), 'move_no'] = 19\n",
" cmatches.append(cmatch)\n",
"\n",
" # 각 coordination node에 대하여 (inc_edge_id, out_edge_id) 부여\n",
" coord['inter_no'] = coord['parent_id'].map(node2inter)\n",
" coord = coord.rename(columns={'child_id':'node_id'})\n",
" coord[['inc_dir', 'out_dir', 'inc_angle','out_angle']] = np.nan\n",
" coord['move_no'] = 20\n",
" coord = coord[['inter_no', 'phase_no', 'ring_type', 'move_no', 'inc_dir', 'out_dir', 'inc_angle','out_angle', 'inc_edge', 'out_edge', 'node_id']]\n",
" \n",
" # display(coord)\n",
" cmatches = pd.concat(cmatches)\n",
" match6 = pd.concat([match5, cmatches, coord]).drop_duplicates().sort_values(by=['inter_no', 'node_id', 'phase_no', 'ring_type'])\n",
" match6.to_csv('../Intermediates/match6.csv')\n",
" return match6"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"def make_matching(match6, inter_node, nema):\n",
" '''\n",
" 이동류 매칭 : 각 교차로에 대하여, 가능한 모든 이동류 (1~18, 21)에 대한 진입·진출엣지ID를 지정한다.\n",
" 모든 이동류에 대해 지정하므로, 시차제시 이전과 다른 이동류가 등장하더라도 항상 진입·진출 엣지 ID를 지정할 수 있다. \n",
" - matching의 컬럼 : inter_no, move_no, inc_dir, out_dir, inc_edge, out_edge, node_id\n",
" \n",
" 설명 : \n",
" - 필요한 리스트, 딕셔너리 등을 정의\n",
" (1) 가능한 (진입방향, 진출방향) 목록 [리스트]\n",
" (2) 각 교차로별 방향 목록 : pdires (possible directions) [딕셔너리]\n",
" (3) 각 (교차로, 진입방향) 별 진입id 목록 : inc2id (incoming direction to incoming edge_id) [딕셔너리]\n",
" (4) 각 (교차로, 진출방향) 별 진출id 목록 : out2id (outgoing direction to outgoing edge_id) [딕셔너리]\n",
" (5) 각 교차로별 가능한 (진입방향, 진출방향) 목록 : pflow (possible flows) [딕셔너리]\n",
" - matching은 빈 리스트로 지정.\n",
" - 모든 노드id에 대하여 다음 과정을 반복\n",
" - 해당 노드id에 대한 모든 가능한 (진입방향, 진출방향)에 대하여 다음 과정을 반복\n",
" - (노드id, 진입방향)으로부터 진입엣지id를 얻어냄. 마찬가지로 진출엣지id도 얻어냄\n",
" - 얻어낸 정보를 바탕으로 한 행(new_row)을 만들고 이것을 matching에 append\n",
" '''\n",
"\n",
" match7 = match6.copy()\n",
" match7 = match7[['inter_no', 'move_no', 'inc_dir', 'out_dir', 'inc_edge', 'out_edge', 'node_id']]\n",
"\n",
" parent_ids = sorted(inter_node[inter_node.inter_type=='parent'].node_id.unique())\n",
" child_ids = sorted(inter_node[inter_node.inter_type=='child'].node_id.unique())\n",
"\n",
" # (1) 가능한 (진입방향, 진출방향) 목록 \n",
" flows = nema.dropna().apply(lambda row: (row['inc_dir'], row['out_dir']), axis=1).tolist()\n",
" # (2) 각 교차로별 방향 목록 : pdires (possible directions)\n",
" pdires = {}\n",
" for node_id in parent_ids:\n",
" dires = match7[match7.node_id == node_id][['inc_dir','out_dir']].values.flatten()\n",
" dires = {dire for dire in dires if type(dire)==str}\n",
" pdires[node_id] = dires\n",
" # (3) 각 (교차로, 진입방향) 별 진입id 목록 : inc2id (incoming direction to incoming edge_id)\n",
" inc2id = {}\n",
" for node_id in parent_ids:\n",
" for inc_dir in pdires[node_id]:\n",
" df = match7[(match7.node_id==node_id) & (match7.inc_dir==inc_dir)]\n",
" inc2id[(node_id, inc_dir)] = df.inc_edge.iloc[0]\n",
" # (4) 각 (교차로, 진출방향) 별 진출id 목록 : out2id (outgoing direction to outgoing edge_id)\n",
" out2id = {}\n",
" for node_id in parent_ids:\n",
" for out_dir in pdires[node_id]:\n",
" df = match7[(match7.node_id==node_id) & (match7.out_dir==out_dir)]\n",
" out2id[(node_id, out_dir)] = df.out_edge.iloc[0]\n",
" # (5) 각 교차로별 가능한 (진입방향, 진출방향) 목록 : pflow (possible flows)\n",
" pflow = {}\n",
" for node_id in parent_ids:\n",
" pflow[node_id] = [flow for flow in flows if set(flow).issubset(pdires[node_id])]\n",
" # (6) 가능한 이동류에 대하여 진입id, 진출id 배정 : matching\n",
" node2inter = dict(zip(match7['node_id'], match7['inter_no']))\n",
" dires_right = ['북', '서', '남', '동', '북'] # ex (북, 서), (서, 남) 등은 우회전 flow\n",
" matching = []\n",
" for node_id in parent_ids:\n",
" inter_no = node2inter[node_id]\n",
" # 좌회전과 직진(1 ~ 16)\n",
" for (inc_dir, out_dir) in pflow[node_id]:\n",
" move_no = nema[(nema.inc_dir==inc_dir) & (nema.out_dir==out_dir)].move_no.iloc[0]\n",
" inc_edge = inc2id[(node_id, inc_dir)]\n",
" out_edge = out2id[(node_id, out_dir)]\n",
" new_row = pd.DataFrame({'inter_no':[inter_no], 'move_no':[move_no],\n",
" 'inc_dir':[inc_dir], 'out_dir':[out_dir],\n",
" 'inc_edge':[inc_edge], 'out_edge':[out_edge], 'node_id':[node_id]})\n",
" matching.append(new_row)\n",
" # 보행신호(17), 전적색(18)\n",
" new_row = pd.DataFrame({'inter_no':[inter_no] * 2, 'move_no':[17, 18],\n",
" 'inc_dir':[None]*2, 'out_dir':[None]*2,\n",
" 'inc_edge':[None]*2, 'out_edge':[None]*2, 'node_id':[node_id]*2})\n",
" matching.append(new_row)\n",
" # 신호우회전(21)\n",
" for d in range(len(dires_right)-1):\n",
" inc_dir = dires_right[d]\n",
" out_dir = dires_right[d+1]\n",
" if {inc_dir, out_dir}.issubset(pdires[node_id]):\n",
" inc_edge = inc2id[(node_id, inc_dir)]\n",
" out_edge = out2id[(node_id, out_dir)]\n",
" new_row = pd.DataFrame({'inter_no':[inter_no], 'move_no':[21],\n",
" 'inc_dir':[inc_dir], 'out_dir':[out_dir],\n",
" 'inc_edge':[inc_edge], 'out_edge':[out_edge], 'node_id':[node_id]})\n",
" matching.append(new_row)\n",
" matching.append(match7[match7.node_id.isin(child_ids)])\n",
" matching = pd.concat(matching)\n",
" matching = matching.dropna().sort_values(by=['inter_no', 'node_id', 'move_no']).reset_index(drop=True)\n",
" matching['move_no'] = matching['move_no'].astype(int)\n",
" matching.to_csv('../Intermediates/matching.csv')\n",
" return matching"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"def make_movements():\n",
" movements_path = '../Intermediates/movement/'\n",
" movements_list = [pd.read_csv(movements_path + file, index_col=0) for file in tqdm(os.listdir(movements_path))]\n",
" movements = pd.concat(movements_list)\n",
" movements = movements.drop(columns=['start_unix'])\n",
" movements = movements.drop_duplicates()\n",
" movements = movements.sort_values(by=['inter_no', 'phas_A', 'phas_B'])\n",
" movements = movements.reset_index(drop=True)\n",
" movements.to_csv('../Intermediates/movements.csv')\n",
" return movements"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"# node2num_cycles : A dictionary that maps a node_id to the number of cycles\n",
"def get_node2num_cycles(plan, inter_node):\n",
" node2inter = dict(zip(inter_node['node_id'], inter_node['inter_no']))\n",
" node_ids = sorted(inter_node.node_id.unique())\n",
"\n",
" Aplan = 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",
" node2numcycles = {node_id : inter2num_cycles[node2inter[node_id]] for node_id in node_ids}\n",
" with open('../Intermediates/node2numcycles.json', 'w') as file:\n",
" json.dump(node2numcycles, file, indent=4)\n",
" return node2numcycles"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"def preprocess_daily():\n",
" path_move = '../Data/tables/move/'\n",
"\n",
" inter_info = pd.read_csv('../Data/tables/inter_info.csv', index_col=0)\n",
" angle = pd.read_csv('../Data/tables/angle.csv', index_col=0, dtype = {f'angle_{alph}{j}':'str' for alph in ['A', 'B'] for j in range(1,9)})\n",
" plan = pd.read_csv('../Data/tables/plan.csv', index_col=0)\n",
" inter_node = pd.read_csv('../Data/tables/inter_node.csv', index_col=0)\n",
" uturn = pd.read_csv('../Data/tables/child_uturn.csv')\n",
" coord = pd.read_csv('../Data/tables/child_coord.csv')\n",
" nema = pd.read_csv('../Data/tables/nema.csv', encoding='cp949')\n",
"\n",
" net = sumolib.net.readNet('../Data/networks/sn.net.xml')\n",
"\n",
" match1 = make_match1(path_move)\n",
" match2 = make_match2(match1)\n",
" match3 = make_match3(match2, nema)\n",
" match4 = make_match4(match3, angle)\n",
" match5 = make_match5(match4, net, inter_node, inter_info)\n",
" match6 = make_match6(match5, inter_node, uturn, coord)\n",
" matching = make_matching(match6, inter_node, nema)\n",
" movements = make_movements()\n",
" node2num_cycles = get_node2num_cycles(plan, inter_node)\n",
" return match6, matching, movements, node2num_cycles"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 0/17280 [00:00<?, ?it/s]"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 17280/17280 [00:14<00:00, 1204.50it/s]\n",
"100%|██████████| 17280/17280 [00:17<00:00, 1004.57it/s]\n"
]
}
],
"source": [
"match6, matching, movements, node2num_cycles = preprocess_daily()"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['Unnamed: 0', 'inter_no', 'angle_A1', 'angle_A2', 'angle_A3', 'angle_A4', 'angle_A5', 'angle_A6', 'angle_A7', 'angle_A8', 'angle_B1', 'angle_B2', 'angle_B3', 'angle_B4', 'angle_B5', 'angle_B6', 'angle_B7', 'angle_B8']\n",
"['Unnamed: 0', 'inter_no', 'start_hour', 'start_minute', 'dura_A1', 'dura_A2', 'dura_A3', 'dura_A4', 'dura_A5', 'dura_A6', 'dura_A7', 'dura_A8', 'dura_B1', 'dura_B2', 'dura_B3', 'dura_B4', 'dura_B5', 'dura_B6', 'dura_B7', 'dura_B8', 'cycle', 'offset']\n",
"['Unnamed: 0', 'inter_no', 'node_id', 'inter_type']\n",
"['parent_id', 'child_id', 'direction', 'condition', 'inc_edge', 'out_edge']\n",
"['Unnamed: 0', 'inter_no', 'end_unix', 'dura_A1', 'dura_A2', 'dura_A3', 'dura_A4', 'dura_A5', 'dura_A6', 'dura_A7', 'dura_A8', 'dura_B1', 'dura_B2', 'dura_B3', 'dura_B4', 'dura_B5', 'dura_B6', 'dura_B7', 'dura_B8', 'cycle', 'offset']\n",
"['Unnamed: 0', 'inter_no', 'inter_name', 'inter_lat', 'inter_lon', 'group_no', 'main_phase_no']\n",
"['parent_id', 'child_id', 'phase_no', 'ring_type', 'inc_edge', 'out_edge']\n"
]
}
],
"source": [
"import os\n",
"import pandas as pd\n",
"table_path = '../Data/tables/'\n",
"cols = []\n",
"for name in set(os.listdir(table_path)) - set(['move', 'nema.csv', 'raw_tables']):\n",
" df = pd.read_csv(table_path + name)\n",
" print(list(df.columns))\n",
"# cols.extend(list(df.columns))\n",
"# for col in sorted(set(cols)):\n",
"# print(col)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'inter_no': 'int',\n",
" 'start_hour': 'int',\n",
" 'start_minute': 'int',\n",
" 'cycle': 'int',\n",
" 'offset': 'int',\n",
" 'node_id': 'str',\n",
" 'inter_type': 'str',\n",
" 'parent_id': 'str',\n",
" 'child_id': 'str',\n",
" 'direction': 'str',\n",
" 'condition': 'str',\n",
" 'inc_edge': 'str',\n",
" 'out_edge': 'str',\n",
" 'end_unix': 'int',\n",
" 'inter_name': 'str',\n",
" 'inter_lat': 'float',\n",
" 'inter_lon': 'float',\n",
" 'group_no': 'int',\n",
" 'main_phase_no': 'int',\n",
" 'phase_no': 'int',\n",
" 'ring_type': 'str',\n",
" 'angle_A1': 'str',\n",
" 'dura_A1': 'int',\n",
" 'angle_A2': 'str',\n",
" 'dura_A2': 'int',\n",
" 'angle_A3': 'str',\n",
" 'dura_A3': 'int',\n",
" 'angle_A4': 'str',\n",
" 'dura_A4': 'int',\n",
" 'angle_A5': 'str',\n",
" 'dura_A5': 'int',\n",
" 'angle_A6': 'str',\n",
" 'dura_A6': 'int',\n",
" 'angle_A7': 'str',\n",
" 'dura_A7': 'int',\n",
" 'angle_A8': 'str',\n",
" 'dura_A8': 'int',\n",
" 'angle_B1': 'str',\n",
" 'dura_B1': 'int',\n",
" 'angle_B2': 'str',\n",
" 'dura_B2': 'int',\n",
" 'angle_B3': 'str',\n",
" 'dura_B3': 'int',\n",
" 'angle_B4': 'str',\n",
" 'dura_B4': 'int',\n",
" 'angle_B5': 'str',\n",
" 'dura_B5': 'int',\n",
" 'angle_B6': 'str',\n",
" 'dura_B6': 'int',\n",
" 'angle_B7': 'str',\n",
" 'dura_B7': 'int',\n",
" 'angle_B8': 'str',\n",
" 'dura_B8': 'int'}"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dtype_loading = {\n",
" 'inter_no':'int', 'start_hour':'int', 'start_minute':'int', 'cycle':'int','offset':'int',\n",
" 'node_id':'str', 'inter_type':'str', 'parent_id':'str','child_id':'str',\n",
" 'direction':'str', 'condition':'str', 'inc_edge':'str', 'out_edge':'str',\n",
" 'end_unix':'int', 'inter_name':'str', 'inter_lat':'float', 'inter_lon':'float',\n",
" 'group_no':'int', 'main_phase_no':'int', 'phase_no':'int','ring_type':'str'\n",
" }\n",
"for alph in ['A', 'B']:\n",
" for j in range(1,9):\n",
" dtype_loading[f'angle_{alph}{j}'] = 'str'\n",
" dtype_loading[f'dura_{alph}{j}'] = 'int'\n",
"dtype_loading"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[176, 202]"
]
},
"execution_count": 71,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plan = pd.read_csv('../data/tables/plan.csv')\n",
"durations = plan[[f'dura_{alph}{j}' for alph in ['A','B'] for j in range(1, 9)]]\n",
"valid_indices = ((durations >= 0) & (durations <= 100)).all(axis=1)\n",
"sorted(plan[~valid_indices].inter_no.unique())\n",
"# durations"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "rts",
"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.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 2
}