• 沒有找到結果。

IFC 資料類型 資料類型 資料類型 資料類型映對 映對 映對 映對

Select Type

END_ENTITY;

4.2 IFC 資料類型 資料類型 資料類型 資料類型映對 映對 映對 映對

為了能夠在程式設計階段根據 IFC 規格進行資訊存取,必須將 EXPRESS 描述的 IFC 資料類型轉換為.Net Framework 的資料型態,本章節介紹如何將 Defined Type、Enumeration、SelectType 及 Entity 四種 IFC 資料類型映對 (mapping)到.Net Framework 的資料型態,並由這些映對的規則建立類別庫。

4.2.1 Defined Type

Defined Type 的映對相當容易,它只是對一個基礎的資料型態提供一個 別名,我們只要直接對那個基礎的資料型態做映對就好,例如,IfcText、

IfcLabel 這兩個 Defined Type 的基礎的資料型態是 STRING 能夠直接映對到 VB.net 的 String 類別。將各種 IFC 的基礎資料型態與 VB.net 類別的資料型態 映對整理如表 4-1,其中 REAL 及 NUMBER 都用於表示數字,差別是 NUMBER 可能代表整數或實數,本研究都將其映對到 Double;LOGICAL 的 值可以是 TRUE、FALSE 或 UNKNOWN,本研究將其與 BOOLEAN 都映對 到 Boolean;BINARY 的值可能是 0 或 1,本研究將其映對到 Byte。

4.2.2 Enumeration

.Net Framework 允許定義 Enum 資料結構,故 Enumeration 能夠直接映對 道相對應的 Enum 資料結構。從 Enumeration 的 EXPRESS 描述直接轉換為 VB.net 的語法的 Enum 資料結構只有少部份語法不同,利用正則表示式 (Regular expression)便能夠快速的進行語法轉換,最後將所有轉換好的 Enum 放置於 Enumerations 類別。轉換範例如圖 4-2,左半邊為 Enumeration 的 EXPRESS 描述,右半部為轉換為 Vb.net 語法的 Enum 資料結構,在 Vb.net 的每個 Enum 資料結構額外增加了一個 EMPTY 狀態,表示此 Enum 屬性的 狀態未設定。在轉換過程中最主要的問題在於 EXPRESS 定義的 Enumeration 內容與 Vb.net 程式語言的關鍵字有衝突,例如: IfcStateEnum 其中有一個內 容為 READONLY,而它剛好是 Vb.net 語言的關鍵字,這時我們在內容的結 尾加上“_”避免衝突,在做資訊擷取及建立時再做判斷,把“_”移除。

4.2.3 Select Type

Select Type 是一種比較特殊的資料型態,它屬於已定義的資料型態之 ㄧ,在擷取資訊時因為沒有固定的資料型態,很容易發生執行時期的錯誤,

例如前述 3.1 節提到的 IfcSimpleValue 這個 Select Type,假設一個軟體將它用 於保存字串資料,而另一個軟體在讀取時並沒有辦法確定它是字串或是其他 資料類型。 Select Type 主要參考 C/C++的 Union 資料類型設計,.Net Framework 沒有辦法建立這種資料結構,對於這種類型的映對方法根據其內 容定義的資料型態分為兩種:

1. Defined Type

若定義的內容為 Defined Type 則選擇其中一種 Defined Type 進行映對,

例如,IfcSimpleValue 可以是 IfcInteger(整數)、IfcReal(實數)、IfcBoolean(布 林值)、IfcIdentifier(字串)、IfcText(字串)、IfcLabel(字串)、IfcLogical(邏 輯符號)其中之一。

2. Entity

若定義的內容為 Entity,則建立一個與此 Select Type 相同名稱的的介面,

裡面不實作任何內容,而它內容所定義的 Entity (映對到 Class,於下節 介紹)必須實作這個介面。以 IfcAxis2Placement 為範例,如圖 4-3,這個 Select Type 具有兩種資料類型(都是 Entity): IfcAxis2Placement2D 與 IfcAxis2Placement3D,這兩種都必須實作 IfcAxis2Placement 介面,如此 一來便可藉由參考這個介面達到多型,也就是 IfcAxis2Placement 能夠指 向 IfcAxis2Placement2D 或 IfcAxis2Placement3D。

4.2.4 Entity

