# groonga - オープンソースのカラムストア機能付き全文検索エンジン

- English

# 7.15.5. `geo_distance`

## 7.15.5.1. 概要

`geo_distance` は二点間の距離を計算します。

## 7.15.5.2. 構文

`geo_distance` は二つの点を指定します。引数 `approximate_type` は省略可能です。

    geo_distance(point1, point2)
    geo_distance(point1, point2, approximate_type)

`approximate_type` のデフォルト値は `"rectangle"` です。 `approximate_type` を省略した場合、 `geo_distance` は二点間の距離を `"rectangle"` が指定されたものとして計算します。

## 7.15.5.3. 使い方

`geo_distance` はGroongaの組み込み関数の一つです。

組み込み関数を grn_expr にて使うことができます。

`geo_distance` 関数は `point1` と `point2` の座標値から二点間の距離(近似値)を計算します。

注釈

Groongaは三つの組み込み関数を距離の計算のために提供しています。 `geo_distance()` 、 `geo_distance2()` 、 `geo_distance3()` です。これらの違いは距離の計算アルゴリズムにあります。 `geo_distance2()` と `geo_distance3()` はバージョン1.2.9より非推奨となりました。 `geo_distance2(point1, point2)` の代りに `geo_distance(point1, point2, "sphere")` を使用してください。 `geo_distance3(point1, point2)` の代りに `geo_distance(point1, point2, "ellipsoid")` を使用してください。

例とともに `geo_distance` について学びましょう。このセクションでは簡単な例を示します。

使い方による違いがわかるようにスキーマ定義とサンプルデータを用意しました。これらのサンプルはニューヨークとロンドンを例に距離の計算方法を示します。

1. 距離の計算にlocationカラムの値を使う ( `Cities` テーブル)
2. 距離の計算に明示的に指定した座標値を使う ( `Geo` テーブル)

### 7.15.5.3.1. locationカラムの値を使う

使用例を示すための `Cities` テーブルのスキーマ定義とサンプルデータは以下の通りです。

    table_create Cities TABLE_HASH_KEY ShortText
    column_create Cities location COLUMN_SCALAR WGS84GeoPoint
    load --table Cities
    [
      {
        "_key", "location"
      },
      {
        "New York City", "146566000x-266422000",
      },
    ]

実行例:

    table_create Cities TABLE_HASH_KEY ShortText
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    column_create Cities location COLUMN_SCALAR WGS84GeoPoint
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    load --table Cities
    [
      {
         "_key", "location"
      },
      {
         "New York City", "146566000x-266422000",
      },
    ]
    # [[0, 1337566253.89858, 0.000355720520019531], 1]

この実行例では `location` というカラムを持つ `Cities` テーブルを作成します。 `location` カラムには座標値を保存します。東京の座標値がサンプルデータとして保存されています。

実行例:

    select Cities --output_columns _score --filter 1 --scorer '_score = geo_distance(location, "185428000x-461000", "rectangle")'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "_score",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         5715104
    #       ]
    #     ]
    #   ]
    # ]

このサンプルは `geo_distance` が `location` カラムと座標値から距離を計算していることを示します。

`geo_distance` の第二引数として渡された値 ("185428000x-461000")はロンドンの座標値です。

### 7.15.5.3.2. 明示的に指定した位置を使う

使用例を示すための `Geo` テーブルのスキーマ定義とサンプルデータは以下の通りです。

    table_create Geo TABLE_HASH_KEY ShortText
    column_create Geo distance COLUMN_SCALAR Int32
    load --table Geo
    [
      {
        "_key": "the record for geo_distance() result"
      }
    ]

実行例:

    table_create Geo TABLE_HASH_KEY ShortText
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    column_create Geo distance COLUMN_SCALAR Int32
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    load --table Geo
    [
      {
        "_key": "the record for geo_distance() result"
      }
    ]
    # [[0, 1337566253.89858, 0.000355720520019531], 1]

この実行例では `distance` カラムを持つ `Geo` テーブルを作成します。 `distance` カラムには距離を保存します。

実行例:

    select Geo --output_columns distance --scorer 'distance = geo_distance("146566000x-266422000", "185428000x-461000", "rectangle")'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "distance",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         5807750
    #       ]
    #     ]
    #   ]
    # ]

このサンプルは `geo_distance` がロンドンの座標とニューヨークの座標から距離を計算していることを示します。

## 7.15.5.4. 引数

### 7.15.5.4.1. 必須引数

必須引数は二つあります。 `point1` と `point2` です。

#### 7.15.5.4.1.1. `point1`

計算しようとしている二点間の開始地点を指定します。

GeoPoint型の値を指定することができます。 [1]

GeoPointについては データ型 を参照してください。

#### 7.15.5.4.1.2. `point2`

計算しようとしている二点間の終了地点を指定します。

GeoPoint型の値か座標を表す文字列を指定することができます。

GeoPointと座標については データ型 を参照してください。

