Skip to main content
DrawingManager do Google Maps e descontinuações da API: guia de migração 2026
Guides

DrawingManager do Google Maps e descontinuações da API: guia de migração 2026

A Drawing Library e a Heatmap Layer saíram da Maps JavaScript API. DirectionsService e DistanceMatrixService são Legacy e estão descontinuados. Status atual, datas e substitutos.

Brent van der HeidenÚltima atualização 13 min read
#Google Maps API#migração de API#DrawingManager#DirectionsService#roteamento#guia para desenvolvedores

Nos últimos dezoito meses o Google descontinuou quatro partes muito usadas da Maps JavaScript API. Duas delas, a Heatmap Layer e a Drawing Library, estão indisponíveis desde maio de 2026. As outras duas, DirectionsService e DistanceMatrixService, são Legacy e estão descontinuadas, mas ainda funcionam e não têm data de desligamento.

Este guia mostra o status atual de cada uma, com links para as páginas do próprio Google, e explica como substituí-las. Quando o substituto é do MapAtlas, o código usa nossos endpoints e formatos de resposta reais.

O que foi descontinuado e o que ainda funciona

ServiçoStatusDatas principaisSubstituto do Google
Heatmap LayerRemovidoDescontinuado em 27 de maio de 2025, desativado na versão 3.65.1c (20 de maio de 2026)Bibliotecas de terceiros como o deck.gl
Drawing Library (DrawingManager)RemovidoDescontinuado em agosto de 2025, indisponível desde maio de 2026 (confirmado na versão 3.65.3b, 4 de junho de 2026)Bibliotecas de terceiros como o Terra Draw
DirectionsServiceLegacy, descontinuadoLegacy desde 1º de março de 2025, descontinuado desde 25 de fevereiro de 2026 (versão 3.64.2b), sem data de desligamentoClasse Route da biblioteca Routes
DistanceMatrixServiceLegacy, descontinuadoLegacy desde 1º de março de 2025, descontinuado desde 25 de fevereiro de 2026 (versão 3.64.2b), sem data de desligamentoClasse RouteMatrix da biblioteca Routes

Fontes: descontinuações da Google Maps Platform, as notas de versão da Maps JavaScript API e a página de produtos Legacy.

Legacy tem um significado específico. Segundo o Google, um serviço Legacy não recebe novos recursos e não pode ser ativado em novos projetos do Cloud, mas continua com suporte nos projetos existentes. O Google se compromete a avisar com pelo menos 12 meses de antecedência antes de desativá-lo, e a nota de versão que descontinuou DirectionsService e DistanceMatrixService diz que não há desativação programada e que regressões graves ainda serão corrigidas. A mesma mudança para Legacy em 1º de março de 2025 afetou os serviços web Directions API e Distance Matrix API, a Places API e o JavaScript Places Service.

O que quebra

Este código falha hoje nas versões atuais da 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();

Este código ainda roda em projetos existentes, mas está descontinuado e não funciona em um novo projeto do Cloud:

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

Se um mapa de calor ou uma ferramenta de desenho do seu site parou de funcionar em maio de 2026, esta é a causa. Corrija isso primeiro. Depois planeje a migração do roteamento, antes que o Google anuncie uma data.

Os substitutos do Google

Para roteamento, o Google oferece dois caminhos, e nenhum obriga você a levar a lógica para um servidor:

  • No navegador: a biblioteca Routes da Maps JavaScript API. A classe Route substitui o DirectionsService e a classe RouteMatrix substitui o DistanceMatrixService.
  • Em um servidor: a Routes API, um serviço REST com os métodos Compute Routes e Compute Route Matrix.

Para visualização, o Google não oferece mais uma opção própria. A página do mapa de calor aponta para o deck.gl, e a página de descontinuações cita o Terra Draw para desenho.

Checklist de migração

1. Audite seu código

Procure as classes afetadas:

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

Registre cada arquivo e componente que as usa, e se cada chamada roda no navegador ou em um servidor.

2. Documente como você usa cada serviço

Para cada uso, anote:

  • Modos de transporte (carro, a pé, bicicleta, transporte público)
  • Pontos intermediários (simples de A a B ou rotas com várias paradas)
  • Campos da resposta que você lê (distância, duração, polilinha, etapas, tarifa)
  • Volume (requisições por dia e por mês, para estimar custos)
  • Requisitos de latência (tempo real para o usuário ou processamento em lote)

