Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

[Server] 3단계 경유지 검색 추가 본문

Project/대중교통 길찾기

[Server] 3단계 경유지 검색 추가

Seung__ 2022. 1. 29. 00:20
  • 대중교통 길찾기에 경유지를 추가해 보자.
  • 구현방법은 간단하다.
  • 지금까지는 "출발지->목적지"에 대해서만 검색을 했다.
  • 이번에는 "출발지->경유지", "경유지->목적지"로 검색을 해보자.
  • 이 때 각 경로의 수는 여러 개이다.
  • 따라서 경로로 중 각각 2개식만 뽑아서 총 4개의 경로를 만든다.

 

1. SearchLocationReq


form에서 받아야할 정보가 하나 늘었다.

@Data
@AllArgsConstructor
@NoArgsConstructor
public class SearchLocationReq {

    private String start;
    private String end;
    private String middle;


    private MultiValueMap<String, String> makeQuery(){

        LinkedMultiValueMap<String, String> map = new LinkedMultiValueMap<>();

        start = start.replace(" ", "+");
        middle = middle.replace(" ", "+");
        end = end.replace(" ", "+");
        map.add("start", start);
        map.add("middle", middle);
        map.add("end", end);

        return map;
    }

}

 

 

2. View-form


기존 form에서 경유지만 추가해줬다.

<!DOCTYPE html>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<html xmlns:th="http://www.thymeleaf.org">
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Find Route</title>
</head>
<body>
<H1><b>대중교통 길찾기</b></H1>

<div class="search box">
  <form action="/With-WayPoint" th:action="@{/With-WayPoint}" th:object="${searchLocationReq}" method="post">
      <div class="input-group mb-3">
          <span class="input-group-text" id="basic-addon1">출발지</span>
          <input type="text" id="start" th:field="*{start}" class="form-control" placeholder="출발지" aria-label="start" aria-describedby="basic-addon1">
      </div>
      <div class="input-group mb-3">
          <span class="input-group-text" id="basic-addon2">경유지</span>
          <input type="text" id="wayPoint" th:field="*{middle}" class="form-control" placeholder="경유지" aria-label="start" aria-describedby="basic-addon1">
      </div>
      <div class="input-group mb-3">
          <span class="input-group-text" id="basic-addon3">목적지</span>
          <input type="text" id="end" th:field="*{end}" class="form-control" placeholder="목적지" aria-label="end" aria-describedby="basic-addon1">
      </div>
      <button type="submit" class="btn btn-primary" th:onclick="">검색</button>
  </form>
</div>

</body>
</html>

 

 

 

3. Controller


위에서 설명한 대로 두개의 길찾기 결과에서 각각 경로는 2개씩 사용한다.

@PostMapping("/With-WayPoint")
public String searchLocation2(@ModelAttribute SearchLocationReq searchLocationReq, Model model){

    //이름 --> 좌표
    JSONObject jsonStartResult = googleClient.searchLocation(searchLocationReq.getStart());
    JSONObject jsonMiddleResult = googleClient.searchLocation(searchLocationReq.getMiddle());
    JSONObject jsonEndResult = googleClient.searchLocation(searchLocationReq.getEnd());

    //시작 -> 경유, 경유 -> 시작 길찾기 req 객체 생성
    SearchRouteReq searchRouteReq1 = getSearchRouteReq(jsonStartResult, jsonMiddleResult);
    SearchRouteReq searchRouteReq2 = getSearchRouteReq(jsonMiddleResult, jsonEndResult);

    //res객체
    SearchRouteRes searchRouteRes1 = searchRoute3(searchRouteReq1);
    SearchRouteRes searchRouteRes2 = searchRoute3(searchRouteReq2);

    //view에 전달.
    model.addAttribute("result1",  searchRouteRes1);
    model.addAttribute("result2",  searchRouteRes2);
    model.addAttribute("start", searchLocationReq.getStart());
    model.addAttribute("middle", searchLocationReq.getMiddle());
    model.addAttribute("end", searchLocationReq.getEnd());

    return "resultPage2";
}

public  SearchRouteRes searchRoute3(@ModelAttribute("searchRouteReq") SearchRouteReq searchRouteReq){
     JSONObject jsonResult = odSayClient.searchRoute(searchRouteReq);
     SearchRouteRes searchRouteRes = new SearchRouteRes(jsonResult);

     //여러 path중 2개만 사용.
     ArrayList<Path> pathList = new ArrayList<>();
     pathList.add(searchRouteRes.getPathList().get(0))
     pathList.add(searchRouteRes.getPathList().get(1));

     //api로 얻은 pathList를 대체함.
     searchRouteRes.setPathList(pathList);

     return searchRouteRes;
}

 

 

 

4. View-result


  • 출발지->경유지: result1
  • 경유지->목적지: result2
  • result1과 result2에서 각각 path를 꺼낸다.
  • result1에서 꺼낸 경로 path1과  result2에서 꺼낸 path2를 차례대로 출력한다.
