Revit二次開發之Parameter單位轉換
由於Revit內部使用英制單位,我們在很多時候需要將Revit內部的各種數值轉換成我們熟悉的公制單位,尤其是對Parameter。好在Revit API為我們提供了單位轉換類UnitUtils,其中定義了各種靜態方法讓我們能很方便地進行單位轉換而不必瞭解各種單位之間的轉換進位制,最常用的就是下面這兩個了:
//將內部單位轉換為某種顯示單位,用於獲取數值
public static double ConvertFromInternalUnits(
double value,
DisplayUnitType displayUnit
)
//將某種顯示單位轉換為內部單位,用於設定數值
public static double ConvertToInternalUnits(
double value,
DisplayUnitType displayUnit
)
對於Parameter,更方便的是其提供了DisplayUnitType這個屬性讓我們能知道這個Parameter是以什麼單位顯示到介面上的,於是我們就可以用下面的程式碼實現任意Parameter的單位轉換,需要注意的是,Parameter有不同的獲取值的方法,用哪個取決於引數的StorageType屬性:
private object GetParameterValue (Parameter parameter)
{
if (parameter.Definition.UnitType != UnitType.UT_Number)
{
DisplayUnitType unit = parameter.DisplayUnitType;
switch (parameter.StorageType)
{
case StorageType.Double:
return UnitUtils.ConvertFromInternalUnits(parameter.AsDouble(), unit);
case StorageType.Integer:
return UnitUtils.ConvertFromInternalUnits(parameter.AsInteger(), unit);
case StorageType.ElementId:
return parameter.AsElementId();
case StorageType.String:
return parameter.AsString();
case StorageType.None:
return null;
}
}
return parameter.AsValueString();
}
你可能會注意到這個方法將UT_Number這個UnitType排除在外了,因為根據測試當UnitType是UT_Number的時候,parameter.DisplayUnitType會丟擲 InvalidOperationException異常,於是我們單獨拿出來,直接提取這個引數的ValueString
為了確保沒有別的UnitType會引發這個異常,我從API文件中篩選了UnitType的所有列舉值,根據其註釋中是否有給出可能的單位,得到了如下一些可能的UnitType,並做了測試:
UnitType | Description | Exception |
---|---|---|
UT_SheetLength | Sheet length | false |
UT_SiteAngle | Site angle | not sure |
UT_Slope | Slope, rise/run | false |
UT_HVAC_Slope | Slope (HVAC) | false |
UT_Piping_Slope | Slope (Piping) | false |
UT_Currency | Currency | false |
由於沒能創建出UnitType是UT_SiteAngle的引數,所以沒有測試出這個引數是否會丟擲異常,有知道如何建立的朋友可以告知我,而其他可疑的UnitType均不會丟擲異常,因此這個方法在絕大多數情況下都是正常的。
另外一個解決思路是使用try catch捕獲異常,捕獲到InvalidOperationException之後,直接提取ValueString。這個思路可行性更高,但會犧牲一些效能,尤其對於模型數量級很大的專案,在匯出資料時,這會讓整個過程非常緩慢。