setPath.js 17.3 KB
const axios = require('axios');
const convert = require('xml-js');
const moment = require('moment');

const apiKey = '';

const reverseGeocoding = async (_x, _y) => {
    try {
        var result = await axios.get("http://apis.vworld.kr/coord2jibun.do?x=" + _x + "&y=" + _y + "&output=xml&epsg=epsg:4326&apiKey=");
        result = convert.xml2js(result.data, {compact: true, spaces: 4});
        result = JSON.parse(JSON.stringify(result));
        var cityName = result.result.ADDR._cdata.split(" ")[0];
        return cityName
    } catch (e) {
        console.error(e);
    }

};

const subwayArrivalTime = async (stationID, wayCode) => {
    try {
        let today = new Date();
        let day = today.getDay();//요일
        let hours = today.getHours();//시
        let minutes = today.getMinutes();//분
        var result = await axios.get("https://api.odsay.com/v1/api/subwayTimeTable?lang=0&stationID=" + stationID + "&wayCode=" + wayCode + `&showExpressTime=1&apiKey=${apiKey}`);
    } catch (e) {
        console.error(e);
    }

}
//subwayArrivalTime(216,1);
const seoulBusStationID = async (stationID) => {
    try {
        var result = await axios.get("https://api.odsay.com/v1/api/busStationInfo?lang=0&stationID=" + parseInt(stationID) + `&apiKey=${apiKey}`);
        result = result.data;
        var _stationID = result.result.arsID;
        _stationID = _stationID.replace("-", "");
        return _stationID;
    } catch (e) {
        console.error(e);
    }
}

const seoulBusArrivalTime = async (stationID, busNum) => {
    try {

        var _stationID = await seoulBusStationID(stationID);

        var result = await axios.get('http://ws.bus.go.kr/api/rest/stationinfo/getStationByUid?serviceKey' + _stationID);
        //console.log(res.data);
        result = convert.xml2js(result.data, {compact: true, spaces: 4});
        result = JSON.parse(JSON.stringify(result));
        //console.log(result.ServiceResult.msgBody.itemList);
        var arrList = result.ServiceResult.msgBody.itemList;
        //console.log(arrList);
        for (var i = 0; i < arrList.length; i++) {
            if (arrList[i].rtNm._text == busNum) {
                var msg = new Object();
                msg.msg1 = arrList[i].arrmsg1._text;
                msg.msg2 = arrList[i].arrmsg2._text;
                msg.timeInterval = 7;
                return msg;
            }
        }
        var msg = new Object();
        msg.msg1 = "도착예정 없음";
        msg.msg2 = "도착예정 없음";
        msg.timeInterval = 7;
        return msg;


    } catch (e) {
        console.error(e);
    }
};

