관리자 글쓰기

본 내용은 혼자서 공부하기 위한 용도로 사용된 것으로 비효율적일 수 있으며 실용적이지 않을 수 있습니다.




주변 정류소 위치를 받아오는 것까지 완료했다. 이제 정류소를 클릭 시 실시간으로 해당 정류소로 들어오는 버스 노선들을 불러와 화면에 보여줄 것이다. 실시간 버스의 경우는 미리 받아올 수 있는 것이 아니기 때문에 실시간으로 API를 받아 xml Parser를 통해 정보를 추출할 것이다.

 

1. 실시간 버스 정보 가져오기(Xml Parser)

/common/util/setting/BusStopParser.java

@Component("busStopParser")
public class BusStopParser {
    public final static String KEY = "키 값";
   
    public List<Map<String,Object>> apiParserNodeRealTime(Map<String,Object> map) throws Exception {
     String apiUrl = "http://openapi.tago.go.kr/openapi/service/ArvlInfoInqireService/getSttnAcctoArvlPrearngeInfoList";
        URL url = new URL(apiUrl+"?ServiceKey="+KEY+"&nodeId="+map.get("NODEID")+"&cityCode=37030");
 
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        factory.setNamespaceAware(true);
        XmlPullParser xpp = factory.newPullParser();
        BufferedInputStream bis = new BufferedInputStream(url.openStream());
        xpp.setInput(bis, "utf-8");
       
        String tag = null;
        int event_type = xpp.getEventType();
       
        List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
        Map<String,Object> tempMap = null;
        while (event_type != XmlPullParser.END_DOCUMENT) {
            if (event_type == XmlPullParser.START_TAG) {
                tag = xpp.getName();
                if(tag.equals("item")) {
                 tempMap=new HashMap<String,Object>();
                }
            } else if (event_type == XmlPullParser.TEXT) {
                if(tag.equals("nodeid")){
                    tempMap.put("NODEID", xpp.getText());
                }
                else if(tag.equals("routeid")){
                 tempMap.put("ROUTEID", xpp.getText());
                }
                else if(tag.equals("routeno")) {
                 tempMap.put("ROUTENO", xpp.getText());
                }
                else if(tag.equals("vehicletp")) {
                 tempMap.put("VEHICLETP", xpp.getText());
                }
                else if(tag.equals("arrprevstationcnt")) {
                 tempMap.put("ARRPREV", xpp.getText());
                }
                else if(tag.equals("arrtime")) {
                 tempMap.put("ARRTIME", xpp.getText());
                }
            } else if (event_type == XmlPullParser.END_TAG) {
                tag = xpp.getName();
                if (tag.equals("item")) {
                    list.add(tempMap);
                }
            }
 
            event_type = xpp.next();
        }
        bis.close();
        return list;
    }
}

- 전에 살펴봤던 xml parser와 비슷하다. 받아오는 정보로는 정류소ID, 노선 ID, 노선번호, 버스종류, 도착 전 정류장 갯수, 도착 시간을 받아와 list에 저장 후 리턴한다.

 

2. Controller

GCBusController.java

 @RequestMapping(value="/nodeRealTime.do")
 public @ResponseBody ModelAndView nodeRealTime(@RequestBody Map<String,Object> map) throws Exception{
  map.put("list", busStopParser.apiParserNodeRealTime(map));
  
  return new ModelAndView("jsonView", map);
 }

- 전에 살펴봤던 것 처럼 @ResponseBody, @RequestBody 형식으로 이루어져 있고 위에서 파싱한 실시간 버스 정보를 받아와 json 형식으로 변환 후 뷰단으로 리턴한다.

 

3. JSP

해당 코드를 추가한다.

node_find.jsp

