diff --git a/BackendJS/BackendTS/routes/navigation.js b/BackendJS/BackendTS/routes/navigation.js index 15322b7..5065a33 100644 --- a/BackendJS/BackendTS/routes/navigation.js +++ b/BackendJS/BackendTS/routes/navigation.js @@ -16,6 +16,28 @@ const request_1 = __importDefault(require("request")); const xml_js_1 = __importDefault(require("xml-js")); const serviceKey_json_1 = __importDefault(require("../KEY/serviceKey.json")); const router = express_1.default.Router(); +const velocity = 0.0468; +function deg2rad(deg) { + return (deg * Math.PI / 180); +} +function rad2deg(rad) { + return (rad * 180 / Math.PI); +} +function distance(lat1, lon1, lat2, lon2) { + if (lat1 === lat2 && lon1 == lon2) { + return 0; + } + else { + let theta = lon1 - lon2; + let dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta)); + dist = Math.acos(dist); + dist = rad2deg(dist); + dist = dist * 60 * 1.1515; + dist = dist * 1.609344; + //dist를 지름으로 한 원 내부의 직각삼각형 두 변의 길이 + return dist * Math.sqrt(2); + } +} router.get('/bybus/:startX/:startY/:endX/:endY', (req, res) => __awaiter(void 0, void 0, void 0, function* () { try { const startX = req.params.startX; @@ -34,25 +56,67 @@ router.get('/bybus/:startX/:startY/:endX/:endY', (req, res) => __awaiter(void 0, }, function (error, response, body) { return __awaiter(this, void 0, void 0, function* () { const parseJSON = xml_js_1.default.xml2json(body); - const restruct = () => __awaiter(this, void 0, void 0, function* () { - return new Promise((res, rej) => { - }); + const navigationList = JSON.parse(parseJSON).elements[0].elements[2].elements; + const navigationInfo = []; + navigationList.forEach((info) => { + const tempInfo = { + distance: "", + pathList: [], + timeList: [], + totalTime: "", + walkTime: 0, //총 도보 이동 시간 + }; + tempInfo.distance = info.elements[0].elements[0].text; + tempInfo.totalTime = info.elements[2].elements[0].text; + //첫 출발지랑 정류장/역 사이 거리 + let x1 = Number(startX); + let y1 = Number(startY); + let x2 = Number(info.elements[1].elements[2].elements[0].text); + let y2 = Number(info.elements[1].elements[3].elements[0].text); + let dist = distance(x1, y1, x2, y2); + tempInfo.timeList.push(Math.floor(dist / velocity)); + tempInfo.walkTime += Math.floor(dist / velocity); + for (let i = 0; i < info.elements[1].elements.length / 10; i++) { + tempInfo.pathList.push({ + fid: info.elements[1].elements[i % 10].elements[0].text, + fname: info.elements[1].elements[i % 10 + 1].elements[0].text, + fx: info.elements[1].elements[i % 10 + 2].elements[0].text, + fy: info.elements[1].elements[i % 10 + 3].elements[0].text, + routeId: info.elements[1].elements[i % 10 + 4].elements[0].text, + routeNm: info.elements[1].elements[i % 10 + 5].elements[0].text, + tid: info.elements[1].elements[i % 10 + 6].elements[0].text, + tname: info.elements[1].elements[i % 10 + 7].elements[0].text, + tx: info.elements[1].elements[i % 10 + 8].elements[0].text, + ty: info.elements[1].elements[i % 10 + 9].elements[0].text, + }); + //마지막 정류장/역과 목적지 사이 도보 이동거리 + x1 = Number(info.elements[1].elements[i % 10 + 2].elements[0].text); + y1 = Number(info.elements[1].elements[i % 10 + 3].elements[0].text); + x2 = Number(info.elements[1].elements[i % 10 + 8].elements[0].text); + y2 = Number(info.elements[1].elements[i % 10 + 9].elements[0].text); + dist = distance(x1, y1, x2, y2); + tempInfo.timeList.push(Math.floor(dist / velocity)); + tempInfo.walkTime += Math.floor(dist / velocity); + } + //마지막 정류장/역과 목적지 사이 도보 이동거리 + x1 = Number(endX); + y1 = Number(endY); + x2 = Number(info.elements[1].elements[info.elements[1].elements.length - 2].elements[0].text); + y2 = Number(info.elements[1].elements[info.elements[1].elements.length - 1].elements[0].text); + dist = distance(x1, y1, x2, y2); + tempInfo.timeList.push(Math.floor(dist / velocity)); + tempInfo.walkTime += Math.floor(dist / velocity); + navigationInfo.push(tempInfo); }); - const navigationInfo = JSON.parse(parseJSON).elements[0].elements[2].elements; - /* //정렬 기준 (1. 환승 경로 개수 / 2. 이동 시간) - navigationInfo.sort((a:itemList,b:itemList)=>{ - - if( a.elements.pathList.elements.length === b.elements.pathList.elements.length){ - return parseInt(a.elements.time.elements[0].text) - parseInt(b.elements.time.elements[0].text); - } - - return a.elements.pathList.elements.length - b.elements.pathList.elements.length - }) - */ - console.log(navigationInfo.length); + navigationInfo.sort((a, b) => { + if (a.pathList.length === b.pathList.length) { + return a.walkTime - b.walkTime; + } + return a.pathList.length - b.pathList.length; + }); return res.status(200).json({ - body: navigationInfo + navigationInfo: navigationInfo }); }); }); @@ -65,8 +129,194 @@ router.get('/bybus/:startX/:startY/:endX/:endY', (req, res) => __awaiter(void 0, }); } })); -router.get('/bysubway', (req, res) => __awaiter(void 0, void 0, void 0, function* () { +router.get('/bysubway/:startX/:startY/:endX/:endY', (req, res) => __awaiter(void 0, void 0, void 0, function* () { + try { + //지하철 환승 이동 시간 필요 + const startX = req.params.startX; + const startY = req.params.startY; + const endX = req.params.endX; + const endY = req.params.endY; + const url = "http://ws.bus.go.kr/api/rest/pathinfo/getPathInfoBySubway"; + let queryParams = '?' + encodeURIComponent('serviceKey') + '=' + serviceKey_json_1.default.serviceKey; + queryParams += '&' + encodeURIComponent('startX') + '=' + startX; + queryParams += '&' + encodeURIComponent('startY') + '=' + startY; + queryParams += '&' + encodeURIComponent('endX') + '=' + endX; + queryParams += '&' + encodeURIComponent('endY') + '=' + endY; + (0, request_1.default)({ + url: url + queryParams, + method: 'GET' + }, function (error, response, body) { + return __awaiter(this, void 0, void 0, function* () { + const parseJSON = xml_js_1.default.xml2json(body); + const navigationList = JSON.parse(parseJSON).elements[0].elements[2].elements; + const navigationInfo = []; + navigationList.forEach((info) => { + const tempInfo = { + distance: "", + pathList: [], + timeList: [], + totalTime: "", + walkTime: 0, //총 도보 이동 시간 + }; + tempInfo.distance = info.elements[0].elements[0].text; + tempInfo.totalTime = info.elements[2].elements[0].text; + //첫 출발지랑 정류장/역 사이 거리 + let x1 = Number(startX); + let y1 = Number(startY); + let x2 = Number(info.elements[1].elements[2].elements[0].text); + let y2 = Number(info.elements[1].elements[3].elements[0].text); + let dist = distance(x1, y1, x2, y2); + tempInfo.timeList.push(Math.floor(dist / velocity)); + tempInfo.walkTime += Math.floor(dist / velocity); + for (let i = 0; i < info.elements[1].elements.length / 10; i++) { + const railLinkList = []; + console.log(JSON.stringify(info.elements[1].elements)); + for (let j = 0; j < info.elements[1].elements[i % 10 + 4].elements.length; j++) { + railLinkList.push(info.elements[1].elements[i % 10 + 4].elements[j].text); + } + tempInfo.pathList.push({ + fid: info.elements[1].elements[i % 10].elements[0].text, + fname: info.elements[1].elements[i % 10 + 1].elements[0].text, + fx: info.elements[1].elements[i % 10 + 2].elements[0].text, + fy: info.elements[1].elements[i % 10 + 3].elements[0].text, + railLinkList: railLinkList, + routeNm: info.elements[1].elements[i % 10 + 5].elements[0].text, + tid: info.elements[1].elements[i % 10 + 6].elements[0].text, + tname: info.elements[1].elements[i % 10 + 7].elements[0].text, + tx: info.elements[1].elements[i % 10 + 8].elements[0].text, + ty: info.elements[1].elements[i % 10 + 9].elements[0].text + }); + //마지막 정류장/역과 목적지 사이 도보 이동거리 + x1 = Number(info.elements[1].elements[i % 10 + 2].elements[0].text); + y1 = Number(info.elements[1].elements[i % 10 + 3].elements[0].text); + x2 = Number(info.elements[1].elements[i % 10 + 8].elements[0].text); + y2 = Number(info.elements[1].elements[i % 10 + 9].elements[0].text); + dist = distance(x1, y1, x2, y2); + tempInfo.timeList.push(Math.floor(dist / velocity)); + tempInfo.walkTime += Math.floor(dist / velocity); + } + //마지막 정류장/역과 목적지 사이 도보 이동거리 + x1 = Number(endX); + y1 = Number(endY); + x2 = Number(info.elements[1].elements[info.elements[1].elements.length - 2].elements[0].text); + y2 = Number(info.elements[1].elements[info.elements[1].elements.length - 1].elements[0].text); + dist = distance(x1, y1, x2, y2); + tempInfo.timeList.push(Math.floor(dist / velocity)); + tempInfo.walkTime += Math.floor(dist / velocity); + navigationInfo.push(tempInfo); + }); + //정렬 기준 (1. 환승 경로 개수 / 2. 이동 시간) + navigationInfo.sort((a, b) => { + if (a.pathList.length === b.pathList.length) { + return a.walkTime - b.walkTime; + } + return a.pathList.length - b.pathList.length; + }); + return res.status(200).json({ + navigationInfo: navigationInfo + }); + }); + }); + } + catch (e) { + console.error(e); + return res.status(500).json({ + error: e, + errorString: e.toString(), + }); + } })); -router.get('/bybusNsubway', (req, res) => __awaiter(void 0, void 0, void 0, function* () { +router.get('/bybusNsubway/:startX/:startY/:endX/:endY', (req, res) => __awaiter(void 0, void 0, void 0, function* () { + //버스 -> 지하철 / 지하철 -> 버스로 이동하는 시간 고려 + try { + //지하철 환승 이동 시간 필요 + const startX = req.params.startX; + const startY = req.params.startY; + const endX = req.params.endX; + const endY = req.params.endY; + const url = "http://ws.bus.go.kr/api/rest/pathinfo/getPathInfoByBusNSub"; + let queryParams = '?' + encodeURIComponent('serviceKey') + '=' + serviceKey_json_1.default.serviceKey; + queryParams += '&' + encodeURIComponent('startX') + '=' + startX; + queryParams += '&' + encodeURIComponent('startY') + '=' + startY; + queryParams += '&' + encodeURIComponent('endX') + '=' + endX; + queryParams += '&' + encodeURIComponent('endY') + '=' + endY; + (0, request_1.default)({ + url: url + queryParams, + method: 'GET' + }, function (error, response, body) { + return __awaiter(this, void 0, void 0, function* () { + const parseJSON = xml_js_1.default.xml2json(body); + const navigationList = JSON.parse(parseJSON).elements[0].elements[2].elements; + const navigationInfo = []; + navigationList.forEach((info) => { + const tempInfo = { + distance: "", + pathList: [], + timeList: [], + totalTime: "", + walkTime: 0, //총 도보 이동 시간 + }; + tempInfo.distance = info.elements[0].elements[0].text; + tempInfo.totalTime = info.elements[2].elements[0].text; + //첫 출발지랑 정류장/역 사이 거리 + let x1 = Number(startX); + let y1 = Number(startY); + let x2 = Number(info.elements[1].elements[2].elements[0].text); + let y2 = Number(info.elements[1].elements[3].elements[0].text); + let dist = distance(x1, y1, x2, y2); + tempInfo.timeList.push(Math.floor(dist / velocity)); + tempInfo.walkTime += Math.floor(dist / velocity); + for (let i = 0; i < info.elements[1].elements.length / 10; i++) { + tempInfo.pathList.push({ + fid: info.elements[1].elements[i % 10].elements[0].text, + fname: info.elements[1].elements[i % 10 + 1].elements[0].text, + fx: info.elements[1].elements[i % 10 + 2].elements[0].text, + fy: info.elements[1].elements[i % 10 + 3].elements[0].text, + routeId: info.elements[1].elements[i % 10 + 4].elements[0].text, + routeNm: info.elements[1].elements[i % 10 + 5].elements[0].text, + tid: info.elements[1].elements[i % 10 + 6].elements[0].text, + tname: info.elements[1].elements[i % 10 + 7].elements[0].text, + tx: info.elements[1].elements[i % 10 + 8].elements[0].text, + ty: info.elements[1].elements[i % 10 + 9].elements[0].text, + }); + //마지막 정류장/역과 목적지 사이 도보 이동거리 + x1 = Number(info.elements[1].elements[i % 10 + 2].elements[0].text); + y1 = Number(info.elements[1].elements[i % 10 + 3].elements[0].text); + x2 = Number(info.elements[1].elements[i % 10 + 8].elements[0].text); + y2 = Number(info.elements[1].elements[i % 10 + 9].elements[0].text); + dist = distance(x1, y1, x2, y2); + tempInfo.timeList.push(Math.floor(dist / velocity)); + tempInfo.walkTime += Math.floor(dist / velocity); + } + //마지막 정류장/역과 목적지 사이 도보 이동거리 + x1 = Number(endX); + y1 = Number(endY); + x2 = Number(info.elements[1].elements[info.elements[1].elements.length - 2].elements[0].text); + y2 = Number(info.elements[1].elements[info.elements[1].elements.length - 1].elements[0].text); + dist = distance(x1, y1, x2, y2); + tempInfo.timeList.push(Math.floor(dist / velocity)); + tempInfo.walkTime += Math.floor(dist / velocity); + navigationInfo.push(tempInfo); + }); + //정렬 기준 (1. 환승 경로 개수 / 2. 이동 시간) + navigationInfo.sort((a, b) => { + if (a.pathList.length === b.pathList.length) { + return a.walkTime - b.walkTime; + } + return a.pathList.length - b.pathList.length; + }); + return res.status(200).json({ + navigationInfo: navigationInfo + }); + }); + }); + } + catch (e) { + console.error(e); + return res.status(500).json({ + error: e, + errorString: e.toString(), + }); + } })); module.exports = router; diff --git a/BackendTS/routes/navigation.ts b/BackendTS/routes/navigation.ts index 90921f9..3172095 100644 --- a/BackendTS/routes/navigation.ts +++ b/BackendTS/routes/navigation.ts @@ -2,10 +2,37 @@ import express, {Request, Response, Router} from 'express' import request from 'request' import convert from 'xml-js' import serviceKey from '../KEY/serviceKey.json' -import {NavigationInfo} from '../../interfaces/Navigation/navigation.interface' +import {NavigationList, BusPathList, SubwayPathList} from '../../interfaces/Navigation/navigation.interface' const router:Router = express.Router(); +const velocity:number = 0.0468; + +function deg2rad(deg:number){ + return (deg * Math.PI / 180); +} + +function rad2deg(rad:number){ + return (rad * 180 / Math.PI); +} + +function distance (lat1:number, lon1:number, lat2:number, lon2:number){ + if(lat1===lat2 && lon1==lon2){ + return 0; + } + else{ + let theta:number = lon1-lon2; + let dist:number = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta)); + dist = Math.acos(dist); + dist = rad2deg(dist); + dist = dist * 60 * 1.1515; + dist = dist * 1.609344; + + //dist를 지름으로 한 원 내부의 직각삼각형 두 변의 길이 + return dist*Math.sqrt(2); + } +} + router.get('/bybus/:startX/:startY/:endX/:endY', async(req:Request, res:Response)=>{ try{ @@ -28,59 +55,333 @@ router.get('/bybus/:startX/:startY/:endX/:endY', async(req:Request, res:Response const parseJSON:string = convert.xml2json(body); - const restruct = async () => new Promise((res:any,rej:any)=>{ - - }) - const navigationList:any = JSON.parse(parseJSON).elements[0].elements[2].elements; - const navigationInfo = []; - navigationList.forEach(info => { - const tempInfo = { - distance: "", - pathList: [], - time: "" + const navigationInfo:Array = []; + navigationList.forEach((info:any) => { + const tempInfo:NavigationList = { + distance: "", //총 이동 거리 + pathList: [], //이동 경로 + timeList: [], //이동 시간 + totalTime: "", // 총 이동 시간 + walkTime: 0, //총 도보 이동 시간 }; tempInfo.distance = info.elements[0].elements[0].text; - tempInfo.time = info.elements[info.elements.length-1].elements[0].text; - info.elements.forEach(pathInfo=>{ - //list parsing - }) + tempInfo.totalTime = info.elements[2].elements[0].text; + + //첫 출발지랑 정류장/역 사이 거리 + let x1:number = Number(startX); + let y1:number = Number(startY); + let x2:number = Number(info.elements[1].elements[2].elements[0].text); + let y2:number = Number(info.elements[1].elements[3].elements[0].text); + let dist:number = distance(x1,y1,x2,y2); + + tempInfo.timeList.push(Math.floor(dist/velocity)); + tempInfo.walkTime += Math.floor(dist/velocity); + + for(let i:number=0;i{ + navigationInfo.sort((a:NavigationList,b:NavigationList)=>{ - if( a.elements.pathList.elements.length === b.elements.pathList.elements.length){ - return parseInt(a.elements.time.elements[0].text) - parseInt(b.elements.time.elements[0].text); + if( a.pathList.length === b.pathList.length){ + return a.walkTime - b.walkTime; } - return a.elements.pathList.elements.length - b.elements.pathList.elements.length + return a.pathList.length - b.pathList.length }) - */ - console.log(navigationList.length); - + return res.status(200).json({ - body: navigationList + navigationInfo: navigationInfo }) + }); } catch(e){ - console.error(e); - return res.status(500).json({ - error: e, - errorString: e.toString(), - }); + console.error(e); + return res.status(500).json({ + error: e, + errorString: e.toString(), + }); } }) -router.get('/bysubway', async(req:Request,res:Response)=>{ +router.get('/bysubway/:startX/:startY/:endX/:endY', async(req:Request,res:Response)=>{ + try{ + + //지하철 환승 이동 시간 필요 + const startX: string = req.params.startX; + const startY: string = req.params.startY; + const endX: string = req.params.endX; + const endY: string = req.params.endY; + + const url:string = "http://ws.bus.go.kr/api/rest/pathinfo/getPathInfoBySubway"; + let queryParams:string = '?' + encodeURIComponent('serviceKey') + '=' + serviceKey.serviceKey; + queryParams += '&' + encodeURIComponent('startX') + '=' + startX; + queryParams += '&' + encodeURIComponent('startY') + '=' + startY; + queryParams += '&' + encodeURIComponent('endX') + '=' + endX; + queryParams += '&' + encodeURIComponent('endY') + '=' + endY; + + request({ + url: url + queryParams, + method: 'GET' + }, async function (error:Error, response:any, body:string) { + + const parseJSON:string = convert.xml2json(body); + + const navigationList:any = JSON.parse(parseJSON).elements[0].elements[2].elements; + + const navigationInfo:Array = []; + navigationList.forEach((info:any) => { + const tempInfo:NavigationList = { + distance: "", //총 이동 거리 + pathList: [], //이동 경로 + timeList: [], //이동 시간 + totalTime: "", // 총 이동 시간 + walkTime: 0, //총 도보 이동 시간 + }; + tempInfo.distance = info.elements[0].elements[0].text; + tempInfo.totalTime = info.elements[2].elements[0].text; + + //첫 출발지랑 정류장/역 사이 거리 + let x1:number = Number(startX); + let y1:number = Number(startY); + let x2:number = Number(info.elements[1].elements[2].elements[0].text); + let y2:number = Number(info.elements[1].elements[3].elements[0].text); + let dist:number = distance(x1,y1,x2,y2); + + tempInfo.timeList.push(Math.floor(dist/velocity)); + tempInfo.walkTime += Math.floor(dist/velocity); + + for(let i:number=0;i = []; + console.log(JSON.stringify(info.elements[1].elements)); + for(let j:number = 0;j{ + + if( a.pathList.length === b.pathList.length){ + return a.walkTime - b.walkTime; + } + + return a.pathList.length - b.pathList.length + }) + + return res.status(200).json({ + navigationInfo: navigationInfo + }) + + }); + } + catch(e){ + console.error(e); + return res.status(500).json({ + error: e, + errorString: e.toString(), + }); + } }) -router.get('/bybusNsubway', async(req:Request,res:Response)=>{ +router.get('/bybusNsubway/:startX/:startY/:endX/:endY', async(req:Request,res:Response)=>{ + //버스 -> 지하철 / 지하철 -> 버스로 이동하는 시간 고려 + try{ + + //지하철 환승 이동 시간 필요 + const startX: string = req.params.startX; + const startY: string = req.params.startY; + const endX: string = req.params.endX; + const endY: string = req.params.endY; + + const url:string = "http://ws.bus.go.kr/api/rest/pathinfo/getPathInfoByBusNSub"; + let queryParams:string = '?' + encodeURIComponent('serviceKey') + '=' + serviceKey.serviceKey; + queryParams += '&' + encodeURIComponent('startX') + '=' + startX; + queryParams += '&' + encodeURIComponent('startY') + '=' + startY; + queryParams += '&' + encodeURIComponent('endX') + '=' + endX; + queryParams += '&' + encodeURIComponent('endY') + '=' + endY; + + request({ + url: url + queryParams, + method: 'GET' + }, async function (error:Error, response:any, body:string) { + + const parseJSON:string = convert.xml2json(body); + + const navigationList:any = JSON.parse(parseJSON).elements[0].elements[2].elements; + const navigationInfo:Array = []; + navigationList.forEach((info:any) => { + const tempInfo:NavigationList = { + distance: "", //총 이동 거리 + pathList: [], //이동 경로 + timeList: [], //이동 시간 + totalTime: "", // 총 이동 시간 + walkTime: 0, //총 도보 이동 시간 + }; + tempInfo.distance = info.elements[0].elements[0].text; + tempInfo.totalTime = info.elements[2].elements[0].text; + + //첫 출발지랑 정류장/역 사이 거리 + let x1:number = Number(startX); + let y1:number = Number(startY); + let x2:number = Number(info.elements[1].elements[2].elements[0].text); + let y2:number = Number(info.elements[1].elements[3].elements[0].text); + let dist:number = distance(x1,y1,x2,y2); + + tempInfo.timeList.push(Math.floor(dist/velocity)); + tempInfo.walkTime += Math.floor(dist/velocity); + + for(let i:number=0;i{ + + if( a.pathList.length === b.pathList.length){ + return a.walkTime - b.walkTime; + } + + return a.pathList.length - b.pathList.length + }) + + return res.status(200).json({ + navigationInfo: navigationInfo + }) + + }); + } + catch(e){ + console.error(e); + return res.status(500).json({ + error: e, + errorString: e.toString(), + }); + } }) export = router; \ No newline at end of file diff --git a/interfaces/Navigation/navigation.interface.ts b/interfaces/Navigation/navigation.interface.ts index e4819e6..b05c447 100644 --- a/interfaces/Navigation/navigation.interface.ts +++ b/interfaces/Navigation/navigation.interface.ts @@ -1,9 +1,9 @@ -export interface PathList { +export interface BusPathList { fid: string, fname: string, fx: string, fy: string, - routeId: string, + routeId?: string, routeNm: string, tid: string, tname: string, @@ -11,8 +11,23 @@ export interface PathList { ty: string, } -export interface NavigationInfo { - distance: number, - pathList: Array, - time: number +export interface SubwayPathList { + routeNm: string, + fid: string, + fname: string, + fx: string, + fy: string, + tid: string, + tname: string, + tx: string, + ty: string, + railLinkList?: Array, +} + +export interface NavigationList { + distance: string, + pathList: Array|Array, + timeList: Array, + totalTime: string, + walkTime: number } \ No newline at end of file