{ "cells": [ { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "import os, sumolib\n", "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from matplotlib_venn import venn2, venn3\n", "from datetime import datetime" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "class DailyPreprocessor:\n", " def __init__(self, config_name='revised', nowTime=datetime.now()):\n", " self.config_name = config_name\n", " self.nowTime = nowTime\n", "self = DailyPreprocessor(nowTime = datetime.now())" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "self.net = sumolib.net.readNet('new_sungnam_network_internal_target_0811.net.xml')" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "# ## 교차로목록 정의\n", "# sixties = pd.read_excel('교차로기반정보_(시범지역).xlsx', header=1)\n", "# self.inter_nos = set(sixties['교차로 ID'].dropna().astype(int))\n", "# # 551, 561은 TC_IF_TOD_RED_YELLO, TN_IF_SIGL_FLOW에 존재하지 않음. TOD 보고서에서도 확인할 수 없음\n", "# # 551 : 보육시설 삼거리, 561 : 공영주차장 단일로\n", "\n", "\n", "# self.inter_nos = self.inter_nos - {551, 561}\n", "# # 464는 매칭테이블에 존재하지 않음. 500에 매칭되는 node_id가 네트워크에 존재하지 않음.\n", "# # 464 : 성남공판장 단일로, 500 : 단남아파트 단일로\n", "# self.inter_nos = self.inter_nos - {464, 500}\n", "# print(len(self.inter_nos))\n", "# inter_nos_display = \", \".join(map(str, sorted(self.inter_nos)))\n", "# inter_nos_display = \"\\n\".join([inter_nos_display[i:i+100] for i in range(0, len(inter_nos_display), 100)])\n", "# # print(len(inter_nos_display))\n", "# print(inter_nos_display)" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [], "source": [ "## 매칭테이블 정의, 교차로-노드 딕셔너리 정의\n", "self.inter_node = pd.read_excel('signal_node_matching.xlsx', dtype={'node_id':str})\n", "self.inter_node = self.inter_node.rename(columns={'signal_id':'inter_no'})\n", "self.inter_node['inter_type'] = 'parent'\n", "self.inter_node = self.inter_node[self.inter_node.node_id.isin(node.getID() for node in self.net.getNodes())]" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "## 매칭테이블 정의, 교차로-노드 딕셔너리 정의\n", "self.inter_node = pd.read_excel('signal_node_matching.xlsx', dtype={'node_id':str})\n", "self.inter_node = self.inter_node.rename(columns={'signal_id':'inter_no'})\n", "self.inter_node['inter_type'] = 'parent'\n", "# self.inter_node = self.inter_node[self.inter_node.inter_no.isin(self.inter_nos)].reset_index(drop=True)\n", "self.inter_nos = sorted(self.inter_node.inter_no)\n", "\n", "# 일대일대응 확인\n", "if not len(self.inter_node) == self.inter_node.inter_no.nunique() == self.inter_node.node_id.nunique():\n", " raise ValueError(\"Warning: 'inter_no'와 'node_id' 간에 일대일대응 관계가 성립하지 않습니다.\")\n", "\n", "# 교차로번호 vs 노드id 간 딕셔너리\n", "self.inter2node = dict(zip(self.inter_node.inter_no, self.inter_node.node_id))\n", "self.node2inter = dict(zip(self.inter_node.node_id, self.inter_node.inter_no))\n", "self.node_ids = {self.inter2node[inter_no] for inter_no in self.inter_nos}" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "# net = sumolib.net.readNet('new_sungnam_network_internal_0809.net.xml')\n", "# inter_node = pd.read_excel('signal_node_matching.xlsx', dtype={'node_id':str})\n", "# print(len(set(inter_node.signal_id)))\n", "# print(inter_nos - set(inter_node.signal_id))\n", "# inter_node = inter_node[inter_node.node_id.isin(node.getID() for node in net.getNodes())]\n", "# print(len(set(inter_node.signal_id)))\n", "# print(inter_nos - set(inter_node.signal_id))" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "## 테이블 표준화\n", "\n", "# 주요 테이블 로드 (실제로는 쿼리문 작성 부분이 되어야 함.)\n", "self.dayplan = pd.read_csv(os.path.join(os.path.abspath('.'), 'sn_admin_tables', 'TC_IF_TOD_DAY_PLAN.csv'))\n", "self.holyplan = pd.read_csv(os.path.join(os.path.abspath('.'), 'sn_admin_tables', 'TC_IF_TOD_HOLIDAY_PLAN.csv'))\n", "self.red_yel = pd.read_csv(os.path.join(os.path.abspath('.'), 'sn_admin_tables', 'TC_IF_TOD_RED_YELLO.csv'))\n", "self.weekplan = pd.read_csv(os.path.join(os.path.abspath('.'), 'sn_admin_tables', 'TC_IF_TOD_WEEK_PLAN.csv'))\n", "# 교차로정보 테이블은 불러오지 않음 (해당 테이블이 실질적으로 쓰이지는 않고, 60개 테이블 정보가 있지도 않음)\n", "# inter_info=pd.read_csv(os.path.join(os.path.abspath('.'), 'sn_admin_tables', 'TM_FA_CRSRD.csv'))\n", "self.flows = pd.read_csv(os.path.join(os.path.abspath('.'), 'sn_admin_tables', 'TN_IF_SIGL_FLOW.csv'))\n", "\n", "# 유효한 교차로들에 대하여만 슬라이싱\n", "self.dayplan = self.dayplan[self.dayplan.CRSRD_ID.isin(self.inter_nos)]\n", "self.weekplan= self.weekplan[self.weekplan.CRSRD_ID.isin(self.inter_nos)]\n", "self.red_yel = self.red_yel[self.red_yel.CRSRD_ID.isin(self.inter_nos)]\n", "self.flows = self.flows[self.flows.CRSRD_ID.isin(self.inter_nos)]\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 ['A', 'B'] for i in range(1,9)}\n", "rename_cname = {**rename_cname_1, **rename_cname_2}\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)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "## self.plan : 신호계획 테이블 생성\n", "\n", "# 날짜, 요일 지정\n", "MM, DD = self.nowTime.month, self.nowTime.day # 날짜\n", "dow_number = self.nowTime.weekday() # 요일\n", "hplan = self.holyplan[(self.holyplan.MM==MM) & (self.holyplan.DD==DD)]\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]))\n", "\n", "# 신호테이블 통합\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": 22, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " | inter_no | \n", "phase_no | \n", "ring_type | \n", "move_no | \n", "STOS_NO | \n", "angle_code | \n", "
---|---|---|---|---|---|---|
0 | \n", "436 | \n", "1 | \n", "A | \n", "5 | \n", "0 | \n", "262358 | \n", "
1 | \n", "436 | \n", "1 | \n", "B | \n", "2 | \n", "0 | \n", "262074 | \n", "
2 | \n", "436 | \n", "2 | \n", "A | \n", "8 | \n", "0 | \n", "174355 | \n", "
3 | \n", "436 | \n", "2 | \n", "B | \n", "3 | \n", "0 | \n", "172263 | \n", "
4 | \n", "436 | \n", "3 | \n", "A | \n", "7 | \n", "0 | \n", "356074 | \n", "
... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "
354 | \n", "639 | \n", "4 | \n", "A | \n", "6 | \n", "0 | \n", "120312 | \n", "
355 | \n", "639 | \n", "4 | \n", "B | \n", "1 | \n", "0 | \n", "126221 | \n", "
356 | \n", "640 | \n", "1 | \n", "A | \n", "8 | \n", "0 | \n", "226052 | \n", "
357 | \n", "640 | \n", "1 | \n", "B | \n", "4 | \n", "0 | \n", "043222 | \n", "
358 | \n", "640 | \n", "2 | \n", "A | \n", "17 | \n", "0 | \n", "None | \n", "
359 rows × 6 columns
\n", "\n", " | inter_no | \n", "phase_no | \n", "ring_type | \n", "move_no | \n", "
---|---|---|---|---|
0 | \n", "436 | \n", "1 | \n", "A | \n", "5 | \n", "
1 | \n", "436 | \n", "1 | \n", "B | \n", "2 | \n", "
2 | \n", "436 | \n", "2 | \n", "A | \n", "8 | \n", "
3 | \n", "436 | \n", "2 | \n", "B | \n", "3 | \n", "
4 | \n", "436 | \n", "3 | \n", "A | \n", "7 | \n", "
... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "
367 | \n", "576 | \n", "2 | \n", "B | \n", "17 | \n", "
368 | \n", "582 | \n", "2 | \n", "B | \n", "17 | \n", "
369 | \n", "632 | \n", "2 | \n", "B | \n", "17 | \n", "
370 | \n", "634 | \n", "4 | \n", "B | \n", "5 | \n", "
371 | \n", "640 | \n", "2 | \n", "B | \n", "17 | \n", "
372 rows × 4 columns
\n", "\n", " | inter_no | \n", "phase_no | \n", "ring_type | \n", "move_no | \n", "
---|---|---|---|---|
0 | \n", "436 | \n", "1 | \n", "A | \n", "5 | \n", "
1 | \n", "436 | \n", "1 | \n", "B | \n", "2 | \n", "
2 | \n", "436 | \n", "2 | \n", "A | \n", "8 | \n", "
3 | \n", "436 | \n", "2 | \n", "B | \n", "3 | \n", "
4 | \n", "436 | \n", "3 | \n", "A | \n", "7 | \n", "
... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "
367 | \n", "576 | \n", "2 | \n", "B | \n", "17 | \n", "
368 | \n", "582 | \n", "2 | \n", "B | \n", "17 | \n", "
369 | \n", "632 | \n", "2 | \n", "B | \n", "17 | \n", "
370 | \n", "634 | \n", "4 | \n", "B | \n", "5 | \n", "
371 | \n", "640 | \n", "2 | \n", "B | \n", "17 | \n", "
372 rows × 4 columns
\n", "\n", " | child_id | \n", "condition | \n", "
---|---|---|
0 | \n", "109187 | \n", "좌회전시 | \n", "
1 | \n", "109188 | \n", "좌회전시 | \n", "
2 | \n", "109189 | \n", "좌회전시 | \n", "
3 | \n", "109192 | \n", "좌회전시 | \n", "
4 | \n", "109193 | \n", "좌회전시 | \n", "
5 | \n", "109595 | \n", "좌회전시 | \n", "
6 | \n", "107169 | \n", "좌회전시 | \n", "
7 | \n", "108093 | \n", "좌회전시 | \n", "
8 | \n", "108098 | \n", "좌회전시 | \n", "
9 | \n", "108102 | \n", "좌회전시 | \n", "
10 | \n", "108099 | \n", "좌회전시 | \n", "
11 | \n", "108106 | \n", "좌회전시 | \n", "
12 | \n", "107717 | \n", "좌회전시 | \n", "
13 | \n", "110754 | \n", "좌회전시 | \n", "
14 | \n", "109205 | \n", "좌회전시 | \n", "
15 | \n", "107270 | \n", "좌회전시 | \n", "