依赖于

3D Tiles 1.0

可选与必须

必须同时呈现在 extensionsUsedextensionsRequired 数组中,即“必须的”。

1. 概述

S2 是一个用于定义单位球体外表的网格框架的程序库,一个网格单元(又叫单元格,Cell)将会横竖各取一半来分成 4 个子单元格,单元格的四个边界线均为测地线(即沿着高空的“直线”)。

S2 所定义的这套地表的网格层次结构,有 6 个根单元格。每个根单元格是由单位立方体投影到球面上取得的。

译者注,单位立方体投影到球面这个形容其实不精确,严格来说是单位立方体各个面与球心连贯而成的四棱锥,与球面相交失去的那 6 个测地四边形。见本文上面的图。

通常,传统的 GIS 会把地球椭球体投影到某个立体或可展成立体的曲面(圆锥、圆柱)上。例如,墨卡托投影就是投影到圆柱体上。墨卡托有一个家喻户晓的问题,那就是离极点越近,形变越大。

S2 这种投射形式就改善了墨卡托的问题,并还有其它的益处,它把地外表宰割成没有奇怪端点、形变较小、瓦片相对来说简直相等的瓦片。

基于上述特色,应用 S2 定义的这套瓦片层次结构的 3D Tiles Next 扩大就特地适合逾越寰球范畴的瓦片数据集。

2. 层级

S2 层级构造中,每个根网格测地四边形(称作“单元格”)能细分到 30 级。下图展现第 "1" 个单元格及其 4 个子单元格的图例:

第 0 级(根 Cell)第 1 级(根 Cell 的子级 Cell)

第一行是地球立方体的第 "1" 个 Cell 及其子 Cell,第二行则是椭球面上的第 "1" 个 Cell 及其 4 个子 Cell,其中子 Cell 上的编号“0c”、“14”等暂且不论,编号会在下文“单元格ID”大节中具体解释。

S2 应用改版希尔伯特曲线来编码一维程序的网格编号,给每一级别任意单元格提供了64位的ID,最高层级的单元格能够准确到厘米级空间范畴。

察看 S2 希尔伯特曲线如下:

在地球立方体外表上在地球椭球面上

3. 单元格ID

单元格ID 应用 64 位宽度的二进制比特位来编码,从左到右的比特位的规定:

  • 第 0~3 位,用来编码属于哪个根单元格,取值范畴 0~5(6 个,二进制示意为 000b 到 110b,刚好)
  • 从第 4 位开始到 63 位,为第 1 级~第 30 级别这 29 个级别的单元格编码,从左到右每 2 个位示意一级,因为同一级别只有 4 个兄弟单元格,两位比特位刚好示意 4 个单元格的编码;
  • 基于下面两条规定,前面再补一个 1 来示意完结
  • 再往右,对于没有用到的位数,应用 0 来填充。譬如第 8 级单元格只须要用到 8×2 + 3 + 1 = 20 个比特位

举例(下列第 i 个的起始均为 第 0 个,即以 0 为索引终点数):

001 1 000000000...000   第 1 个根单元格001 01 10000000...000   第 1 个根单元格的第 1 个子单元格001 01 11 100000...000   第 1 个根单元格的第 1 个子单元格的第 3 个子单元格001 01 11 00 1000...000   第 1 个根单元格的第 1 个子单元格的第 3 个子单元格的第 0 个子单元格

上述数字用十进制示意即

3458764513820540928317053413766882918433867069197826129923332663724254167040

4. 令牌(Token)

为了更简便地表白单元格ID,以及更好批示其级别,先将二进制的单元格ID 转换为十六进制,并去掉尾部所有的 0,这样就失去了单元的令牌。

对于第 3 节中的例子,按上述规定生成令牌即:

32c2f2e4
译者注 转成十六进制后,其字符长度刚好就是单元的等级(依然是 0 为索引终点)

5. 空间范畴长方体

S2 的单元(Cell)形容了地球椭球面上的一块四边形区域,记录四边形的四个角点。为了造成空间范畴长方体,这四个角点要沿着它在椭球面的法线方向(通常就是垂直地表向上)拉伸。

此时,用 minimumHeight 示意空间范畴立方体的底面高度,用 maximumHeight 示意顶面高度,留神,这两个高度的 0 值为地球椭球面,单位均为米。

当本文形容的这个扩大来示意瓦片对象的 boundingVolume(空间范畴长方体)时,瓦片对象的 transform 属性将被疏忽。

若应用 3DTILES_bounding_volume_S2 扩大,那么必须保障瓦片必须在空间上是间断紧挨的。

此扩大能够作用于瓦片对象的 boundingVolume 或者瓦片对象的内容属性的 boundingVolume 属性。

将地球椭球体映射到地球立方体时,S2 库提供三种投影,即线性、二次方投影、切线模式,3DTILES_bounding_volume_S2 应用二次方投影,因为精确且无效。

上面是一个例子,它的单元格ID 令牌模式为 "89c6c7":

它的大略地位位于美国费城核心城区,最小高度 minimumHeight 被设为 0,最大高度 maximumHeight 被设为了 1000 米。

具体 JSON 中的对象示意如下:

"boundingVolume": {  "extensions": {    "3DTILES_bounding_volume_S2": {      "token": "89c6c7",      "minimumHeight": 0,      "maximumHeight": 1000    }  }}

再举一例:

{  "asset": {    "version": "1.0"  },  "geometricError": 1000000,  "extensionsUsed": [    "3DTILES_bounding_volume_S2"  ],  "extensionsRequired": [    "3DTILES_bounding_volume_S2"  ],  "root": {    "boundingVolume": {      "extensions": {        "3DTILES_bounding_volume_S2": {          "token": "3",          "minimumHeight": 0,          "maximumHeight": 1000000        }      }    },    "refine": "REPLACE",    "geometricError": 50000,    "children": [      {        "boundingVolume": {          "extensions": {            "3DTILES_bounding_volume_S2": {              "token": "2c",              "minimumHeight": 0,              "maximumHeight": 500000            }          }        },        "refine": "REPLACE",        "geometricError": 500000,        "children": [          {            "boundingVolume": {              "extensions": {                "3DTILES_bounding_volume_S2": {                  "token": "2f",                  "minimumHeight": 0,                  "maximumHeight": 250000                }              }            },            "refine": "REPLACE",            "geometricError": 250000,            "children": [              {                "boundingVolume": {                  "extensions": {                    "3DTILES_bounding_volume_S2": {                      "token": "2ec",                      "minimumHeight": 0,                      "maximumHeight": 125000                    }                  }                },                "refine": "REPLACE",                "geometricError": 125000              }            ]          }        ]      }    ]  }}

6. 与隐式瓦片扩大一起应用

当此扩大与 3DTILES_implicit_tiling 扩大一起应用时,尤其是后者应用四叉树来组织瓦片索引时,那么瓦片的空间范畴体就遵循 S2 所定义的空间档次范畴规定。

当 3DTILES_implicit_tiling 扩大应用的是八叉树组织瓦片的索引时,那么空间范畴长方体的宰割也能够遵循S2 的计划,只不过在四叉树的根底上,在垂直方向的宰割将位于 minimumHeight 和 maximumHeight 的两头点。(请细细品味这一点,在横竖方向上八叉树的空间范畴长方体的最大最小值和四叉树的一样,垂直高度则取两头分两半)

如下图所示

Token 格局的 ID 为 "04" 的单元格四叉树宰割后八叉树宰割后

为了保障 S2 用到的希尔伯特曲线的连贯性,地球立方体的 6 个投影立体按如下图示方向旋转。

下面有第 4 个和第 1 个根单元的图,读者能够比对看看。

要十分注意这一点,在配合隐式瓦片宰割计划时,奇数面的遍历程序和偶数面的遍历程序是相同的。

