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:...