twkb-parser
Version:
TWKB parser and serializer
201 lines (127 loc) • 6.88 kB
Markdown
# twkb-parser
This library is used to convert TWKB geometry into GeoJSON geometry
TWKB is a compressed binary format for geographic data.
The specification is available on [Github](https://github.com/TWKB/Specification/blob/master/twkb.md).
## Installation
This library is available on npmjs:
```sh
npm install twkb-parser
```
Import the library in JavaScript:
```js
import { TWKB } from 'twkb-parser'
```
CommonJS and IIFE builds are also available. You can download the files from this repository, or import them with a CDN:
- https://cdn.jsdelivr.net/npm/twkb-parser@1.0.0/build/twkb-parser.iife.js
- https:/unpkg.com/twkb-parser@1.0.0/build/twkb-parser.iife.js
Import the library in HTML:
```html
<script src="https://cdn.jsdelivr.net/npm/twkb-parser@1.0.0/build/twkb-parser.iife.js">
```
## Usage
### Encoding
To convert a GeoJSON geometry to TWKB bytes:
```js
const geometry = { type: "Polygon", coordinates: [...] };
const bytes = TWKB.fromGeoJSON(geometry).toByteArray();
console.log(bytes); // Uint8Array<[...]>
```
TWKB encoding requires two input: a _geometry_ and a coordinates _precision_.
The precision is the number of significant digits on the fractionnal parts of the coordinates. For example, a precision of 4 will convert _9.12345678_ to _9.1234_.
It is used to reduce the size of the output, and it must be chosen based on the precision of the geometry and the projection system of the coordinates.
By default, `precision = 6`.
To convert a GeoJSON geometry in WGS84 with coordinates precision up to 1 meter, a precision of 5 is adequate:
```js
const geometry = { type: "LineString", coordinates: [...] };
const precision = 5;
const string = TWKB.fromGeoJSON(geometry, precision).toBase64();
console.log(string); // aGVsbG8gdGhlcmU...
```
There are other optionnal parameters that can be specified when compressing a geometry: the precision for Z coordinates, the inclusion of a bouding box, etc.
See section _API_ for more details
### Decoding
To convert a TWKB byte array into a GeoJSON geometry:
```js
const bytes = new Uint8Array(...);
const geometry = TWKB.fromArray(bytes).toGeoJSON();
console.log(geometry); // { type: "MultiPoint", coordinates: [...] }
```
TWKB decoding only require a single input: the TWKB data. All encoding parameters are already included in the TWKB format.
## API
A single `TWKB` interface is exposed in this library.
All methods use the same structure: `TWKB.fromInput(...).toOutput()`.
### `TWKB.fromGeoJSON(geojson: object, precision?: number, parameters?: object)`
This method allows the conversion of a GeoJSON geometry.
__Arguments__
- `geojson`: a geometry object in GeoJSON format. Only `Geometry`, `MultiGeometry` and `GeometryCollection` are supported, not `Feature` objects.
- `precision` (optionnal): a number used to reduce the coordinates precision. Must be in range `[-7, 7]`.
- `parameters` (optionnal): an object containing additionnal encoding parameters.
The `parameters` attribute has the following interface:
```js
parameters = {
precisionZ?: number,
precisionM?: number,
includeBbox?: boolean,
includeSize?: boolean,
ids?: IdList
}
```
- precisionZ: a number used to reduce the Z coordinates precision. Must be in range `[0, 7]`.
- precisionM: a number used to reduce the M coordinates precision. Must be in range `[0, 7]`.
- includeBbox: a boolean to toggle the encoding of the GeoJSON bouding box. The `bbox` attribute must be defined on the geometry.
- includeSize: a boolean to toggle the encoding of the size of the data. See TWKB specs for details.
- ids: an array of number representing individual geometry ID. Only valid on MultiGeometry / GeometryCollection. See TWKB specs for details.
#### `TWKB.fromGeoJSON(...).toArray(): number[]`
Convert the GeoJSON geometry to a TWKB geometry
#### `TWKB.fromGeoJSON(...).toByteArray(): Uint8Array`
Convert the GeoJSON geometry to a TWKB geometry
#### `TWKB.fromGeoJSON(...).toBase64(): string`
Convert the GeoJSON geometry to a TWKB geometry, encoded as a Base64 string.
### `TWKB.fromArray(twkb: number[] | Uint8Array)`
This method allows the conversion of a TWKB geometry.
__Arguments__
- twkb: an array of byte (0-255) values representing a TWKB geometry.
#### `TWKB.fromArray(...).toGeoJSON(): GeoJSON`
Convert the TWKB geometry to a GeoJSON geometry.
#### `TWKB.fromArray(...).toBase64(): string`
Convert the TWKB geometry to the same geometry, encoded as a Base64 string. This is basically just Base64 encoding.
### `TWKB.fromBase64(twkb: string)`
This method allows the conversion of a TWKB geometry.
__Arguments__
- twkb: a Base64 string representing a TWKB geometry.
#### `TWKB.fromBase64(...).toGeoJSON(): string`
Convert the TWKB geometry to a GeoJSON geometry.
#### `TWKB.fromBase64(...).toArray(): number[]`
Convert the TWKB geometry to the same geometry. This is basically just Base64 decoding.
#### `TWKB.fromBase64(...).toByteArray(): Uint8Array`
Convert the TWKB geometry to the same geometry. This is basically just Base64 decoding.
## Alternatives
The [wkx](https://github.com/cschwarz/wkx) library can also be used to convert TWKB geometry, and support more geometry format (WKT, WKB, etc).
There are some downsides to the wkx library:
- The coordinates precision for TWKB compression is fixed at __5__.
- The coordinates are __truncated__ and not rounded, which may result in a loss of data after decompression.
- The compression / decompression is __30x to 1000x__ slower, and it increases exponentially based on the geometry size (see _Benchmark_ section).
The [geobuf](https://github.com/mapbox/geobuf) library implements a format with simlar properties and compression performance. It is based on Google's protocol buffer, and can encode entire Feature object.
## Benchmark
System: Pop_OS 22.04
CPU: Intel i7-8665U @1.90Hz
RAM: 16 Go
Node v20.18.2
```
conversion of a GeoJSON LineString with 5,000 points
--------------------
JSON | size: 130.7 KB
TWKB (twkb-parser) | size: 11.2 KB | compression: 91.4% | time: 6.9 ms
TWKB (wkx) | size: 11.2 KB | compression: 91.4% | time: 257.7 ms
Geobuf | size: 17.8 KB | compression: 86.4% | time: 9.8 ms
WKB (wkx) | size: 78.1 KB | compression: 40.2% | time: 6.1 ms
WKT (wkx) | size: 121.0 KB | compression: 7.5% | time: 5.0 ms
conversion of a GeoJSON LineString with 500,000 points
--------------------
JSON | size: 12.8 MB
TWKB (twkb-parser) | size: 1.1 MB | compression: 91.5% | time: 182.7 ms
TWKB (wkx) | size: 1.1 MB | compression: 91.5% | time: 124970.5 ms (!!)
Geobuf | size: 1.7 MB | compression: 86.4% | time: 115.3 ms
WKB (wkx) | size: 7.6 MB | compression: 40.2% | time: 161.1 ms
WKT (wkx) | size: 11.8 MB | compression: 7.5% | time: 606.8 ms
```