大家在使用TerraExplorer Developer開發包進行二次開發的時候,特別是進行WEB開發的時候,經常會遇到這樣一個問題,就是在WEB頁面(html、aspx或者jsp等)中嵌入TerraExplorer Object對象,即
<OBJECT ID="TE" CLASSID="CLSID:3a4f9191-65a8-11d5-85c1-0001023952c1"></OBJECT>,
然後運行該WEB頁面,在頁面載入的過程中,會將TerraExplorer View或者TerraExplorer Pro軟體運行起來,
一般情況下,只要在當前頁面中添加另外一個用於三維情境顯示的控制項
<OBJECT ID=" TerraExplorer3DWindow" CLASSID="CLSID:3a4f9192-65a8-11d5-85c1-0001023952c1" width=500 height=400></OBJECT>
並且需要保證TerraExplorer3DWindow對象先於TE對象被初始化,即可消除前面提到的問題。
但在有些時候,我們開發的系統中可能會嵌入許多WEB頁面,而且在這些頁面中也都會涉及到對TE介面的調用,這時運行我們的系統,也有可能把TerraExplorer軟體運行起來,這是我們不想看到的,其實也可以說這就是一種邏輯錯誤,而消除這個錯誤的方法很簡單,就是我們必須保證所有對TE介面的調用,都要放在TerraExplorer3DWindow對象載入之後。
但是我們如何保證在複雜的系統中,理清他們之間的先後順序呢?
這裡可以給大家介紹一個實用的解決方案。就是把TE對象放到一個函數裡面去初始化,而不是像原來那樣直接嵌在頁面裡。
例如:
function _$SGCreateTEObj()
{
var obj = window.document.getElementById("TE");
if(obj== null)
{
obj = document.createElement('object');
document.body.appendChild(obj);
obj.name = "TE";
obj.id= "TE";
obj.classid= "CLSID:3a4f9191-65a8-11d5-85c1-0001023952c1";
}
return obj;
}
這樣,在其他需要調用TE介面的時候,我們只需要重新執行個體化一下TE對象即可。
var TE=_$SGCreateTEObj();
var IPlane = TE.interface("IPlane5");
這時,大家也許還會有疑問,就是對於TE裡面的事件介面_ITerraExplorerEvents5該如何引用呢?
在以前Skyline提供給大家的例子中,我們可以看到用javascript中的寫法是
function TE::OnLoadFinished()
{
}
或者用vbscript的寫法是
sub TE_OnLoadFinished()
end sub
如果說對於TE的事件介面只能用上述固定的方式來實現的話,那麼就又回到了最開始的狀態,封裝TE函數也就沒有什麼實際意義了。其實在TE的ITerraExplorer51介面中,我們發現有AttachEvent和DetachEvent兩個方法,這樣就可以做到我們在需要調用TE的事件介面時Attach,不需要的時候Detach:
function _$SGCreateEvent()
{
var TE=_$SGCreateTEObj();
var ITerraExplorer = TE.interface("ITerraExplorer51");
ITerraExplorer.AttachEvent("OnLButtonDown",_$SGEventOnLButtonDown);
}
function _$SGDelEvent()
{
var TE=_$SGCreateTEObj();
var ITerraExplorer = TE.interface("ITerraExplorer51");
ITerraExplorer.DetachEvent("OnLButtonDown",_$SGEventOnLButtonDown);
}
如此,我們就可以更加靈活地使用TE的事件介面。
希望上述文字能夠給大家提供一些協助或者啟發,感謝大家對Skyline的支援。