3. Escolha o destino

Opção A: continuar com o Google. Migre para as classes Route e RouteMatrix ou para a Routes API. Compare os campos que você usa com os guias de migração, porque os formatos de resposta são diferentes dos das classes Legacy.

Opção B: trocar de provedor. Você vai reescrever a integração de qualquer forma, então compare provedores com base nos requisitos do passo 2.

4. Rode o antigo e o novo em paralelo

Não migre no lugar. Rode as duas implementações lado a lado por um período e compare distância, duração e latência nas suas rotas reais antes de trocar.

5. Atualize o tratamento de erros

As classes Legacy informavam erros por um valor de status em um callback. Os substitutos REST retornam códigos de status HTTP e corpos de erro, então o tratamento de erros precisa mudar.

Substituindo cada serviço pelo MapAtlas

Os endpoints de roteamento do MapAtlas são serviços REST em gateway.mapmetrics-atlas.net, documentados na documentação da API do MapAtlas. Eles recebem um token como parâmetro de consulta, então chame-os do seu backend.

De DirectionsService para a Directions API do MapAtlas

Antes (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);
    }
  }
);

Depois (Directions API do MapAtlas):

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);

Principais diferenças:

  • Chamada REST em vez de uma classe JavaScript, feita a partir do seu backend.
  • Pontos intermediários são as entradas do meio de locations.
  • Formato de resposta diferente. Os totais ficam em trip.summary e cada trecho tem uma polilinha codificada em shape. Decodifique-a antes de desenhar a rota (veja o exemplo de backend mais abaixo).

De DistanceMatrixService para a Matrix API do MapAtlas

A Matrix API do MapAtlas retorna tempo de viagem e distância para cada par de origem e destino em uma única chamada. Nosso endpoint limita cada par a 400 km de distância de rota, por isso o exemplo usa lugares em volta de Berlim.

Antes (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);
        });
      });
    }
  }
);

Depois (Matrix API do MapAtlas):

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");
  });
});

A grade equivale a rows e elements do Google. As distâncias chegam como números na unidade que você pedir e os tempos em segundos, então a formatação fica com você.

Substituto da Heatmap Layer

Opção 1: uma camada de mapa de calor no MapLibre GL JS (código aberto)

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,
    },
  });
});

O mapa de calor é renderizado pela própria biblioteca de mapas, sem serviço extra.

Opção 2: a HeatmapLayer do deck.gl, sugerida pela documentação do Google:

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,
});

As duas funcionam. O MapLibre GL JS lê os estilos do MapAtlas diretamente, e o deck.gl pode ficar por cima de qualquer mapa base.

Substituto da Drawing Library

O DrawingManager permitia que usuários desenhassem marcadores, linhas, círculos e polígonos no mapa. O Terra Draw, biblioteca citada pela página de descontinuações do Google, oferece os mesmos modos e tem adaptadores para várias bibliotecas de mapas, incluindo Google Maps e MapLibre GL JS. As formas voltam em GeoJSON, que você pode salvar ou enviar sem alterações para um serviço de geofencing ou de isócronas.

Comparação de custos

Os preços de tabela do Google são os mesmos para os SKUs Legacy de roteamento e para os SKUs Essentials dos substitutos. Todos os preços abaixo vêm da página de preços da Google Maps Platform e da página de preços do MapAtlas, conferidas em 26 de setembro de 2026.

ServiçoGoogle, grátis por mêsGoogle, por 1.000 depois disso (primeira faixa)MapAtlas, grátis por mêsMapAtlas, por 1.000 depois disso (primeira faixa)
Directions (Legacy) ou Compute Routes Essentials10.000US$ 5,00100.000 requisições de navegação€ 1,53
Directions Advanced (Legacy) ou Compute Routes Pro5.000US$ 10,00Mesma faixa de navegação€ 1,53
Distance Matrix (Legacy) ou Compute Route Matrix Essentials10.000 elementosUS$ 5,00Veja a página de preçosVeja a página de preços
Geocoding10.000US$ 5,0025.000€ 3,90

O Google cobra em dólares americanos e o MapAtlas em euros, então converta antes de comparar. Os dois aplicam tarifas menores em volumes maiores. Um exemplo com 500.000 requisições de rota por mês:

  • Google Compute Routes Essentials: 10.000 grátis, 90.000 a US$ 5,00 e 400.000 a US$ 4,00, ou seja, US$ 2.050.
  • Navegação MapAtlas: 100.000 grátis e 400.000 a € 1,53, ou seja, cerca de € 610.

