Last active
February 21, 2019 21:14
-
-
Save donmccurdy/7a7e3afc4c1ba059e689805d96b7293e to your computer and use it in GitHub Desktop.
Maps API + DeckGL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const {Deck} = require('@deck.gl/core'); | |
const {GeoJsonLayer} = require('@deck.gl/layers'); | |
// Outlines of US States. Source: Natural Earth http://www.naturalearthdata.com/ via geojson.xyz | |
const US_MAP_GEOJSON = | |
'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_110m_admin_1_states_provinces_shp.geojson'; | |
const TILE_SIZE = 256; | |
const INITIAL_VIEW_STATE = { | |
latitude: 40, | |
longitude: -100, | |
zoom: 4, | |
pitch: 0 | |
}; | |
function initMap() { | |
const mapEl = document.getElementById('map'); | |
const map = new google.maps.Map(mapEl, { | |
mapTypeId: 'hybrid', | |
center: { | |
lat: INITIAL_VIEW_STATE.latitude, | |
lng: INITIAL_VIEW_STATE.longitude | |
}, | |
zoom: INITIAL_VIEW_STATE.zoom + 1, | |
tilt: INITIAL_VIEW_STATE.pitch | |
}); | |
const overlay = new google.maps.OverlayView(); | |
overlay.setMap(map); | |
let deck; | |
let isMounted = false; | |
let {clientWidth, clientHeight} = mapEl; | |
const canvasEl = document.createElement('canvas'); | |
canvasEl.width = clientWidth; | |
canvasEl.height = clientHeight; | |
canvasEl.position = 'absolute'; | |
deck = createDeck(map, canvasEl); | |
window.addEventListener('resize', () => { | |
const width = mapEl.clientWidth; | |
const height = mapEl.clientHeight; | |
canvasEl.width = width; | |
canvasEl.height = height; | |
if (deck) { | |
deck.setProps({width, height}); | |
} | |
}); | |
overlay.draw = () => { | |
// Methods like map.getCenter() and map.getZoom() return rounded values that | |
// don't stay in sync during zoom and pan gestures, so compute center and | |
// zoom from the overlay projection, instead. | |
// Don't call overlay.getPanes() until map has initialized. | |
if (!isMounted) { | |
const overlayLayerEl = overlay.getPanes().overlayLayer; | |
overlayLayerEl.appendChild(canvasEl); | |
} | |
// Fit canvas to current viewport. | |
const bounds = map.getBounds(); | |
const nwContainerPx = new google.maps.Point(0, 0); | |
const nw = overlay.projection.fromContainerPixelToLatLng(nwContainerPx); | |
const nwDivPx = overlay.projection.fromLatLngToDivPixel(nw); | |
canvasEl.style.top = nwDivPx.y + 'px'; | |
canvasEl.style.left = nwDivPx.x + 'px'; | |
// Compute fractional zoom. | |
const zoom = Math.log2( overlay.projection.getWorldWidth() / TILE_SIZE ) - 1; | |
// Compute fractional center. | |
const centerPx = new google.maps.Point(clientWidth / 2, clientHeight / 2); | |
const centerContainer = overlay.projection.fromContainerPixelToLatLng(centerPx); | |
const latitude = centerContainer.lat(); | |
const longitude = centerContainer.lng(); | |
deck.setProps({viewState: { zoom, latitude, longitude }}); | |
if (deck.layerManager) { | |
deck.animationLoop.redraw(); | |
} | |
}; | |
} | |
function createDeck(map, canvasEl) { | |
const deck = window.deckInstance = new Deck({ | |
canvas: canvasEl, | |
width: canvasEl.width, | |
height: canvasEl.height, | |
initialViewState: INITIAL_VIEW_STATE, | |
// Google maps has no rotating capabilities, so we disable rotation here. | |
controller: { | |
scrollZoom: false, | |
dragPan: false, | |
dragRotate: false, | |
doubleClickZoom: false, | |
touchZoom: false, | |
touchRotate: false, | |
keyboard: false, | |
}, | |
layers: [ | |
new GeoJsonLayer({ | |
data: US_MAP_GEOJSON, | |
stroked: true, | |
filled: true, | |
lineWidthMinPixels: 2, | |
opacity: 0.4, | |
getLineColor: [255, 100, 100], | |
getFillColor: [200, 160, 0, 180] | |
}) | |
] | |
}); | |
return deck; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment