Public
Edited
Aug 1, 2022
Importers
1 star
Insert cell
Insert cell
Insert cell
Insert cell
function renderMapLayer({map, id, data, type, paint = {}, layout = {}}) {
const sourceId = `${id}-source`;
const layerId = `${id}-layer`;
let source = map.getSource(sourceId);
// Add the source and layer if we haven't created them yet
if (!source) {
map.addSource(sourceId, {
type: 'geojson',
data
});
map.addLayer({
id: layerId,
source: sourceId,
type,
paint,
layout
});
source = map.getSource(sourceId);
}

// Update the geojson data
source.setData(data);
// Update styles
Object.keys(paint).forEach(key => {
map.setPaintProperty(layerId, key, paint[key]);
});
Object.keys(layout).forEach(key => {
map.setLayoutProperty(layerId, key, layout[key]);
});
}
Insert cell
Insert cell
fixTransmeridian = {
function fixTransmeridianCoord(coord) {
const lng = coord[0];
coord[0] = lng < 0 ? lng + 360 : lng;
}

function fixTransmeridianLoop(loop) {
let isTransmeridian = false;
for (let i = 0; i < loop.length; i++) {
// check for arcs > 180 degrees longitude, flagging as transmeridian
if (Math.abs(loop[0][0] - loop[(i + 1) % loop.length][0]) > 180) {
isTransmeridian = true;
break;
}
}
if (isTransmeridian) {
loop.forEach(fixTransmeridianCoord);
}
}

function fixTransmeridianPolygon(polygon) {
polygon.forEach(fixTransmeridianLoop);
}

function fixTransmeridian(feature) {
const {type} = feature;
if (type === 'FeatureCollection') {
feature.features.map(fixTransmeridian);
return;
}
const {type: geometryType, coordinates} = feature.geometry;
switch (geometryType) {
case 'LineString':
fixTransmeridianLoop(coordinates);
return;
case 'Polygon':
fixTransmeridianPolygon(coordinates);
return;
case 'MultiPolygon':
coordinates.forEach(fixTransmeridianPolygon);
return;
default:
throw new Error(`Unknown geometry type: ${geometryType}`);
}
}
return fixTransmeridian;
}
Insert cell
function renderH3IndexesToMap(map, id, h3Indexes, paint=null, transmeridian=false) {
const geojson = h3ToGeoJSON(h3Indexes);
if (transmeridian) fixTransmeridian(geojson);
renderMapLayer({
map,
id,
data: geojson,
type: 'fill',
paint: {
'fill-color': 'red',
'fill-opacity': 0.4,
...paint
}
});
}
Insert cell
function h3ToGeoJSON(hexes) {
return {
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [...hexes].map(h3Index => [h3.h3ToGeoBoundary(h3Index, true)])
}
}
}
Insert cell
md`## Data`
Insert cell
Insert cell
md`# Dependencies`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more