Entity 為 IFC 最複雜的資料型態,其也是用以表示資訊最主要的方式。

Entity 很明顯必須映對到類別(Class),但除了將 EXPRESS 定義的 Entity 轉換 為 Class,也要考慮到跟 IFCsvr 的繫結,才能建立資訊於實體檔案。類別的 映對比較複雜,其中有幾個原則:

1. 每個 Entity 都映對到一個相同名稱的 Class,並根據 IFC 定義的繼承 關係繼承父類別,若 Entity 為抽象資料型態 Class 則必須加上 MustInherit 關鍵字,定義為抽象類別。

2. 每個類別都有一個 IFCsvr.Entity 物件屬性,利用這個物件將類別的資 訊保存到資訊模型中,或是從資訊模型擷取資料。

3. 所有的類別都必須具有 IfcEntity 介面,藉此提供建立、刪除、更新 Entity 物件的能力。抽象類別由於無法建立實體,故不需要實作內容,

但這些方法的修飾子(modifier)必須設為“MustOverride”,表示這個方法必 須由子類別實現;非抽象的類別必須實作內容,用“Overrides”修飾子表 示其覆寫父類別的方法,而實作內容會隨著類別而異,例如 IfcProject 與 IfcBuilding 各擁有不同屬性,建立的物件時所填入的資訊也不同。

4. 所有類別都必須具有三個方法:DataAbstract,負責抽取 Entity 物件的 資料並儲存於類別;DataStuff,負責將類別的資料填入 Entity 物件;

DataUpdate,負責將類別的資料更新到 Entity 物件。這些方法的修飾子 該為“Overrides”,表示其覆寫父類別的方法,這三個方法與 IfcEntity 介 面及建構子有相當重要的關係,不同於 IfcEntity 介面的方法,就算是非 抽象類別也必須實現這些方法的內容。

5. 每個 Class 提供兩個建構子(Constructor),一個以 IFCsvr.Entity 為參 數,目的在將 Entity 物件的資料儲存於類別;另一個不需要任何參數,

可藉此建立新的 Entity 物件。

6. 根據 Entity 的每個屬性名稱及其資料型態一對一映對到類別,若資料 型態為集合體則利用陣列表示。

7. 若 EXPRESS 定義屬性為 OPTIAONL,則在映對 Class 的屬性字尾加 上“_Optional”。

9. Entity 的法則(Rule)不進行轉換。

以 IfcProject 這個 Entity 的映對為例,根據上述原則之編號對照如圖 4-4,並 分別依照順序闡述如下:

1. Entity IfcProject 映 對 到 相 同 名 稱 的 類 別 “IfcProject” 。 由 於 Entity IfcProject 繼承自 Entity IfcObject,故映對之類別同樣繼承 IfcObject 類別。

2. IfcProject 類別具有 IFCsvr.Entity 物件。

3. IfcProject 為非抽象類別故必須實作 IfcEntity 介面的內容,由於每個類 別實作的內容都不同,故這邊必須使用覆寫(Overrides)的方式實作這些方 法的內容。

4. 實作資料處理的方法,這些方法的權限為 “Protected”表示其只能為同 類別的方法或是子類別的方法呼叫。

5. 定義 IfcProject 類別的兩個建構子。

6. 將 IfcProject Entity 的所有屬性,按照其資料型態映對到 IfcProject 的 類 別 中 。 LongName 屬 性 資 料 型 態 為 IfcLabel(Defined Type) 映 對 到 String;Phase 屬性資料型態為 IfcLabel(Defined Type)映對到 String;

RepresentationContexts 屬性資料型態為 IfcRepresentationContext (Entity) 集合體,映對到 IfcRepresentationContext 類別陣列;UnitsInContext 屬性 為 IfcUnitAssignment(Entity)映對到 IfcUnitAssignment 類別。

7. LongName 及 Phase 這兩個屬性在 EXPRESS 定義為 OPTIONAL,在轉 換到類別後在其名稱後面加上“_OPTIONAL”。

IfcProject Class 藉由帶參數的建構子擷取 IFCsvr.Entity 物件的資訊,這個建 構子實作內容如下:

建構子先判斷 Entity 是否存在,再檢核 Entity 名稱是否為 IfcProject,若名稱 正確再呼叫 DataAbstract 方法進行 Entity 資料擷取,DataAbstract 實作內容如 下:

Protected Overrides Sub DataAbstract(ByRef _Entity As IFCsvr.Entity) MyBase.DataAbstract(_Entity)

LongName_Optional= _Entity.Attributes("LongName").value Phase_Optional= _Entity.Attributes("Phase").value

… End Sub

IfcProject 的 DataAbstract 方 法 先 藉 由 呼 叫 父 類 別 的 DataAbstract 方 法 (MyBase.DataAbstract)進行父類別屬性的擷取,再將將本身的屬性從 Entity 物件擷取出來(LongName、Phase 等屬性)。以這個例子而言其父類別為 IfcObject,藉由呼叫 IfcObject 的 DataAbstract 進行 IfcObject 所有屬性的資訊 擷取。IfcObject 的 DataAbstract 方法如下:

Protected Overrides Sub DataAbstract(ByRef _Entity As IFCsvr.Entity) MyBase.DataAbstract(_Entity)

ObjectType_Optional= _Entity.Attributes("ObjectType").value End Sub

IfcObject 只有一個 ObjectType 屬性,在擷取這個屬性的資訊之前一樣先呼叫 父類別的 DataAbstract 方法,依此類推直到繼承的頂端為止,如此一來就可 以將 IfcProject 所有屬性資料擷取出來,由父類別的 DataAbstract 方法將繼承 而來屬性資訊擷取出來。呼叫順序如圖 4-5,從 IfcProject 開始一直到 IfcRoot 再遞迴到 IfcProject。

IfcEntity 界面的 CreateEntity 方法用於在資訊模型建立 Entity 物件,其實作方 式與建構子相當類似,藉由呼叫 DataStuff 將資料填入 Entity 物件。IfcProject 的 CreateEntity 方法如下:

Public Overrides Function CreateEntity(ByRef design As IFCsvr.Design) As IFCsvr.Entity If myEntity Is Nothing Then

CreateEntity 在呼叫時必須傳入 IFCsvr.Design 當作參數,表示此欲建立 Entity 物件的資訊模型。若 myEntity 屬性沒有內容,表示此類別尚未建立 Entity 物 件,則直接於資訊模型新增 Entity 物件(design.Add),若 Entity 物件存在,則

會檢查此 Entity 物件是否存在於欲建立此物件的資訊模型,若不存在則建 立,存在則對資料進行更新。藉由 IFCsvr.Design 建立 Entity 物件後,呼叫 DataStuff 方法將類別的屬性填入 Entity 中。IfcProject 的 DataStuff 方法內容 如下:

Protected Overrides Sub DataStuff(ByRef _Entity As IFCsvr.Entity, ByRef design As IFCsvr.Design) MyBase.DataStuff(_Entity, design)

_Entity.Attributes("LongName").vlue = LongName_OptionalŠ _Entity.Attributes("Phase").value = Phase_Optional

… End Sub

IfcProject 的 DataStuff 方法先呼叫父類別的 DataStuff 方法,再將自己的屬性 填入 Entity 物件,藉由父類別的 DataStuff 方法將繼承而來屬性資訊填入 Entity 物件中,IfcProject 父類別 IfcObject 的 DataStuff 方法內容如下:

Protected Overrides Sub DataStuff(ByRef _Entity As IFCsvr.Entity,ByRef design As IFCsvr.Design) MyBase.DataStuff(_Entity,design)

_Entity.Attributes("ObjectType").value=ObjectType_Optional End Sub

IfcObject 的 DataStuff 方法一樣先呼叫父類別的 DataStuff,再將自己的屬性資 料填入 Entity 物件,藉此就可以將 IfcProject 所有屬性資料填入 Entity 物件。

IfcProject 的 DataStuff 呼叫順序與 DataAbstract 方法一樣從 IfcProject 開始一 直到 IfcRoot 再遞迴到 IfcProject。

為了更有效率的將 IFC Entity 轉換為類別,本研究撰寫一個類別轉換器 將 EXPRESS 的 Entity 轉換為類別。最後將轉換好的類別以類別庫方式封裝 成.Net Framework 組件(Assembly),以 DLL 形式存在,讓其他程式專案能夠 參考引用此類別庫,部份已轉換的類別見圖 4-6,類別庫的使用範例及應用 將於第五章進行介紹。

相關文件