i3s,esri主推到ogc的一種三維開源GIS數據標准。
版權聲明:原創。博客園/B站/小專欄/知乎/CSDN @秋意正寒
轉載請標注原地址並聲明轉載: https://www.cnblogs.com/onsummer/p/12082584.html
1. i3s及其實現
i3s是一種用樹結構來組織大體積量三維數據的數據格式標准,比如在位圖界的jpg格式一樣,只不過i3s是“標准”,具體實現的文件格式另有一說。
i3s采用json文件來描述數據,采用二進制文件(格式為.bin)來存儲三維地理數據。
i3s是OGC規范,目前OGC版本是1.0,但是在Esri維護的社區項目中,i3s已經演進到1.7了。可以說是“一般”與“特殊”的區別。
OGC標准一旦制定就不應該頻繁更改,但是社區維護版本可以根據實際生產需要,基於OGC標准做結構優化等。
i3s標准將三維地理數據切分,用“節點”的概念組織起來,然后這些節點被有序地寫在“節點頁”中。說白了就是樹形結構。
i3s將三維地理數據組織起來后,可以放在服務器上通過REST接口訪問。
i3s目前由slpk格式的文件實現。
附:i3s對三維地理數據的分類
- 3d模型——傳統3d建模的精模轉換數據
- 表面模型——傾斜攝影數據
- 三維點
- 三維點雲
- 建築——BIM數據
為什么不用bim文件、為什么不用現有的三維數據格式呢?
首先,商業軟件的三維數據格式並不開源,而i3s格式是開源的,只要熟讀標准可以自己編程創建(難度比較大就是了)。
其次,開源的三維數據格式不具備地理信息。
最后,bim數據不面向地理信息系統。
所以,在三維GIS萌芽的今天(指這個年代),一種開源的三維地理數據規范就顯得十分重要。
1.1. i3s標准的數據組織和結構
在前文提到i3s使用的是樹結構組織數據,同時支持規則四叉樹或者R樹組織。每個樹節點代表的地理數據的范圍,由外包圍球(mbs)或外包圍(obb)盒表示。
官方推薦使用外包圍盒表示范圍(和二維的外包矩形,類似),點雲數據僅支持外包圍盒。
1.1.1. 節點和節點頁
一份三維地理數據應該合理的切分,i3s使用樹結構切分,以適應大量數據的快速分發、顯示。
切分的結果就是“節點(Node)”,組織這些節點的結構叫做“節點頁(NodePage)”。
在1.6及早期版本中,節點信息是寫在一個叫3DNodeIndexDocument.json.gz文件中的,即3DNodeIndexDocument文檔,節點一多,遍歷小文件頻率增加,對IO性能有不小的影響。
所以在1.7版本中,將這個3DNodeIndexDocument文檔聚合到“節點頁”中去了,類似於索引的功能(i3s的i就是index嘛)。
官方給出的樹狀結構示意圖。
1.1.2. 節點構成
節點由兩個部分構成:要素和節點資源。
即 Node = Feature + NodeResources
要素的概念和二維上的要素是一樣的,都表示一個地理實體,比如一棟建築。
節點資源,包括要素的幾何數據、屬性數據(這兩個數據見我的博客《聊聊GIS數據的四個分層》),以及三維數據中的材質紋理信息。
即 NodeResources = Geometry + Attributes + Textures
注意:並不是所有的節點都包括這三大資源的。3d模型類型的地理數據和建築數據均包括這三大資源。
① Geometry
幾何數據在不同版本的i3s(社區版本)有不同的表達。在1.7版本中,3d模型和表面模型幾何數據用draco壓縮格式的二進制文件存儲。
在構造三角面時,順序為逆時針方向(這點我不太清楚,圖形學的朋友可以深入一下)。
所有幾何頂點的坐標均相對於1.1中提及的obb或者mbs的中心的。obb或者mbs的中心若為零點原點,則還需要加上頂點偏移,使其偏移到正確的坐標系上,這個偏移量在json文件中是有的。
應指定坐標軸的正方向,默認是x-東,y-北,z-高程。
② Attribute
同一個要素的幾何數據和屬性數據分別存在兩個不同的二進制文件中。屬性數據的順序和幾何數據的順序一樣。
③ Texture
紋理就是指紋理圖像文件,被存儲為二進制文件。
=============
為了確保與1.6版本的兼容性,1.7的i3s標准還需要包括3dNodeIndexDocument.json描述文件,以及可用於任何節點的sharedResources目錄。
1.2. i3s中的統計數據
統計數據用來定義符號,這樣可以避免讀取所有的數據。比如,你要用唯一值進行制圖,那就可以從統計信息里獲取唯一值,而不是遍歷一次節點的屬性數據進行統計。
當然,統計數據還可以用來做空間過濾。
1.3. 坐標系和高程
i3s使用WKT來指定坐標系統。使用WKT1或者WKT2均可。
全局i3s數據僅支持WGS84坐標系和中國國家2000坐標系,注意是僅支持地理坐標系,x和y代表十進制的經度、緯度。
局部小場景支持任意坐標系統。若WKID不是4326或者4490,那就被視作局部小場景i3s數據。
1.5版本添加了對高程坐標系的支持。
=====================================================
上面是i3s的普遍定義,如果對i3s還是很模糊,請閱讀下文的i3s實現——slpk文件。
2. slpk
根據第一節內容,我們得知slpk是i3s規范的一種實現。
slpk是一種壓縮方法為“存儲”的zip格式文件,后綴名是slpk(SceneLayer Package)。slpk內的json文件、二進制文件均使用gzip壓縮。
表示紋理材質的png、jpg文件不壓縮。
根據第一節的內容,可以知道i3s有五種類型的切分,普通3d模型、點雲、建築等,所以slpk也有5種,雖然都是slpk文件,但是其內部組織不盡一樣。
就好像都是jpg文件,像素的顏色深度也可以不盡一樣。不同i3s版本的slpk對這些類型的支持是不同的:
- 1.7支持3d模型、表面模型、建築場景
- 1.6支持3d模型、表面模型、建築場景、點
- 2.0僅支持點雲
2.1. slpk的生產
slpk主要由ArcGIS Pro來制作,在工具箱搜索slpk就能找到很多打包3d圖層為slpk的工具。
Bentley的ContextCapture、Skyline的PhotoMesh也支持slpk。
存儲在geodatabase中的多面體三維數據可以打包為slpk,屬於3d模型的slpk。
ArcGIS Pro 2.5支持直接把rvt文件拖拽到3d圖層上進行顯示,並且直接打包為slpk。
2.2. slpk的讀取
slpk可以直接由ArcGIS Pro及上文提及的軟件讀取,也可以由ArcGIS Earth讀取(Earth支持的i3s版本可能不太高)。
當然,slpk也可以由ArcGIS Portal代為托管存儲並解包發布成場景服務,供ArcGIS jsAPI使用。
ArcGIS RuntimeSDK、CityEngine、Drone2Map for ArcGIS都支持slpk讀取,CityEngine還支持生產。
2.3. slpk有什么用
slpk只有一個文件,通常我們說簡單就是美,slpk單文件方便傳遞。
目前,slpk用於ArcGIS Portal發布場景服務是比較方便的,也可以用於runtime sdk開發的輕量軟件或者ArcGIS Earth來讀取查看。可惜Earth 1.9支持的i3s版本並不是很高,期待2.0。
3. slpk的文件結構
以3d模型和建築模型的slpk為例,混雜1.6和1.7版本的來講。
3.1. i3s 1.7版本的3d模型slpk
這是一個1.7版本的3d模型類型slpk的結構,用zip打開就是四個文件夾和一個3dSceneLayer.json.gz文件,以及一個hash文件。
- 3dSceneLayer.json.gz描述的是整個slpk的信息
- nodePages目錄存放“節點頁”信息,節點頁用json文件來記錄
- nodes目錄存放“節點”信息,每個節點用文件夾表示,文件夾名稱即節點名
- statistics目錄存放的是統計數據,每個要素一個文件夾,文件夾名即要素名,文件夾下是該要素的統計數據,用json文件來記錄
根目錄下還可能會有metadata.json文件,如下圖所示:
nodes目錄下有一個特殊的節點,即根節點root。1.7版本的i3s為了保證與1.6的兼容,保留了shared目錄和3dNodeIndexDocument.json.gz文件(節點描述文件)。
那么,如何查詢每個json描述文件的各個屬性的定義呢?
官方github文檔中是有的:https://github.com/Esri/i3s-spec/tree/master/docs/1.7
以slpk根目錄下的3dSceneLayer.json為例,這整個json文件的定義就寫在了這個文檔下:https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DSceneLayer.cmn.md
例如,spatialReference屬性就是坐標系信息。但是如果是不太明白的屬性,例如store屬性:
我們還是去上面說的github官方文檔查詢store的文檔:https://github.com/Esri/i3s-spec/blob/master/docs/1.7/store.cmn.md
json文件很容易通過官方文檔+明文閱讀的方式了解每個屬性的含義,如果是二進制文件,那就需要費一番功夫了。
以幾何數據二進制文件(0.bin)為例,二進制幾何文件的文檔在這里:
https://github.com/Esri/i3s-spec/blob/master/docs/1.7/geometryBuffer.cmn.md
https://github.com/Esri/i3s-spec/blob/master/docs/1.7/vertexAttribute.cmn.md
這兩個文檔講得並不是很詳細,在我的實踐中,已知用python或者js的ArrayBuffer進行讀取,1~4字節是頂點數量,5~8是要素數量。
然后每4*3個字節為一組3個Float32數字(x,y,z),一共“頂點數量”組。
緊接着便是下一個幾何數據,可能是法線、uv等,要看3dSceneLayer.json內的store屬性下的defaultGeometrySchema屬性下的order屬性值。
這個建議看ogc的標准文檔:http://docs.opengeospatial.org/cs/17-014r5/17-014r5#69.html
8.2節就是幾何數據二進制文件的格式,雖然也比較簡陋,不過比esri的文檔好一些。
這張圖虛線框大概表達的是“非必要屬性”。
筆者不才,在3dSceneLayer.json中找到的vertexAttributes屬性並沒出現offset的值(plus:在每個節點目錄下的feature目錄下的json里!),盡管vertexAttributes每個屬性在二進制文件中的的偏移量均可自己用已知數字計算,但是終究沒有直接給值來的方便,也沒有能力將讀取到的position。
日后有機會,還會介紹如何用python或js來讀取二進制文件內的vertexAttributes,甚至二進制要素屬性數據。
3.2. i3s 1.6版本 建築slpk
BIM數據是有多個分層的(樓板、機電、門窗、外立面等),每個分層用子圖層(sublayers)表示。
每一個sublayers相當於一個獨立的3d模型slpk:
此例為1.6的slpk,所以沒有nodepages目錄,在每個節點上,描述節點的文件仍舊是3dNodeIndexDocument.json。
這是一個BIM文件打包成slpk后的樹狀結構(發布成場景服務,以URL訪問的形式)。因為沒有nodepages,所以在1.6版本中,節點文件夾的名稱會出現"0-1-1"的表示,即0節點下的1節點下的1節點。
4. slpk中的主要json的類定義
①3dSceneLayerInfo.json.gz
位於slpk壓縮包內的根目錄,用於描述整個slpk的信息;可以人為繼續往這個json里加屬性,不影響已有屬性的查詢。
查詢文檔:https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DSceneLayer.cmn.md
②3dNodeIndexDocument.json.gz
位於slpk壓縮包內根目錄下nodes文件夾下的每個頂點文件夾下,root節點也有,1.7為了兼容1.6保留了這個文件,1.7改用nodepages來提高性能。
查詢文檔:https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md
③節點頁
slpk壓縮包根目錄下的nodepages下的*.json.gz(可能有多個)是節點頁信息,用來描述整個slpk節點樹形結構和每個節點的大致信息。
查詢文檔(node的文檔,因為節點頁json就是節點json數組):https://github.com/Esri/i3s-spec/blob/master/docs/1.7/node.cmn.md
④統計數據
slpk壓縮包根目錄下的statistics目錄下的每個字段文件夾(f_*)下的0.json.gz文件,用來描述這個字段的統計信息。
查詢文檔:https://github.com/Esri/i3s-spec/blob/master/docs/1.7/statsInfo.cmn.md
⑤要素數據
slpk壓縮包根目錄下的nodes文件夾下的每個頂點文件夾下的features文件夾下的*.json.gz文件,描述的是要素的信息(要素包括幾何數據和屬性數據)。
查詢文檔:https://github.com/Esri/i3s-spec/blob/master/docs/1.7/featureData.cmn.md
⑥共享資源
1.7兼容1.6的json文檔,位於每個頂點文件夾下的shared文件夾下,*.json.gz文件。
查詢文檔:https://github.com/Esri/i3s-spec/blob/master/docs/1.7/sharedResource.cmn.md
主要的json文件就是這么多(以3d模型的slpk為例,bim的slpk應該類似),二進制文件的讀寫主要一烤要素數據的json,這個以后再談(其實是筆者沒有整理好)。
5. 同類標准3dtiles/gltf與s3m
既然說到標准,就不得不提一下同類競爭對手。
cesium是一個做3dWebGIS的api,主推的標准是3dtiles/gltf,主要資料如下:
https://github.com/KhronosGroup/glTF
http://docs.opengeospatial.org/cs/18-053r2/18-053r2.html
https://github.com/AnalyticalGraphicsInc/3d-tiles
s3m是我國推動的三維地理數據標准,主要由超圖等公司建設設計,主要資料如下:
https://download.csdn.net/download/cRGBc/12082994
gltf/s3m/i3s/3dtiles我了解的不多,甚至不了解gltf和3dtiles的關系,但是它們的共同特點是:都使用樹結構描述一個三維數據(不一定是地理數據),都使用json文件描述數據,都使用二進制文件存儲數據。
6. 三維標准博客展望
未來,筆者還要更精細地研讀i3s,盡快學習3dtiles和gltf標准,簡單了解s3m標准。
不僅僅要在文檔、類結構上熟悉,還要盡可能地利用這些開源標准來獲取這些數據。