Exemplo completo: rota de backend e mapa

Este padrão mantém a chave de API no servidor e envia ao navegador só a geometria da rota.

Rota de API no backend (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,
  });
}

Componente de mapa (React e 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" }} />;
}

Como testar a migração

Passo 1: compare as duas implementações

Durante um período de teste, chame o serviço antigo e o novo com as mesmas requisições. Registre distância e duração dos dois e analise as diferenças nas suas rotas reais, principalmente balsas, pedágios e vias com restrição.

Passo 2: use uma feature flag

Coloque o provedor atrás de uma flag para poder voltar sem um deploy:

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

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

Passo 3: monitore as taxas de erro

Depois da troca, acompanhe:

  • Taxas de HTTP 4xx e 5xx da nova API
  • Mudanças de latência
  • Campos ausentes que a sua interface lê
  • Diferenças de rota em casos extremos como balsas, rodovias com pedágio e áreas restritas

Passo 4: teste de carga antes de ir para produção

Se o seu tráfego tem picos, por exemplo no despacho da manhã em uma plataforma de logística, faça um teste de carga da nova API com o dobro do seu volume de pico antes de depender dela.

O que fazer agora

  1. Se você ainda carrega a Heatmap Layer ou a Drawing Library: substitua-as primeiro. Elas não funcionam mais nas versões atuais da Maps JavaScript API.
  2. Audite o código de roteamento: encontre cada chamada a DirectionsService, DirectionsRenderer e DistanceMatrixService.
  3. Escolha o substituto: as classes Route e RouteMatrix, a Routes API ou outro provedor.
  4. Migre um serviço por vez, atrás de uma feature flag, e compare os resultados antes da troca.
  5. Acompanhe a página de descontinuações do Google caso surja uma data de desligamento. O Google se comprometeu com pelo menos 12 meses de aviso para serviços Legacy.

Para testar as APIs de roteamento do MapAtlas, crie uma conta gratuita e leia a documentação da API. Para ajuda com uma migração, use a página de contato.

Perguntas frequentes

A Drawing Library do Google Maps ainda está disponível?

Não. O Google descontinuou a Drawing Library, incluindo o DrawingManager, em agosto de 2025, e a página de descontinuações a lista como indisponível desde maio de 2026. As notas da versão 3.65.3b da Maps JavaScript API (4 de junho de 2026) confirmam que o DrawingManager não está mais disponível. O Google cita o Terra Draw como alternativa.

A Heatmap Layer ainda está disponível?

Não. O Google descontinuou a Heatmap Layer em 27 de maio de 2025, e a versão 3.65.1c de 20 de maio de 2026 informa que ela foi desativada. O Google sugere no lugar bibliotecas de terceiros, como a HeatmapLayer do deck.gl.

Quando DirectionsService e DistanceMatrixService vão parar de funcionar?

O Google não definiu data. Os dois estão em status Legacy desde 1º de março de 2025 e descontinuados desde 25 de fevereiro de 2026. Segundo as notas de versão do Google, não há desativação programada, eles continuam recebendo correções para regressões graves e haverá pelo menos 12 meses de aviso antes do fim do suporte. Serviços Legacy não estão disponíveis para novos projetos do Cloud, então um projeto novo precisa das classes Route e RouteMatrix ou de outro provedor.

Posso migrar aos poucos ou preciso trocar tudo de uma vez?

Você pode migrar um serviço por vez. Cada classe descontinuada é independente. Substitua primeiro a Drawing Library e a Heatmap Layer, que já não funcionam, e depois DirectionsService e DistanceMatrixService no seu próprio ritmo.

O MapAtlas aceita pontos intermediários e vários modos de transporte?

Sim. A Directions API do MapAtlas recebe uma lista ordenada de locais, então cada ponto entre o primeiro e o último é um ponto intermediário, e aceita os modelos de custo auto, bicycle, pedestrian, bus, truck, taxi e motor_scooter. É um endpoint REST, então chame-o do seu backend para a chave de API não chegar ao cliente.

Achou útil? Compartilhe.

Sobre o autor

Brent van der Heiden

Escrito por

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.

Ver todos os artigos →
Voltar ao blog