2010-07-20 34 views
1

試圖使用OpenLayers(最終)加載標記,矢量& WMS在谷歌地球插件基礎地圖上。 Google地球似乎沒有「與其他玩家一起玩」。如何使用谷歌地圖底圖繪製開放層功能

如果我在'google way'中實例化地圖: google.earth.createInstance('map',initCB,failCB);

我得到一個谷歌地圖,我可以添加谷歌地標,但我不能將該實例傳遞給OpenLayers。

使用以下:

map = new OpenLayers.Map('ol-map'); 
map.addControl(new OpenLayers.Control.LayerSwitcher()); 

var gphy = new OpenLayers.Layer.Google(
    "Google Physical", 
    {type: G_PHYSICAL_MAP} 
); 
var gmap = new OpenLayers.Layer.Google(
    "Google Streets", // the default 
    {numZoomLevels: 20} 
); 
var ghyb = new OpenLayers.Layer.Google(
    "Google Hybrid", 
    {type: G_HYBRID_MAP, numZoomLevels: 20} 
); 
var gsat = new OpenLayers.Layer.Google(
    "Google Satellite", 
    {type: G_SATELLITE_MAP, numZoomLevels: 22} 
); 
var gearth = new OpenLayers.Layer.Google(
    "Google Earth", 
    {type: G_SATELLITE_3D_MAP} 
); 

map.addLayers([gphy, gmap, ghyb, gsat, gearth]); 

map.setCenter(new OpenLayers.LonLat(-120, 32), 5) 
addMarker(); 

這就形成了一個基本的OL地圖5個曲棍球層。當任何地圖圖層選擇gearth時除外,我可以看到我添加的標記。只要我加載谷歌地球地圖,它'接管'整個div。所有的OL控件(如LayerSwitcher)都沒有了,我一直無法弄清楚如何從OL訪問谷歌地球實例。

我假設標記仍然存在,但在底圖後面。在底圖上設置不透明度不起作用。

問題:

  1. 這是一個記錄的限制嗎?我找不到任何表明它不應該成爲可能的東西。
  2. 是否有解決方法,我可以將OpenLayers地圖/圖層實例傳遞給Google地球的getEarthInstance調用?或相反亦然?看起來這將是兩全其美,讓我可以在需要時訪問GE API,但我可以在OL中使用所有WFS處理來完成大多數任務。

半熟的想法歡迎。

回答

1

一般來說,OpenLayers絕對不支持Google Earth 3D模式。 (我是OpenLayers的開發人員,我只知道這是可能的通過這個問題。)由於3D顯示代碼的工作方式(通過第三方插件),我無法想象任何方式默認的OpenLayers工具 - 用於繪圖等 - 正在發揮作用:OpenLayers需要整合的部分根本不存在於3D API中。

OpenLayers - 主要是一個2D繪圖客戶端 - 不太可能實現將所有各種調用轉換爲Google Maps/Earth API調用的東西。

OpenLayers確實支持協議和格式:理論上,這將允許您在與Google Earth API等第三方API進行交互時在某種程度上使用OpenLayers WFS處理工具鏈。但是,我希望在這種情況下,您不能從中獲得足夠的解決您的問題的辦法。

總之:這不起作用,並沒有簡單的解決方案。如果你想3D,你可能需要自己創造更多。

+0

感謝您的反饋。我也與一些谷歌工程師聯繫,所以如果我學到了什麼,我會保持你的發佈。 – DaveParillo 2010-07-21 23:35:14

+1

你是對的。我與谷歌工程師的談話無助於此,但指出如果您想將Google Earth插件實施到定製的Web應用程序中,GE插件API(earth_loader_plugin.js)的本地副本必須是加載並且必須設置一些環境變量來配置API密鑰和GEE服務器錯誤頁面的位置。加載Google地球插件並連接到私有GEE服務器的示例網頁可以在http://gmdemo.keyhole.com/geplugin/gee-basic-example.html上查看以供參考。 – DaveParillo 2010-08-06 17:55:24

1

我想這個問題與Google Maps v2有關,因爲我不認爲在v3中有類型:G_SATELLITE_3D_MAP。

的谷歌地球插件通過script from the google-maps-utility-library-v3 (googleearth.js)

這種方法筆者@jlivni已經是聽谷歌地圖V3添加/刪除事件,並添加相應的谷歌地球API對象支持谷歌地圖v3是(測試版)。 我相信類似的方法可以用於OpenLayers。我是OpenLayers的新手,剛開始研究這個,但我會在這裏發佈更新。

我現在可以添加的唯一事情是關於谷歌地球插件的初始化,即在V3不同:

function GoogleEarth(olmap) { 
this.olmap_ = olmap; 
this.layer_ = new OpenLayers.Layer.Google(
    "Google Earth", 
    {type: google.maps.MapTypeId.SATELLITE, numZoomLevels: 22, visibility: false} 
); 
this.olmap_.addLayers([ this.layer_ ]); 
this.map_ = this.layer_.mapObject; 
this.mapDiv_ = this.map_.getDiv(); 

... 
var earthMapType = /** @type {google.maps.MapType} */({ 
tileSize: new google.maps.Size(256, 256), 
maxZoom: 19, 
name: this.earthTitle_, 
// The alt helps the findMapTypeControlDiv work. 
alt: this.earthTitle_, 
getTile: 
    /** 
    * @param {google.maps.Point} tileCoord the tile coordinate. 
    * @param {number} zoom the zoom level. 
    * @param {Node} ownerDocument n/a. 
    * @return {Node} the overlay. 
    */ 
    function(tileCoord, zoom, ownerDocument) { 
    var div = ownerDocument.createElement('DIV'); 
    return div; 
    } 
}); 

this.map_.mapTypes.set(GoogleEarth.MAP_TYPE_ID, earthMapType); 

this.layer_.type = GoogleEarth.MAP_TYPE_ID; 

var that = this; 
google.maps.event.addListener(map, 'maptypeid_changed', function() { 
    that.mapTypeChanged_(); 
    }); 
} 

的令人費解的部分是,我們需要定義谷歌地球新的地圖類型,並將此類型添加到Google Map對象。但是,如果我們不創建一個帶有類型的圖層,Google Map對象不存在,我最初設置爲google.maps.MapTypeId.SATELLITE。 不是很乾淨,但至少它讓我和谷歌地圖v3這篇文章的作者一樣。 最後有可能是一種方法,使的OpenLayers控制可見通過修改功能findMapTypeControlDiv_():

var mapTypeControlDiv = this.findMapTypeControlDiv_(); 
if (mapTypeControlDiv) { 
    this.setZIndexes_(mapTypeControlDiv); 
    this.addShim_(mapTypeControlDiv); 
} 

[更新]

我已經修改了功能findMapTypeControlDiv_()。我現在期待的的OpenLayers LayerSwitcher代替:

GoogleEarth.prototype.findLayerSwitcherDiv_ = function() { 
// var title = 'title="' + this.earthTitle_ + '"'; 
    var id = 'LayerSwitcher'; 

    var siblings = this.controlDiv_.parentNode.childNodes; 
    for (var i = 0, sibling; sibling = siblings[i]; i++) { 
    if (sibling.id.indexOf(id) != -1) { 
     return sibling; 
    } 
    } 
}; 

的LayerSwitcher的z索引被正確地設置和在div表示在頂部,直到google.earth.createInstance()被調用,然後消失。我會花更多的時間在上面,它看起來並不難解​​決。

[更新2]

我周圍的LayerSwitcher面板問題的工作。訣竅是將Google Earth Plugin div附加到正確的div(GMaps的原始代碼將其附加到Map Controls陣列)。另一個問題是設置zIndex以確保LayerSwitcher處於最佳狀態。 GE插件運行時我仍然遇到問題,我嘗試最小化LayerSwitcher,調用OpenLayers.Event.stop()會導致GE插件崩潰(Chrome)或LayerSwitcher消失(IE8)。 我想分離Google的原始代碼並製作適用於OpenLayers的GE插件層。 任何人都可以建議如何做到這一點?謝謝。

總之,這裏是我的最新變化:

GoogleEarth.prototype.findLayerSwitcherDiv_ = function() { 
    var id = 'LayerSwitcher'; 

    var siblings = this.mapDiv_.parentNode.childNodes; 
    for (var i = 0, sibling; sibling = siblings[i]; i++) { 
    if (sibling.id.indexOf(id) != -1) { 
     return sibling; 
    } 
    } 
}; 

GoogleEarth.prototype.addEarthControl_ = function() { 
... 
inner.appendChild(earthDiv); 
var parentNode = this.findLayerSwitcherDiv_().parentNode; 
parentNode.appendChild(control); 

... 
GoogleEarth.prototype.setZIndexes_ = function(mapTypeControlDiv) { 
    var oldIndex = mapTypeControlDiv.style.zIndex; 
    var siblings = this.controlDiv_.parentNode.childNodes; 
    for (var i = 0, sibling; sibling = siblings[i]; i++) { 
    sibling['__gme_ozi'] = sibling.style.zIndex; 
    // Sets the zIndex of all controls to be behind Earth. 
    sibling.style.zIndex = 0; 
    } 

    mapTypeControlDiv['__gme_ozi'] = oldIndex; 
    this.controlDiv_.style.zIndex = 2000; 
    mapTypeControlDiv.style.zIndex = 2001; 
}; 

[更新3] 我已經設置了這裏github上的項目:https://github.com/ZiglioNZ/GoogleEarth-for-OpenLayers

[更新4] 對於演示,請訪問http://ziglionz.github.com/GoogleEarth-for-OpenLayers/ol.html

0

我不再那麼熟悉OpenLayers中的不同圖層類型,但關鍵是Google Earth API和Google Maps API是真正不同的野獸。乍一看,我不明白爲什麼你需要將它添加到Google Maps類型(假設這是我的想法)。

正如Chris所暗示的那樣,只要將您的Earth API集成視爲與現有Google圖層完全獨立的新事物;至少據我所知,這些API中的語法和概念並沒有足夠的相似性,因此您無法獲得在OpenLayers中繼承現有Google Maps集成的任何優勢。

這就是說我希望地圖V3 /地球集成的代碼將有助於您將OpenLayer與OpenLayers集成在一起。同時我也看到其他一些人也給了這個鏡頭,比如這個geoExt例子,你可能也會發現它很有用:http://dev.geoext.org/sandbox/cmoullet/ux/GoogleEarthPanel/examples/GoogleEarthPanelExample.html