카카오 Maps API를 이용해서 커스텀 지도를 만들기

유소정·2024년 5월 18일
1
post-thumbnail

🙋 이 문서를 보고 나면

  • 카카오 Maps API를 이용해서 커스텀 지도를 만들 수 있다.
  • 커스텀 지도를 확대 및 축소 할 수 있다.

🧑‍🚀 문서를 쓴 이유

커스텀 지도를 만드는 방법은 커스텀 타일셋1에 나와있습니다.

하지만 해당 문서는 설명이 충분하지 않아서 커스텀 지도를 만드는데 애를 먹었고,
그 과정에서 얻게 된 내용을 자세히 작성했습니다.

📝 카카오 지도를 커스텀 지도로 교체

1. 지도가 동작하는 원리를 알아야 하는 이유

지도가 동작하는 원리를 알아야 커스텀 지도를 만들 수 있습니다.

이유는 커스텀 지도 이미지 1개를 넣는다고 지도가 만들어지지 않기 때문입니다.

이동, 확대 그리고 축소가 가능하려면 1장의 이미지도 규칙에 맞게 분할해서 넣어야 합니다.
원리를 알아야 하는 이유입니다.

2. 지도가 동작하는 원리를 알아보자

커스텀 타일셋1에서 제공해준 코드를 보겠습니다.

var domain = 'https://i1.daumcdn.net';
var path = '/dmaps/apis/openapi/sampleimg/';
var plan = function( x, y, z ) {
    y = -y - 1;
    var limit = Math.ceil( 3 / Math.pow( 2, z ) );

    if ( 0 <= y && y < limit && 0 <= x && x < limit ) {
        return domain + path + 'planh' +
            z + '_' + y + '_' + x + '.png';
    } else {
        return 'https://i1.daumcdn.net/dmaps/apis/white.png';
    }
};

함수를 보면 x, y, z를 인자로 받게 됩니다.

  • x: x좌표 (0 <= x < limit)
  • y: y좌표 (0 <= y < limit)
  • z: 지도 확대 수준

z를 기준으로 limit이 결정됩니다.
이유는 확대 범위에 따라 x, y 좌표가 가능한 범위도 달라지기 때문입니다.
보여지는 범위가 많아지면 이동할 수 있는 범위도 늘어나니까요.

결론적으로 x, y, z 값을 이용해서 위치에 맞는 이미지를 불러오면 됩니다.
이렇게 해야 이미지의 화질과 이동이 자연스럽습니다.

3. 확대 범위 결정하기

확대 범위는 다음 코드로 결정할 수 있습니다.

new kakao.maps.Tileset(512, 512, plan, '', false, 최대 확대 값, 최소 확대 값)

카카오 Maps API 공식문서에서는 최솟값이 0으로, 최댓값은 2로 잡혀있습니다.
확대가 2번까지 가능한 것입니다.

kakao.maps.Tileset.add(
  'PLAN',
  new kakao.maps.Tileset(512, 512, plan, '', false, 0, 2),
);

4. 지도 분할하기

카카오 지도 Maps API에 나온 예제를 이용해서 지도를 분할해보겠습니다.

최솟값이 0으로, 최댓값은 2로 잡혀있습니다. 확대가 2번 가능한 상태입니다.

4-1. 필요한 지도의 개수 찾기

지도의 개수는 확대 범위와 관련이 있습니다. 확대 범위만큼 지도의 개수가 필요합니다.

최솟값이 0이고, 최댓값은 2라서 확대가 2번 가능하니, 지도는 3개가 필요합니다.

  • 최대 확대한 지도 (0단계)
  • 중간 지도 (1단계)
  • 최소 확대한 지도 (2단계)

위의 지도는 커스텀 타일셋1에 들어간 다음, 개발자 도구의 Network 탭에서 다운 받으실 수 있습니다.

4-2. 필요한 지도의 분할 개수 찾기

지도의 분할 개수는 x, y, z와 모두 관련이 있습니다.

위에서 지도가 3개 필요하다고 결론 내렸습니다.

그러면 각 지도마다 이동 가능한 x, y 의 범위가 있을텐데요,
x, y, z의 범위를 직접 계산해보면 필요한 지도의 분할 개수를 찾을 수 있습니다.

하지만 주어진 코드를 이용하면 x, y, z의 범위를 찾기 편합니다.

