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

Commit

Permalink
chore(gdds-geohash): Geohash polish
Browse files Browse the repository at this point in the history
  • Loading branch information
ibgreen committed Oct 13, 2023
1 parent 737e519 commit 7f557bc
Show file tree
Hide file tree
Showing 36 changed files with 431 additions and 0 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
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

0 comments on commit 7f557bc

Please sign in to comment.