Skip to main content
Guides

Google Maps DrawingManager와 API 지원 중단: 2026 마이그레이션 가이드

Drawing Library와 Heatmap Layer는 Maps JavaScript API에서 제거되었습니다. DirectionsService와 DistanceMatrixService는 Legacy 상태이며 지원 중단되었습니다. 현재 상태, 날짜, 대체 수단을 정리합니다.

Brent van der Heiden최종 업데이트 19 min read
#Google Maps API#API 마이그레이션#DrawingManager#DirectionsService#경로 탐색#개발자 가이드
Google Maps DrawingManager와 API 지원 중단: 2026 마이그레이션 가이드

Google은 지난 18개월 동안 Maps JavaScript API에서 널리 쓰이던 기능 네 가지를 지원 중단했습니다. 그중 Heatmap Layer와 Drawing Library는 2026년 5월부터 사용할 수 없습니다. 나머지 DirectionsService와 DistanceMatrixService는 Legacy 상태이며 지원 중단되었지만, 여전히 작동하고 종료 날짜도 없습니다.

이 가이드는 각 기능의 현재 상태를 Google 공식 페이지 링크와 함께 정리하고 교체 방법을 설명합니다. MapAtlas를 대안으로 쓰는 부분의 코드는 실제 엔드포인트와 응답 형식을 사용합니다.

지원 중단된 것과 아직 작동하는 것

서비스상태주요 날짜Google의 대안
Heatmap Layer제거됨2025년 5월 27일 지원 중단, 3.65.1c 버전(2026년 5월 20일)에서 서비스 종료deck.gl 같은 서드파티 라이브러리
Drawing Library(DrawingManager)제거됨2025년 8월 지원 중단, 2026년 5월부터 사용 불가(3.65.3b 버전, 2026년 6월 4일에 확인)Terra Draw 같은 서드파티 라이브러리
DirectionsServiceLegacy, 지원 중단2025년 3월 1일부터 Legacy, 2026년 2월 25일부터 지원 중단(3.64.2b 버전), 종료 날짜 없음Routes 라이브러리의 Route 클래스
DistanceMatrixServiceLegacy, 지원 중단2025년 3월 1일부터 Legacy, 2026년 2월 25일부터 지원 중단(3.64.2b 버전), 종료 날짜 없음Routes 라이브러리의 RouteMatrix 클래스

출처: Google Maps Platform 지원 중단 페이지, Maps JavaScript API 릴리스 노트, Legacy 제품 페이지.

Legacy에는 정해진 의미가 있습니다. Google에 따르면 Legacy 서비스는 새 기능이 추가되지 않고 새 Cloud 프로젝트에서 활성화할 수 없지만, 기존 프로젝트에서는 계속 지원됩니다. Google은 이런 서비스를 종료하기 최소 12개월 전에 공지하겠다고 약속했으며, DirectionsService와 DistanceMatrixService를 지원 중단한 릴리스 노트도 종료 계획이 없고 심각한 회귀 문제는 계속 수정된다고 밝힙니다. 2025년 3월 1일의 같은 Legacy 전환에는 웹 서비스인 Directions API와 Distance Matrix API, 그리고 Places API와 JavaScript Places Service도 포함되었습니다.

작동하지 않는 코드

다음 코드는 현재 버전의 Maps JavaScript API에서 이미 실패합니다.

// Removed in 2026: these constructors no longer work
const heatmap = new google.maps.visualization.HeatmapLayer({ data: points });
const drawingManager = new google.maps.drawing.DrawingManager();

다음 코드는 기존 프로젝트에서는 아직 실행되지만 지원 중단되었으며, 새 Cloud 프로젝트에서는 작동하지 않습니다.

// Legacy and deprecated, no shutdown date yet
const directionsService = new google.maps.DirectionsService();
const distanceMatrixService = new google.maps.DistanceMatrixService();