var domain = 'https://i1.daumcdn.net';
var path = '/dmaps/apis/openapi/sampleimg/';
var plan = function( x, y, z ) {
    y = -y - 1;
    var limit = Math.ceil( 3 / Math.pow( 2, z ) );

    if ( 0 <= y && y < limit && 0 <= x && x < limit ) {
      
        console.log(x, y, z); // 이 구문으로 범위를 찾으세요!
      
        return domain + path + 'planh' +
            z + '_' + y + '_' + x + '.png';
    } else {
        return 'https://i1.daumcdn.net/dmaps/apis/white.png';
    }
};![](https://velog.velcdn.com/images/kaori-killer/post/332955c9-9644-4d00-8cb9-1ed8e6dac5e1/image.png)

그럼 다음과 같은 결론을 얻을 수 있습니다.

  • 0단계

    • 0_0_0
    • 0_0_1
    • 0_0_2
    • 0_1_0
    • 0_1_1
    • 0_1_2
    • 0_2_0
    • 0_2_1
    • 0_2_2
  • 1단계

    • 1_0_0
    • 1_0_1
    • 1_1_0
    • 1_1_1
  • 2단계

    • 2_0_0

4-3. 이미지 분할 편집하기

편집은 하나의 이미지 512x512 크기가 되게 해주시면 됩니다.

  • 0단계 (1536x1536): 512x512 9장
  • 1단계 (1024x1024): 512x512 4장
  • 2단계 (512x512): 512x512 1장

피그마로 편집하시면 편합니다.

카카오 Dev Talk에 이미지를 편집해주는 툴이 없는지 문의했는데, 제공해줄 순 없다고 합니다.
직접하는 것이 답입니다.

4-4. 지도가 이상하게 보인다면?

지도를 편집하면서 3가지 문제가 발생했었습니다.

1. 지도에 언덕이 생긴다.

정사각형으로 이미지를 자르기 않아서 이미지에 균열이 생긴 것입니다. 512x512로 자르시면 문제가 없습니다.

2. 확대/축소 할 때 지도가 자연스럽지 않고, 두둥거린다

이미지의 크기를 다음과 같이 했나요?

  • 0단계 (1536x1536)
  • 1단계 (1024x1024)
  • 2단계 (512x512)

하지만 축소했을 때, 이미지 자체에 변화가 생기면 완전 다른 이미지가 됩니다.
다음과 같이 축소했을 때 이미지의 위치가 동일해야 합니다.

즉, 0단계에서 1단계로 축소했을 때 이미지가 동일해야 합니다.

2. 이미지의 화질이 안 좋다

기본 이미지를 확대한 후에 분할 작업을 진행하면, 확대했기 때문에 이미지의 화질이 떨어질 수 있습니다.

SVG로 저장하면 화질은 좋지만, 이미지의 용량이 커져서 애플리케이션의 속도가 느려집니다.

이럴 때는 피그마를 이용하면 됩니다.

저장할 때 피그마에서 배율을 5x 정도로 하면 화질이 유지됩니다. 안된다면 더 숫자를 높여보세요.

5. 커스텀 지도 기본값 설정하기

kakao.maps.Tileset.add( 'PLAN',
        new kakao.maps.Tileset(
            512, 512, plan, '', false, 0, 2 ) ); // 지도의 확대 범위

var node = document.getElementById( 'map' );
var map = new kakao.maps.Map( node, {
    projectionId: null,
    mapTypeId: kakao.maps.MapTypeId.PLAN,
    $scale: false,
    center: new kakao.maps.Coords( 650, -550 ), // 지도의 초기 좌표
    level: 2 // 지도의 초기 확대 수준
} );
var center = map.getCenter();
var marker = new kakao.maps.Marker({
    position: center
});
marker.setMap(map);

📘 정리

카카오 Maps Api를 이용해서 커스텀 지도를 만들 수 있었습니다.

지도에서 보이는 이미지는 단순히 1개의 이미지를 축소/확대 하는 것이 아니라,
여러 개의 이미지를 좌표와 확대 깊이에 맞게 불러오는 것이었습니다.

이미지를 편집하는데 시간이 꽤 걸렸지만, 커스텀 지도를 제공하는 서비스를 만드는 경험을 했습니다.

profile
기술을 위한 기술이 되지 않도록!

0개의 댓글