代码之家  ›  专栏  ›  技术社区  ›  DaveParillo

如何使用googleearth底图绘制openlayers特性

  •  1
  • DaveParillo  · 技术社区  · 14 年前

    尝试使用 OpenLayers (最终)加载标记、向量和;在googleearth插件基础地图上的WMS。谷歌地球(googleearth)似乎并没有“与他人玩得好”。

    google.earth.createInstance('map',initCB,failCB);

    我得到了一个google地图,我可以在其中添加google placemarks,但是我不能将该实例传递给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();
    

    这将创建一个具有5个粘性层的基本OL图。当任何一个图层 除了 选择gearth时。一旦我加载googleearth地图,它就会“接管”整个div。所有的OL控件(比如LayerSwitcher)都不见了,而且我还没有弄清楚如何从OL访问googleearth实例。

    问题:

    1. 这是有记录的限制吗?我找不到任何迹象表明这不可能。

    不成熟的想法是受欢迎的。

    3 回复  |  直到 14 年前
        1
  •  2
  •   Christopher Schmidt    14 年前

    一般来说,OpenLayers绝对不支持googleearth的3D模式(我是OpenLayers的开发人员,我只知道这是 可能的

    OpenLayers主要是一个2D绘图客户机,不太可能实现将其所有调用转换为GoogleMaps/EarthAPI调用的功能。

    简而言之:这是行不通的,没有简单的解决方案。如果你想要3D,你可能需要自己构建更多。

        2
  •  1
  •   ZiglioUK    4 年前

    Google地图v3的googleearth插件通过 script from the google-maps-utility-library-v3 (googleearth.js)

    @jlivni 已经采取的措施是监听googlemapsv3的add/remove事件并添加相应的googleearth Api对象。 我相信类似的方法也可以用于OpenLayers。我是OpenLayers的新手,刚刚开始研究这个问题,但我会在这里发布更新。

    我现在唯一能补充的是Google Earth插件的初始化,这在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_();
      }); 
    }
    

    复杂的部分是我们需要为googleearth定义一个新的地图类型,并将这个类型添加到googlemap对象中。但是如果不创建一个类型为Google.maps.MapTypeId.SATELLITE的图层,Google地图对象就不存在了。 不是很干净,但至少它让我的状态与作者的这篇文章谷歌地图v3。 最后,可以通过修改findMapTypeControlDiv()函数使OpenLayers控件可见:

    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;
        }
      }
    };
    

    [更新2]

    我已经解决了图层切换面板的问题。诀窍是将googleearth插件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;
    };
    

    我在这里建立了一个github项目: https://github.com/ZiglioUK/GoogleEarth-for-OpenLayers

        3
  •  0
  •   jlivni    13 年前

    我对OpenLayers中不同的层类型已经不太熟悉了,但关键是googleearth API和googlemapsapi是完全不同的。乍一看,我不明白为什么需要将它添加到googlemaps类型中(假设我是这么认为的)。

    正如Chris已经暗示的那样,只需将您的Earth API集成视为与任何现有Google层完全不同的全新事物;这些API中的语法和概念并不十分相似,至少据我所知,它们不足以让您获得在OpenLayers中对现有Google地图集成进行子类化的任何优势。

    也就是说,我希望mapsv3/Earth集成的代码将是有帮助的,并且类似于将它与OpenLayers集成所需的操作。同时,我也看到一些其他人也对此进行了尝试,比如这个geoExt示例,您可能也会发现它很有用: http://dev.geoext.org/sandbox/cmoullet/ux/GoogleEarthPanel/examples/GoogleEarthPanelExample.html