사이트의 히트맵이나 그리기 도구가 2026년 5월에 작동을 멈췄다면 원인은 이것입니다. 먼저 이 부분을 고치십시오. 그다음 Google이 날짜를 발표하기 전에 경로 탐색 마이그레이션을 계획하십시오.

Google이 제공하는 대안

경로 탐색에 대해 Google은 두 가지 방법을 제공하며, 둘 다 로직을 서버로 옮기라고 강요하지 않습니다.

  • 브라우저에서: Maps JavaScript API의 Routes 라이브러리. Route 클래스가 DirectionsService를, RouteMatrix 클래스가 DistanceMatrixService를 대체합니다.
  • 서버에서: Compute Routes와 Compute Route Matrix 메서드를 제공하는 REST 서비스인 Routes API.

시각화에 대해서는 Google 자체 옵션이 더 이상 없습니다. 히트맵 페이지는 deck.gl을 안내하고, 지원 중단 페이지는 그리기용으로 Terra Draw를 제시합니다.

마이그레이션 체크리스트

1. 코드베이스 점검

해당 클래스를 검색합니다.

# Find all files using deprecated Google Maps services
grep -rn "DirectionsService\|DistanceMatrixService\|DirectionsRenderer\|HeatmapLayer\|DrawingManager" \
  --include="*.js" --include="*.ts" --include="*.tsx" --include="*.jsx" src/

이 클래스를 쓰는 모든 파일과 컴포넌트를 기록하고, 각 호출이 브라우저와 서버 중 어디에서 실행되는지 적어 두십시오.

2. 서비스별 사용 방식 기록

사용 위치마다 다음을 기록합니다.

  • 이동 수단(자동차, 도보, 자전거, 대중교통)
  • 경유지(단순한 A에서 B, 또는 여러 정류장을 거치는 경로)
  • 읽는 응답 필드(거리, 소요 시간, 폴리라인, 단계, 요금)
  • 사용량(비용 추정을 위한 일별, 월별 요청 수)
  • 지연 시간 요구 사항(사용자 대상 실시간 처리 또는 일괄 처리)

3. 대상 선택

옵션 A: Google을 계속 사용합니다. Route와 RouteMatrix 클래스 또는 Routes API로 옮기십시오. 응답 형식이 Legacy 클래스와 다르므로 사용하는 필드를 마이그레이션 가이드와 대조하십시오.

옵션 B: 제공업체를 바꿉니다. 어차피 통합 코드를 다시 작성해야 하므로 2단계의 요구 사항을 기준으로 제공업체를 비교하십시오.

4. 기존과 새 구현 병행 운영

제자리에서 바로 교체하지 마십시오. 한동안 두 구현을 함께 실행하고, 전환하기 전에 실제 경로에서 거리, 소요 시간, 지연 시간을 비교하십시오.

5. 오류 처리 업데이트

Legacy 클래스는 콜백의 상태 값으로 오류를 알렸습니다. REST 대안은 HTTP 상태 코드와 오류 본문을 반환하므로 오류 처리도 바꿔야 합니다.

MapAtlas로 각 서비스 교체하기

MapAtlas의 경로 탐색 엔드포인트는 gateway.mapmetrics-atlas.net에 있는 REST 서비스이며 MapAtlas API 문서에 설명되어 있습니다. 토큰을 쿼리 매개변수로 받으므로 백엔드에서 호출하십시오.

DirectionsService에서 MapAtlas Directions API로

이전(Google, Legacy):

const directionsService = new google.maps.DirectionsService();

directionsService.route(
  {
    origin: { lat: 52.52, lng: 13.405 },
    destination: { lat: 48.8566, lng: 2.3522 },
    travelMode: google.maps.TravelMode.DRIVING,
    waypoints: [
      { location: { lat: 50.9375, lng: 6.9603 }, stopover: true }
    ],
  },
  (result, status) => {
    if (status === "OK") {
      const route = result.routes[0];
      console.log("Distance:", route.legs[0].distance.text);
      console.log("Duration:", route.legs[0].duration.text);
    }
  }
);

이후(MapAtlas Directions API):

