Dalam delapan belas bulan terakhir, Google menyatakan usang empat bagian Maps JavaScript API yang banyak dipakai. Dua di antaranya, Heatmap Layer dan Drawing Library, tidak tersedia sejak Mei 2026. Dua lainnya, DirectionsService dan DistanceMatrixService, berstatus Legacy dan usang, tetapi masih berfungsi dan belum punya tanggal penghentian.
Panduan ini merangkum status terkini masing-masing, dengan tautan ke halaman Google sendiri, dan menunjukkan cara menggantinya. Jika penggantinya dari MapAtlas, kodenya memakai endpoint dan format respons kami yang sebenarnya.
Apa yang usang dan apa yang masih berfungsi
| Layanan | Status | Tanggal penting | Pengganti dari Google |
|---|---|---|---|
| Heatmap Layer | Dihapus | Usang sejak 27 Mei 2025, dinonaktifkan di versi 3.65.1c (20 Mei 2026) | Library pihak ketiga seperti deck.gl |
| Drawing Library (DrawingManager) | Dihapus | Usang sejak Agustus 2025, tidak tersedia sejak Mei 2026 (dikonfirmasi di versi 3.65.3b, 4 Juni 2026) | Library pihak ketiga seperti Terra Draw |
| DirectionsService | Legacy, usang | Legacy sejak 1 Maret 2025, usang per 25 Februari 2026 (versi 3.64.2b), belum ada tanggal penghentian | Class Route di library Routes |
| DistanceMatrixService | Legacy, usang | Legacy sejak 1 Maret 2025, usang per 25 Februari 2026 (versi 3.64.2b), belum ada tanggal penghentian | Class RouteMatrix di library Routes |
Sumber: halaman deprecation Google Maps Platform, catatan rilis Maps JavaScript API, dan halaman produk Legacy.
Legacy punya arti yang jelas. Menurut Google, layanan Legacy tidak mendapat fitur baru dan tidak bisa diaktifkan di proyek Cloud baru, tetapi tetap didukung di proyek yang sudah ada. Google berjanji memberi pemberitahuan minimal 12 bulan sebelum menonaktifkannya, dan catatan rilis yang menyatakan DirectionsService dan DistanceMatrixService usang menyebut penghentiannya belum dijadwalkan serta regresi serius tetap akan diperbaiki. Perubahan ke Legacy yang sama pada 1 Maret 2025 juga mencakup layanan web Directions API dan Distance Matrix API, serta Places API dan JavaScript Places Service.
Apa yang rusak
Kode ini sudah gagal di versi Maps JavaScript API saat ini:
// Removed in 2026: these constructors no longer work
const heatmap = new google.maps.visualization.HeatmapLayer({ data: points });
const drawingManager = new google.maps.drawing.DrawingManager();
Kode ini masih berjalan di proyek yang sudah ada, tetapi sudah usang dan tidak akan berjalan di proyek Cloud baru:
// Legacy and deprecated, no shutdown date yet
const directionsService = new google.maps.DirectionsService();
const distanceMatrixService = new google.maps.DistanceMatrixService();
Jika heatmap atau alat menggambar di situs Anda berhenti berfungsi pada Mei 2026, inilah penyebabnya. Perbaiki itu dulu. Setelah itu, rencanakan migrasi routing sebelum Google mengumumkan tanggal.
Pengganti dari Google
Untuk routing, Google menawarkan dua jalur, dan keduanya tidak memaksa Anda memindahkan logika ke server:
- Di browser: library Routes di Maps JavaScript API. Class
Routemenggantikan DirectionsService, dan classRouteMatrixmenggantikan DistanceMatrixService. - Di server: Routes API, layanan REST dengan metode Compute Routes dan Compute Route Matrix.
Untuk visualisasi, Google tidak lagi menyediakan opsi sendiri. Halaman heatmap mengarahkan ke deck.gl, dan halaman deprecation menyebut Terra Draw untuk menggambar.
Checklist migrasi
1. Periksa codebase Anda
Cari class yang terdampak:
# Find all files using deprecated Google Maps services
grep -rn "DirectionsService\|DistanceMatrixService\|DirectionsRenderer\|HeatmapLayer\|DrawingManager" \
--include="*.js" --include="*.ts" --include="*.tsx" --include="*.jsx" src/
Catat setiap file dan komponen yang memakainya, dan apakah setiap panggilan berjalan di browser atau di server.
2. Catat cara Anda memakai tiap layanan
Untuk setiap pemakaian, catat:
- Moda perjalanan (mobil, jalan kaki, sepeda, transportasi umum)
- Titik singgah (sekadar dari A ke B, atau rute dengan beberapa perhentian)
- Field respons yang dibaca (jarak, durasi, polyline, langkah, tarif)
- Volume (request per hari dan per bulan, untuk memperkirakan biaya)
- Kebutuhan latensi (real-time untuk pengguna, atau proses batch)
3. Pilih tujuan
Opsi A: tetap di Google. Pindah ke class Route dan RouteMatrix atau ke Routes API. Cocokkan field yang Anda pakai dengan panduan migrasi, karena format responsnya berbeda dari class Legacy.
Opsi B: ganti penyedia. Anda toh akan menulis ulang integrasinya, jadi bandingkan penyedia berdasarkan kebutuhan dari langkah 2.
4. Jalankan yang lama dan yang baru berdampingan
Jangan bermigrasi di tempat. Jalankan kedua implementasi secara paralel selama beberapa waktu dan bandingkan jarak, durasi, dan latensi pada rute nyata sebelum beralih.
5. Perbarui penanganan error
Class Legacy melaporkan error lewat nilai status di callback. Pengganti berbasis REST mengembalikan kode status HTTP dan body error, jadi penanganan error Anda harus ikut berubah.
Mengganti setiap layanan dengan MapAtlas
Endpoint routing MapAtlas adalah layanan REST di gateway.mapmetrics-atlas.net dan dijelaskan di dokumentasi API MapAtlas. Endpoint ini menerima token sebagai parameter query, jadi panggil dari backend Anda.
Dari DirectionsService ke MapAtlas Directions API
Sebelum (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);
}
}
);
Sesudah (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);
Perbedaan utama:
- Panggilan REST, bukan class JavaScript, dilakukan dari backend Anda.
- Titik singgah adalah entri di tengah
locations. - Struktur respons berbeda. Total ada di
trip.summary, dan setiap bagian rute punya polyline terenkode dishape. Dekode dulu sebelum menggambar rute (lihat contoh backend di bawah).
Dari DistanceMatrixService ke MapAtlas Matrix API
MapAtlas Matrix API mengembalikan waktu tempuh dan jarak untuk setiap pasangan asal dan tujuan dalam satu panggilan. Endpoint kami membatasi setiap pasangan hingga 400 km jarak rute, karena itu contohnya memakai tempat di sekitar Berlin.
Sebelum (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);
});
});
}
}
);
Sesudah (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");
});
});
Grid ini sama dengan rows dan elements milik Google. Jarak dikembalikan sebagai angka dalam satuan yang Anda minta dan waktu dalam detik, jadi format tampilannya Anda atur sendiri.
Pengganti Heatmap Layer
Opsi 1: layer heatmap di MapLibre GL JS (open source)
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,
},
});
});
Heatmap dirender langsung oleh library peta, tanpa layanan tambahan.
Opsi 2: HeatmapLayer dari deck.gl, yang disarankan dokumentasi 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,
});
Keduanya bisa dipakai. MapLibre GL JS membaca style MapAtlas secara langsung, dan deck.gl bisa ditempatkan di atas peta dasar apa pun.
Pengganti Drawing Library
DrawingManager memungkinkan pengguna menggambar marker, garis, lingkaran, dan poligon di peta. Terra Draw, library yang disebut halaman deprecation Google, menyediakan mode yang sama dan punya adapter untuk beberapa library peta, termasuk Google Maps dan MapLibre GL JS. Bentuk yang digambar dikembalikan sebagai GeoJSON, yang bisa Anda simpan atau kirim apa adanya ke layanan geofencing atau isokron.
Perbandingan biaya
Harga daftar Google sama untuk SKU routing Legacy dan SKU Essentials penggantinya. Semua harga di bawah ini diambil dari halaman harga Google Maps Platform dan halaman harga MapAtlas, keduanya dicek pada 26 September 2026.
| Layanan | Google, gratis per bulan | Google, per 1.000 setelahnya (tingkat pertama) | MapAtlas, gratis per bulan | MapAtlas, per 1.000 setelahnya (tingkat pertama) |
|---|---|---|---|---|
| Directions (Legacy) atau Compute Routes Essentials | 10.000 | $5,00 | 100.000 request navigasi | €1,53 |
| Directions Advanced (Legacy) atau Compute Routes Pro | 5.000 | $10,00 | Tingkat navigasi yang sama | €1,53 |
| Distance Matrix (Legacy) atau Compute Route Matrix Essentials | 10.000 elemen | $5,00 | Lihat halaman harga | Lihat halaman harga |
| Geocoding | 10.000 | $5,00 | 25.000 | €3,90 |
Google menagih dalam dolar AS dan MapAtlas dalam euro, jadi konversikan dulu sebelum membandingkan. Keduanya menurunkan tarif pada volume yang lebih tinggi. Contoh perhitungan untuk 500.000 request rute per bulan:
- Google Compute Routes Essentials: 10.000 gratis, 90.000 dengan $5,00 dan 400.000 dengan $4,00, total $2.050.
- Navigasi MapAtlas: 100.000 gratis dan 400.000 dengan €1,53, total sekitar €610.
Contoh lengkap: route backend dan peta
Pola ini menyimpan API key di server dan hanya mengirim geometri rute ke browser.
Route API 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,
});
}
Komponen peta (React dan 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" }} />;
}
Cara menguji migrasi
Langkah 1: bandingkan kedua implementasi
Selama masa uji, panggil layanan lama dan baru dengan request yang sama. Catat jarak dan durasi dari keduanya, lalu periksa perbedaannya di rute nyata Anda, terutama untuk kapal feri, jalan tol, dan jalan dengan akses terbatas.
Langkah 2: gunakan feature flag
Letakkan penyedia di balik flag agar Anda bisa kembali tanpa deploy:
const useMapAtlasDirections = process.env.FEATURE_MAPATLAS_DIRECTIONS === "true";
const directions = useMapAtlasDirections
? await fetchMapAtlasDirections(origin, destination)
: await fetchGoogleDirections(origin, destination);
Langkah 3: pantau tingkat error
Setelah beralih, pantau:
- Tingkat HTTP 4xx dan 5xx dari API baru
- Perubahan latensi
- Field yang hilang yang dibaca UI Anda
- Perbedaan rute pada kasus khusus seperti kapal feri, jalan tol, dan area terbatas
Langkah 4: uji beban sebelum go-live
Jika trafik Anda punya puncak, misalnya saat pengiriman pagi di platform logistik, uji beban API baru dengan dua kali volume puncak Anda sebelum mengandalkannya.
Yang perlu dilakukan sekarang
- Jika Anda masih memuat Heatmap Layer atau Drawing Library: ganti keduanya lebih dulu. Keduanya tidak lagi berfungsi di versi Maps JavaScript API saat ini.
- Periksa kode routing: temukan setiap panggilan DirectionsService, DirectionsRenderer, dan DistanceMatrixService.
- Pilih pengganti: class
RoutedanRouteMatrix, Routes API, atau penyedia lain. - Migrasikan satu layanan dalam satu waktu, di balik feature flag, dan bandingkan hasilnya sebelum beralih.
- Pantau halaman deprecation Google kalau-kalau tanggal penghentian diumumkan. Google berjanji memberi pemberitahuan minimal 12 bulan untuk layanan Legacy.
Untuk mencoba API routing MapAtlas, buat akun gratis dan baca dokumentasi API. Untuk bantuan migrasi, gunakan halaman kontak.
Pertanyaan yang Sering Diajukan
Apakah Drawing Library Google Maps masih tersedia?
Tidak. Google menyatakan Drawing Library, termasuk DrawingManager, usang pada Agustus 2025, dan halaman deprecation mencantumkannya tidak tersedia sejak Mei 2026. Catatan rilis Maps JavaScript API versi 3.65.3b (4 Juni 2026) menegaskan bahwa DrawingManager tidak lagi tersedia. Google menyebut Terra Draw sebagai alternatif.
Apakah Heatmap Layer masih tersedia?
Tidak. Google menyatakan Heatmap Layer usang pada 27 Mei 2025, dan versi 3.65.1c pada 20 Mei 2026 menyebutnya sudah dinonaktifkan. Google menyarankan library pihak ketiga seperti HeatmapLayer dari deck.gl sebagai gantinya.
Kapan DirectionsService dan DistanceMatrixService berhenti berfungsi?
Google belum menetapkan tanggal. Keduanya berstatus Legacy sejak 1 Maret 2025 dan dinyatakan usang sejak 25 Februari 2026. Menurut catatan rilis Google, penghentiannya belum dijadwalkan, regresi serius tetap diperbaiki, dan akan ada pemberitahuan minimal 12 bulan sebelum dukungan berakhir. Layanan Legacy tidak tersedia untuk proyek Cloud baru, jadi proyek baru memerlukan class Route dan RouteMatrix atau penyedia lain.
Bisakah saya bermigrasi bertahap atau harus mengganti semuanya sekaligus?
Anda bisa memigrasikan satu layanan dalam satu waktu. Setiap class yang usang berdiri sendiri. Ganti dulu Drawing Library dan Heatmap Layer karena keduanya sudah tidak berfungsi, lalu DirectionsService dan DistanceMatrixService sesuai jadwal Anda sendiri.
Apakah MapAtlas mendukung titik singgah dan beberapa moda perjalanan?
Ya. MapAtlas Directions API menerima daftar lokasi yang berurutan, jadi setiap titik di antara yang pertama dan terakhir adalah titik singgah. API ini mendukung model biaya auto, bicycle, pedestrian, bus, truck, taxi, dan motor_scooter. Ini adalah endpoint REST, jadi panggil dari backend Anda agar API key tidak sampai ke klien.

