npm package: @reearth/spatial-id-sdk
Description: The reference implementation of the Spatial ID Object Model Specification for JavaScript or TypeScript consumers.
Author: Geolonia
Latest version: 0.0.0

# 3D 空間 ID 共通ライブラリ

これは 3D 空間 ID の共通ライブラリの JavaScript 版のプロトタイプです。

### 概要

このライブラリは位置情報と空間 ID を相互変換したり操作するための共通ライブラリとして利用されるべき機能を提供します。

コンストラクタである `Space()` に対して、座標及び高度、または空間 ID を引数として渡して実行すると、空間オブジェクトを生成します。

空間オブジェクトは以下のプロパティを持っており、空間を移動するためのいくつかのメソッドも提供します。

* 中心点の緯度及び経度
* 高度
* ズームレベル（分解能）
* ZFXY（3次元タイル番号）
* タイルハッシュ（3次元タイル番号をハッシュ化した値）

メソッドについては以下のリンク先をご参照ください。

https://github.com/spatial-id/spatial-object-model-specification#readme

### 空間IDとその表現形式

「空間ID」は、3次元空間を指し示すための識別子であり、いくつかの表現方法があります。このライブラリでは、主に以下の3つの方法で表現できます。

1. **ZFXY形式** (`/zoom/floor/x/y` のURL形式)
    * `zoom=0` の場合、`f=0/x=0/y=0` の1つの空間IDが全世界を表します。
    * `zoom=1` では、`zoom=0` の空間IDを8分割します。北西下が `0,0,0` として、`f/x/y` の値を設定します。

