Manhattan demo - 3D tiles

by felixp

HTML

<!DOCTYPE html>
<html>

  <head>
    <title>Manhattan demo - 3D tiles</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <!-- Only required for H3 Layer -->
    <script src="https://unpkg.com/h3-js@^3.0.0"></script>
    <script src="https://unpkg.com/[email protected]/dist.min.js"></script>
    <script src="https://unpkg.com/@deck.gl/[email protected]/dist.min.js"></script>
    <script src="https://unpkg.com/@deck.gl/[email protected]/dist.min.js"></script>
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.0/mapbox-gl.css' rel='stylesheet' />
    <script src="https://unpkg.com/range-slider-input@2"></script>
    <!-- jsFiddle will insert css and js -->
  </head>

  <body>
    <div id="map"></div>
    <div id="range-slider"></div>
  </body>

</html>

CSS

/* Always set the map height explicitly to define the size of the div element that contains the map. */
#map {
  height: 100%;
}

/* Optional: Makes the sample page fill the window. */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#legend {
  position: absolute;
  top: 10px;
  right: 10px;
  opacity: 0;
  transition: opacity 0.5s ease-in;
}

#range-slider {
  width: calc(100vw - 50px);
  margin: 30px 25px;
  position: absolute;
  bottom: 0px;
}

#range-slider .range-slider__thumb {
  transition: transform .3s;
}

#range-slider .range-slider__thumb[data-active] {
  transform: translate(-50%, -50%) scale(1.25);
}

JavaScript

const cartoMapId = '7fe0992f-ee41-4d6d-9dd2-8038d53368b4';
const GOOGLE_MAPS_API_KEY = 'AIzaSyDiRUa7i2MNFEZypzxD5glFIYMvQGFz6As';
let deckgl = null;
let builderLayers = null;
let range = [1950, 1980];

async function fetchLayers() {
  const {initialViewState, layers} = await deck.carto.fetchMap({cartoMapId});
  builderLayers = layers;
  deckgl = new deck.DeckGL({container: 'map', controller: true, initialViewState});
  render();
}
fetchLayers();

function render() {
  const [zipCodes, buildings, centroids] = builderLayers;
  const layers = [
    buildings.clone({
      extensions: [
        new deck.DataFilterExtension({filterSize: 1}),
        new deck._TerrainExtension()
      ],

		  getFilterValue: f => f.properties.yearbuilt,
      pickable: false,
  		filterRange: range,
      maskId: 'mask',
    }),
    new deck.Tile3DLayer({
      id: 'google-3d-tiles',
      data: 'https://tile.googleapis.com/v1/3dtiles/root.json',
      loadOptions: {
        fetch: {headers: {'X-GOOG-API-KEY': GOOGLE_MAPS_API_KEY}}
      },
      operation: 'terrain+draw'
    })
  ]
  deckgl.setProps({layers});
}

rangeSlider(document.querySelector('#range-slider'), {
  min: 1900, max: 2023, step: 01, value: range, onInput: newRange => {
    range = newRange;
    render();
  }
});