const response = await fetch(
  `https://gateway.mapmetrics-atlas.net/directions/?token=${process.env.MAPATLAS_API_KEY}`,
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      // Ordered stops: origin, waypoints, destination
      locations: [
        { lat: 52.52, lon: 13.405 },
        { lat: 50.9375, lon: 6.9603 },
        { lat: 48.8566, lon: 2.3522 },
      ],
      costing: "auto", // auto, bicycle, pedestrian, bus, truck, taxi, motor_scooter
      units: "kilometers",
    }),
  }
);

const { trip } = await response.json();
console.log("Distance (km):", trip.summary.length);
console.log("Duration (s):", trip.summary.time);
// Each leg carries its geometry as an encoded polyline (precision 6)
const shapes = trip.legs.map((leg) => leg.shape);

주요 차이점:

  • JavaScript 클래스 대신 백엔드에서 실행하는 REST 호출입니다.
  • 경유지는 locations의 중간 항목입니다.
  • 응답 구조가 다릅니다. 합계는 trip.summary에 있고, 각 구간은 shape에 인코딩된 폴리라인을 가집니다. 경로를 그리기 전에 디코딩하십시오(아래 백엔드 예제 참고).

DistanceMatrixService에서 MapAtlas Matrix API로

MapAtlas Matrix API는 출발지와 목적지의 모든 쌍에 대해 이동 시간과 거리를 한 번의 호출로 반환합니다. 이 엔드포인트는 각 쌍의 경로 거리를 400km로 제한하므로 예제에서는 베를린 주변 지역을 사용합니다.

이전(Google, Legacy):

const service = new google.maps.DistanceMatrixService();

service.getDistanceMatrix(
  {
    origins: [
      { lat: 52.52, lng: 13.405 },
      { lat: 52.3906, lng: 13.0645 },
    ],
    destinations: [
      { lat: 51.3397, lng: 12.3731 },
      { lat: 51.0504, lng: 13.7373 },
    ],
    travelMode: google.maps.TravelMode.DRIVING,
  },
  (response, status) => {
    if (status === "OK") {
      response.rows.forEach((row, i) => {
        row.elements.forEach((element, j) => {
          console.log(`Origin ${i} -> Dest ${j}:`,
            element.distance.text, element.duration.text);
        });
      });
    }
  }
);

이후(MapAtlas Matrix API):

const response = await fetch(
  `https://gateway.mapmetrics-atlas.net/matrix/?token=${process.env.MAPATLAS_API_KEY}`,
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      sources: [
        { lat: 52.52, lon: 13.405 },
        { lat: 52.3906, lon: 13.0645 },
      ],
      targets: [
        { lat: 51.3397, lon: 12.3731 },
        { lat: 51.0504, lon: 13.7373 },
      ],
      costing: "auto",
      units: "kilometers",
    }),
  }
);

const data = await response.json();

// One row per source, one cell per target
data.sources_to_targets.forEach((row: any[], i: number) => {
  row.forEach((cell, j) => {
    console.log(`Origin ${i} -> Dest ${j}:`, cell.distance, "km", cell.time, "s");
  });
});

이 격자는 Google의 rows와 elements에 해당합니다. 거리는 요청한 단위의 숫자로, 시간은 초 단위로 반환되므로 표시 형식은 직접 맞추십시오.

Heatmap Layer 대체

옵션 1: MapLibre GL JS 히트맵 레이어(오픈 소스)

import maplibregl from "maplibre-gl";

const map = new maplibregl.Map({
  container: "map",
  style: "https://gateway.mapmetrics-atlas.net/styles/?fileName=YOUR_ACCOUNT_ID/mapstyle.json&token=YOUR_API_KEY",
  center: [13.405, 52.52],
  zoom: 10,
});

map.on("load", () => {
  map.addSource("heat-data", {
    type: "geojson",
    data: {
      type: "FeatureCollection",
      features: heatmapPoints.map((point) => ({
        type: "Feature",
        geometry: { type: "Point", coordinates: [point.lng, point.lat] },
        properties: { weight: point.weight },
      })),
    },
  });

  map.addLayer({
    id: "heatmap-layer",
    type: "heatmap",
    source: "heat-data",
    paint: {
      "heatmap-weight": ["get", "weight"],
      "heatmap-intensity": 1,
      "heatmap-radius": 20,
      "heatmap-opacity": 0.7,
    },
  });
});

히트맵은 추가 서비스 없이 지도 라이브러리에서 직접 렌더링됩니다.

옵션 2: Google 문서가 권장하는 deck.gl HeatmapLayer

import { HeatmapLayer } from "@deck.gl/aggregation-layers";

const heatmapLayer = new HeatmapLayer({
  data: heatmapPoints,
  getPosition: (d) => [d.lng, d.lat],
  getWeight: (d) => d.weight,
  radiusPixels: 30,
});

둘 다 사용할 수 있습니다. MapLibre GL JS는 MapAtlas 스타일을 직접 읽고, deck.gl은 어떤 베이스맵 위에도 올릴 수 있습니다.

Drawing Library 대체

DrawingManager를 쓰면 사용자가 지도에 마커, 선, 원, 다각형을 그릴 수 있었습니다. Google 지원 중단 페이지가 제시하는 Terra Draw는 같은 그리기 모드를 제공하며 Google Maps와 MapLibre GL JS를 포함한 여러 지도 라이브러리용 어댑터가 있습니다. 그린 도형은 GeoJSON으로 반환되므로 그대로 저장하거나 지오펜싱 또는 등시선 서비스에 보낼 수 있습니다.

비용 비교

Google 정가는 경로 탐색 Legacy SKU와 그 대안인 Essentials SKU가 같습니다. 아래 가격은 모두 Google Maps Platform 가격 페이지와 MapAtlas 가격 페이지에서 가져왔으며 2026년 9월 26일에 확인했습니다.

서비스Google 월 무료 사용량Google 초과분 1,000건당(첫 구간)MapAtlas 월 무료 사용량MapAtlas 초과분 1,000건당(첫 구간)
Directions(Legacy) 또는 Compute Routes Essentials10,0005.00달러내비게이션 요청 100,000건1.53유로
Directions Advanced(Legacy) 또는 Compute Routes Pro5,00010.00달러같은 내비게이션 구간1.53유로
Distance Matrix(Legacy) 또는 Compute Route Matrix Essentials10,000개 요소5.00달러가격 페이지 참고가격 페이지 참고
Geocoding10,0005.00달러25,0003.90유로

Google은 미국 달러로, MapAtlas는 유로로 청구하므로 비교 전에 환산하십시오. 두 곳 모두 사용량이 많을수록 단가가 낮아집니다. 월 50만 건의 경로 요청을 예로 계산하면 다음과 같습니다.

  • Google Compute Routes Essentials: 10,000건 무료, 90,000건은 5.00달러, 400,000건은 4.00달러로 합계 2,050달러.
  • MapAtlas 내비게이션: 100,000건 무료, 400,000건은 1.53유로로 합계 약 610유로.

전체 예제: 백엔드 경로와 지도

이 구성은 API 키를 서버에 두고 브라우저에는 경로 지오메트리만 보냅니다.

백엔드 API 경로(Next.js)

// app/api/directions/route.ts
import { NextRequest, NextResponse } from "next/server";

// Decode an encoded polyline with precision 6 into [lon, lat] pairs
function decodePolyline6(str: string): [number, number][] {
  const coords: [number, number][] = [];
  let index = 0, lat = 0, lng = 0;
  while (index < str.length) {
    for (const axis of [0, 1]) {
      let result = 0, shift = 0, byte: number;
      do {
        byte = str.charCodeAt(index++) - 63;
        result |= (byte & 0x1f) << shift;
        shift += 5;
      } while (byte >= 0x20);
      const delta = result & 1 ? ~(result >> 1) : result >> 1;
      if (axis === 0) lat += delta; else lng += delta;
    }
    coords.push([lng / 1e6, lat / 1e6]);
  }
  return coords;
}