2. **タイルハッシュ形式**
    * [Z曲線](https://ja.wikipedia.org/wiki/Z%E9%9A%8E%E6%95%B0%E6%9B%B2%E7%B7%9A)や[ヒルベルト曲線](https://ja.wikipedia.org/wiki/%E3%83%92%E3%83%AB%E3%83%99%E3%83%AB%E3%83%88%E6%9B%B2%E7%B7%9A)で利用できます。
    * 空間IDは再帰的に計算でき、ズームレベル1から指定のズームレベルまで、各ズームレベルでの相対的な位置（北西下、北東下、南西下、南東下、上などの8方向）を1文字ずつ追加して、グローバルな位置を特定します。
    * ある空間IDが他の空間IDに含まれているかどうかは、文字列の**前方一致**で判定できます。

3. **インデックス形式**
    * ヒルベルト曲線で利用できます。
    * 指定したズームレベルでのヒルベルト曲線上の位置を、0から最大値までの数字で表します。

それぞれの形式には短所と長所があり、用途に応じて使い分けることができます。

* **ZFXY形式**
    * 地図ライブラリで使われる XYZ タイルを拡張した形であるため、既存のライブラリや Web サーバー技術との相性が高い。
    * 空間IDの計算や処理が直感的で簡単です。

* **タイルハッシュ形式**
    * 異なるズームレベルの複数の空間IDを評価することが容易です。前方一致によって包含関係を確認でき、数字が近ければ地理的にも近いことを示します。
    * 1つの文字列が1つのズームレベルに対応するため、高いズームレベル（例：ズーム25）では25文字の長さが必要になります。

* **インデックス形式**
    * 数値型であるため、ビット演算やデータベースでの保存に適しています。
    * ズームレベルを別途指定しないと、正しい空間IDを計算できない可能性があります。

## インストール方法

```
$ npm install https://github.com/spatial-id/javascript-sdk -S
```

## モジュールのロード

以下の方法でモジュールを読み込んでください。

```
import { Space } from '@spatial-id/javascript-sdk'
```

## コンストラクタ

```
Space( input, zoom? )
```

新しい空間オブジェクトを返します。

### 引数

#### input

座標及び高度または空間 ID を以下のフォーマットで指定することができます。

* LngLatWithAltitude: 緯度経度及び高度を含むオブジェクト。（例: `{ lng: number, lat: number, alt?: number }`）
* ZFXYTile: ZFXY（3次元タイル番号）を示す文字列。（例: `/15/6/2844/17952`）
* TileHash: ZFXY をハッシュ化した値（Z曲線方式）。（例: `311234211322651`）
* Hilbert Tilehash: ZFXYをヒルベルト曲線に利用したハッシュ化した値。（例: `H535663435842141`）

#### zoom

ズームレベル（分解能）を整数で指定することができます。

この引数は省略も可能で、デフォルトは `25` です。

## 補助コンストラクタ

```
Space.boundingSpaceForGeometry( geometry, minZoom? )
```

`geometry` に渡された GeoJSON の Geometry オブジェクトに対して、最小分解能（ズームレベル）での空間IDを返す。
`minZoom` が指定している場合は、より少ない分解能（ズームレベル）の空間IDが作られるにしても、 `minZoom` での空間IDを返す。

```
Space.spacesForGeometry( geometry, zoom )
```

`geometry` に渡された GeoJSON の Geometry オブジェクトに対して、その Geometry と指定の `zoom` での分解能（ズームレベル）の空間IDの共通集合を配列として返す。

## メソッド

このライブラリは [Spatial Object Model](https://github.com/spatial-id/spatial-object-model-specification#readme) を参照に実装しています。

`Space` のメソッドのドキュメンテーションは下記となります。

### `.center`

* 現在の空間オブジェクトの中央点 (3Dの `{lng: number, lat: number, alt: number}` 型)

### `.alt`

* 現在の空間オブジェクトの最低高さ (floor)

### `.zoom`

* 現在の空間オブジェクトのズームレベル（分解能）

### `.zfxy`

* 現在の空間オブジェクトが表現している ZFXY を ZFXYTile 型 (`{ z: number, f: number, x: number, y: number }`)

### `.id`, `.tilehash`

* 現在の空間オブジェクトが表現している ZFXY の tilehash の文字列
* tilehashの文字列数はズームレベルに相当します。
* 文字列の後ろから数字を削ると、そのズームレベルの親ズームレベルの空間IDを表現できます。

### `.hilbertTilehash`

* 現在の空間オブジェクトが表現している ZFXY のヒルベルト曲線 tilehash の文字列
  * `tilehash` と区別するために、ヒルベルト曲線の文字列は `H` から始まります。
* tilehashの文字列数（冒頭の `H` を除く）はズームレベルに相当します。
* 文字列の後ろから数字を削ると、そのズームレベルの親ズームレベルの空間IDを表現できます。

### `.hilbertIndex`

* 現在の空間オブジェクトのヒルベルト空間内の位置を一次元の数字で表す。
* ビット操作や最適化したデータベースのインデックスなど、距離推定計算などに使用ください。
* BigInt型として値が入っています。ズーム10ぐらい以降、JavaScriptのNumber型に入れないので、ご注意ください。
* ズームレベルの情報が含まれていない。

### `.zfxyStr`

* 現在の空間オブジェクトが表現している ZFXY を URL のパス型に変換したもの

### `.up(by?: number)`

![up](https://user-images.githubusercontent.com/309946/168220328-47e09300-c4dc-4ad1-adae-2cb17aff23ab.png)

* パラメータがない場合は、現在の空間オブジェクトのひとつ上の空間オブジェクトを返す
* パラメータが指定されている場合は、その個数分の空間オブジェクトを配列で返す

### `.down(by?: number)`

![down](https://user-images.githubusercontent.com/309946/168220818-f89a73b1-b99c-462d-9fcb-5eae0eac03eb.png)

* パラメータがない場合は現在の空間オブジェクトのひとつ下の空間オブジェクトを返す
* パラメータが指定されている場合は、その個数分の空間オブジェクトを配列で返す

### `.north(by?: number), .east(by?: number), south(by?: number), .west(by?: number)`

![north](https://user-images.githubusercontent.com/309946/168221234-b03809ef-6c69-442b-98d3-583b4391108e.png)

* パラメータがない場合は、現在の空間オブジェクトの隣のオブジェクトを返す
* パラメータが指定されている場合は、その個数分の空間オブジェクトを配列で返す

### `.move(by: Partial<Omit<ZFXYTile, 'z'>>)`

* 現在の空間オブジェクトから相対的な新しいオブジェクトを返す。 `by` は少なくとも `x, y, f` の一つ以上を含めてください

```
space.move({x: 1, y: 5, f: -1})
```

上記の例の場合では、返り値は西1マス、北5マス、下1マスにある空間オブジェクト

### `.surroundings()`

![surroundings](https://user-images.githubusercontent.com/309946/168221371-b1ec30c7-f501-4a6b-ad64-5a6345fb9665.png)

* 現在の空間オブジェクトのまわりにあるすべての空間オブジェクトを配列で返す。

### `.parent(atZoom?: number)`

* 現在の空間オブジェクトから、分解能（ズームレベル）を `atZoom` のズームレベルまで下げる。デフォルトでは1段階下げます。

### `.children()`

* 現在の空間オブジェクトから、分解能（ズームレベル）を一つ上げて、そこに含まれるすべての空間オブジェクトを返す。

### `.contains()`

* 指定された緯度経度が、指定されたボクセル内に含まれるかどうかを判定して bool 値を返す。

### `.vertices3d()`

* 現在の空間オブジェクトの3Dバウンディングボックスを作る8点の座標を配列として返す。