function fn_clickNode(obj){
   setMarkers(null);
   //if(customOverlay!=null){
   // customOverlay.setMap(null);
   //}
   
   if($("a[name^='node']").hasClass("selected")){
    $("a[name^='node']").removeClass("selected");
    fn_clickSearchButton();
    
   }else{
    $("a[name^='node']").addClass("selected");
    
    fn_nodeRealTime(obj);
   }
  }

  function fn_nodeRealTime(obj){
   //버스 노선 페이지에서 검색된 경로의 정류장의 정보보기의 기능 활성화의 경우를 위한 변수들 초기화
   if($("#nodeidVal").val()!=null&&!($("#nodeidVal").hasClass("used"))){
    var str = "<a href='#this' nodeid='"+$("#nodeidVal").val()+"' lat='"+$("#latVal").val()+"' lng='"+$("#lngVal").val()+"' name='node1' id='node1' class='result sc_node_result'>"+$("#nodenameVal").val()+"</a>";
    $("#resultBox").append(str);
    obj=$("#node1");    $(obj).addClass("selected");
    $("#nodeidVal").addClass("used");
   }
   //지도 중심을 변경합니다.
   map.setCenter(new daum.maps.LatLng(obj.attr("lat"),obj.attr("lng")));
   //선택한 정류장의 오버레이를 활성화합니다.
   //fn_setOverlay(obj);
   var divStr="<div id='routeBox' class='result'><div id='pageDiv'></div></div>";
   obj.siblings().remove(); 
   obj.parent().append(divStr);
   //선택한 정류장의 위치에 마커를 표시한다.
   fn_nodeMarkerMaker(obj);   /*
   이 부분에서 정류장 ID를 서버로 보내주고 서버에서는 OPEN API를 통해 정류장 실시간 도착 노선 정보를 가져와 ajax로 리턴해준다.
   보내는 데이터 : nodeID
   받는 데이터 : 정류장 실시간 도착 정보
   */
   $.ajax({
    dataType:"json",
    type:"POST",
    contentType:"application/json",
    url:"/gcbus/nodeRealTime.do",
    data:JSON.stringify({NODEID:obj.attr("nodeid")}),
    success:function(result){
      for(var i=0;i<result["list"].length;i++){
       var map=result["list"][i];
       var arrtime= Math.floor(map["ARRTIME"]/60);
       var str = "<a href='#this' routeno='"+map["ROUTENO"]+"' routeid='"+map["ROUTEID"]+"' name='route"+i+"' id='route"+i+"' class='result sc_real_route_result'>"+map["ROUTENO"]
       +"("+map["VEHICLETP"]+")<p>"+map["ARRPREV"]+"정류장 전("+arrtime+"분)</p></a>";       $("#routeBox").append(str);
      }      $("#routeBox").css("height", 52*result["list"].length);
      $("#routeBox").append("<a href='#this' id='busList_Btn' class='btn' >모든 버스 노선 보기</a>");
      $("a[name^=route]").on("click",function(e){
       e.preventDefault();
       //fn_routeInfo($(this));
      });      
      
      $("#busList_Btn").on("click",function(e){
       e.preventDefault();
       //fn_nodeToRoute(obj);
      });
      },
    error:function(){
     alert("error");
    }
   })
      
  }

- fn_clickNode() 함수의 경우 자바스크립트로 해당 Div가 가진 클래스를 확인하여 정류소를 처음 클릭하면 실시간 버스 정보가 출력되지만 다시 클릭할 시 다시 정류소 리스트 화면으로 돌아 가기 위한 함수이다. 다음 fn_nodeReadlTime()는 controller에서 보낸 실시간 버스 정보를 받아오기 위한 함수로 먼저 버스 노선 페이지에서 해당 페이지로 전환되었을 때 정류장 정보를 할당해주는 부분이므로 지금은 넘어가도록 하고 나중에 다시 살펴보길 바란다(20~25).

- 27~34라인

검색 버튼을 누를 경우 지도의 중앙을 해당 정류소로 먼저 설정해준 뒤 29라인 부분은 나중에 사용하게 될 예정이다. 현재는 주석처리하고 나중에 주석을 해제할 것이다. 다음 노선을 나타낼 노선박스를 작성한 후 선택한 정류장 위치에 마커로 표시 한다.

-39~67라인

nodeRealTime.do로 정류장ID 값을 보낸다. 그리고 정류장에 실시간으로 도착하는 버스노선에 대한 정보를 받아와 적당히 이쁘게 꾸미고(49~51) 출력한다. 그리고 미리 버스노선 버튼에 대한 클릭 이벤트를 만들어놓았지만 다음 포스팅에서 다룰 것이다.

 

4. 테스트

여기까지 따라왔다면 밑과 같은 결과값을 낼 수 있을 것이다.

- 위 버튼을 클릭 할 시

 

- 다음과 같은 화면이 나타난다면 오늘의 과정도 잘 따라왔다는 것을 확인 할 수 있다.(모든 버스 노선 보기, 노선에 대한 클릭의 클릭 이벤트는 다음 포스팅에서 다루겠다.)