ベクタータイルスキーマ
キーワード「 must 」、「 must NOT」、「 required 」、「 shall 」、「 Shall not 」、 このドキュメントの「SHOULD」、「SHOULD NOT」、「RECOMMENDED」、「MAY」、および「OPTIONAL」は、 RFC 2119 に記述されているように解釈されます。
ベクタータイル形式では 、Googleプロトコルバッファをエンコード形式として使用します。 プロトコルバッファは、構造化データをシリアル化するための、言語に依存しない、プラットフォームに依存しない拡張可能なメカニズムです。
投影と境界
ベクタータイルは、投影法内の正方形の範囲に基づくデータを表します。 ベクタータイルには、境界と投影法に関する情報を含めることはできません。 ファイル形式では、デコーダがベクタータイルの境界と投影を認識してからデコードすることを前提としています。
Web Mercator は参照の投影法であり、 Google Tileスキームは 参照のタイル範囲規約です。 これらを組み合わせる ことで、特定の地理的領域(特定の詳細レベル)とhttps://example.com/17/65535/43602.mvt
などのパスとの間の1対1の関係が提供されます。
ベクタータイルは、任意の投影法およびタイル範囲スキームを使用してデータを表すために使用できます。
内部構造
このドキュメントでは、ベクタータイル内のデータの構造について説明します。 このドキュメントを検討する前に 、ベクタータイルのprotobufのスキーマ と定義されている構造を確認してください。
レイヤー
ベクタータイルは、名前付きレイヤーのセットで構成されます。 レイヤには、ジオメトリーフィーチャとそのメタデータが含まれます。 レイヤフォーマットは、レイヤに必要なデータがメモリ内で連続しているように設計されており、既存のデータを変更せずにレイヤをベクタータイルに追加できるようになっています。
ベクタータイルには、少なくとも1つのレイヤーが含まれている必要があります。 レイヤには少なくとも1つのフィーチャが含まれている必要があります。
レイヤーには 、レイヤーが準拠するベクタータイル仕様のメジャーバージョン番号を持つフィールドversion
が含まれている必要があります。 たとえば、仕様のバージョン2.1に準拠しているレイヤに version
は、整数値のフィールド2
が含ま れます。 version
フィールドはレイヤ内の最初のフィールドにする必要があります。 デコーダは 最初のversion
を解析して、各レイヤをデコードできることを確認する必要があります。 ベクタータイルコンシューマが不明なバージョンのベクタータイルレイヤーに遭遇した場合、そのレイヤーを解釈しようとするベストエフォート型の試みが行われたり、レイヤーがスキップされたりすることがあります。 いずれの場合も、ベクタータイル内の後続のレイヤーの処理を続行します。
レイヤにはフィールド name
が含まれている必要があります。 ベクタータイルには 、値name
がバイト単位で同一の2つ以上のレイヤーを含めることはできません。 既存のベクタータイルにレイヤーを追加する前に、エンコーダーは 重複を防ぐために既存のフィールド name
をチェックする必要があります。
レイヤ内の各フィーチャには、メタデータとして1つ以上のキーと値のペアが含まれている場合があります。 キーと値は、 レイヤのフィーチャ間で共有される2つのリストkeys
とvalues
のインデックスです。
レイヤーのフィールドkeys
内の各エレメントは文字列です。 keys
には、レイヤーで使用されているフィーチャーのすべてのキーが含ま れます。各キーは、このセットkeys
の位置インデックスによって参照され、最初のキーのインデックスは 0 になります。 keys
のセット には、バイト単位で 2 つ以上の同一の値を含めることはできません。
レイヤーのフィールドvalues
の各エレメントは、いくつかのタイプの値をエンコードします ( 以下を参照 ) 。 values
は 、レイヤーで使用されているフィーチャーのすべての値を表し ます。各値は、このセットvalues
の位置インデックスによって参照され、最初の値はインデックス 0 になります。 values
のセット には、バイト単位で同じタイプの 2 つ以上の同一の値を含めることはできません。
さまざまな文字列、ブール型 、整数、および浮動小数点型の値をサポートするために、 Protobuf エンコードのフィールドvalue
は一連のフィールドoptional
で構成されています。 値には、これらの任意のフィールドのいずれか 1 つだけを含める必要があります。
レイヤーには、タイルの幅と高さを整数座標で記述する extent
を含める必要があります。 ベクタータイル内のジオメトリーは、extent
で定義されたタイルの領域の境界を超えて拡張される場合があります。 extent
で定義されているように、タイルの領域を超えて拡張するジオメトリー は、隣接する複数のタイルと重なるレンダリング機能のバッファとしてよく使用されます。
たとえば、タイルの extent
が 4096 の場合、タイル内の座標単位はその正方形の寸法の 1/4096 を指します。0 の座標はタイル の上端または左端にあり、 4096 の座標は下端または右端にあります。 1 ~ 4095 までの座標はタイル の範囲内にあり、 0 未満または 4096 を超える座標はタイル の範囲外にあります。 (1,10)
または(4095,10)
の点はタイルの範囲内にあります。 (0,10)
または(4096,10)
の点は範囲の端にあります。 (-1,10)
または(4097,10)
の点はタイルの範囲外にあります。
フィーチャー
フィーチャーには、フィールドgeometry
が含まれている必要があります。
フィーチャーに は、 ジオメトリータイプ セクションで説明されているフィールドtype
が含まれている必要があります。
フィーチャに はフィールドtags
が含まれている場合があります。 フィーチャーレベルのメタデータ がある場合は 、そのフィールドtags
に保存する必要があります。
フィーチャに はフィールドid
が含まれている場合があります。 フィーチャーに フィールドid
がある場合 、id
の値は親レイヤーのフィーチャー間で一意である必要があります。
ジオメトリーのエンコーディング
ベクタータイルのジオメトリーデータは、画面座標系で定義されます。 タイルの左上隅(デフォルトで表示)が座標系の原点です。 X軸は右方向に正、Y軸は下方向に正です。 ジオメトリー内の座標は整数でなければなりません。
ジオメトリーは、フィーチャーのフィールド geometry
で 32 ビットの符号なし整数のシーケンスとしてエンコードされます。 各整数は CommandInteger
、または ParameterInteger
です。 デコーダーは、これらを順序付けられた一連の操作として解釈して、ジオメトリーを生成します。
コマンドは、再定義可能な「カーソル」を基準にした位置を参照します。 フィーチャー内の最初のコマンドの場合、カーソルは 座標系の中 (0,0)
にあります。 一部のコマンドではカーソルが移動し、後続のコマンドに影響があります。
コマンドの整数
CommandInteger
は、コマンドが実行されるコマンドをコマンド ID として示し、そのコマンドが実行される回数をコマンド数で示します。
コマンド ID は、 CommandInteger
の最下位 3 ビットで符号なし整数として符号化され、 0 ~ 7 の範囲になります。 コマンド数は、 CommandInteger
の残りの 29 ビットで符号なし整数としてエンコード され、0
~ pow(2, 29) - 1
の範囲になります。
コマンド ID 、コマンド数、および CommandInteger
は、次のビット単位の演算によって関連付けられます。
CommandInteger = (id & 0x7) | (count << 3)
id = CommandInteger & 0x7
count = CommandInteger >> 3
コマンド ID は、次のいずれかのコマンドを指定します。
コマンド | ID | パラメーター | パラメータ数 |
移動先 | 1 | dX , dY | 2 |
LineTo | 2 | dX , dY | 2 |
ClosePath | 7 | パラメータがありません | 0 |
コマンドの整数の例
コマンド | ID | カウント | CommandInteger | バイナリ表現 [Count][Id] |
移動先 | 1 | 1 | 9 | [00000000 00000000 0000000 00001][001] |
移動先 | 1 | 120 | 961 | [00000000 00000000 0000011 11000][001] |
LineTo | 2 | 1 | 10 | [00000000 00000000 0000000 00001][010] |
LineTo | 2 | 3 | 26 | [00000000 00000000 0000000 00011][010] |
ClosePath | 7 | 1 | 15 | [00000000 00000000 0000000 00001][111] |
パラメータの整数
パラメータを必要とするコマンドの後には、そのコマンドで必要とされる各パラメータ ParameterInteger
が続きます。 CommandInteger
の後に続くの数ParameterIntegers
は、コマンドのパラメータ数CommandInteger
にのコマンド数を掛けた値 になります。 たとえば、コマンド数が 3 の MoveTo
コマンドを伴う CommandInteger
の後には、6の ParameterIntegers
が続きます
ParameterInteger
はジグザグにエンコードされ、小さい負の値と正の値が両方とも小さい整数としてエンコードされます。 パラメーター値をParameterInteger
にエンコードするには、次の式を使用します。
ParameterInteger = (value << 1) ^ (value >> 31)
pow(2,31) - 1
より大きい または -1 * (pow(2,31) - 1)
より小さいパラメータ値はサポートされていません。
次の数式は、ParameterInteger
を値にデコードするために使用されます。
value = ((ParameterInteger >> 1) ^ (-(ParameterInteger & 1)))
コマンドタイプ
コマンドのすべての説明で、カーソルの初期位置は座標(cX, cY)
にあると記述します。cX
は、X 軸上のカーソルの位置 、cY
は Y 軸上のcursor
の位置です
MoveTo コマンド
コマンド数n
を持つコマンド MoveTo
は 、ParameterInteger
のn
ペアが続かなければなりません。各ペア (dX, dY)
:
- 座標
(pX, pY)
、場所pX = cX + dX
、 およびpY = cY + dY
が定義されます。 - ポイントジオメトリー内で、この座標によって新しいポイントが定義されます。
- LineString ジオメトリー
内で、この座標は新しい行の開始頂点が定義されます。
- ポリゴンジオメトリ内で、この座標は新しいリニアリングの開始頂点が定義されます。
- カーソルを
(pX, pY)
に移動します。
LineTo コマンドを使用します
コマンド数n
を持つコマンド LineTo
は 、ParameterInteger
のn
ペアが続かなければなりません。各ペア (dX, dY)
:
- カーソル
(cX, cY)
位置で始まり 、座標(pX, pY)
で終わるセグメント を定義し ます。ここで、pX = cX + dX
とpY = cY + dY
を参照してください。 - LineString ジオメトリー内で、このセグメントは現在の行を拡張します。
- ポリゴンジオメトリ内で、このセグメントは現在のリニアリングを延長します。
- カーソルを
(pX, pY)
に移動します。
(dX, dY)
とdX
の任意のペアについて 、dY
が両方とも0
にすることはできませ ん。
ClosePath コマンド
コマンドClosePath
のコマンド数は 1 で、パラメータはありません。 このコマンド は、カーソル(cX, cY)
の位置から現在のリニアリングの開始頂点で終わる線分を介してポリゴンジオメトリの現在のリニアリングを閉じます。
このコマンドを使用しても、カーソル位置は変更されません。
ジオメトリータイプ
各フィーチャーのフィールド geometry
は、enumGeomType
の値でなければならないフィールドtype
によって記述されます。次のジオメトリタイプがサポートされています。
ジオメトリーコレクションはサポートされていません。
不明なジオメトリータイプです
この仕様では 、意図的に不明なジオメトリータイプがオプションとして残されています 。このジオメトリータイプは、エンコーダが実装することを選択できる実験的なジオメトリータイプをエンコードします。 デコーダは、このGeometry Typeのフィーチャーをすべて無視することもできます。
ポイントのジオメトリータイプ
ジオメトリータイプ POINT
は、ポイントまたはマルチポイント ジオメトリをエンコードします。 ポイントジオメトリーのジオメトリーコマンドシーケンスは、 0 より大きいコマンド数を持つ 1 つのコマンドMoveTo
で構成されている必要があります。
ジオメトリーPOINT
に対するコマンドMoveTo
のコマンド数が 1 の場合、そのジオメトリーは単一のポイントとして解釈されなければなりません。そうでない場合、ジオメトリー
はマルチポイントジオメトリとして解釈され、ParameterInteger
の各ペアが単一のポイントをエンコードします。
LineStringのジオメトリーのタイプ
LINESTRING
ジオメトリータイプeは、 LineString または MultilinesString ジオメトリーをエンコードします。 LineString ジオメトリーのジオメトリーコマンドシーケンスは、次のシーケンスの 1 つ以上の繰り返しで構成されている必要があります。
- コマンド数が 1 のコマンド
MoveTo
- コマンド数が 0 より大きいコマンド
LineTo
ジオメトリータイプLINESTRING
のコマンドシーケンスに 1 つのコマンドMoveTo
のみが含まれている場合は、ジオメトリーを単一の LineString として解釈する必要があります。そうでない場合は、ジオメトリーを Multilines String ジオメトリーとして解釈する必要があります。それぞれのMoveTo
は、新しい LineString の始まりを示します。
ポリゴンのジオメトリー タイプ
ジオメトリータイプPOLYGON
は、ポリゴンまたは マルチポリゴン のジオメトリーをエンコードします。各ポリゴンは、ゼロ個以上の内部リングを含む 1 つの外部リングで構成されます。 ポリゴンジオメトリコマンドシーケンスは、次のシーケンスの 1 つ以上の繰り返しで構成されます。
- An
ExteriorRing
- 0
InteriorRing
秒以上
ExteriorRing
およびInteriorRing
は、次 の順序で構成されている必要があります。
- コマンド数が 1 のコマンド
MoveTo
- コマンド数が 1 より大きいコマンド
LineTo
ClosePath
コマンド
外部リングは、 タイル 座標でポリゴンの頂点にsurveyor's fomulaを適用して計算された正の領域を持つ線形リングとして定義されます。 タイル 座標系では (Y 軸を正の位置に、 X 軸を正の位置にして ) 、外側のリングの巻線の順序が時計回りに表示されます。
内側のリングは、 タイル 座標でpolygonの頂点にsurveyor’s fomulaを適用して計算された負の領域を持つリニアリングとして定義されます。 タイル 座標系では (Y 軸を正の位置に、 X 軸を正の位置にして ) 、内側のリングの巻線の順序が反時計回りに表示されます。
ジオメトリータイプPOLYGON
のコマンドシーケンスに外部リングが 1 つだけ含まれている場合、ジオメトリーは単一のポリゴンとして解釈される必要があります。含まれていない場合、ジオメトリーは マルチポリゴン ジオメトリーとして解釈され、各外部リングが新しいポリゴンの先頭であることを示します。ポリゴンに内部リングがある場合は、その内側のリングが属するポリゴンの外部リングの直後にエンコードする必要があります。
リニアリングは、自己交差や自己接線など、異常なジオメトリーポイントを持たないジオメトリー オブジェクトである必要があります。 ClosePath
リニアリングのコマンドを呼び出す前のカーソルの位置は、長さゼロの線分が作成されるため、リニアリングの最初の点と同じ位置を繰り返してはなりません(SHALL NOT)リニアリングには、surveyor's fomulaで計算された面積が 0 であってはなりません。これは、異常なジオメトリポイントを持つリングを意味するためです。
ポリゴンの形状には、交差する内側のリングがないようにし、また、内側のリングは外側のリングで囲む必要があります。
ジオメトリーのエンコード例
ポイントの例
次の場所にあるポイントのエンコード例を示します。
これには、次ののコマンドが必要です。
Encoded as: [ 9 50 34 ]
| | `> Decoded: ((34 >> 1) ^ (-(34 & 1))) = +17
| `> Decoded: ((50 >> 1) ^ (-(50 & 1))) = +25
| ===== relative MoveTo(+25, +17) == create point (25,17)
`> [00001 001] = command id 1 (MoveTo), command count 1
マルチポイントの例
次の場所にある 2 つのポイントのエンコード例を示します。
これには、次の 2 つのコマンドが必要です
- moveTo (+5,+7)
- moveTo (-2, -5)
Encoded as: [ 17 10 14 3 9 ]
| | | | `> Decoded: ((9 >> 1) ^ (-(9 & 1))) = -5
| | | `> Decoded: ((3 >> 1) ^ (-(3 & 1))) = -2
| | | === relative MoveTo(-2, -5) == create point (3,2)
| | `> Decoded: ((34 >> 1) ^ (-(34 & 1))) = +7
| `> Decoded: ((50 >> 1) ^ (-(50 & 1))) = +5
| ===== relative MoveTo(+5, +7) == create point (5,7)
`> [00010 001] = command id 1 (MoveTo), command count 2
LineString の例
ポイントを使用した行のエンコード例 :
これには、次の 3 つのコマンドが必要です
- moveTo (+2,+2)
- lineTo (+0,+8)
- lineTo (+8,+0)
Encoded as: [ 9 4 4 18 0 16 16 0 ]
| | ==== relative LineTo(+8, +0) == Line to Point (10, 10)
| | ==== relative LineTo(+0, +8) == Line to Point (2, 10)
| `> [00010 010] = command id 2 (LineTo), command count 2
| === relative MoveTo(+2, +2)
`> [00001 001] = command id 1 (MoveTo), command count 1
複数の LineString を含む例
ポイントを使用した 2 つの行のエンコード例 :
この場合、次のコマンドが必要になります。
- moveTo (+2,+2)
- lineTo (+0,+8)
- lineTo (+8,+0)
- moveTo (-9,-9)
- lineTo (+2,+4)
Encoded as: [ 9 4 4 18 0 16 16 0 9 17 17 10 4 8 ]
| | | | === relative LineTo(+2, +4) == Line to Point (3,5)
| | | `> [00001 010] = command id 2 (LineTo), command count 1
| | | ===== relative MoveTo(-9, -9) == Start new line at (1,1)
| | `> [00001 001] = command id 1 (MoveTo), command count 1
| | ==== relative LineTo(+8, +0) == Line to Point (10, 10)
| | ==== relative LineTo(+0, +8) == Line to Point (2, 10)
| `> [00010 010] = command id 2 (LineTo), command count 2
| === relative MoveTo(+2, +2)
`> [00001 001] = command id 1 (MoveTo), command count 1
ポリゴンの例
ポイントを持つポリゴンフィーチャのエンコード例 :
- (3,6)
- (8,12)
- (20,34)
- (3,6) 最後のポイントとしてパスが終了しています
は、次のコマンドを使用してエンコードされます。
- moveTo (3, 6)
- lineTo (5) 、 6)
- lineTo (12,22)
- ClosePath
Encoded as: [ 9 6 12 18 10 12 24 44 15 ]
| | `> [00001 111] command id 7 (ClosePath), command count 1
| | ===== relative LineTo(+12, +22) == Line to Point (20, 34)
| | ===== relative LineTo(+5, +6) == Line to Point (8, 12)
| `> [00010 010] = command id 2 (LineTo), command count 2
| ==== relative MoveTo(+3, +6)
`> [00001 001] = command id 1 (MoveTo), command count 1
マルチポリゴンの例
2 つのポリゴンの複雑なエンコーディングの例。 1 つは穴があるポリゴンです。 ポリゴンのポイントの位置を以下に示します。 この例では、内側のリングと新しいポリゴンの違いを示すため、ポリゴンの巻線の順序が非常に重要です。
- ポリゴン 1 :
- 外部リング :
- (0,0)
- (10,0)
- (10,10)
- (0,10)
- (0,0) 最後のポイントとしてパスが終了しています
- ポリゴン 2 :
- 外部リング :
- (11,11)
- (20,11)
- (20,20)
- (11,20)
- (11.11) 最後のポイントとしてパスが終了しています
- 内部リング :
- (13,13)
- (13,17)
- (17,17)
- (17,13)
- (13,13) 最後のポイントとしてパスが終了しています
このポリゴンは、次のコマンドセットでエンコードされます。
- moveTo (+0,+0)
- lineTo (+10,+0)
- lineTo (+0,+10)
- lineTo(-10 、 +0)// このコマンドの後の 0 、 10 にカーソルを置く
- closePath // ポリゴン 1 の末尾
- moveTo(+11, +1)// これは最後の lineTo!
- lineTo (+9,+0)
- lineTo (+0,+9)
- lineTo(-9,+0)// このコマンドの後の 11,20 にカーソルを置く
- closePath // エリアが正の数であるため、これは新しいポリゴンです。
- moveTo(+2,-7)// これは最後の lineTo!
- lineTo (+0,+4)
- lineTo (+4,+0)
- lineTo(+0,-4)// 17 、 13 の位置にカーソルを置く
- closePath // エリアが負の値であるため、内部リングです。
Encoded as: [ 9 0 0 26 20 0 0 20 19 0 15 9 22 2 26 18 0 0 18 17 0 15 9 4 13 26 0 8 8 0 0 7 15 ]
| | | | | | | | `> [00001 111] (ClosePath)
| | | | | | | `> [00011 010] = (LineTo), command count 3
| | | | | | `> [00001 001] = command id 1 (MoveTo), command count 1
| | | | | `> [00001 111] (ClosePath)
| | | | `> [00011 010] = (LineTo), command count 3
| | | `> [00001 001] = command id 1 (MoveTo), command count 1
| | `> [00001 111] (ClosePath)
| `> [00011 010] = (LineTo), command count 3
`> [00001 001] = command id 1 (MoveTo), command count 1
4.4. フィーチャー属性
フィーチャー属性は、フィーチャーのフィールドtag
で整数のペアとしてエンコードされます。 各ペアの最初の整数は 、そのフィーチャーがが属するlayer
のセット内のゼロから始まるkeys
のキーのインデックスを表します。各ペアの 2 番目の整数は 、フィーチャが属するlayer
のvalues
セット内の値のゼロから始まるインデックスを表します。 すべてのキーインデックスは、そのフィーチャー内で一意である必要があります。そのため、そのフィーチャー内の他の属性ペアに同じキーインデックスがないようにする必要があります。 フィーチャー には偶数のフィールドtag
が必要です。 フィーチャ tag
フィールドには、それぞれレイヤーの セットkeys
または セットvalues
の要素数以上のキー インデックスまたは値インデックスを含めてはなりません。
例
たとえば、次のような GeoJSON フィーチャがあります。
{
"type": "FeatureCollection",
"features": [
{
"geometry": {
"type": "Point",
"coordinates": [
-8247861.1000836585,
4970241.327215323
]
},
"type": "Feature",
"properties": {
"hello": "world",
"h": "world",
"count": 1.23
}
},
{
"geometry": {
"type": "Point",
"coordinates": [
-8247861.1000836585,
4970241.327215323
]
},
"type": "Feature",
"properties": {
"hello": "again",
"count": 2
}
}
]
}
次のような構造になります。
layers {
version: 2
name: "points"
features: {
id: 1
tags: 0
tags: 0
tags: 1
tags: 0
tags: 2
tags: 1
type: Point
geometry: 9
geometry: 2410
geometry: 3080
}
features {
id: 2
tags: 0
tags: 2
tags: 2
tags: 3
type: Point
geometry: 9
geometry: 2410
geometry: 3080
}
keys: "hello"
keys: "h"
keys: "count"
values: {
string_value: "world"
}
values: {
double_value: 1.23
}
values: {
string_value: "again"
}
values: {
int_value: 2
}
extent: 4096
}
形状の正確な値は、タイル の投影および範囲によって異なることに注意してください。