@studnicky/geo-layer-postal
US ZCTA postal-code lookup by coordinate, backed by a geohash-indexed cell table with adaptive-depth overrides.
This package resolves a (lat, lon) coordinate to the US ZCTA (ZIP Code Tabulation Area) code containing it, or null outside every mapped ZCTA. Cell classification, adaptive-depth override descent, and artifact encoding are delegated to @studnicky/geo-boundary-layer-kit; this package supplies only the ZCTA-specific NamedFeatureResolver oracle (properties.ZCTA5 extraction from TIGERweb GeoJSON) that the kit builds and looks up against.
Install
pnpm add @studnicky/geo-layer-postalRequires @studnicky:registry=https://npm.pkg.github.com in .npmrc.
Basic lookup
PostalLookup.default() loads the bundled synthetic fixture artifact, and exposes coverage and provenance metadata:
import { PostalLookup } from '../src/index.js';
function logPlaceholderWarning(message: string): void {
console.log('placeholder warning:', message);
}
function demonstrateBasicLookup(): { 'insideResult': string | null; 'outsideResult': string | null; 'synthetic': boolean } {
// the layer's coverage — this layer only has boundary data for the US
console.log('coverage:', PostalLookup.coverage);
// PostalLookup.default() loads the bundled synthetic fixture artifact
const lookup = PostalLookup.default({ 'onPlaceholderWarning': logPlaceholderWarning });
// provenance of the loaded artifact
console.log('metadata:', lookup.metadata);
// a point inside one of the fixture's 4 synthetic ZCTA squares (near Philadelphia, PA)
const insideResult = lookup.lookup(40.025, -75.075);
console.log('lookup(40.025, -75.075):', insideResult);
// a point outside every mapped ZCTA resolves to null, never throws
const outsideResult = lookup.lookup(0, 0);
console.log('lookup(0, 0):', outsideResult);
return { 'insideResult': insideResult, 'outsideResult': outsideResult, 'synthetic': lookup.metadata.synthetic };
}Building a custom artifact
PostalBuilder.build() builds a real artifact against live (or faked) US Census TIGERweb data, then PostalLookup.fromArtifact() loads it:
import { PostalBuilder, PostalLookup } from '../src/index.js';
async function demonstrateBuildCustomArtifact(): Promise<{ 'cellCount': number; 'insideResult': string | null; 'outsideResult': string | null; 'sourceId': string; 'tupleCount': number }> {
// a single synthetic ZCTA square near Philadelphia, PA — stands in for a real TIGERweb response
const fakeFeatureCollection = {
'features': [
{
'geometry': {
'coordinates': [[
[-75.10, 40.00],
[-75.00, 40.00],
[-75.00, 40.10],
[-75.10, 40.10],
[-75.10, 40.00]
]],
'type': 'Polygon' as const
},
'properties': { 'ZCTA5': 'ZDEMO01' },
'type': 'Feature' as const
}
],
'type': 'FeatureCollection' as const
};
const buildBbox: [number, number, number, number] = [-75.15, 39.95, -74.95, 40.15];
const result = await PostalBuilder.build({
'adapter': USCensusTigerAdapter.create(() => {
const response = new Response(JSON.stringify(fakeFeatureCollection), { 'status': 200 });
return Promise.resolve(response);
}),
'bbox': buildBbox,
'maxDescentDepth': 4
});
console.log('tupleCount:', result.tupleCount);
console.log('cellCount:', result.cellCount);
// build a lookup directly from the freshly-built artifact
const lookup = PostalLookup.fromArtifact(result.artifact);
// a point inside the synthetic square resolves to its ZCTA5 code
const insideResult = lookup.lookup(40.05, -75.05);
console.log('lookup(40.05, -75.05):', insideResult);
// a point outside the build bbox resolves to null
const outsideResult = lookup.lookup(0, 0);
console.log('lookup(0, 0):', outsideResult);
return {
'cellCount': result.cellCount,
'insideResult': insideResult,
'outsideResult': outsideResult,
'sourceId': result.artifact.metadata.sourceId,
'tupleCount': result.tupleCount
};
}