h3Indexes = {
const {minLat, maxLat, minLng, maxLng} = bounds;
const height = maxLat - minLat;
const width = maxLng - minLng;
const rowCount = imageData.height;
const colCount = imageData.width;
const px2coord = (row, col) => ({
lat: maxLat - (row / rowCount) * height,
lng: (col / 4 / colCount) * width + minLng
});
const indexes = {};
for (let r = 0; r < rowCount; r++) {
for (let c = 0; c < colCount * 4; c += 4) {
const {lat, lng} = px2coord(r, c);
const h3Index = h3.geoToH3(lat, lng, h3Resolution);
if (!indexes[h3Index]) {
indexes[h3Index] = {sum: 0, count: 0, transparent: 0};
}
const rValue = imageData.data[r * colCount * 4 + c];
const aValue = imageData.data[r * colCount * 4 + c + 3];
indexes[h3Index].sum += rValue;
if (!aValue) indexes[h3Index].transparent++;
indexes[h3Index].count++;
}
}
for (const h3Index of Object.keys(indexes)) {
const neighbors = h3.kRing(h3Index, 1);
for (const n of neighbors) {
if (!indexes[n]) {
const nNeighbors = h3.kRing(n, 1);
const neighborCount = nNeighbors.reduce(
(count, nn) => count += indexes[nn] ? 1 : 0, 0
);
if (neighborCount > 5) {
const filler = indexes[n] = {sum: 0, count: 0, transparent: 0};
nNeighbors.forEach(nn => {
filler.sum += indexes[nn].sum;
filler.count += indexes[nn].count;
filler.transparent += indexes[nn].transparent;
});
}
}
}
}
const out = [];
Object.keys(indexes).forEach(h3Index => {
const {sum, count, transparent} = indexes[h3Index];
if (transparent / count < 0.5) {
out.push({h3Index, value: sum / count});
}
});
return out;
}