diff --git a/modules/carto/src/api/basemap.ts b/modules/carto/src/api/basemap.ts index e5200a22d13..52f1cb0d700 100644 --- a/modules/carto/src/api/basemap.ts +++ b/modules/carto/src/api/basemap.ts @@ -112,9 +112,16 @@ export async function fetchBasemapProps({ } const googleBasemapDef = GOOGLE_BASEMAPS[styleType]; if (googleBasemapDef) { + const initialViewState = config.mapState; return { type: 'google-maps', - options: googleBasemapDef + options: { + ...googleBasemapDef, + center: {lat: initialViewState.latitude, lng: initialViewState.longitude}, + zoom: initialViewState.zoom + 1, + tilt: initialViewState.pitch, + heading: initialViewState.bearing + } }; } return { diff --git a/test/apps/carto-map/app.ts b/test/apps/carto-map/app.ts index 170ec201f88..2362cf6c2f4 100644 --- a/test/apps/carto-map/app.ts +++ b/test/apps/carto-map/app.ts @@ -2,36 +2,33 @@ import {BASEMAP, fetchMap, FetchMapOptions} from '@deck.gl/carto'; import {Deck} from '@deck.gl/core'; import mapboxgl from 'mapbox-gl'; import 'mapbox-gl/dist/mapbox-gl.css'; +import {Loader} from '@googlemaps/js-api-loader'; + +import {_getStyleUrl} from '@deck.gl/carto'; +import {FetchMapResult} from 'modules/carto/src/api/fetch-map'; +import {GoogleBasemapProps, MaplibreBasemapProps} from 'modules/carto/src/api/basemap'; +import {GoogleMapsOverlay} from '@deck.gl/google-maps'; // // Simplest instantiation // const cartoMapId = 'ff6ac53f-741a-49fb-b615-d040bc5a96b8'; // fetchMap({cartoMapId}).then(map => new Deck(map)); +// Get proper API key to be able to render Google basemaps, otherwise we +// render on maplibre/positron style +const GOOGLE_MAPS_API_KEY = ''; + const apiBaseUrl = 'https://gcp-us-east1.api.carto.com'; // const apiBaseUrl = 'https://gcp-us-east1-05.dev.api.carto.com'; -async function createMap(cartoMapId: string) { +async function createMapWithMapLibre(result: FetchMapResult) { + let map: mapboxgl.Map | undefined; const deck = new Deck({canvas: 'deck-canvas'}); - const options: FetchMapOptions = {apiBaseUrl, cartoMapId}; - - // Auto-refresh (optional) - const autoRefresh = false; - if (autoRefresh) { - // Autorefresh the data every 5 seconds - options.autoRefresh = 5; - options.onNewData = ({layers}) => { - deck.setProps({layers}); - }; - } - - // Get map info from CARTO and update deck - const {initialViewState, basemap, layers} = await fetchMap(options); - deck.setProps({initialViewState, layers}); + const basemap = result.basemap as MaplibreBasemapProps; // Mapbox basemap (optional) - const map = new mapboxgl.Map({ + map = new mapboxgl.Map({ container: 'map', - style: basemap?.type === 'maplibre' ? basemap.style : BASEMAP.POSITRON, + style: basemap?.style || BASEMAP.POSITRON, interactive: false, attributionControl: false }).addControl( @@ -40,6 +37,9 @@ async function createMap(cartoMapId: string) { }) ); + const {initialViewState, layers} = result; + deck.setProps({initialViewState, layers}); + deck.setProps({ controller: true, onViewStateChange: ({viewState}) => { @@ -47,6 +47,53 @@ async function createMap(cartoMapId: string) { map.jumpTo({center: [longitude, latitude], ...rest}); } }); + return deck; +} + +async function createMapWithGoogleMaps(result: FetchMapResult) { + // we don't need additional canvas, hide it + document.getElementById('deck-canvas')!.style.display = 'none'; + + const loader = new Loader({apiKey: GOOGLE_MAPS_API_KEY}); + + const googlemaps = await loader.importLibrary('maps'); + + const basemap = result.basemap as GoogleBasemapProps; + const map = new googlemaps.Map(document.getElementById('map')!, { + ...basemap.options, + disableDefaultUI: true, + }); + + const overlay = new GoogleMapsOverlay({ + layers: result.layers + }); + + overlay.setMap(map); + return overlay; +} + +async function createMap(cartoMapId: string) { + const options: FetchMapOptions = {apiBaseUrl, cartoMapId}; + + let deck: Deck | GoogleMapsOverlay | undefined; + // Auto-refresh (optional) + const autoRefresh = false; + if (autoRefresh) { + // Autorefresh the data every 5 seconds + options.autoRefresh = 5; + options.onNewData = ({layers}) => { + deck?.setProps({layers}); + }; + } + + // Get map info from CARTO and update deck + const result = await fetchMap(options); + + if (GOOGLE_MAPS_API_KEY && result.basemap?.type === 'google-maps') { + deck = await createMapWithGoogleMaps(result); + } else { + deck = await createMapWithMapLibre(result); + } } // Helper UI for dev diff --git a/test/apps/carto-map/package.json b/test/apps/carto-map/package.json index 8f645dc7f4f..f59dcfafa9c 100644 --- a/test/apps/carto-map/package.json +++ b/test/apps/carto-map/package.json @@ -8,7 +8,8 @@ "@deck.gl/core": "^8.6.0", "@deck.gl/geo-layers": "^8.6.0", "@deck.gl/layers": "^8.6.0", - "@deck.gl/mesh-layers": "^8.6.0" + "@deck.gl/mesh-layers": "^8.6.0", + "@googlemaps/js-api-loader": "^1.16.6" }, "devDependencies": { "vite": "^4.0.0"