본문 바로가기
스터디일지/PROJECT

Final Project - Random Navi - 마커 표시하기 - 최근 목적지 - PART 4

by 똥쟁이핑크 2023. 11. 5.

네비게이션에서 경로 안내를 받으면 

안내 받은 경로 그대로 저장이 된다.

 

경로가 저장이 되면 최근 목적지에 들어가서 확인이 가능하다.

최근 목적지를 클릭하고 들어가면

그동안 안내 받았던 경로 목록이 뜨고 그 경로를 다시 가고 싶다면 해당 목록을 클릭해서 

그 경로 그대로 안내가 된다.

 

다만, 출발지, 도착지, 경유지 마커가 표시 되지 않아

경로만 본다면 어디서 출발하고 도착하는지 또 어디를 경유하는지 알수가 없다.

그래서 마커를 표시하기로 했다.

 

마커를 표시하기 전에 좌표를 알아야 해서

data를 확인했고 내용은 다음과 같다.

 

내용 대로만 본다면 histories.js에서 가능할 것 같아 코드를 다음과 같이 짰다.

1차 코드는 최근 목적지의 행의 route_id를 가져와서 코드를 구현했는데 다음과 같다.

// 히스토리 마커
function historiesMarker(historiesData){
    history.forEach(item => {
        const routeData = item;

        const originAddress = routeData.originAddress;
        const destinationAddress = routeData.destinationAddress;

        // 주소-좌표 변환 객체를 생성합니다
        var geocoder = new kakao.maps.services.Geocoder();

        var addresses = [originAddress, destinationAddress];
        addresses.forEach(address => {
            geocoder.addressSearch(address, function (result, status) {
                // 정상적으로 검색이 완료됐으면
                if (status === kakao.maps.services.Status.OK) {
                    historiesMakeMarker(result);
                    const json = JSON.stringify(address);
                    console.log(document.write(json));
                }
            });
        });
    });
}

function historiesMakeMarker(result) {
    // 출발지 도착지 마커 표시하기
    var let_ori = result[0].y;
    var lon_ori = result[0].x;
    var lat_des = result[1].y;
    var lon_des = result[1].x;

    var positions = [
        {
            title: '출발',
            latlng: new kakao.maps.LatLng(let_ori, lon_ori),
            image: 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/red_b.png'
            //"https://cdn-icons-png.flaticon.com/512/6213/6213694.png"
        },
        {
            title: '도착',
            latlng: new kakao.maps.LatLng(lat_des, lon_des),
            image: 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/blue_b.png'
            //"https://cdn-icons-png.flaticon.com/512/4856/4856582.png"
        }

    ]
// 마커를 지도에 표시하기
    for (var i = 0; i < positions.length; i++) {
        // 마커 이미지 크기
        var imageSize = new kakao.maps.Size(30, 40);
        var markerImage = new kakao.maps.MarkerImage(positions[i].image, imageSize);
        var marker = new kakao.maps.Marker({
            map: map,
            position: positions[i].latlng,
            title: positions[i].title,
            image: markerImage,
        })
    }

// 경유지 마커 표시
    var imageWay = 'https://file.notion.so/f/f/0bb6a7f0-5b10-43e2-ad69-0657263c6dff/ccc1ee90-0fa2-4d98-a1a6-80f40600896f/%EA%B2%BD%EC%9C%A0%EC%A7%80-01.png?id=6eaca2df-ea86-468a-bf07-51df643bf11b&table=block&spaceId=0bb6a7f0-5b10-43e2-ad69-0657263c6dff&expirationTimestamp=1698933600000&signature=256uSQ0yL4SEQ_vhA4Ejx0_PTykB_Nj-2KJev6apoOI&downloadName=%EA%B2%BD%EC%9C%A0%EC%A7%80-01.png';
    var imageSize = new kakao.maps.Size(40, 35);
    // 마커 이미지를 생성합니다
    var markerImage = new kakao.maps.MarkerImage(imageWay, imageSize);

    // 경유지 마커 표시하기
    for (var i = 0; i < data.routes[0].sections.length; i++) {
        var section = data.routes[0].sections[i];
        for (var j = 0; j < section.guides.length; j++) {
            var guide = section.guides[j];
            if (guide.type === 1000) {
                var lat_way = guide.y;
                var lon_way = guide.x;

                var latlng = new kakao.maps.LatLng(lat_way, lon_way)

                var marker = new kakao.maps.Marker({
                    map: map,
                    position: latlng,
                    image: markerImage
                });
            }
        }
    }
}

 

