@studnicky/geo-layer-voting-district
US congressional/voting-district geohash lookup layer, built from US Census TIGERweb voting-district boundaries.
This package resolves a WGS-84 coordinate to its US congressional (voting) district name in O(1), decoding a compact geohash-4 cell table with an override tree for boundary cells. VotingDistrictBuilder builds that artifact from TIGERweb data (or any compatible adapter); VotingDistrictLookup decodes it and answers lookup(lat, lon) queries. TIGER is a US-only publisher, so coverage is US-only — every non-US coordinate resolves to null.
Install
pnpm add @studnicky/geo-layer-voting-districtRequires @studnicky:registry=https://npm.pkg.github.com in .npmrc.
Lookup against the bundled fixture
VotingDistrictLookup.default() loads a synthetic placeholder fixture (three fake latitude-banded districts) — it proves the decode/lookup path end to end and fires onPlaceholderWarning since metadata.synthetic is true:
import { VotingDistrictLookup } from '../src/index.js';
function demonstrateLookupBundledFixture(): { 'equatorResult': string | null; 'northResult': string | null; 'sourceId': string; 'southResult': string | null; 'synthetic': boolean; 'uncoveredResult': string | null; 'warningCount': number } {
// This layer only covers the US — TIGER is a US-only publisher.
console.log('coverage:', VotingDistrictLookup.coverage);
const warnings: string[] = [];
function collectWarning(message: string): void {
warnings.push(message);
}
// .default() loads the bundled synthetic fixture — no network access required.
// It warns via onPlaceholderWarning since the fixture isn't real district data.
const lookup = VotingDistrictLookup.default({ 'onPlaceholderWarning': collectWarning });
console.log('placeholder warning:', warnings[0]);
console.log('metadata.synthetic:', lookup.metadata.synthetic);
console.log('metadata.sourceId:', lookup.metadata.sourceId);
// The bundled fixture has three latitude-banded districts.
const northResult = lookup.lookup(60, 0);
const equatorResult = lookup.lookup(0, 0);
const southResult = lookup.lookup(-60, 0);
console.log('lookup(60, 0):', northResult);
console.log('lookup(0, 0):', equatorResult);
console.log('lookup(-60, 0):', southResult);
// A coordinate outside every mapped district resolves to null.
const uncoveredResult = lookup.lookup(0, 179);
console.log('lookup(0, 179):', uncoveredResult);
return {
'equatorResult': equatorResult,
'northResult': northResult,
'sourceId': lookup.metadata.sourceId,
'southResult': southResult,
'synthetic': lookup.metadata.synthetic,
'uncoveredResult': uncoveredResult,
'warningCount': warnings.length
};
}Building from an adapter
VotingDistrictBuilder.build() builds a production-accurate table against a TIGERweb-compatible adapter, then VotingDistrictLookup.fromArtifact() loads the result:
import { VotingDistrictBuilder, VotingDistrictLookup } from '../src/index.js';
async function demonstrateBuildAndLookup(): Promise<{ 'cellTableBinPath': string; 'districtName': string; 'insideResult': string | null; 'mixedCellCount': number; 'outsideResult': string | null; 'tupleCount': number }> {
const districtName = 'Example Congressional District';
const bbox: [number, number, number, number] = [-170, -80, 170, 80];
const feature: Feature = {
'geometry': {
'coordinates': [[[-170, -80], [170, -80], [170, 80], [-170, 80], [-170, -80]]],
'type': 'Polygon'
},
'properties': { 'NAME': districtName },
'type': 'Feature'
};
const featureCollection: FeatureCollection = { 'features': [feature], 'type': 'FeatureCollection' };
// A minimal in-memory adapter — real callers use `USCensusTigerAdapter` from
// `@studnicky/geo-adapters` to fetch live TIGERweb data instead.
class ExampleAdapter implements AdministrativeSystemAdapterInterface<FeatureCollection> {
readonly coverage: readonly string[] = ['US'];
readonly layers: readonly AdminLayerType[] = ['voting-district'];
readonly systemId: string = 'example-voting-district';
fetchLayer(_layer: AdminLayerType, _parameters: FetchParametersType): Promise<RawDatasetType<FeatureCollection>> {
const rawDataset: RawDatasetType<FeatureCollection> = {
'data': featureCollection,
'fetchedAt': new Date(0).toISOString(),
'license': 'example — not for production use',
'sourceId': 'example-voting-district'
};
return Promise.resolve(rawDataset);
}
}
const outputDir = mkdtempSync(join(tmpdir(), 'geo-layer-voting-district-example-'));
try {
const buildResult = await VotingDistrictBuilder.build({
'adapter': new ExampleAdapter(),
'bbox': bbox,
'maxDescentDepth': 2,
'outputDir': outputDir
});
console.log('tupleCount:', buildResult.tupleCount);
console.log('mixedCellCount:', buildResult.mixedCellCount);
console.log('cellTableBinPath:', buildResult.cellTableBinPath);
const lookup = VotingDistrictLookup.fromArtifact(buildResult.artifact);
const insideResult = lookup.lookup(0, 0);
const outsideResult = lookup.lookup(0, 179);
console.log('lookup(0, 0):', insideResult);
console.log('lookup(0, 179):', outsideResult);
return {
'cellTableBinPath': buildResult.cellTableBinPath,
'districtName': districtName,
'insideResult': insideResult,
'mixedCellCount': buildResult.mixedCellCount,
'outsideResult': outsideResult,
'tupleCount': buildResult.tupleCount
};
}
finally {
rmSync(outputDir, { 'force': true, 'recursive': true });
}
}