const gyeonggiLocalData = async (stationID, busID) => {
    try {
        var result = await axios.get("https://api.odsay.com/v1/api/busStationInfo?lang=0&stationID=" + parseInt(stationID) + `&apiKey=${apiKey}`);
        result = result.data;
        var stationLocalId = result.result.localStationID;
        for (var i = 0; i < result.result.lane.length; i++) {
            if (result.result.lane[i].busID == busID) {
                busLocalId = result.result.lane[i].busLocalBlID;

                return [stationLocalId, busLocalId];
            }
        }
    } catch (e) {
        console.error(e);
    }
};
const gyeonggiBusArrivalTime = async (stationID, busID) => {
    try {
        var localData = await gyeonggiLocalData(stationID, busID);
        var stationLocalID = localData[0];
        var busLocalID = localData[1];
        var result = await axios.get('http://openapi.gbis.go.kr/ws/rest/busarrivalservice/station?&stationId=' + stationLocalID);
        result = convert.xml2js(result.data, {compact: true, spaces: 4});
        result = JSON.parse(JSON.stringify(result));

        var msg = new Object();
        if (result.response.msgHeader.resultMessage._text == "결과가 존재하지 않습니다.") {
            msg.msg1 = "도착 정보 없음";
            msg.msg2 = "도착 정보 없음";
            msg.timeInterval = 7;
            console.log(msg);
            return msg;

        } else if (result.response.msgHeader.resultMessage._text == '정상적으로 처리되었습니다.') {

            var arrList = result.response.msgBody.busArrivalList;
            for (var i = 0; i < arrList.length; i++) {
                var item = arrList[i];
                if (item.routeId._text == busLocalID) {
                    msg.msg1 = item.predictTime1._text + "분 남음" + "(" + item.locationNo1._text + "개 역 전에 도착)";
                    if (parseInt(item.predictTime2._text) > 0) {
                        msg.msg2= msg.msg2 = item.predictTime2._text + "분 남음" + "(" + item.locationNo2._text + "개 역 전에 도착)";
                        msg.timeInterval = (parseInt(item.predictTime2._text) - parseInt(item.predictTime1._text))/60;//초
                        console.log("time interval,",msg.timeInterval);
                    } else {
                        msg.msg2="도착 정보 없음";
                        msg.timeInterval = parseInt(item.predictTime1._text);
                    }
                    console.log(msg);
                    return msg;//JSON타입 데이터

                }
            }
            msg.msg1 = "도착 정보 없음";
            msg.msg2 = "도착 정보 없음";
            msg.timeInterval = 7;
            console.log(msg);
            return msg;

        }

    } catch (e) {
        console.error(e);
    }
}

function printSubwayInfo(subPath) {
    console.log("-------지하철 이동---------");
    console.log("소요시간:", subPath.time);
    console.log("총 정거장수:", subPath.stationCnt);
    console.log("지하철 정보:");
    for (var i = 0; i < subPath.laneList.length; i++) {
        console.log(subPath.laneList[i].name);
    }
    console.log("출발역:", subPath.startName);
    console.log("도착역:", subPath.endName);
    console.log("station 리스트");
    console.log("------노선-------");
    for (var i = 0; i < subPath.stationList.length; i++) {
        console.log("|")
        console.log(subPath.stationList[i]);
    }


}

function printBusInfo(subPath) {
    console.log("--------버스 이동----------");
    console.log("소요시간:", subPath.time);
    console.log(subPath.stationCnt, "개 정류장 이동");
    for (var i = 0; i < subPath.arrivalInfo.length; i++) {
        console.log("버스 번호:", subPath.arrivalInfo[i].busNo);
        console.log(subPath.arrivalInfo[i].msg);
        console.log("-----------------------");
    }
    //console.log("대체버스:",subPath.busNumberList);
    console.log("출발역:", subPath.startName);
    console.log("도착역:", subPath.endName);
    console.log("-------노선--------");
    for (var i = 0; i < subPath.stationList.length; i++) {
        console.log("|");
        console.log(subPath.stationList[i].stationName);
    }


}

function printWalkInfo(subPath) {
    console.log("--------도보 이동----------");
    console.log("도보 이동 시간:", subPath.time);
    console.log("도보 이동 거리:", subPath.distance);


}

