상세 컨텐츠

본문 제목

공공데이터 API - 대전광역시 버스정보 1부 (노선정보조회 서비스)

programing/API

by ZelKun 2017. 7. 24. 13:00

본문

반응형

대전광역시 버스정보 API 이용해서 평소 타고다니는

/퇴근 버스 도착시간 평균을 구해보자 라는 취지로 API 이용해보기로했다

 

대전버스라는 어플이 있지만 언제쯤 도착(실시간)한다는거지

시간대별( 단위) 평균 버스도착시간을 알려주질 않으니

 

평균 도착시간을 이용해서 다음건 언제 오겠구나

지금 타야하는구나(택시타야 되나?) 이런걸 알고 싶었다

늦장 대마왕이라...

 

한마디로 지극히 개인적인 이유로 API 이용한다는 소리


  • 같이보면 좋을듯
  1. 교통체증
  2. 교통사고
  3. 날씨

근데 교통체증도 제공해주는진 모르겠고...

교통정보 공개서비스(http://openapi.its.go.kr), 공간정보 오픈플랫폼(http://dev.vworld.kr)에서 제공하는듯..

자세한건 안봐서...

좀더 확인해보긴 해야겠지만 네비게이션 서비스의 API가 이런게 다 되 있을 확률이 높다

(실시간 교통정보를 이용해 안내를 해주니)

그런의미로 SK플래닛의 T-MAP (https://developers.skplanetx.com/apidoc/kor/t-map/traffic-report/)도 API를 제공하는듯 하다

교통사고정보 개방시스템(http://taas.koroad.or.kr/)

교통체증과 교통사고 데이터를 받아와서 도착시간을 같이 보는것도 나쁘지 않을듯, 근데 험난할듯.. 버스노선 GIS로 받아와서 노선의 정체구간이랑... 생각만 해도 머리아픔

날씨야 뭐 기상청API쓰면됨

 

이러한 외부정보를 이용하는건 예측불가능한 상황이 발생할 수 있기때문인데

월~금을 기준으로 특정요일에 차가 막히는경우, 날씨가 안좋아서 서행하는경우

해당구간에 교통사고가 발생한경우, 버스가 엔진이 꺼진경우 등등의 상황이 있기때문에

무시할 수 없기 때문이다

 

노선만해도 버스정류장이 정해져있기 때문에  특히나 탑승정류장의 도착시간만 계산한다고 했을때

쉬워보이지만 쉽지가 않다

105번 버스를 놓고 보면 비래동에서 어은동까지 지나치는 동이 다양하고

날씨, 교통체증, 교통사고등의 다양한 정보를 모아봐야

그 시점에 왜 버스가 늦게 도착했는지에 대해 알 수 있다

교통사고가 발생해서 10분 늦게 도착했을때, 혹은 공휴일 교통체증이라는 변수를 캐치할 수 없어

단순 평균 계산 시 전혀 의외의 시간이 나오기 때문이다

 

이러한 외부데이터를 연계하기 위해선 버스 노선에 대한 주소와 날씨정보, 공휴일 등를 복합적으로 사용해야

신뢰도가 높아지고, 당연하게도 신뢰성을 높이기위해선 데이터양이 많아야 된다

이런걸 빅데이터 분석이라고 부른다...

 

데이터 연계를 위해선 지번주소, 법정동, 행정동 등의 위치기반 데이터를 구축하고

교통체증 구간과, 사고구간, 날씨, 대한민국 공휴일 등의 변수를 대입해야한다

 

그리고 정류장에서 제공하는 도착예상시간이 단지 거리만 계산해서 나온건지

교통 체증, 날씨 등의 외부적인 요소를 포함된건지를 알 수 있기 때문이다

 

단순하게 시작했는데 전혀 단순하지가 않아서

일단 처음 의도한 대로 심플하게 구성하기로 했다(요일... 공휴일 따위...)

이것저것 섞는건 하나라도 제대로 하고, 연계방향을 세우고 한다음에 해도 늦지않으니...


이것저것 합치면 논문지 투고해도 될듯...

 


출처: https://www.data.go.kr/dataset/3034842/openapi.do

 

대전광역시 버스정보 API 6종류를 제공함 (망할 XML 지원...)

근데 보이는 순서랑 서비스명(국문)  API 문서랑 다름, 영문명으로 구분해야함..

  • 버스위치정보 조회 서비스 / busposinfo
  • 정류소정보조회 서비스 / stationinfo
  • 정류소별 도착정보 조회 서비스 / arrive
  • 차량등록정보 조회 서비스 / busreginfo
  • 운수회사 정보 조회 서비스 / buscompinfo
  • 노선정보조회 서비스 / busRouteInfo

 

상세정보를 누르면 EndPoint 라던지 대략적인 정보를 제공하니 확인은 직접..

참고한 API문서는

 

  • 전체 서비스 목록

No

서비스명(국문)

서비스명(영문)

1

버스운행정보 조회 서비스

busRouteInfo

2

버스정류장정보 조회 서비스

stationinfo

3

버스위치정보 조회 서비스

busposinfo

4

정류장 버스도착 정보 조회 서비스

arrive

5

버스 차량 등록 정보 조회 서비스

busreginfo

6

운수회사 등록 정보 조회 서비스

buscompinfo

 

편의상 API문서기준으로 진행...

EndPoint 서비스명(영문) 서비스별 상세 기능으로 구분됨

 

차량등록정보, 운수회사는 조회할 일이 거의 없을것 같으니

4개의 서비스를 이용해보기로 했다

그래도 하는김에 전부 보지뭐

 

서비스 이용에 있어 사용되는 필수 Key 값은 4개로 보임

당연한 이야기지만 인증키인 serviceKey 없으면 API 사용못함..

 

  • 요청 Key 목록
  • 노선ID, 정류소ID(5,7자리) 문서에서 제공안하니 응답코드에서 찾아야함

No

항목명(영문)

항목명(국문)

항목크기

항목설명

1

reqPage

요청페이지

3

요청페이지

2

busRouteId

노선ID

8

노선의고유식별자

3

BusStopID

정류소ID(7자리)

7

정류소ID(7자리)

4

aroId arsId

정류소ID(5자리)

5

정류소ID(5자리)

 

  • 공통 응답
  • 나머지 응답은 기능별로 상이 하나, 서비스별로 비슷비슷함 자세한건 아래에서

No

항목명(영문)

항목명(국문)

항목크기

항목설명

1

headerCd

결과코드

2

결과코드

2

headerMsg

결과메세지

50

결과메세지

3

msgBody

결과리스트

4

결과리스트

4

currentPage

요청된 페이지

3

요청된 페이지

5

itemCnt

결과값 총 수

6

결과값 총 수

6

itemPageCnt

결과 페이지 수

5

결과 페이지 수

 

출처: https://www.data.go.kr/


인증키를 받고 개발계정 상세페이지를 보면 응답 XML 확인해볼수 있다

참고로 하단의 미리보기는 xml 브라우져에서 볼수 있고

나머진 파일로 다운받는다


근데 XML 지원하니 눌러볼 필요가없다(API 명세에도 XML 지원만써있다)

포탈공통 프레임이라 버튼이 있는듯 하다 기능이 없으면 안보이게 해주지

json 지원하는줄 알고 잠시 설례였음...

 

  • 개발가이드를 눌러보면 샘플코드를 지원한다

 

출처: https://www.data.go.kr/


실행해보면 아래처럼 샘플로 데이터를 볼수 있다

출처: http://openapitraffic.daejeon.go.kr


XML이니 트리(tree)구조로

  • ServiceResult 시작한다
  • comMsgHeadr 뭐가 나오는지 아직 못봤다, 모르고 싶다
  • msgHeader 부분이 공통이고
  • msgBody 부분이 서비스별 응답이 들어간다

 

XML 파싱은 JSOP(JAVA 기준) 쓰면 된다

 

  1. 버스운행정보 조회 서비스 / busRouteInfo
  • 필수키로 reqPage 받는건 전체 데이터를 제공하니 필수로 실행해봐야함

No

오퍼레이션명(영문)

오퍼레이션명(국문)

필수 key

1

getStaionByRoute

노선별 경유 정류소 목록 조회

busRouteId

2

getStaionByRouteAll

전체 노선별 경유 정류소 목록 조회

reqPage

3

getRouteInfo

노선정보 상세 조회

busRouteId

4

getRouteInfoAll

전체 노선별 노선정보 조회

reqPage

 

  • 노선별 경우 정류소 응답명세(1,2 공통)

No

항목명(영문)

항목명(국문)

항목크기

항목설명

1

BUSSTOP_ENG_NM

정류소영문명

50

정류소영문명

2

BUSSTOP_NM

정류소명

50

정류소명

3

BUSSTOP_SEQ

경유정류소순번

3

경유정류소순번

4

BUSSTOP_TP

정류소타입

1

정류장 유형(1:기점 2: 종점 3: 일반)

5

BUS_NODE_ID

정류소ID

7

정류소ID

6

BUS_STOP_ID

정류소ARS-ID

5~6

정류소ARS-ID 대전(5), 광역(6)

7

GPS_LATI

정류소 위도좌표

15

정류소 위도좌표

8

GPS_LONG

정류소 경도좌표

15

정류소 경도좌표

9

ROAD_NM

도로명

50

도로명

10

ROAD_NM_ADDR

도로주소

200

도로주소

11

ROUTE_CD

노선ID

8

노선ID

12

TOTAL_DIST

누적거리

8

누적거리

 

전체 정류소 정보를 알아야 하니 실행해봤다 그것도 reqPage=0 으로

http://openapitraffic.daejeon.go.kr/api/rest/busRouteInfo/getStaionByRouteAll?ServiceKey=서비스키&reqPage=0

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<ServiceResult>

<comMsgHeader/>

<msgHeader>

<currentPage>0</currentPage>

<headerCd>0</headerCd>

<headerMsg>정상적으로 처리되었습니다.</headerMsg>

<itemCnt>9480</itemCnt>

<itemPageCnt>95</itemPageCnt>

</msgHeader>

<msgBody/>

</ServiceResult>

결과는 예상을 뛰어넘었다... 에러따윈 없다

itemPageCnt 95개로 나오는데.. msgBody 내용이 없다

1-95페이지까지 있다는 소린가보다

혹시몰라 96 시도해보니 0페이지랑 같다

 

  • 노선정보 응답명세 (3,4 공통)

No

항목명(영문)

항목명(국문)

항목크기

항목설명

1

ALLO_INTERVAL

배차간격

3

배차간격

2

ALLO_INTERVAL_SAT

휴일배차간격

4

휴일배차간격

3

ALLO_INTERVAL_SUN

공휴일배차간격

4

공휴일배차간격

4

BUSSTOP_CNT

정류장개수

3

정류장개수

5

END_NODE_ID

종점정류소ID(7자리)

7

종점정류소ID(7자리)

6

END_STOP_ID

종점정류소ID(5자리)

5

종점정류소ID(5자리)

7

ORIGIN_END

평일 기점 막차시간

4

평일 기점 막차시간

8

ORIGIN_END_SAT

토요일 기점 막차시간

4

토요일 기점 막차시간

9

ORIGIN_END_SUN

일요일 종점 막차시간

4

일요일 종점 막차시간

10

ORIGIN_START

평일 기점 첫차시간

4

평일 기점 첫차시간

11

ORIGIN_START_SAT

토요일 기점 첫차시간

4

토요일 기점 첫차시간

12

ORIGIN_START_SUN

일요일 기점 첫차시간

4

일요일 기점 첫차시간

13

ROUTE_CD

노선ID

8

노선ID

14

ROUTE_NO

노선명칭

10

노선명칭

15

ROUTE_TP

노선유형

1

노선타입

(1:급행, 2:간선,3:지선,

4:외곽, 5:마을, 6:첨단)

16

RUN_DIST_HALF

반환지점  거리(KM)

20

반환지점  거리(KM)

17

RUN_TM

평균 운행시간

4

평균 운행시간

18

START_NODE_ID

기점정류소ID(7자리)

7

기점정류소ID(7자리)

19

START_STOP_ID

기점정류소ID(5자리)

5

기점정류소ID(5자리)

20

TURN_END

평일 반환지점 막차시간

4

평일 반환지점

막차시간

21

TURN_END_SAT

토요일 반환지점 막차시간

4

토요일 반환지점

막차시간

22

TURN_END_SUN

일요일 반환지점 막차시간

4

일요일 반환지점

막차시간

23

TURN_NODE_ID

반환정류소ID(7자리)

7

반환정류소ID(7자리)

24

TURN_START

평일 반환지점 첫차시간

4

평일 반환지점

첫차시간

25

TURN_START_SAT

토요일 반환지점 첫차시간

4

토요일 반환지점

첫차시간

26

TURN_START_SUN

일요일 반환지점 첫차시간

4

일요일 반환지점

첫차시간

27

TURN_STOP_ID

반환정류소ID(5자리)

5

반환정류소ID(5자리)

27개나 된다 많다

휴일과 공휴일의 차이가 뭘까 고민했는데 의미 없는 짓이었다

SAT, SUN 으로 끝나는데 설마설마 했는데

역시나 아래에는 토요일, 일요일이라고 명시해놨다, 통일좀 하지

 

노선은 몇개나 될까

역시나 reqPage=0 으로 시도해봤다

http://openapitraffic.daejeon.go.kr/api/rest/busRouteInfo/getStaionByRouteAll?ServiceKey=서비스키&reqPage=0

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<ServiceResult>

<comMsgHeader/>

<msgHeader>

<currentPage>0</currentPage>

<headerCd>0</headerCd>

<headerMsg>정상적으로 처리되었습니다.</headerMsg>

<itemCnt>122</itemCnt>

<itemPageCnt>2</itemPageCnt>

</msgHeader>

<msgBody/>

</ServiceResult>

122개의 노선을 가지고 있나보다 page 2개로 보인다

참고로 결과값을 보면 전부 숫자로 되어있는데 공백이 여기저기 포함되있다

trim으로 제거해줘야 정신건강에 좋다 아니면 전부 문자처리해도 될듯

 

  • 전체 노선별 경유 정류소 목록 조회

우선 전체 노선별 경유 정류소목록조회를 시도하였다

정류소 ID 노선을 알아야 만들던가 하니까 말이다

정류소 데이터는 9489건으로 95페이지나 조회해야한다

 

API명세서를 보고 대충 DB 테이블을 만들고

(귀찮으니 위경도 빼고, 전부 varchar 잡아줬다, PK설명이 없으니 PK 안줬다)

XML 파서를 만들어서 INSERT 작업을 수행하게 하였다

근데 전체건수를 맞춰보는중 멘붕아닌 멘붕에빠졌다

9240건으로 249건이나 안맞았다

대충 보니 눈에 띄는 에러는 데이터 사이즈였다..

정류소영문명 정류소ARS-ID 컬럼을 명세서대로 해놨더니 자릿수가 넘어가는게 있었나보다

2-3번의 컬럼사이즈 조정후 건수확인하니 전체건수가 맞아 떨어진다

(9240 insert문을 살펴보느니 error 메시지를 모아서 한번에 보여주도록 기능도 추가했다...)

자리수 비교를 위해 length 함수와 max 함수를 이용해서 실제 크기를 비교해봤다

No

항목명(영문)

항목명(국문)

항목크기

실제 크기(Max 기준)

1

BUSSTOP_ENG_NM

정류소영문명

50

70

2

BUSSTOP_NM

정류소명

50

41

3

BUSSTOP_SEQ

경유정류소순번

3

3

4

BUSSTOP_TP

정류소타입

1

1

5

BUS_NODE_ID

정류소ID

7

7

6

BUS_STOP_ID

정류소ARS-ID

5~6

7

7

GPS_LATI

정류소 위도좌표

15

7

8

GPS_LONG

정류소 경도좌표

15

7

9

ROAD_NM

도로명

50

24

10

ROAD_NM_ADDR

도로주소

200

9

11

ROUTE_CD

노선ID

8

8

12

TOTAL_DIST

누적거리

8

6

 

정류소 영문명, 정류소ARS-ID 두개의 크기가 달랐다

사소한건 넘어가고 PK 잡아보기로 했다

대충봐서는 노선ID, 정류소ID 두개를 잡으면 될것 같았다

근데 실패했다...

노선ID 정류소ID 합친 문자열을 중복제거하니  9340건으로 140건이나 차이난다

노선ID 보면 122건으로 전체 노선별 노선정보 조회 건수랑 일치한다

정류소 ID 만보면 3165 건이다

정류소ARS-ID NULL인게 2건이나오고, 중복제거하면 3061(null 포함) 이다

노선ID, 정류소ID, 정류소ARS-ID 세개를 묶어도 9338건이다..  142건이 차이난다..

PK잡지말까... 생각이 들었다..

 

일단 무시하고...

다음 으로 넘어가기로 했다


아.. 참고로 영문명이 없는경우 --- 가 들어있다

null로 치환했다...

 

  • 전체 노선별 노선정보 조회

전체 노선별 경유 정류소 목록 조회에서 노선ID 봤을때는 중복제거 카운트가 일치하니

안심하고 진행했다 설마...


응답 메시지 1-2개를 봤을땐 전부 숫자니

테이블도 숫자로 잡을까 하다가 varchar로 잡았다 나중에 삽질하기 싫었다..

 

역시 예상은 했지만 stop_id 로 끝나는 컬럼이 사이즈문제로 에러가났다 7로 조정해주고 다시 진행했다

(7로 조정했지만 다시확인해보니 6이었다)

노선ID가 중복이 없어서 깔끔하게 끝났다

 

참고로 전체노선별 경유 정류소 목록조회에서

정류소영문명 자릿수가 50이 넘어가는 항목은 97건이고

정류소ARS-ID 자릿수가 7인 항목은 141건이다


*PS.

설마 활용신청 자동승인인 서비스인데 무슨일이 있겠냐만은.. 

문제 있을시 알려주시면 내리겠습니다

반응형

관련글 더보기

댓글 영역