例如,第 1 个根单元是逆时针编号四个子单元格(隐式子瓦片),第 4 个根单元则是顺时针编号。

可用性信息编码

当此扩大与 3DTILES_implicit_tiling 一起应用时,其 subtree 文件内记录的瓦片可用性数据的编码程序,必须按 Morton 索引程序统一,如下图:

例子①

以下为 3DTILES_bounding_volume_S2 与 3DTILES_implicit_tiling 搭配应用的 JSON 例子:

{  "asset": {    "version": "1.0"  },  "geometricError": 10000,  "extensionsUsed": [    "3DTILES_implicit_tiling",    "3DTILES_bounding_volume_S2"  ],  "extensionsRequired": [    "3DTILES_implicit_tiling",    "3DTILES_bounding_volume_S2"  ],  "root": {    "boundingVolume": {      "extensions": {        "3DTILES_bounding_volume_S2": {          "token": "04",          "minimumHeight": 0,          "maximumHeight": 500000        }      }    },    "refine": "REPLACE",    "geometricError": 5000,    "content": {      "uri": "content/{level}/{x}/{y}.glb"    },    "extensions": {      "3DTILES_implicit_tiling": {        "subdivisionScheme": "QUADTREE",        "subtreeLevels": 4,        "maximumLevel": 7,        "subtrees": {          "uri": "subtrees/{level}/{x}/{y}.subtree"        }      }    }  }}

例子②

以下例子为 3DTILES_bounding_volume_S2 表白 S2 的 6 个根单元网格,能够很显著看出它能平均笼罩寰球:

其 JSON 为

{  "asset": {    "version": "1.0"  },  "geometricError": 10000,  "extensionsUsed": [    "3DTILES_implicit_tiling",    "3DTILES_bounding_volume_S2"  ],  "extensionsRequired": [    "3DTILES_implicit_tiling",    "3DTILES_bounding_volume_S2"  ],  "root": {    "boundingVolume": {      "region": [        -3.141592653589793,        -1.5707963267948966,        3.141592653589793,        1.5707963267948966,        0,        250000      ]    },    "refine": "REPLACE",    "geometricError": 10000,    "children": [      {        "boundingVolume": {          "extensions": {            "3DTILES_bounding_volume_S2": {              "token": "1",              "minimumHeight": 0,              "maximumHeight": 1000000            }          }        },        "refine": "REPLACE",        "geometricError": 5000,      },      {        "boundingVolume": {          "extensions": {            "3DTILES_bounding_volume_S2": {              "token": "3",              "minimumHeight": 0,              "maximumHeight": 1000000            }          }        },        "refine": "REPLACE",        "geometricError": 5000,      },      {        "boundingVolume": {          "extensions": {            "3DTILES_bounding_volume_S2": {              "token": "5",              "minimumHeight": 0,              "maximumHeight": 1000000            }          }        },        "refine": "REPLACE",        "geometricError": 5000,      },      {        "boundingVolume": {          "extensions": {            "3DTILES_bounding_volume_S2": {              "token": "7",              "minimumHeight": 0,              "maximumHeight": 1000000            }          }        },        "refine": "REPLACE",        "geometricError": 5000,      },      {        "boundingVolume": {          "extensions": {            "3DTILES_bounding_volume_S2": {              "token": "9",              "minimumHeight": 0,              "maximumHeight": 1000000            }          }        },        "refine": "REPLACE",        "geometricError": 5000,      },      {        "boundingVolume": {          "extensions": {            "3DTILES_bounding_volume_S2": {              "token": "b",              "minimumHeight": 0,              "maximumHeight": 1000000            }          }        },        "refine": "REPLACE",        "geometricError": 5000,      }    ]  }}

JSON 模式标准

  • boundingVolume.3DTILES_bounding_volume_S2.schema.json

代码库实现相干案例

  • S2Geometry C++实现
  • S2Geometry Java 实现
  • CesiumJS 中的 S2Cell 实现