const searchPubTransPath = async (sx, sy, ex, ey, avgSpeed, endTime) => {
    //출발지점x좌표,  출발지점 y좌표, 도착지점 x좌표, 도착지점 y좌표, 보행자 평균 속도, 희망 도착시간(stringtype 2digit->hour, 2digit->min)
    try {
        var result = await axios.get("https://api.odsay.com/v1/api/searchPubTransPath?SX=" + sx + "&SY=" + sy + "&EX=" + ex + "&EY=" + ey + `&apiKey=${apiKey}`);
        result = result.data;
        var endTime = moment(endTime).format('HH:mm').split(':');
        console.log(endTime);

        var arrivalTime = parseInt(endTime[0]) * 60 + parseInt(endTime[1]);//endTime의 시각을 minute단위로 바꿈
        if (result.result.searchType == 0) {//도시내 이동
            var pathList = new Array();
            for (var i = 0; i < result.result.path.length; i++) {
                var path = result.result.path[i];
                console.log("========================================================================================");
                console.log("========================================================================================");
                console.log(i + 1, "번째 경로");
                var pathObj = new Object();
                if (path.pathType == 1) {
                    pathObj.pathType = "지하철";
                } else if (path.pathType == 2) {
                    pathObj.pathType = "버스";
                } else {
                    pathObj.pathType = "지하철&버스";
                }
                pathObj.walkTime = 0;
                pathObj.info = path.info;
                pathObj.walkDistance = 0;
                pathObj.busTimeInterval = 0;
                console.log(pathObj.pathType);
                console.log("총소요시간:", pathObj.info.totalTime);
                console.log("비용:", pathObj.info.payment);
                console.log("출발역:", pathObj.info.firstStartStation);
                console.log("도착역:", pathObj.info.lastEndStation);
                console.log("도보:", pathObj.info.totalWalk, " 이동");
                console.log("총", pathObj.info.totalStationCount, "개 역 이동");
                console.log("버스:", pathObj.info.busStationCount, "개 역 이동");
                console.log("지하철:", pathObj.info.subwayStationCount, "개 역 이동");
                console.log("=======경로 상세정보========");
                pathObj.subPathList = new Array();
                //console.log(pathObj.info);
                for (var j = 0; j < path.subPath.length; j++) {
                    var subPath = new Object();
                    if (path.subPath[j].trafficType == 1) {//지하철 환승
                        subPath.trafficType = "지하철";
                        subPath.time = path.subPath[j].sectionTime;
                        subPath.stationCnt = path.subPath[j].stationCount;
                        subPath.laneList = path.subPath[j].lane;
                        subPath.startName = path.subPath[j].startName;
                        subPath.startID = path.subPath[j].startID;
                        subPath.endName = path.subPath[j].endName;
                        subPath.endID = path.subPath[j].endID;
                        subPath.stationList = new Array();
                        for (var k = 0; k < path.subPath[j].passStopList.stations.length; k++) {
                            subPath.stationList.push(path.subPath[j].passStopList.stations[k].stationName);
                        }
                        printSubwayInfo(subPath);
                    } else if (path.subPath[j].trafficType == 2) {//버스=>실시간 정보!
                        subPath.trafficType = "버스";
                        subPath.time = path.subPath[j].sectionTime;//총소요시간
                        subPath.stationCnt = path.subPath[j].stationCount;
                        subPath.startName = path.subPath[j].startName;
                        subPath.startID = path.subPath[j].startID;
                        subPath.endName = path.subPath[j].endName;
                        subPath.endID = path.subPath[j].endID;
                        subPath.stationList = path.subPath[j].passStopList.stations;
                        subPath.arrivalInfo = new Array();
                        var cityName = await reverseGeocoding(path.subPath[j].passStopList.stations[0].x, path.subPath[j].passStopList.stations[0].y);
                        if (cityName == "서울특별시") {//stationID와 busNo로 도착 예정시간 추출
                            //seoulBusArrivalTime(path.subPath[j].passStopList.stations[0].stationID,busNumberList);
                            for (var a = 0; a < path.subPath[j].lane.length; a++) {
                                var busArrivalInfoItem = new Object();
                                var _msg = await seoulBusArrivalTime(subPath.startID, path.subPath[j].lane[a].busNo);
                                busArrivalInfoItem.busID = path.subPath[j].lane[a].busID;
                                busArrivalInfoItem.busNo = path.subPath[j].lane[a].busNo;
                                busArrivalInfoItem.msg = _msg;
                                subPath.arrivalInfo.push(busArrivalInfoItem);
                                pathObj.busTimeInterval = _msg.timeInterval; //초->분단위로 바꿈
                                console.log(_msg.timeInterval);
                                if (a == 2)//버스 최대 3개까지만 출력시킴
                                    break;
                            }
                            printBusInfo(subPath);
                        } else if (cityName == "경기도") {
                            for (var a = 0; a < path.subPath[j].lane.length; a++) {
                                var busArrivalInfoItem = new Object();
                                var _msg = await gyeonggiBusArrivalTime(subPath.startID, path.subPath[j].lane[a].busID);
                                busArrivalInfoItem.busID = path.subPath[j].lane[a].busID;
                                busArrivalInfoItem.busNo = path.subPath[j].lane[a].busNo;
                                busArrivalInfoItem.msg = _msg;
                                subPath.arrivalInfo.push(busArrivalInfoItem);
                                console.log("----------메시지메시지-----------", _msg);
                                pathObj.busTimeInterval = _msg.timeInterval;

                                if (a == 2)//버스 최대 3개까지만 출력
                                    break;
                            }
                            printBusInfo(subPath);
                        } else {
                            //서울, 경기를 제외한 지역은 실시간 정보 제공 불가
                            printBusInfo(subPath);
                        }
                    } else {//도보이동
                        pathObj.walkTime += path.subPath[j].sectionTime;
                        pathObj.walkDistance += path.subPath[j].distance;
                        subPath.trafficType = "도보";
                        subPath.time = path.subPath[j].sectionTime;
                        subPath.distance = path.subPath[j].distance;
                        printWalkInfo(subPath);
                    }
                    pathObj.subPathList.push(subPath);

                }

                pathList.push(pathObj);
                var optTotalTime = pathObj.info.totalTime - pathObj.walkTime + pathObj.walkDistance / avgSpeed;//사용자의 보행속도를 고려한 이동시간
                console.log("arrrrrrrrrrr",arrivalTime)
                var departureTime1 = parseInt(arrivalTime - optTotalTime);

                if(departureTime1<0){
                    departureTime1+=1440;
                }
                if(path.pathType==1){//지하철의 경우 시간간격 4분으로
                    pathObj.busTimeInterval=4;
                }
                var departureTime2 = parseInt(arrivalTime - optTotalTime - pathObj.busTimeInterval);
                if(departureTime2<0){
                    departureTime2+=1440;
                }
                console.log(pathObj.busTimeInterval);
                console.log("dp1",departureTime1);
                console.log("dp2",departureTime2);

                console.log("pathType",path.pathType);
                console.log("departure time 1",departureTime1);
                console.log("departure time 2",departureTime2);
                var hour1 = departureTime1 / 60;
                var min1 = departureTime1 % 60;
                var hour2 = departureTime2 / 60;
                var min2 =departureTime2 % 60;
                pathObj.info.hour1=parseInt(hour1).toString();
                pathObj.info.min1=parseInt(min1).toString();
                pathObj.info.hour2=parseInt(hour2).toString();
                pathObj.info.min2=parseInt(min2).toString();
                console.log(pathObj.info.hour1,"시 ",pathObj.info.min1,"분");
                console.log(pathObj.info.hour2,"시 ",pathObj.info.min2,"분");
                if (i == 2)//경로 3개까지만 출력
                    break;


            }
            return {pathList};
        } else if (result.result.searchType == 1) {//도시간 이동
            var path = new Object();
            path.trainList = new Array();
            for (var j = 0; j < result.result.trainRequest.count; j++) {
                var train = new Object();
                train = result.result.trainRequest.OBJ[j];
                path.trainList.push(train);
                if (j == 2)
                    break;
            }
            path.exBusList = new Array();
            for (var j = 0; j < result.result.exBusRequest.count; j++) {
                var exBus = new Object();
                exBus = reuslt.result.exBusRequest.OBJ[j];
                path.exBusList.push(exBus);
                if (j == 2)
                    break;
            }
            path.outBusList = new Array();
            for (var j = 0; j < result.result.outBusRequest.count; j++) {
                var outBus = new Object();
                outBus = result.result.outBusRequest.OBJ[j];
                path.outBusList.push(outBus);
                if (j == 2)
                    break;
            }
            return path;

        }

    } catch (e) {
        console.error(e);
    }
};
searchPubTransPath(126.999451,37.266670, 126.986990,37.541386,60,"00:10");
module.exports = searchPubTransPath;