[Flutter] 플러터에서 Kakao Map 사용하기

Dal.001·2022년 11월 29일
0

Flutter

목록 보기
4/4
post-thumbnail

Flutter 개발중에 지도를 표시 해야할 사용해야할 일이 생겼다.
kakao map에서 지원하는 api를 사용해보기로 했다.

카카오 맵은 현재(2022.11.29) 공식적으로 플러터를 지원하지 않는다.

하지만 그렇다고 카카오 맵을 사용 할 수 없는 것은 아니다.
카카오 맵에서 지원하는 map api를 사용해서 webview 형태로 보여줄 수 있다.

구현 환경

kakaomap_webview (0.6.2)

kakao map을 웹뷰로 보여주는걸 도와주기 위해 만들어진 package이다.

그냥 webview가 한번 더 wrapping되어 있는 형태다.
해당 패키지를 사용하지 않아도 웹뷰로 다이렉트하게 구현할 수 있다.
kakaomap_webview


Kakao 지도 Web API

카카오 맵에서 지원하는 api 중, web용 api를 사용해서 웹뷰로 띄워진 카카오맵을 컨트롤 한다.
자세한 내용은 아래 웹사이트에 나와 있다.

kakao 지도 web api



동작 방식

kakaomap_webview에서 mapcontroller를 받아서,
해당 내용에게 runJavascript를 통해 js 코드를 넘겨주는 방식으로 동작한다.

만약 kakaomap_webview를 사용하지 않았다면, 그냥 웹뷰 컨트롤러에게 넘겨주면 된다.

예시)

mapController.runJavascript(
    '''
      map.panTo(new kakao.maps.LatLng(${position.latitude}, ${position.longitude}));
    '''
  );



기능 구현

기능별로 구분하고, 각각에 대한 함수를 만든 다음,
필요한 화면에서 호출하는 방식으로 구현했다.

모든 위치는 위도, 경도 값으로 설정된다.

구현할 기능은 크게 3가지로 구분했다.

1. 마커표시

지도 위에 마커를 표시하는 기능이다.
마커의 위치를 전달해주면 해당 위치에 지도 위에 마커가 표시된다.

마커의 이미지를 따로 전달해 줄 수도 있다.
따로 명시하지 않으면, 카카오 맵의 기본 마커가 표시된다.

예시)
1. 마커 이미지를 따로 명시한 경우

mapController.runJavascript(
    '''
    function addMarker(position) {
      let imageSrc = 'https://마커이미지주소'; // 마커이미지의 주소    
      let imageSize = new kakao.maps.Size(15, 15); // 마커이미지의 크기
      let imageOption = {offset: new kakao.maps.Point(1, 1)};

      // 마커의 이미지정보를 가지고 있는 마커이미지를 생성합니다
      let markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize, imageOption);

      let testMarker = new kakao.maps.Marker({
        position: position,
        image: markerImage
      });

      testMarker.setMap(map);
    }

    addMarker(new kakao.maps.LatLng(${position.latitude} + 0.0003, ${position.longitude} + 0.0003));

    '''
  );
  1. 마커 이미지에 기본 값이 들어가는 경우(비명시)
    mapController.runJavascript(
      '''
      function addMarker(position) {
        let testMarker = new kakao.maps.Marker({
          position: position,
        });

        testMarker.setMap(map);
      }
      addMarker(new kakao.maps.LatLng(${positionList[i].latitude}, ${positionList[i].longitude}));
      '''
    );

2. 시점 이동

카메라를 특정 위치로 움직이는 기능이다.
panTo 기능을 사용한다.

mapController.runJavascript(
    '''
      map.panTo(new kakao.maps.LatLng(${position.latitude}, ${position.longitude}));
    '''
  );

3. Zoom 컨트롤

Zoom In/Zoom Out을 컨트롤 하는 기능이다.
setLevel 기능을 사용한다.

  mapController.runJavascript(
    '''
      map.setLevel($level);
    '''
  );



Work around

1. 현재위치 표시

현재 위치 표시하는 기능이 없어서 곤란했다.

현재 위치를 표시하기 위해서 마커를 사용하면, 마커가 내가 이동하는 길에 계속 생겨서 원하는 대로 동작하지 않는다.(헨젤과 그레텔?)

그래서 마커를 만들고 바로 일정 시간 뒤에 마커를 지우도록 (setTimeout 사용) 설정했다.

그리고 이 일정시간에 해당하는 값을 동일하게 플러터에서도 적용시켜, 일정시간마다 현재 위치를 체크하고 마커를 표시한다.

이러면 내 위치를 지속적으로 트래킹하고 마커도 하나로 유지할 수 있다.

예시)

updateMyMaker(mapController, Coordinate position){
  mapController.runJavascript(
    '''
      markers = [];
      function addMarker(position) {
        let imageSrc = 'https://raw.githubusercontent.com/hyunminyoo/wdygo_flutter/main/red_dot_with_%20halo.png'; // 마커이미지의 주소    
        let imageSize = new kakao.maps.Size(15, 15); // 마커이미지의 크기
        let imageOption = {offset: new kakao.maps.Point(1, 1)};

        // 마커의 이미지정보를 가지고 있는 마커이미지를 생성합니다
        let markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize, imageOption);

        let testMarker = new kakao.maps.Marker({
          position: position,
          image: markerImage
        });

        markers.push(testMarker);

        testMarker.setMap(map);
      }

      function deleteMarker() {
          for (var i = 0; i < markers.length; i++) {
              markers[i].setMap(null);
          }
      }

      addMarker(new kakao.maps.LatLng(${position.latitude} + 0.0003, ${position.longitude} + 0.0003));
      setTimeout(()=>{
        deleteMarker();
      }, ${UPDATE_LOC_TIME_SECONDS * 1000});
    '''
  );
}

또한 여기서 삭제할 리스트(markers)를 관리하고 있어야하는데, 이 리스트가 이미 선언 되었는지 런타임내에서 혼동이 오는 문제 때문에, 따로 분기해서 처리했다.

2. 초기 마커 표시 오류

kakaomap_webview 에서 있는 문제인데,
초기 값이 먼저 들어가고, 내 현재 위치 정보가 나중에 불러지기 때문에
처음에 원하지 않는 곳에 마커가 생겨버리는 오류가 발생한다.

이를 방지하기 위해서, 초기에 설정하는 값에는 마커가 보이지 않도록 설정했다.

마커 url에 투명한 이미지에 해당하는 값을 넣어서 해결했다.

profile
App/Server Software Engineer

1개의 댓글

comment-user-thumbnail
2023년 11월 14일

안녕하세요
위 내용으로 플러터 공부중인데 전체 소스를 받아볼 수 있을까요?..

답글 달기