위의 코드로 진행 했을 때는 해당 주소로 좌표를 받아 올수 없기 때문에 수정했다.

 

2차 코드는 api를 요청 할수 있는 navi.js에서 진행했는데 histories.js는 경로만 저장하게끔 되어 있고 값을 받아올수 없는 구조여서 주소를 요청 할 수 있도록 설계된 navi.js에서 진행했다.

// 2차 코드
const markerOriginAddress = history.originAddress;
const markerDestinationAddress = history.destinationAddress;

......


 if (markerOriginAddress !== null || markerDestinationAddress !== null) {
                    historiesMarker(markerOriginAddress, markerDestinationAddress);
                }
                
                ....
                
                }
                
        }
}
                
                
// 히스토리 마커
function historiesMarker(formattedOriginAddress, formattedDestinationAddress, row) {

    // 주소-좌표 변환 객체를 생성합니다
    var geocoder = new kakao.maps.services.Geocoder();

    var addresses = [formattedOriginAddress, formattedDestinationAddress];
    addresses.forEach(address => {
        geocoder.addressSearch(address, function (result, status) {
            // 정상적으로 검색이 완료됐으면
            if (status === kakao.maps.services.Status.OK) {
                historiesMakeMarker(result);
            }
        });
    });
}


function historiesMakeMarker(result) {
    // 출발지 도착지 마커 표시하기
    var let_ori = result[0].y;
    var lon_ori = result[0].x;
    var lat_des = result[1].y;
    var lon_des = result[1].x;

    var positions = [
        {
            title: '출발',
            latlng: new kakao.maps.LatLng(let_ori, lon_ori),
            image: 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/red_b.png'
            //"https://cdn-icons-png.flaticon.com/512/6213/6213694.png"
        },
        {
            title: '도착',
            latlng: new kakao.maps.LatLng(lat_des, lon_des),
            image: 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/blue_b.png'
            //"https://cdn-icons-png.flaticon.com/512/4856/4856582.png"
        }

    ]
// 마커를 지도에 표시하기
    for (var i = 0; i < positions.length; i++) {
        // 마커 이미지 크기
        var imageSize = new kakao.maps.Size(30, 40);
        var markerImage = new kakao.maps.MarkerImage(positions[i].image, imageSize);
        var marker = new kakao.maps.Marker({
            map: map,
            position: positions[i].latlng,
            title: positions[i].title,
            image: markerImage,
        })
    }

// 경유지 마커 표시
    var imageWay = 'https://file.notion.so/f/f/0bb6a7f0-5b10-43e2-ad69-0657263c6dff/ccc1ee90-0fa2-4d98-a1a6-80f40600896f/%EA%B2%BD%EC%9C%A0%EC%A7%80-01.png?id=6eaca2df-ea86-468a-bf07-51df643bf11b&table=block&spaceId=0bb6a7f0-5b10-43e2-ad69-0657263c6dff&expirationTimestamp=1698933600000&signature=256uSQ0yL4SEQ_vhA4Ejx0_PTykB_Nj-2KJev6apoOI&downloadName=%EA%B2%BD%EC%9C%A0%EC%A7%80-01.png';
    var imageSize = new kakao.maps.Size(40, 35);
    // 마커 이미지를 생성합니다
    var markerImage = new kakao.maps.MarkerImage(imageWay, imageSize);

    // 경유지 마커 표시하기
    for (var i = 0; i < data.routes[0].sections.length; i++) {
        var section = data.routes[0].sections[i];
        for (var j = 0; j < section.guides.length; j++) {
            var guide = section.guides[j];
            if (guide.type === 1000) {
                var lat_way = guide.y;
                var lon_way = guide.x;

                var latlng = new kakao.maps.LatLng(lat_way, lon_way)

                var marker = new kakao.maps.Marker({
                    map: map,
                    position: latlng,
                    image: markerImage
                });
            }
        }
    }
}

 

// 3차 코드
// 히스토리 마커용 추가

    // // Initialize markers for departure and arrival
    // let departureMarker, arrivalMarker;
    //
    // for (var i = 0; i < data.guides.length; i++) {
    //     if (data.guides[i].type === 100) {
    //         var lat_ori = data.guides[i].y;
    //         var lng_ori = data.guides[i].x;
    //
    //         departureMarker = new kakao.maps.Marker({
    //             position: new kakao.maps.LatLng(lat_ori, lng_ori),
    //             title: '출발',
    //             image: 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/red_b.png'
    //         });
    //     }
    //
    //     if (data.guides[i].type === 101) {
    //         var lat_des = data.guides[i].y;
    //         var lng_des = data.guides[i].x;
    //
    //         arrivalMarker = new kakao.maps.Marker({
    //             position: new kakao.maps.LatLng(lat_des, lng_des),
    //             title: '도착',
    //             image: 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/blue_b.png'
    //         });
    //     }
    // }

 

