@loaders.gl/shapefile
Version:
Loader for the Shapefile Format
79 lines (70 loc) • 2.14 kB
text/typescript
// loaders.gl
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors
import type {ObjectRowTableBatch, ArrayRowTableBatch} from '@loaders.gl/schema';
type RowTableBatch = ObjectRowTableBatch | ArrayRowTableBatch;
/**
* Zip two iterators together
*
* @param iterator1
* @param iterator2
*/
export async function* zipBatchIterators(
iterator1: AsyncIterator<RowTableBatch> | Iterator<RowTableBatch>,
iterator2: AsyncIterator<RowTableBatch> | Iterator<RowTableBatch>,
shape: 'object-row-table' | 'array-row-table'
): AsyncGenerator<RowTableBatch, void, unknown> {
const batch1Data: unknown[] = [];
const batch2Data: unknown[] = [];
let iterator1Done: boolean = false;
let iterator2Done: boolean = false;
// TODO - one could let all iterators flow at full speed using `Promise.race`
// however we might end up with a big temporary buffer
while (!iterator1Done && !iterator2Done) {
if (batch1Data.length === 0 && !iterator1Done) {
const {value, done} = await iterator1.next();
if (done) {
iterator1Done = true;
} else {
// @ts-expect-error
batch1Data.push(...value);
}
}
if (batch2Data.length === 0 && !iterator2Done) {
const {value, done} = await iterator2.next();
if (done) {
iterator2Done = true;
} else {
batch2Data.push(...value);
}
}
const batchData = extractBatchData(batch1Data, batch2Data);
if (batchData) {
yield {
batchType: 'data',
shape,
length: batchData.length,
data: batchData
};
}
}
}
/**
* Extract batch of same length from two batches
*
* @param batch1
* @param batch2
* @return array | null
*/
function extractBatchData(batch1: any[], batch2: any[]): any[] | null {
const batchLength: number = Math.min(batch1.length, batch2.length);
if (batchLength === 0) {
return null;
}
// Non interleaved arrays
const batch: any[] = [batch1.slice(0, batchLength), batch2.slice(0, batchLength)];
// Modify the 2 batches
batch1.splice(0, batchLength);
batch2.splice(0, batchLength);
return batch;
}