학부공부/데이터마이닝과통계

특정 버스의 버스경로에서 특정 정류장 위치 뽑기.

IT grow. 2018. 12. 18. 14:56
반응형

API를 사용하여서 , 실시간 버스의 위치를 뽑아오는것 까지는 해보았다.


그런데 , 버스가 아니라 , 정류장의 위치를 뽑아 낼 수도 있을까..?


그래서 해보았다.


코드를 통해서 확인해 보자.


일단 , 지도로 위치를 markup해줄것이기 때문에 , 특정 라이브러리를 로딩시켜줘야 한다.

library(XML)

library(ggmap)


여기서 url을 보게 되면 공공데이터 포털 사이트에서 인증 받은 API 키가 포함되어 있다.

공공데이터 포털사이트 가서 자신의 API Key를 받아주자.


그리고 , 뒤에 보게 되면 strSrch = 146 은 146번의 버스를 의미한다.


url <- paste("http://ws.bus.go.kr/api/rest/busRouteInfo/getBusRouteList?serviceKey="특정API Key값"&strSrch=146")



지정 해준 , url을 xml로써 parse 시켜준다.

xmefile <- xmlParse(url)




parse 시켜준 값들의 Root값을 확인해 본다 . 

xmlRoot(xmefile)


xmlRoot 결과값 

<ServiceResult>

  <comMsgHeader/>

  <msgHeader>

    <headerCd>0</headerCd>

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

    <itemCount>0</itemCount>

  </msgHeader>

  <msgBody>

    <itemList>

      <busRouteId>100100025</busRouteId>

      <busRouteNm>146</busRouteNm>

      <corpNm>삼화상운  02-936-6000</corpNm>

      <edStationNm>강남역</edStationNm>

      <firstBusTm>20181218040500</firstBusTm>

      <firstLowTm>              </firstLowTm>

      <lastBusTm>20181218230000</lastBusTm>

      <lastBusYn> </lastBusYn>

      <lastLowTm>20150717230400</lastLowTm>

      <length>57.2</length>

      <routeType>3</routeType>

      <stStationNm>상계주공7단지</stStationNm>

      <term>10</term>

    </itemList>

146번의 버스만 가져와 보았다.

xmlRoot를 해보면 알겠지만 , 146이라는 숫자가 포함된 버스도 같이 뽑혀오는것을 알 수 있기 때문이다.


이제 우리는 필요한 값만 추출할 필요가 있다.

그러기 위해서는 값에 접근해야 한다.

위에서 보시다 싶이 , itemList라는 맨 상위 노드내에 값들이 존재하는 것을 알 수 있다.

우리는 다음처럼 접근할 생각을 할 수 있다.

df <- xmlToDataFrame(getNodeSet(xmefile,"//itemList"))


접근한 Node를 data프레임으로 변환시켜 주었는데 

다음을 통해 결과값을 확인해 본다 .


head(df)


다음은 결과값이다 . 위에서 말한 것처럼 146뿐만 아니라 , 8146번 버스도 같이 포함되서 출력된다.

우리는 다음과 같은 결과값을 통해서 , 버스 노선과 버스 시간대 , 텀 , 등 정보를 확인할 수 있게 된다 .

  busRouteId busRouteNm                corpNm edStationNm     firstBusTm     firstLowTm      lastBusTm lastBusYn

1  100100025        146 삼화상운  02-936-6000      강남역 20181218040500                20181218230000          

2  241001340   8146고양                  경기  동아방송대 20181218062000                20181218215000          

       lastLowTm length routeType   stStationNm term

1 20150717230400   57.2         3 상계주공7단지   10

2                     0         8    남부터미널   10



이제 우리는 146번의 버스만 뽑아 볼 것이다.

Reference에서도 확인 가능하듯 , busRouteNm 은 버스 번호를 의미한다.

이 때 , subset 함수를 사용한다.

df_busRoute <- subset(df, busRouteNm==146)


우리는 위에서 146번의 버스정보만 뽑아 보았다.

이제 우리는 이 버스번호를 통해서 , 버스정류장의 위도와 경도를 추출해 볼 것이다.

그러기 위해서는 하나의 API 정보가 더 필요하다 . 


"노선정보조회 서비스" 도 API Key를 받아주자 .


busRouteid를 확인해 준다.

df_busRoute$busRouteId



url2 <-"http://ws.bus.go.kr/api/rest/buspos/getBusPosByRtid?serviceKey="API Key 값"&busRouteId=100100025"


146번의 버스 실시간 정보의 위치를 위처럼 가져오면 된다 .

그런데 , 우리는 버스의 실시간 정보가 아닌 . 146번이 지나는 버스 정류장의 특정 버스 정류장의 위치를 뽑고 싶은것이다.


그래서 다음처럼 확인작업을 할 수 있었다.




나는 도봉면허시험장과 상계주공1단지 중계역의 위치를 뽑아 오고 싶었다.

그래서 3개의 위치에 해당하는 버스정류장의 gpsx , gpsy를 추출해 본 것이다.


이값을 gpsX , gpsY 값에 각각 벡터로써 저장시켜준다.



xmefile <- xmlParse(url2)


xmlRoot(xmefile)


df <- xmlToDataFrame(getNodeSet(xmefile,"//itemList"))


df


gpsX <- as.numeric(as.character(df$gpsX))


gpsY <- as.numeric(as.character(df$gpsY))

위의 코드는 처음 해 보았던 코드들인데 , 여기서 주의깊게 보아야 할 곳은

gpsX , gpsY부분이다.


나는 itemList 하단에 있는 모든 값들을 가져왔다.

왜냐하면 , 146 버스가 지나는 버스정류장의 위도와 경도를 다 포함하고 있는줄 알았다.


그것이 아니고 , 146번 버스의 실시간 위치정보였다.


그래서 아까 구해준 위도와 경도 값들을 각각 gpsX , gpsY에 1~3까지 넣어주었다.

gpsX <-NULL

gpsY <-NULL


gpsX[1] <- 127.0595

gpsY[1] <- 37.6573


gpsX[2] <- 127.0628

gpsY[2] <- 37.6471


gpsX[3] <- 127.0644

gpsY[3] <- 37.6438


위 처럼 하고 , 우리는 이 3개의 위도와 경도의 값을 하나의 dataframe으로 만들어 준다. 


gc <-data.frame(lon=gpsX, lat=gpsY)


위도와 경도의 각각의 평균값들 하나의 변수에 저장시켜준다.

cen <- c(mean(gc$lon), mean(gc$lat))



key <- "API Key의 특정 값"


map <- get_googlemap(center = cen , maptype = "roadmap" , zoom=15 , markers = gc , key = key)



ggmap(map)


결과값은 다음과 같다 . 



반응형