export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url);
  const [oLat, oLon] = searchParams.get("origin")!.split(",").map(Number);
  const [dLat, dLon] = searchParams.get("destination")!.split(",").map(Number);

  const response = await fetch(
    `https://gateway.mapmetrics-atlas.net/directions/?token=${process.env.MAPATLAS_API_KEY}`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        locations: [{ lat: oLat, lon: oLon }, { lat: dLat, lon: dLon }],
        costing: "auto",
        units: "kilometers",
      }),
    }
  );
  if (!response.ok) {
    return NextResponse.json({ error: "routing failed" }, { status: 502 });
  }

  const { trip } = await response.json();
  const coordinates = trip.legs.flatMap((leg: { shape: string }) => decodePolyline6(leg.shape));
  return NextResponse.json({
    coordinates,
    distanceKm: trip.summary.length,
    durationS: trip.summary.time,
  });
}

지도 컴포넌트(React와 MapLibre GL JS)

import { useEffect, useRef } from "react";
import maplibregl from "maplibre-gl";

function DirectionsMap({ origin, destination }: {
  origin: { lat: number; lng: number };
  destination: { lat: number; lng: number };
}) {
  const mapRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const map = new maplibregl.Map({
      container: mapRef.current!,
      style: "https://gateway.mapmetrics-atlas.net/styles/?fileName=YOUR_ACCOUNT_ID/mapstyle.json&token=YOUR_API_KEY",
      center: [origin.lng, origin.lat],
      zoom: 7,
    });

    map.on("load", async () => {
      const res = await fetch(
        "/api/directions?" +
          new URLSearchParams({
            origin: `${origin.lat},${origin.lng}`,
            destination: `${destination.lat},${destination.lng}`,
          })
      );
      if (!res.ok) return;
      const { coordinates } = await res.json();

      map.addSource("route", {
        type: "geojson",
        data: {
          type: "Feature",
          geometry: { type: "LineString", coordinates },
          properties: {},
        },
      });

      map.addLayer({
        id: "route-line",
        type: "line",
        source: "route",
        paint: { "line-color": "#4A90D9", "line-width": 5 },
      });

      const bounds = coordinates.reduce(
        (b: maplibregl.LngLatBounds, coord: [number, number]) => b.extend(coord),
        new maplibregl.LngLatBounds(coordinates[0], coordinates[0])
      );
      map.fitBounds(bounds, { padding: 50 });
    });

    return () => map.remove();
  }, [origin, destination]);

  return <div ref={mapRef} style={{ width: "100%", height: "400px" }} />;
}

마이그레이션 테스트 방법

1단계: 두 구현 비교

테스트 기간 동안 같은 요청으로 기존 서비스와 새 서비스를 모두 호출합니다. 두 응답의 거리와 소요 시간을 기록하고 실제 경로에서 차이를 확인하십시오. 특히 페리, 유료 도로, 통행 제한 도로를 살펴보십시오.

2단계: 기능 플래그 사용

배포 없이 되돌릴 수 있도록 제공업체 선택을 플래그 뒤에 두십시오.

const useMapAtlasDirections = process.env.FEATURE_MAPATLAS_DIRECTIONS === "true";

const directions = useMapAtlasDirections
  ? await fetchMapAtlasDirections(origin, destination)
  : await fetchGoogleDirections(origin, destination);

3단계: 오류율 모니터링

전환 후에는 다음을 모니터링하십시오.

  • 새 API의 HTTP 4xx 및 5xx 비율
  • 지연 시간 변화
  • UI가 읽는 누락된 필드
  • 페리, 유료 도로, 통행 제한 구역 같은 예외 상황의 경로 차이

4단계: 출시 전 부하 테스트

물류 플랫폼의 아침 배차처럼 트래픽이 몰리는 시간이 있다면, 새 API에 의존하기 전에 최대 트래픽의 두 배로 부하 테스트를 하십시오.

