kakao map api로 지도 구현하기!

2021. 9. 26. 20:33TIL

카카오 map api

https://apis.map.kakao.com/


1. 지도 가져오기

function Map({carId, tripId}) {

    var container = document.getElementById('map'); //지도를 담을 영역의 DOM 레퍼런스
    var options = { //지도를 생성할 때 필요한 기본 옵션
        center: new kakao.maps.LatLng(33.450701, 126.570667), //지도의 중심좌표.
        level: 3 //지도의 레벨(확대, 축소 정도)
    };
    
    var map = new kakao.maps.Map(container, options); //지도 생성 및 객체 리턴

    return (
            <Container id='map'/>
    );
}

const Container = styled.div`
width: 100%;
height: 400px;
`;

 

2. 지도에 마커 올리기 & 경로 나타내기

position안에서 위도와 경도를 넣으면 지도 위 마커가 생성되는데,

나는 차량의 출발지점과 도착지점만 마커를 찍어주고 그 중간 경로는 polyline으로 띄워줄거다.

그리고 bounds를 이용해 전체 경로가 화면의 중앙에 오도록 해준다.

 

[Marker]

   var marker = new kakao.maps.Marker({
        map: map,
        position: new kakao.maps.LatLng(33.450701, 126.570667)
    });

 

[Polyline]

var polyline = new kakao.maps.Polyline({
    map: map,
    path: [
    	// polyline이 찍힐 좌표가 들어가는 배열
        // 나는 여기 받아온 좌표 배열을 맵돌려 넣어줄거다.
        // 현재는 예시
        new kakao.maps.LatLng(33.452344169439975, 126.56878163224233),
        new kakao.maps.LatLng(33.452739313807456, 126.5709308145358),
        new kakao.maps.LatLng(33.45178067090639, 126.5726886938753) 
    ],
    strokeWeight: 2,
    strokeColor: '#FF00FF',
    strokeOpacity: 0.8,
    strokeStyle: 'dashed'
});

[bounds]

var sw = new kakao.maps.LatLng(36, 127),
    ne = new kakao.maps.LatLng(37, 128);

var bounds = new kakao.maps.LatLngBounds(sw, ne); // 인자를 주지 않으면 빈 영역을 생성한다.

 

 

지도에 좌표를 찍어주는 api를 연결하기위해선 차량id와 이동경로id가 필요하다.

상위 컴포넌트에서 두 데이터를 props로 넘겨주고 api통신 후 id가 일치하는 데이터에대한 경로를 가져와준다.

경로는 배열로 이루어진 5초마다 차량의 이동 좌표들이다.

 

[위의 세 코드를 활용해 새롭게 짠 코드]

useEffect(() => {
        if (map && list.length > 0) {
            
            // 새로운 경로를 띄울때 이전 경로를 맵에서 지워주기위해 promise사용
            new Promise((resolve, reject) => {
            	// 새로운 데이터를 부를때마다 경로 지워줘야함
                // polyline이 이미 있으면 setMap(null)로 폴리라인 제거
                if (polyline) {
                    console.log('yes', polyline)
                    polyline.setMap(null)
                }
               
               // tempMarker는 출발, 도착 두개 마커
               // 새로운 tempMarker가 있으면 현재 마커 제거 해줘야함
                if (tempMarker.length > 0) {
                    for (let i in tempMarker) {
                        tempMarker[i].setMap(null)
                        if (tempMarker.length - 1 == i) {
                            resolve()
                        }
                    }
                } else {
                    resolve()
                }
            }).then((result) => {
                let imageSrc = car_start, // 마커이미지의 주소  
                imageSize = new kakao.maps.Size(64, 69), // 마커이미지의 크기
                imageOption = {offset: new kakao.maps.Point(27, 69)}; // 마커이미지 옵션: 마커의 좌표와 일치시킬 이미지 안에서의 좌표 설정
    
                // 마커의 이미지정보를 가지고 있는 마커이미지 생성
                let markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize, imageOption),
                    markerPosition = list.map(item => new kakao.maps.LatLng(item.location.latitude, item.location.longitude)); // 마커가 표시될 위치
                // 서버에서 받아온 전체 경로 좌표를 담고있는 배열인 list를 맵돌려준다.
        
        		// 차량 시작과 끝 지점의 마커를 화면의 중앙에 오도록 만들어줌
                let marker = []
                let bounds = new kakao.maps.LatLngBounds();
				// 배열의 제일 앞과 끝 좌표에 아이콘 넣어줌
                // markerPosition = list의 위도 경도만 담긴 배열
                markerPosition.map((item, index) => {
                    if (markerPosition[0] == item || markerPosition[markerPosition.length - 1] == item) {
                        marker.push(new kakao.maps.Marker({
                            position: item, // item.pa ??
                            image: markerImage
                        }))
                    }
                    bounds.extend(item); // item 좌표 포함하도록 영역 정보 확장 
                })
                map.setBounds(bounds); // 주어진 영역이 화면 안에 전부 나타날 수 있도록 지도의 중심 좌표와 확대 수준 설정

                setPolyline(new kakao.maps.Polyline({
                    map: map,
                    path:markerPosition, // polyline찍힐 좌표
                    strokeWeight: 5,
                    strokeColor: '#FF00FF',
                    strokeOpacity: 0.8,
                    strokeStyle: 'dashed'
                })
                )

                setTempMarker(marker) // 아이콘이 찍힐 첫과 끝 좌표
    
                // 마커가 지도 위에 표시되도록 설정
                marker.map(
                    item => (
                        item.setMap(map)
                    )
                )
            }).catch((e) => {
            })
        }
    }, [list])

 

많은 시행착오 끝에 완성 된 지도 경로 띄우기!

 

polyline css를 안 바꿔줘서 아직 보기좋진 않지만 그래도 쪼아... 좋은 시작이..다.....ㅎㅎㅎㅎㅎㅎ흐흐