How to load a Google Maps baselayer in Leaflet (after june 2018)?

Loading tiles from Google Maps by just specifying the URL of an undocumented API is against the Google Maps terms of service. Let me quote from them:

  1. License Restrictions.

10.1 Administrative Restrictions.

No access to APIs or Content except through the Service. You will not access the Maps API(s) or the Content except through the Service.
For example, you must not access map tiles or imagery through
interfaces or channels (including undocumented Google interfaces)
other than the Maps API(s).

You will also note that the tile URLs are not documented in their development documentation (as of early june 2018).

What you can do, however, is load one instance of a Google Map per instance of Leaflet, keep both map sizes and centers in sync, and use mutation observers to monitor whenever the Google Map instance loads a tile, so you can rip it off the Google Map DOM tree and put it in the Leaflet DOM tree (if you just use tricky CSS to show Leaflet on top of Google Maps, eventually you’ll run into problems about syncing the zoom animations of both).

If this sounds too scary, don’t worry. Leaflet.GoogleMutant does all the heavy lifting for you. Let me quote from its readme:

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY" async defer></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet@latest/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@latest/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet.gridlayer.googlemutant@latest/Leaflet.GoogleMutant.js"></script>

var roads = L.gridLayer.googleMutant({ type: 'roadmap' }).addTo(map);

Note that there’s a perfectly obvious place for your API key (which is your main worry), and that GoogleMutant only uses the public (and documented) API (which you should worry about, too, since it’s in the ToS).

Leave a Comment