<!DOCTYPE html>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Result</title>
</head>
<body>
    <H1><b>길찾기 검색 결과</b></H1>

    <div id="summary">
        <table class="table table-striped" >
            <tr>
                <td>출발지</td>
                <td th:text="${start}">서울역</td>
            </tr>
            <tr>
                <td>경유지</td>
                <td th:text="${middle}">서울역</td>
            </tr>
            <tr>
                <td>목적지</td>
                <td th:text="${end}">서울역</td>
            </tr>
            <tr>
                <td>직선거리</td>
                <td th:text="${result1.pointDistance}+${result2.pointDistance}+m">a m</td>
            </tr>
        </table>
    </div>

    <div class="paths">
        <th:block th:each="path1:${result1.pathList}">
            <th:block th:each="path2 : ${result2.pathList}" class="accordion-item" th:field="${path}">
                <div class="accordion accordion-flush" id="accordionFlushExample">
                    <div class="accordion-item">
                        <h2 class="accordion-header" id="headingOne">
                            <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
                                <b><span th:text="${path1.totalTime}+${path2.totalTime}+분 "><b>소요시간(분) </b></span></b>
                                <span th:text=" ${path1.totalDistance}+${path2.totalDistance}+m">이동거리(미터)</span>
                            </button>
                        </h2>
                        <div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="headingOne" data-bs-parent="#accordionExample">
                            <div class="accordion-body">
                                <b><span th:text="${start}+' 출발'">서울역</span></b>
                                <table class="table table-striped" >
                                    <th:block th:each="subPath : ${path1.subPathList}">

                                        <!--li th:text="${subPath.toString()}"></li-->
                                        <tr>
                                            <!--span th:text="${subPath?.trafficType}?:'데이터 없음'"></span-->
                                            <li th:object="${subpath}"  th:if="${subPath?.trafficType} == 3" th:text="|걷기 ${subPath?.sectionTime}분|">도보 이동거리</li>
                                        </tr>
                                        <tr>
                                            <!--span th:text="${subPath?.trafficType}?:'데이터 없음'"></span-->
                                            <li th:object="${subpath}"  th:if="${subPath?.trafficType} == 2" th:text="|${subPath?.startName}정류장 ${subPath.lane.busNo}번 승차|">버스탑승</li>
                                        </tr>
                                        <tr>
                                            <!--span th:text="${subPath?.trafficType}?:'데이터 없음'"></span-->
                                            <li th:object="${subpath}"  th:if="${subPath?.trafficType} == 2" th:text="|${subPath?.endName}정류장 하차|">버스하차</li>
                                        </tr>
                                        <tr>
                                            <!--span th:text="${subPath?.trafficType}?:'데이터 없음'"></span-->
                                            <li th:object="${subpath}"  th:if="${subPath?.trafficType} == 1" th:text="|${subPath?.startName} ${subPath.lane.name} 승차|">지하철 승차</li>
                                        </tr>
                                        <tr>
                                            <!--span th:text="${subPath?.trafficType}?:'데이터 없음'"></span-->
                                            <li th:object="${subpath}"  th:if="${subPath?.trafficType} == 1" th:text="|${subPath?.endName}역 하차|">지하철 하차</li>
                                        </tr>
                                    </th:block>
                                    <b><span th:text="${middle}+' 도착'">서울역</span></b>
                                    <th:block th:each="subPath2 : ${path2.subPathList}">
                                        <!--li th:text="${subPath.toString()}"></li-->
                                        <tr>
                                            <!--span th:text="${subPath?.trafficType}?:'데이터 없음'"></span-->
                                            <li th:object="${subPath2}"  th:if="${subPath2?.trafficType} == 3" th:text="|걷기 ${subPath2?.sectionTime}분|">도보 이동거리</li>
                                        </tr>
                                        <tr>
                                            <!--span th:text="${subPath?.trafficType}?:'데이터 없음'"></span-->
                                            <li th:object="${subPath2}"  th:if="${subPath2?.trafficType} == 2" th:text="|${subPath2?.startName}정류장 ${subPath2.lane.busNo}번 승차|">버스탑승</li>
                                        </tr>
                                        <tr>
                                            <!--span th:text="${subPath?.trafficType}?:'데이터 없음'"></span-->
                                            <li th:object="${subPath2}"  th:if="${subPath2?.trafficType} == 2" th:text="|${subPath2?.endName}정류장 하차|">버스하차</li>
                                        </tr>
                                        <tr>
                                            <!--span th:text="${subPath?.trafficType}?:'데이터 없음'"></span-->
                                            <li th:object="${subPath2}"  th:if="${subPath2?.trafficType} == 1" th:text="|${subPath2?.startName} ${subPath2.lane.name} 승차|">지하철 승차</li>
                                        </tr>
                                        <tr>
                                            <!--span th:text="${subPath?.trafficType}?:'데이터 없음'"></span-->
                                            <li th:object="${subPath2}"  th:if="${subPath2?.trafficType} == 1" th:text="|${subPath2?.endName}역 하차|">지하철 하차</li>
                                        </tr>
                                    </th:block>
                                </table>
                                <b><span th:text="${end}+' 도착'">서울역</span></b>
                            </div>
                        </div>
                    </div>
                </div>
            </th:block>
        </th:block>
    </div>
</body>
</html>

 

 

 

5. 결과


 

* 그런데 출발~도착(경유)가 700미터 이하면... 검색 지원을 안한다.

* 우짜지

* 다음은 실시간 정보 연동

6. GitHub: 220128 add Waypoint


 

GitHub - bsh6463/commuteMap

Contribute to bsh6463/commuteMap development by creating an account on GitHub.

github.com

 

Comments