실제로 굉장히 많이 코드를 수정했지만 

2~3차 코드에서 크게 바뀌지 않아서 2~3차 코드만 첨부했다.

위의 코드에서의 문제점은 다음과 같다.

 

1. 경로를 찾을 수 없는 문제점.

- 이 문제는 histories.js에서 넘어오는 Address 정보가 넘어올때 split해서 가공한 정보가 넘어 오기 때문에 original이 아니다.

 

2. 코드의 문제점

- historiesMarker의 함수에서 또 make함수로 넘어가는데 make함수에서는 이중 for문이 있기에 계산 하는 과정에서 시간이 초과해서 롤백이 되어 버렸다.

- 계산이 되었다 해도 original이 아닌 주소로 계산을 했기 때문에 경로가 맞지 않아 catch문에 있는 error로 넘어가게 된다. - 문제점을 인지하기 까지 시간이 좀 걸렸다. 

 

 

해결책

1. console.log로 넘어오는 data 확인하기

- 코드 내에서 log를 찍어 가며 데이터 값을 확인하였고 

최종적으로는 관리자 도구 Console에서 데이터 값을 다시 한번 확인했고 결과는 아래와 같다.

 

2. 넘어오는 data로 코드 다시 재수정하기

data안에 guides에서 원하는 값이 담기는것을 다시 한번 확인했고

코드를 재수정했다.

var imageSize = new kakao.maps.Size(30, 40); // 출발지와 도착지의 이미지 크기는 동일하게 가져가기 위해 먼저 선언함
for (var i = 0; i < data.guides.length; i++) {
    if (data.guides[i].type === 100) { // 100은 출발지
        var lat_ori = data.guides[i].y;
        var lng_ori = data.guides[i].x;
    }

    if (data.guides[i].type === 101) { // 101은 도착지
        var lat_des = data.guides[i].y;
        var lng_des = data.guides[i].x;
    }


    var positions = [
        {
            title: '출발',
            latlng: new kakao.maps.LatLng(lat_ori, lng_ori),
            image: 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/red_b.png'
            //"https://cdn-icons-png.flaticon.com/512/6213/6213694.png"
        },
        {
            title: '도착',
            latlng: new kakao.maps.LatLng(lat_des, lng_des),
            image: 'https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/blue_b.png'
            //"https://cdn-icons-png.flaticon.com/512/4856/4856582.png"
        }
    ]

}
// 마커를 지도에 표시하기
for (var i = 0; i < positions.length; i++) {
    // 마커 이미지 크기

    var markerImage = new kakao.maps.MarkerImage(positions[i].image, imageSize);
    var marker = new kakao.maps.Marker({
        map: map,
        position: positions[i].latlng,
        title: positions[i].title,
        image: markerImage,
    })
}

// 경유지 마커 표시
var imageWay = 'https://cdn-icons-png.flaticon.com/128/4198/4198066.png';
var imageSize = new kakao.maps.Size(40, 35);
// 마커 이미지를 생성합니다
var markerImage = new kakao.maps.MarkerImage(imageWay, imageSize);
// 경유지 마커 표시하기
for (var i = 0; i < data.guides.length; i++) {
    if (data.guides[i].type === 1000) { // 경유지
        var lat_way = data.guides[i].y;
        var lon_way = data.guides[i].x;

        var latlng = new kakao.maps.LatLng(lat_way, lon_way)

        var marker = new kakao.maps.Marker({
            map: map,
            position: latlng,
            image: markerImage
        });
    }
}

marker.setMap(map) // 지도에 표시하기

 

 

마커를 표시하는 코드를 짜면서 

다시한번 느꼈다.

1. 코드 흐름을 한번 더 제대로 확인하기

2. 데이터 값이 어떻게 형성되는지 확인하기

3. 1~2번은 제발 잊어버리지 말자.....

 

위의 코드 결과는 아래와 같은데 생각한 대로 잘 나왔다.

 

 

 

참고한 사이트

https://apis.map.kakao.com/web/documentation/#Marker,

https://apis.map.kakao.com/web/sample/multipleMarkerImage/,

https://apis.map.kakao.com/web/sample/staticMapWithMarker/,

https://apis.map.kakao.com/web/sample/addr2coord/,

https://apis.map.kakao.com/web/sample/staticMapWithMarkerText/