npm package: @gkucmierz/geo-number
Description: High-precision geographic coordinate hashing engine using the HEALPix algorithm. Encodes exact Latitude and Longitude to equal-area mathematical String/BigInt representations bounding global precision up to 1m^2.
Author: Grzegorz Kucmierz
Latest version: 1.0.3

# @gkucmierz/geo-number

High-precision geographic coordinate hashing engine utilizing the HEALPix (Hierarchical Equal Area isoLatitude Pixelization) algorithm.

`geo-number` mathematically encodes exact Latitude and Longitude pairs into single large `BigInt` identifiers (hashes), guaranteeing equal-area surface projections. It natively supports extreme resolutions beyond order 52, bounding global planetary precision down to `1 m²` without suffering from standard JSON float/32-bit bitshift precision bottlenecks.

## Description

Unlike traditional Geohashing (Z-ordered curves) where precision grids distort severely depending on their geographic position (e.g. stretching at poles), `geo-number` relies on HEALPix tessellation to guarantee that every single hash area globally maintains exactly the same square area.
This library serves as a bulletproof engine to compress coordinate coordinates into raw deterministic IDs or to resolve encoded tokens back to a center point.

## Installation

```bash
npm install @gkucmierz/geo-number
```

## Features

- **Extreme Scaling**: Safely implements HEALPix Order 52 bounds (`nside` scaling up to `10^15`).
- **Equal-Area Hash Tessellation**: Guarantees standard spherical dimensions regardless of origin geometry.
- **Floating-Point Limits Avoidance**: Overrides traditional JS operators with custom `BigInt` Math logic bounds.
- **ES Modules**: Fully modern JS build natively supporting Typescript environments and modern Web Bundlers.

## Usage

### 1. Encoding Coordinates (Lat / Lng -> BigInt)

Converts a geographic point to a HEALPix grid `BigInt` cell ID depending on the provided resolution `order`.

```javascript
import { encode, decode } from '@gkucmierz/geo-number';

// Parameters: lat, lng, resolution order (default is very high stringency: 52n)
const lat = 52.2297;
const lng = 21.0122;

const hashId = encode(lat, lng, 30n);
console.log(hashId); // e.g. 195843475988225588n
```

### 2. Decoding a Hash (BigInt -> Lat / Lng)

Resolves a previously encoded `geo-number` token back into its exact geometric face center coordinate over the given `order`.

```javascript
import { encode, decode } from '@gkucmierz/geo-number';

// Parse BigInt hash directly
const hashId = 195843475988225588n;

// Decode with matching initialization order
const point = decode(hashId, 30n);

console.log(`Latitude: ${point.lat}, Longitude: ${point.lng}`);
```

## Precision Scales / Order Sizes
The strictness of compression relies on the specific `order` scaling (where total global sphere regions = `12 * 2^(2 * order)`). In standard operations resolving typical Earth representations (Area ~ 510,072,000 km²):
- **Order 15**: ~1,820 m²
- **Order 20**: ~1.73 m²
- **Order 23**: ~0.60 m² (Half-meter sq - **Ideal for Street Level**)
- **Order 24**: ~0.15 m²
- **Order 26**: ~0.009 m² (~1 dm²)
- **Order 52**: Absolute JS `BigInt` Library Boundary (Extremely deep Sub-millimeter scales natively supported without overflow).

The library inherently restricts coordinate floats to physical boundaries (Lat `[-90, 90]`, Lng `[-180, 180]`). Values exceeding this sphere will securely clamp or normalize wrap.

## Dictionary Encoding & Checksum Tradeoffs
When mapping these `BigInt` identifiers to a dictionary of words (e.g. BIP39 where each word provides exactly **11 bits** of entropy), a **5-word** sequence yields exactly **55 bits** of payload payload.

The specific `order` you choose directly determines how many of those 55 bits are consumed by the geographic ID, and how many are reserved for a checksum (which detects user spelling/dictation errors).
Here is a complete mathematical breakdown analyzing the UX tradeoff between **Order 23** and **Order 24** inside a 5-word encoding system:

```javascript
const EARTH_AREA_M2 = 510.072e12; // sq meters
const BITS_PER_WORD = 11;
const TOTAL_WORDS = 5;
const TOTAL_BITS = TOTAL_WORDS * BITS_PER_WORD; // 55 bits total

function evaluateTradeoff(order) {
  // Total HEALPix pixels globally for the given order: 12 * (4^order)
  const totalPixels = 12 * Math.pow(4, order);
  
  const areaSqMeters = EARTH_AREA_M2 / totalPixels;
  const payloadBits = Math.ceil(Math.log2(totalPixels));
  const checksumBits = TOTAL_BITS - payloadBits;
  
  // Chance that a completely random typo accidentally matches a valid checksum
  const falsePositiveRate = 1 / Math.pow(2, checksumBits);
  const errorDetectionRate = (1 - falsePositiveRate) * 100;
  
  return { 
    areaSqMeters: areaSqMeters.toFixed(2), 
    payloadBits, 
    checksumBits, 
    errorDetectionRate: errorDetectionRate.toFixed(2) + '%' 
  };
}

console.log("Order 23:", evaluateTradeoff(23));
// -> { areaSqMeters: "0.60", payloadBits: 50, checksumBits: 5, errorDetectionRate: "96.88%" }

console.log("Order 24:", evaluateTradeoff(24));
// -> { areaSqMeters: "0.15", payloadBits: 52, checksumBits: 3, errorDetectionRate: "87.50%" }
```
**Conclusion**: `Order 23` is the optimal engineering choice. By sacrificing sub-meter precision down to `0.60 m²` (still equivalent to a paving stone, well within the boundary limits of phone GPS accuracy), the system retains a robust 5-bit checksum. This guarantees a **~96.9% native rejection rate** for user typos and dictation mistakes, whereas `Order 24` would quietly accept false addresses in 1 out of 8 typos.

[Run this calculation on InstaCode](https://instacode.app/run/FAYw9gdgzgLgBAUwIYCcYAsCCLlwLxwCsAjAAwB0pA7AEwLE0DccA9C3AJYRxQCOArqgRwAtghgIUUUJFhwYAdzAAFMAsI18cTQCodRUszZwI-EQCNJcMADM4OAOYdZcJABsRYOQgHuAnnAAJhwAbhyBCIHAMtDwDuIAYkggCFBa4QAe+AB8cADewHD24vwo3Axw+gAslfqZjMAAvg3ANmAocAAUbuKcWoZ9ADzaVMwA1GMcAJT5hXDgsXA2yala8TBJKVCd0w1FC94ZAA5aALJIGOQpHG6d55duYA40nctbU1N787LwR2paun0CGOXwO8EecgIfwUcAAtEsVlBQT84EdJCkIPACAADAAkeW6XhgLDeqR0ZFIU3IMDACQ4GUinRoU0aAFJsXMDmAeuRHg4dgAaODrTapHZTIXAo5C6FCiEwGXohCYz5NaJgzgQCJZAg0ADMLWMSBCkiQ8R4HAAXsJbBaIA4esUnJAAFzAPF5ZBoLA4JCsYWJRE7LXAlk8XiicSSKDYhpAA)