エンコード済みポリライン アルゴリズム方式
エンコード済みポリラインは、一連の地点について、エンコードされた 2 種類の情報を保存します。この情報は、各地点を表示する最大ズーム レベルと、各地点の緯度と経度です。ズーム レベルは、符号なしの値を使用してエンコードします。一方、地点の座標の場合は、座標ごとにエンコード プロセスが異なるため、符号付きの値を使用する必要があります。このプロセスについては、下記で説明します。地点が移動せず、数が少ない場合は、対話型のポリライン エンコーディング ユーティリティを使用することもできます。
緯度と経度をエンコードする
エンコード プロセスでは、一般的な base64 エンコーディング スキームを使用して 2 進数値を一連の ASCII 文字に変換します。これらの文字が適切に表示されるようにするため、エンコードされる値は、63(ASCII 文字の「?」)を加算してからASCII に変換されます。また、このアルゴリズムでは、各バイト グループの最下位ビットをチェックし、指定された地点の文字がさらに続いているかどうかを確認します。最下位ビットが 1 の場合、その地点はまだ完全なものではなく、その後にもデータが続いています。
データ量を節約するために、各地点には直前の地点からのオフセットのみが格納されます(最初の地点は除く)。緯度と経度は符号付きの値なので、地点はすべて符号付き整数として base64 にエンコードされます。ポリラインのエンコード形式では、緯度と経度を表す 2 つの座標を妥当な精度で表す必要があります。最大経度(+/- 180 度)を小数第 5 位までの精度(180.00000~-180.00000)で表す場合、32 ビットの符号付き 2 進整数値を必要とします。
バックスラッシュ(\)は、文字列リテラル内でエスケープ文字として解釈されます。このような文字列をエンコードする場合は、文字列リテラル内のバックスラッシュをバックスラッシュ 2 個に変換する必要があります。
このような符号付きの値をエンコードする手順は以下のとおりです。
- 最初の符合付き値を取得します:
-179.9832104
- 10 進値を取得して 1e5 で乗算すると、結果は丸められます:
-17998321
- この 10 進値を 2 進値に変換します。負の値は2 進値に変換し、2 の補数を使用して算出して、1 を加える必要があることに注意してください。
00000001 00010010 10100001 11110001
11111110 11101101 01011110 00001110
11111110 11101101 01011110 00001111
- 2 進値の 1 ビットを左にシフトします。
11111101 11011010 10111100 00011110
- 元の 10 進値が負の場合は、このエンコーディング結果を反転します。
00000010 00100101 01000011 11100001
- 2 進値を 5 ビット単位に分割します(右側から)。
00001 00010 01010 10000 11111 00001
- 5 ビットの集合を逆の順序に並べ替えます。
00001 11111 10000 01010 00010 00001
- 後続のビット集合が続く場合は、各値に 0x20 の論理和演算を行います。
100001 111111 110000 101010 100010 000001
- 各値を 10 進値に変換します。
33 63 48 42 34 1
- 各値に 63 を加算します。
96 126 111 105 97 64
- 各値を対応する ASCII 文字に変換します。
`~oia@
以下の表は、エンコードされた地点の例を表しています。エンコードは、前の地点からのオフセットとして行われています。
例
地点: (38.5, -120.2), (40.7, -120.95), (43.252, -126.453)
| 38.5 |
-120.2 |
3850000 |
-12020000 |
+3850000 |
-12020000 |
_p~iF |
~ps|U |
_p~iF~ps|U |
| 40.7 |
-120.95 |
4070000 |
-12095000 |
+220000 |
-75000 |
_ulL |
nnqC |
_ulLnnqC |
| 43.252 |
-126.453 |
4325200 |
-12645300 |
+255200 |
-550300 |
_mqN |
vxq`@ |
_mqNvxq`@ |
エンコード済みポリライン: _p~iF~ps|U_ulLnnqC_mqNvxq`@
レベルをエンコードする
エンコード済みポリラインには、描画する際の精度を指定する情報も保存されます。この情報を使用することで、必要とされていない精度のズーム レベルではセグメントは地図に描画されなくなります。エンコード済みポリラインの各地点の levels 文字列にこの情報は格納されています。この文字列も地点と一緒にエンコードされています。
注: このエンコードされた「レベル」は、ズーム レベルに直接対応していませんが、関連付けられています。より正確には、numLevels パラメータで既存のズーム レベル(現時点では 18)をズーム レベルのグループに分割します。たとえば、numLevels の値が 4 の場合、ズーム レベルは次のレベルにグループ分けされます:
| レベル 0 |
ズーム レベル 0~5 |
| レベル 1 |
ズーム レベル 6~10 |
| レベル 2 |
ズーム レベル 11~14 |
| レベル 3 |
ズーム レベル 15~18 |
この場合、エンコード済みレベルが 3 であれば、地点はすべてのズーム レベルで表示されます。一方、レベルが 0 の場合は、5 を超えるズーム レベルが指定された地点は無視されます。通常、ポリラインの開始地点と終了地点には、両地点がすべてのズーム レベルで表示され、線が適切に描画されるよう、エンコードされた最大のレベルを設定します。
最適化するために、zoomFactor パラメータには、numLevels で指定したズーム レベル グループ間のおおよその拡大率を示す値を指定します。たとえば、ズーム レベルごとに拡大率が 2 倍になり、各グループに 4 つのズーム レベルが含まれている場合、この値には 16 を設定します。
これらのレベルの値は、符号なし整数として base64 にエンコードされます。レベルの値は通常は小さな値のため、5 ビットの境界を超えることはまずありません。そのため、レベルをエンコードした結果はとてもシンプルです。単に 63 を追加した値になります。ただし、以下のエンコード プロセスでは、2 進数値に変換した後、再変換することを想定しています。API が改訂され、レベルの値に変更があった場合に備えて、コードではこの変換を行うようにしてください。
符号なしの値をエンコードする手順は以下のとおりです:
- 最初の符合なし値を取得します。
174
- この 10 進値を 2 進値に変換します。
10101110
- 2 進値を 5 ビット単位に分割します(右側から)。
101 01110
- 5 ビットの集合を逆の順序に並べ替えます。
01110 101
- 後続のビット集合が続く場合は、各値に 0x20 の論理和演算を行います。
101110 00101
- 各値を 10 進値に変換します。
46 5
- 各値に 63 を加算します。
109 68
- 各値を対応する ASCII 文字に変換します。
mD