Simple fetchMap

Docs: https://deck.gl/docs/api-reference/carto/fetch-map

by felixp

HTML

<!DOCTYPE html>
<html>

  <head>
    <title>CartoMap</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://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' />

    <!-- jsFiddle will insert css and js -->
  </head>

  <body>
    <div id="map"></div>
    <div id="legend">
      <fieldset id="fields">
        <legend>Layers</legend>
      </fieldset>
    </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;
}

JavaScript

const cartoMapId = 'f2fe468e-5db3-414e-a0f5-2b4f3bb189ac';
let builderLayers = null;
let layerWidget = null;
const fieldsElement = document.getElementById('fields');
const mapStyle = 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json';

const deckgl = new deck.DeckGL({
  container: 'map',
  controller: true,
  mapStyle,
  initialViewState: {
    longitude: -80,
    latitude: 28,
    zoom: 5
  }
});

async function fetchLayers() {
  const {layers} = await deck.carto.fetchMap({cartoMapId});
  builderLayers = layers;
  for (const l of builderLayers) {
    const {cartoLabel, visible} = l.props;
    addField(cartoLabel, visible, isVisible => {
      builderLayers = builderLayers.map(layer => {
        
        return layer.props.cartoLabel === cartoLabel ? layer.clone({visible: isVisible}) : layer;
      });
      update();
    });
  }
  document.getElementById('legend').style.opacity = 1;

  update();
}
fetchLayers();

function update() {
  deckgl.setProps({layers: builderLayers});
}


let i = 0;
function addField(name, checked, onChange) {
  const field = document.createElement('div');
  const checkbox = document.createElement('input');
  checkbox.type = 'checkbox';
  checkbox.id = `field-${i++}`;
  checkbox.checked = checked;
  checkbox.addEventListener('change', e => {
    onChange(event.currentTarget.checked);
  });
  
  const label = document.createElement('label');
  label.setAttribute('for', checkbox.id);
  label.innerHTML = name;
  field.appendChild(checkbox)
  field.appendChild(label);
  fields.appendChild(field); 
}