/ From Google Maps

Coming from Google Maps

Your Google Maps JavaScript API code on the 3D globe
npm i @ortho-earth/gmaps @ortho-earth/globe

@ortho-earth/gmaps gives you a google.maps namespace. Its Map, Marker, InfoWindow, shapes and Data draw through MapLibre GL: either on the Ortho Earth globe (@ortho-earth/globe/maplibre) or on the real maplibre-gl. Code written for Google Maps keeps its shape; only the import changes. The map itself needs no Google API key and sends nothing to Google.

// on the globe
import google from "@ortho-earth/gmaps/globe";   // { maps }

const map = new google.maps.Map(document.getElementById("map"), { center: { lat: 35.6812, lng: 139.7671 }, zoom: 15, tilt: 45 });
const marker = new google.maps.Marker({ map, position: { lat: 35.6812, lng: 139.7671 }, title: "Tokyo Station" });
const info = new google.maps.InfoWindow({ content: "<b>Tokyo Station</b>" });
marker.addListener("click", () => info.open({ map, anchor: marker }));
map.data.loadGeoJson("/parks.geojson");
map.data.setStyle(f => ({ fillColor: f.getProperty("kind") === "park" ? "green" : "gray" }));

Code that loads the API with @googlemaps/js-api-loader can take the Loader from @ortho-earth/gmaps/globe instead, and google.maps.importLibrary("maps" | "marker" | "places" | …) works too. To keep a flat map, give createGoogleMaps(maplibregl, { styles }) a MapLibre style per map type; installGlobal(maps) sets window.google.maps for code that reads the global.

What is translated

Google MapsOn the globe
Map options and methods (center, zoom, heading, tilt, restriction, moveCamera, panTo, fitBounds, controls[ControlPosition] …)the camera. Zoom is shifted by one (Google zoom z = MapLibre zoom z − 1, 256 px vs 512 px tiles). mapTypeId and mapId pick a MapLibre style
Map events (click, idle, bounds_changed, zoom_changed, dragend …)MapLibre events with Google's event object (latLng, pixel, stop()). A click on a marker or a clickable shape is not also a map click, as in Google Maps
Marker (icon as URL, Icon or Symbol, label, draggable), marker.AdvancedMarkerElement, marker.PinElementMapLibre markers with Google's red pin, your image, or the SVG symbol
InfoWindow (content, headerContent, pixelOffset, open({ map, anchor }))a MapLibre popup above the marker, following it when it moves
Polyline, Polygon (holes), Circle, Rectangle, MVCArray paths, geodesic, zIndexGeoJSON line and fill layers; editing the path redraws it, and geodesic follows the great circle
Data (addGeoJson, loadGeoJson, setStyle as an object or a function, overrideStyle, feature events)one GeoJSON source; each feature's style is evaluated into its properties
LatLng, LatLngBounds, MVCObject, MVCArray, event.*, geometry.spherical, geometry.encoding, geometry.polyplain values; the geometry library is computed on a sphere of radius 6,378,137 m, as Google does

Google's services, with your key

The services that live on Google's servers need your own key: createGlobeMaps({ apiKey, language, region }), maps.setApiKey(key), or new Loader({ apiKey }). The key is sent only to *.googleapis.com, and Google's terms and billing apply to these calls. Without a key the methods answer REQUEST_DENIED and the map keeps working.

Google MapsRelayed to
Geocoder.geocodeGeocoding API
DirectionsService.route, DirectionsRenderer, DistanceMatrixServiceRoutes API (the renderer draws the route and lettered markers on the map, and the steps in its panel)
ElevationServiceElevation API
places.PlacesService, places.AutocompleteService, places.AutocompletePlaces API (New)
StreetViewService.getPanorama, StreetViewPanoramaStreet View metadata and Static APIs: a still image that turns when dragged. Google does not publish its panorama tiles outside its own API, so there is no smooth 360° view

What is not

Checking a port

Anything the namespace does not translate is reported once in the console as [gmshim] unsupported: …; it never throws. google.maps.unsupportedReport() lists them, so you can check a port just by running it. For anything else, map.getMapLibre() returns the map underneath, and on the globe that map also has everything in the engine: terrain, 3D Tiles, the shared clock and the night side.

The test suite runs the calls above against the real globe (npm run verify:ui -- t-gmaps in packages/globe), and every service against a stand-in for Google's servers. Unlike MapLibre and CesiumJS, there is no gallery of Google's own samples yet, so the tables on this page are the list of what is covered.

Coming from other libraries? See From Leaflet, From MapLibre GL JS and From CesiumJS.

@ortho-earth/gmaps · GPL-3.0 · Kenji Yoshida · 2026