樹結構組織,json描述,bin存儲,三維資料标準打的不要不要的。
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
https://www.khronos.org/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标準。
不僅僅要在文檔、類結構上熟悉,還要盡可能地利用這些開源标準來擷取這些資料。