Skip to content
This repository has been archived by the owner on Jul 12, 2024. It is now read-only.

chore(gdds-geohash): Geohash polish #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions modules/dggs-geohash/src/geohash/geohash-functions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Geohash Functions

Note: This page should be moved to documentation repo.

Geohash: Gustavo Niemeyer’s geocoding system.

### API Reference

##### geohashIsValid

Check if a value is a string representing an geohash

```typescript
geohashIsValid(value: string): boolean;
```

- `value` value to test
- Returns false if not a geohash, true means it can be a geohash

##### geoToGeohash

Encode latitude/longitude to geohash, either to specified precision or to automatically
evaluated precision.

```typescript
geoToGeohash(lngLat: number[], precision?: number): string;
geoToGeohash(lng: number, lat: number, precision?: number): string;
```

- `lat` - Latitude in degrees.
- `lon` - Longitude in degrees.
- `precision` - Number of characters in resulting geohash.

- Returns Geohash of supplied latitude/longitude

```typescript
const geohash = geoToGeohash([0.119, 52.205], 7); // => 'u120fxw'
```

##### geohashToGeo

Decode geohash to latitude/longitude (location is approximate centre of geohash cell,
to reasonable precision).

```typescript
geohashToGeo(geohash: string): number[];
```

- `geohash` - Geohash string to be converted to latitude/longitude.
- Returns `[lng, lat]` Center of geohashed location.

```typescript
const latlon = Geohash.decode('u120fxw'); // => { lat: 52.205, lon: 0.1188 }
```

##### geohashToBounds

Returns SW/NE latitude/longitude bounds of specified geohash.

```typescript
geohashToBounds(geohash: string, closed?: boolean): geojson;
```

- `geohash` - Cell that bounds are required of.
- `closed` - Whether first vertex should be duplicated at end

- Returns Polygon representing bounds of geohash

##### geohashToNeighbor

Determines adjacent cell in given direction.

```typescript
geohashToNeighbor(geohash: string, direction: string): string;
```

- `geohash` - Cell to which adjacent cell is required.
- `direction` - Direction from geohash (`'N'`/`'S'`/`'E'`/`'W'`).

- Returns Geocode of adjacent cell.

##### geohashToNeighbors

Returns all 8 adjacent cells to specified geohash.

```typescript
geohashToNeighbors(geohash: string): string[];
```

- `geohash` - Geohash neighbors are required of.

- Returns array of 8 adjacent geohashes
107 changes: 107 additions & 0 deletions modules/dggs-geohash/src/geohash/geohash.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright 2022 Foursquare Labs, Inc. All Rights Reserved.

import Geohash from './latlon-geohash';

const BASE32_GEOHASH_REGEX = /^[0-9bcdefghjkmnpqrstuvwxyz]+$/;

/**
* Check if a value is a string representing an geohash
* @returns false if not a geohash, true means it can be a geohash
*/
export function geohashIsValid(geohash: unknown): boolean {
return typeof geohash === 'string' && BASE32_GEOHASH_REGEX.test(geohash);
}
/**
* Encodes latitude/longitude to geohash, either to specified precision or to automatically
* evaluated precision.
*
* @param lng Longitude in degrees.
* @param lat Latitude in degrees.
* @param precision Number of characters in resulting geohash.
* @returns Geohash of supplied latitude/longitude.
* @throws Invalid geohash.
*
* @example
* const geohash = geoToGeohash([0.119, 52.205], 7); // => 'u120fxw'
*/
export function geoToGeohash(lngLat: [number, number], precision?: number): string;
export function geoToGeohash(lng: number, lat: number, precision?: number): string;
export function geoToGeohash(
lng: number | [number, number],
latOrPrecision?: number,
precision?: number
): string {
if (Array.isArray(lng)) {
return Geohash.encode(lng[1], lng[0], latOrPrecision);
}
return Geohash.encode(Number(latOrPrecision), lng, precision);
}

/**
* Decode geohash to latitude/longitude (location is approximate centre of geohash cell,
* to reasonable precision).
*
* @param geohash - Geohash string to be converted to latitude/longitude.
* @returns [lng, lat] Center of geohashed location.
* @throws Invalid geohash
*/
export function geohashToGeo(geohash: string): [number, number] {
const latlng = Geohash.decode(geohash);
return [latlng.lon, latlng.lat];
}

/**
* Returns SW/NE lng/lat bounds of specified geohash.
*
* @param geohash - Cell that bounds are required of.
* @param closed - Whether first vertex should be duplicated at end
* @returns Polygon representing bounds of geohash, in [lng, lat] order
* @throws Invalid geohash.
*/
export function geohashToBounds(geohash: string): [number, number][] {
const extents = Geohash.bounds(geohash);
return [
[extents.sw.lon, extents.sw.lat],
[extents.sw.lon, extents.ne.lat],
[extents.ne.lon, extents.ne.lat],
[extents.ne.lon, extents.sw.lat],
// close polygon
[extents.sw.lon, extents.sw.lat]
];
}
/**
* Determines adjacent cell in given direction.
*
* @param geohash - Cell to which adjacent cell is required.
* @param direction - Direction from geohash (n/s/e/w).
* @returns Geocode of adjacent cell.
* @throws Invalid geohash.
*/
export function geohashToNeighbor(geohash: string, direction: 'n' | 's' | 'e' | 'w'): string {
return Geohash.adjacent(geohash, direction);
}

/**
* Returns all 8 adjacent cells to specified geohash.
*
* @param geohash - Geohash neighbors are required of.
* @returns array of 8 adjacent geohashes
* @throws Invalid geohash.
*/
export function geohashToNeighbors(geohash: string): string[] {
const n = geohashToNeighbor(geohash, 'n');
const e = geohashToNeighbor(geohash, 'e');
const s = geohashToNeighbor(geohash, 's');
const w = geohashToNeighbor(geohash, 'w');

return [
n,
geohashToNeighbor(n, 'e'),
e,
geohashToNeighbor(s, 'e'),
s,
geohashToNeighbor(s, 'w'),
w,
geohashToNeighbor(n, 'w')
];
}
10 changes: 10 additions & 0 deletions modules/dggs-geohash/src/geohash/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright 2022 Foursquare Labs, Inc. All Rights Reserved.

export {
geohashIsValid,
geoToGeohash,
geohashToGeo,
geohashToBounds,
geohashToNeighbor,
geohashToNeighbors
} from './geohash';
Loading
Loading