Negli ultimi diciotto mesi Google ha deprecato quattro parti molto usate della Maps JavaScript API. Due di esse, la Heatmap Layer e la Drawing Library, non sono più disponibili da maggio 2026. Le altre due, DirectionsService e DistanceMatrixService, sono Legacy e deprecate, ma funzionano ancora e non hanno una data di dismissione.
Questa guida riporta lo stato attuale di ciascuna, con i link alle pagine di Google, e mostra come sostituirle. Quando il sostituto è MapAtlas, il codice usa i nostri endpoint e formati di risposta reali.
Cosa è deprecato e cosa funziona ancora
| Servizio | Stato | Date chiave | Sostituto di Google |
|---|---|---|---|
| Heatmap Layer | Rimosso | Deprecato il 27 maggio 2025, dismesso nella versione 3.65.1c (20 maggio 2026) | Librerie di terze parti come deck.gl |
| Drawing Library (DrawingManager) | Rimosso | Deprecato ad agosto 2025, non disponibile da maggio 2026 (confermato nella versione 3.65.3b, 4 giugno 2026) | Librerie di terze parti come Terra Draw |
| DirectionsService | Legacy, deprecato | Legacy dal 1° marzo 2025, deprecato dal 25 febbraio 2026 (versione 3.64.2b), nessuna data di dismissione | Classe Route della libreria Routes |
| DistanceMatrixService | Legacy, deprecato | Legacy dal 1° marzo 2025, deprecato dal 25 febbraio 2026 (versione 3.64.2b), nessuna data di dismissione | Classe RouteMatrix della libreria Routes |
Fonti: deprecazioni di Google Maps Platform, le note di rilascio della Maps JavaScript API e la pagina dei prodotti Legacy.
Legacy ha un significato preciso. Secondo Google un servizio Legacy non riceve nuove funzionalità e non si può attivare nei nuovi progetti Cloud, ma resta supportato nei progetti esistenti. Google si impegna a dare almeno 12 mesi di preavviso prima di dismetterlo, e la nota di rilascio che ha deprecato DirectionsService e DistanceMatrixService dice che la dismissione non è prevista e che le regressioni gravi verranno ancora corrette. Lo stesso passaggio a Legacy del 1° marzo 2025 ha riguardato i servizi web Directions API e Distance Matrix API, la Places API e il JavaScript Places Service.
Cosa si rompe
Questo codice oggi fallisce con le versioni attuali della 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();
Questo codice funziona ancora nei progetti esistenti, ma è deprecato e non funziona in un nuovo progetto Cloud:
// Legacy and deprecated, no shutdown date yet
const directionsService = new google.maps.DirectionsService();
const distanceMatrixService = new google.maps.DistanceMatrixService();
Se una mappa di calore o uno strumento di disegno del tuo sito ha smesso di funzionare a maggio 2026, la causa è questa. Risolvi prima questo punto. Poi pianifica la migrazione del routing, prima che Google annunci una data.
I sostituti di Google
Per il routing Google offre due strade, e nessuna ti obbliga a spostare la logica su un server:
- Nel browser: la libreria Routes della Maps JavaScript API. La classe
Routesostituisce DirectionsService e la classeRouteMatrixsostituisce DistanceMatrixService. - Su un server: la Routes API, un servizio REST con i metodi Compute Routes e Compute Route Matrix.
Per la visualizzazione Google non offre più un'opzione propria. La sua pagina sulla mappa di calore rimanda a deck.gl, e la pagina delle deprecazioni indica Terra Draw per il disegno.
Checklist per la migrazione
1. Analizza il codice
Cerca le classi coinvolte:
# Find all files using deprecated Google Maps services
grep -rn "DirectionsService\|DistanceMatrixService\|DirectionsRenderer\|HeatmapLayer\|DrawingManager" \
--include="*.js" --include="*.ts" --include="*.tsx" --include="*.jsx" src/
Annota ogni file e ogni componente che le usa, e se ogni chiamata gira nel browser o su un server.
2. Documenta come usi ogni servizio
Per ogni utilizzo annota:
- Modalità di trasporto (auto, a piedi, bici, trasporto pubblico)
- Tappe intermedie (semplice da A a B o percorsi con più fermate)
- Campi della risposta che leggi (distanza, durata, polilinea, passi, tariffa)
- Volume (richieste al giorno e al mese, per stimare i costi)
- Requisiti di latenza (in tempo reale per l'utente o in batch)
3. Scegli la destinazione
Opzione A: restare con Google. Passa alle classi Route e RouteMatrix o alla Routes API. Confronta i campi che usi con le guide di migrazione, perché i formati di risposta sono diversi da quelli delle classi Legacy.
Opzione B: cambiare fornitore. Riscrivi comunque l'integrazione, quindi confronta i fornitori sui requisiti del passo 2.
4. Esegui vecchio e nuovo in parallelo
Non migrare sul posto. Esegui le due implementazioni in parallelo per un periodo e confronta distanza, durata e latenza sui tuoi percorsi reali prima di passare al nuovo sistema.
5. Aggiorna la gestione degli errori
Le classi Legacy segnalavano gli errori con un valore di stato nella callback. I sostituti REST restituiscono codici di stato HTTP e corpi di errore, quindi la gestione degli errori deve cambiare.
Come sostituire ogni servizio con MapAtlas
Gli endpoint di routing di MapAtlas sono servizi REST su gateway.mapmetrics-atlas.net, descritti nella documentazione dell'API MapAtlas. Richiedono un token come parametro di query, quindi chiamali dal tuo backend.
Da DirectionsService alla Directions API di MapAtlas
Prima (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);
}
}
);
Dopo (Directions API di 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);
Differenze principali:
- Chiamata REST invece di una classe JavaScript, eseguita dal tuo backend.
- Le tappe intermedie sono le voci centrali di
locations. - Risposta con una struttura diversa. I totali sono in
trip.summarye ogni tratta ha una polilinea codificata inshape. Decodificala prima di disegnare il percorso (vedi l'esempio di backend più sotto).
Da DistanceMatrixService alla Matrix API di MapAtlas
La Matrix API di MapAtlas restituisce tempo di percorrenza e distanza per ogni coppia di origine e destinazione in una sola chiamata. Il nostro endpoint limita ogni coppia a 400 km di distanza stradale, per questo l'esempio usa località intorno a Berlino.
Prima (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);
});
});
}
}
);
Dopo (Matrix API di 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");
});
});
La griglia corrisponde a rows ed elements di Google. Le distanze arrivano come numeri nell'unità richiesta e i tempi in secondi, quindi la formattazione spetta a te.
Sostituire la Heatmap Layer
Opzione 1: un layer di calore in 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,
},
});
});
La mappa di calore viene disegnata dalla libreria di mappe stessa, senza servizi aggiuntivi.
Opzione 2: la HeatmapLayer di deck.gl, suggerita dalla documentazione di 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,
});
Funzionano entrambe. MapLibre GL JS legge direttamente gli stili di MapAtlas, e deck.gl si può sovrapporre a qualsiasi mappa di base.
Sostituire la Drawing Library
DrawingManager permetteva agli utenti di disegnare marker, linee, cerchi e poligoni sulla mappa. Terra Draw, la libreria indicata nella pagina delle deprecazioni di Google, offre le stesse modalità e ha adattatori per diverse librerie di mappe, tra cui Google Maps e MapLibre GL JS. Le forme vengono restituite in GeoJSON, che puoi salvare o inviare senza modifiche a un servizio di geofencing o di isocrone.
Confronto dei costi
I prezzi di listino di Google sono gli stessi per gli SKU Legacy di routing e per gli SKU Essentials dei loro sostituti. Tutti i prezzi qui sotto vengono dalla pagina dei prezzi di Google Maps Platform e dalla pagina dei prezzi di MapAtlas, controllate il 26 settembre 2026.
| Servizio | Google, gratis al mese | Google, per 1.000 oltre la soglia (prima fascia) | MapAtlas, gratis al mese | MapAtlas, per 1.000 oltre la soglia (prima fascia) |
|---|---|---|---|---|
| Directions (Legacy) o Compute Routes Essentials | 10.000 | 5,00 $ | 100.000 richieste di navigazione | 1,53 € |
| Directions Advanced (Legacy) o Compute Routes Pro | 5.000 | 10,00 $ | Stessa fascia di navigazione | 1,53 € |
| Distance Matrix (Legacy) o Compute Route Matrix Essentials | 10.000 elementi | 5,00 $ | Vedi la pagina dei prezzi | Vedi la pagina dei prezzi |
| Geocoding | 10.000 | 5,00 $ | 25.000 | 3,90 € |
Google fattura in dollari statunitensi e MapAtlas in euro, quindi converti prima di confrontare. Entrambi applicano tariffe più basse ai volumi più alti. Un esempio con 500.000 richieste di percorso al mese:
- Google Compute Routes Essentials: 10.000 gratis, 90.000 a 5,00 $ e 400.000 a 4,00 $, cioè 2.050 $.
- Navigazione MapAtlas: 100.000 gratis e 400.000 a 1,53 €, cioè circa 610 €.
Esempio completo: route di backend e mappa
Questo schema tiene la chiave API sul server e manda al browser solo la geometria del percorso.
Route API nel 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 mappa (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" }} />;
}
Come testare la migrazione
Passo 1: confronta le due implementazioni
Per un periodo di prova, chiama il vecchio e il nuovo servizio con le stesse richieste. Registra distanza e durata di entrambi e controlla le differenze sui tuoi percorsi reali, soprattutto traghetti, pedaggi e strade con accesso limitato.
Passo 2: usa un feature flag
Metti il fornitore dietro un flag, così puoi tornare indietro senza un deploy:
const useMapAtlasDirections = process.env.FEATURE_MAPATLAS_DIRECTIONS === "true";
const directions = useMapAtlasDirections
? await fetchMapAtlasDirections(origin, destination)
: await fetchGoogleDirections(origin, destination);
Passo 3: monitora i tassi di errore
Dopo il passaggio, tieni d'occhio:
- Tassi di HTTP 4xx e 5xx della nuova API
- Variazioni di latenza
- Campi mancanti che la tua interfaccia legge
- Differenze di percorso nei casi limite come traghetti, strade a pedaggio e zone con accesso limitato
Passo 4: test di carico prima del go-live
Se il tuo traffico ha dei picchi, per esempio durante lo smistamento del mattino su una piattaforma logistica, fai un test di carico della nuova API al doppio del tuo volume di picco prima di affidartici.
Cosa fare adesso
- Se carichi ancora la Heatmap Layer o la Drawing Library: sostituiscile per prime. Non funzionano più con le versioni attuali della Maps JavaScript API.
- Analizza il codice di routing: trova ogni chiamata a DirectionsService, DirectionsRenderer e DistanceMatrixService.
- Scegli il sostituto: le classi
RouteeRouteMatrix, la Routes API o un altro fornitore. - Migra un servizio alla volta, dietro un feature flag, e confronta i risultati prima del passaggio.
- Segui la pagina delle deprecazioni di Google nel caso arrivi una data di dismissione. Google si è impegnata a dare almeno 12 mesi di preavviso per i servizi Legacy.
Per provare le API di routing di MapAtlas, crea un account gratuito e leggi la documentazione dell'API. Per un aiuto con la migrazione, usa la pagina dei contatti.
Domande frequenti
La Drawing Library di Google Maps è ancora disponibile?
No. Google ha deprecato la Drawing Library, incluso DrawingManager, ad agosto 2025, e la sua pagina delle deprecazioni la indica come non disponibile da maggio 2026. Le note di rilascio della versione 3.65.3b della Maps JavaScript API (4 giugno 2026) confermano che DrawingManager non è più disponibile. Google indica Terra Draw come alternativa.
La Heatmap Layer è ancora disponibile?
No. Google ha deprecato la Heatmap Layer il 27 maggio 2025, e la versione 3.65.1c del 20 maggio 2026 la dichiara dismessa. Google suggerisce al suo posto librerie di terze parti come la HeatmapLayer di deck.gl.
Quando smetteranno di funzionare DirectionsService e DistanceMatrixService?
Google non ha fissato una data. Entrambi sono in stato Legacy dal 1° marzo 2025 e deprecati dal 25 febbraio 2026. Secondo le note di rilascio di Google non è prevista la dismissione, continueranno a ricevere correzioni per le regressioni gravi e ci saranno almeno 12 mesi di preavviso prima della fine del supporto. I servizi Legacy non sono disponibili per i nuovi progetti Cloud, quindi un nuovo progetto deve usare le classi Route e RouteMatrix o un altro fornitore.
Posso migrare un pezzo alla volta o devo cambiare tutto insieme?
Puoi migrare un servizio alla volta. Ogni classe deprecata è indipendente. Sostituisci prima Drawing Library e Heatmap Layer, che già non funzionano, poi DirectionsService e DistanceMatrixService secondo i tuoi tempi.
MapAtlas supporta tappe intermedie e più modalità di trasporto?
Sì. La Directions API di MapAtlas accetta un elenco ordinato di posizioni, quindi ogni punto tra il primo e l'ultimo è una tappa intermedia, e supporta i modelli di costo auto, bicycle, pedestrian, bus, truck, taxi e motor_scooter. È un endpoint REST: chiamalo dal tuo backend così la chiave API non arriva al client.