### 7.15.5.4.2. 省略可能引数

省略可能な引数として `approximate_type` があります。

#### 7.15.5.4.2.1. `approximate_type`

距離を計算するときに地形をどのように近似するかを指定します。

`approximate_type` の値は以下を指定することができます。

> - `rectangle`
> - `sphere`
> - `ellipsoid`

注釈

`geo_distance` には制限があります。 `sphere` や `ellipsoid` を近似方法として選択した場合、子午線や日付変更線、赤道といった境界をまたぐ距離の計算を行うことができません。この制限は `rectangle` を近似方法として選択した場合にはありません。これはGroongaの実装上の一時的な制限ですが、将来的には修正される予定です。

##### 7.15.5.4.2.1.1. `rectangle`

この引数を指定すると地形を方形近似して距離を計算します。

簡易な式で距離の計算を行うので、高速に距離を求めることができますが、極付近では誤差が増大します。

`rect` を省略表記として指定することができます。

カラムの値で距離を計算するサンプルは以下の通りです。

実行例:

    select Cities --output_columns _score --filter 1 --scorer '_score = geo_distance(location, "185428000x-461000", "rectangle")'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "_score",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         5715104
    #       ]
    #     ]
    #   ]
    # ]

明示的に位置を指定して距離を計算するサンプルは以下の通りです。

実行例:

    select Geo --output_columns distance --scorer 'distance = geo_distance("146566000x-266422000", "185428000x-461000", "rectangle")'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "distance",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         5807750
    #       ]
    #     ]
    #   ]
    # ]

明示的に子午線や赤道、日付変更線をまたぐような位置を指定して距離を計算するサンプルは以下の通りです。

実行例:

    select Geo --output_columns distance --scorer 'distance = geo_distance("175904000x8464000", "145508000x-13291000", "rectangle")'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "distance",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         1051322
    #       ]
    #     ]
    #   ]
    # ]

このサンプルは子午線をまたいだ場合の距離を示します。 `geo_distance("175904000x8464000", "145508000x-13291000", "rectangle")` はパリ(フランス)からマドリード(スペイン)間の距離を返します。

実行例:

    select Geo --output_columns distance --scorer 'distance = geo_distance("146566000x-266422000", "-56880000x-172310000", "rectangle")'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "distance",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         6880439
    #       ]
    #     ]
    #   ]
    # ]

このサンプルは赤道をまたいだ場合の距離を示します。 `geo_distance("146566000x-266422000", "-56880000x-172310000", "rectangle")` はニューヨーク(アメリカ)からブラジリア(ブラジル)間の距離を返します。

実行例:

    select Geo --output_columns distance --scorer 'distance = geo_distance("143660000x419009000", "135960000x-440760000", "rectangle")'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "distance",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         10475660
    #       ]
    #     ]
    #   ]
    # ]

このサンプルは日付変更線をまたいだ場合の距離を示します。 `geo_distance("143660000x419009000", "135960000x-440760000", "rectangle")` は北京(中国)からサンフランシスコ(アメリカ)間の距離を返します。

注釈

`geo_distance` は方形近似をデフォルトとして使用します。 `approximate_type` を省略すると `geo_distance` は `rectangle` が指定されたものとして振舞います。

注釈

`geo_distance` は `approximate_type` の値が `"rectangle"` であるときに `point1` の値として座標を表す文字列を受けつけます。もし `sphere` や `ellipsoid` と一緒に座標を表す文字列を `point1` へ指定した場合、 `geo_distance` は距離の値として0を返します。

##### 7.15.5.4.2.1.2. `sphere`

この引数を指定すると球面近似で地形を近似して距離を計算します。

球面近似は `rectangle` よりも遅いです。しかし `rectangle` よりも誤差は小さくなります。

`sphr` を省略表記として指定することができます。

カラムの値で距離を計算するサンプルは以下の通りです。

実行例:

    select Cities --output_columns _score --filter 1 --scorer '_score = geo_distance(location, "185428000x-461000", "sphere")'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "_score",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         5715102
    #       ]
    #     ]
    #   ]
    # ]

##### 7.15.5.4.2.1.3. `ellipsoid`

この引数を指定すると楕円近似で地形を近似して距離を計算します。

ヒュベニの距離計算式により距離を計算します。 `sphere` よりも遅いですが、 `sphere` より誤差は小さくなります。

`ellip` を省略表記として指定することができます。

カラムの値で距離を計算するサンプルは以下の通りです。

実行例:

    select Cities --output_columns _score --filter 1 --scorer '_score = geo_distance(location, "185428000x-461000", "ellipsoid")'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "_score",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         5706263
    #       ]
    #     ]
    #   ]
    # ]

## 7.15.5.5. 戻り値

`geo_distance` はFloat型の値を距離として返します。単位はメートルです。

脚注

[1] | 日本測地系座標か世界測地系座標のいずれかを指定することができます。