지금 해야 할 일

  1. Heatmap Layer나 Drawing Library를 아직 불러오고 있다면: 먼저 교체하십시오. 현재 버전의 Maps JavaScript API에서는 더 이상 작동하지 않습니다.
  2. 경로 탐색 코드 점검: DirectionsService, DirectionsRenderer, DistanceMatrixService 호출을 모두 찾으십시오.
  3. 대안 선택: Route와 RouteMatrix 클래스, Routes API, 또는 다른 제공업체.
  4. 한 번에 하나씩 마이그레이션하고, 기능 플래그 뒤에서 전환 전에 결과를 비교하십시오.
  5. Google 지원 중단 페이지를 계속 확인해 종료 날짜 발표에 대비하십시오. Google은 Legacy 서비스에 대해 최소 12개월 전 공지를 약속했습니다.

MapAtlas 경로 탐색 API를 사용해 보려면 무료 계정을 만들고 API 문서를 읽어 보십시오. 마이그레이션 지원이 필요하면 문의 페이지를 이용하십시오.

자주 묻는 질문

Google Maps Drawing Library를 아직 사용할 수 있습니까?

아닙니다. Google은 DrawingManager를 포함한 Drawing Library를 2025년 8월에 지원 중단했고, 지원 중단 페이지에는 2026년 5월부터 사용할 수 없다고 적혀 있습니다. Maps JavaScript API 3.65.3b 버전(2026년 6월 4일) 릴리스 노트도 DrawingManager를 더 이상 사용할 수 없다고 확인합니다. Google은 대안으로 Terra Draw를 제시합니다.

Heatmap Layer를 아직 사용할 수 있습니까?

아닙니다. Google은 Heatmap Layer를 2025년 5월 27일에 지원 중단했고, 2026년 5월 20일 3.65.1c 버전에서 서비스를 종료했다고 밝혔습니다. 대신 deck.gl의 HeatmapLayer 같은 서드파티 라이브러리를 권장합니다.

DirectionsService와 DistanceMatrixService는 언제 작동을 멈춥니까?

Google은 날짜를 정하지 않았습니다. 두 서비스 모두 2025년 3월 1일부터 Legacy 상태이며 2026년 2월 25일부터 지원 중단되었습니다. Google 릴리스 노트에 따르면 종료 계획은 없고, 심각한 회귀 문제는 계속 수정되며, 지원 종료 최소 12개월 전에 공지됩니다. Legacy 서비스는 새 Cloud 프로젝트에서 사용할 수 없으므로 새 프로젝트에는 Route와 RouteMatrix 클래스나 다른 제공업체가 필요합니다.

단계적으로 마이그레이션할 수 있습니까, 아니면 한 번에 모두 바꿔야 합니까?

서비스를 하나씩 마이그레이션할 수 있습니다. 지원 중단된 클래스는 서로 독립적입니다. 이미 작동하지 않는 Drawing Library와 Heatmap Layer를 먼저 교체하고, DirectionsService와 DistanceMatrixService는 자체 일정에 맞춰 교체하십시오.

MapAtlas는 경유지와 여러 이동 수단을 지원합니까?

지원합니다. MapAtlas Directions API는 순서가 있는 위치 목록을 받으므로 처음과 마지막 사이의 모든 지점이 경유지가 됩니다. auto, bicycle, pedestrian, bus, truck, taxi, motor_scooter 비용 모델을 지원합니다. REST 엔드포인트이므로 API 키가 클라이언트에 노출되지 않도록 백엔드에서 호출하십시오.

유용하셨나요? 공유해 보세요.

저자 소개

Brent van der Heiden

작성자

Brent van der Heiden

Co-Founder & CEO at MapAtlas

Brent built MapAtlas out of a conviction that developers deserve location APIs with fair pricing and genuine end-user privacy. Before that he co-founded MapMetrics, a community mapping and navigation app. He writes about geospatial infrastructure, map data, AI search visibility, and how location data powers the products people rely on every day.

모든 기사 보기 →
블로그로 돌아가기