Global H3 sizing

by felixp

HTML

<!DOCTYPE html>
<html>

  <head>
    <title>Global H3</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <script src="https://unpkg.com/h3-js"></script>
    <script src="https://unpkg.com/[email protected]/dist.min.js"></script>

    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&v=beta&map_ids=fae05836df2dc8bb"></script>
    <!-- jsFiddle will insert css and js -->
  </head>

  <body>
    <div id="map"></div>
    <div id="textfield">Hexagons</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%;
}

#textfield {
  position: absolute;
  left: 10px;
  top: 10px;
  background: snow;
  box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3);
  padding: 10px;
  
}

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

JavaScript

// Relative scale factor (0 = no biasing, 2 = a few hexagons cover view)
const bias = 0;

// Resolution conversion function. Takes a WebMercatorViewport and returns
// a H3 resolution such that the screen space size of the hexagons is
// similar
function getHexagonResolution(viewport) {
  const hexagonScaleFactor = (2 / 3) * viewport.zoom;
  const latitudeScaleFactor = Math.log(1 / Math.cos(Math.PI * viewport.latitude / 180));

  // Clip and bias
  return Math.max(0, Math.floor(hexagonScaleFactor + latitudeScaleFactor - bias));
}

// Stats
// Iterate over globe and compute min/max hexagon counts. The tighter the
// ratio, the better
const LAT_LIMIT = 80;
const longitude = 0;
let min = Infinity;
let max = -Infinity;

for (let zoom = 5; zoom < 15; zoom += 1) {
  let min2 = Infinity;
  let max2 = -Infinity;

  for (let latitude = -LAT_LIMIT; latitude < LAT_LIMIT; latitude += 1) {
    const viewState = {
      latitude,
      longitude,
      zoom,
      width: 400,
      height: 800
    };
    const n = getHexagonsInView(viewState).length;
    min2 = Math.min(n, min2);
    max2 = Math.max(n, max2);
  }
  //console.log('z', zoom, 'min', min2, 'max', max2, 'ratio', max2 / min2);
  min = Math.min(min, min2);
  max = Math.max(max, max2);

}
console.log('min', min, 'max', max, 'ratio', max / min)


// Visualization
function createHexagonLayer(viewState) {
  const hexagons = getHexagonsInView(viewState);
  const el = document.getElementById('textfield');
  el.innerHTML = `Hexagons: ${hexagons.length}`;

  return new deck.H3HexagonLayer({
    id: 'hexagon',
    data: hexagons,
    getHexagon: d => d,

    extruded: false,
    filled: false,
    stroked: true,
    getLineWidth: 2,
    lineWidthUnits: 'pixels'
  });
}

const COUNTRIES =
  'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_admin_0_scale_rank.geojson';
const baseMap = new deck.GeoJsonLayer({
  id: 'base-map',
  data: COUNTRIES,
  // Styles
  stroked: true,
  filled: true,
  lineWidthMinPixels:...