2

OpenLayersを使用して、(最終的に) マーカー、ベクター、および WMS を Google Earth プラグイン ベース マップの上にロードしようとしています。Google Earth は「他のユーザーとうまく連携」していないようです。

「Google の方法」でマップをインスタンス化する場合: google.earth.createInstance('map', initCB, failCB);

Googleの目印を追加できるGoogleマップを取得しましたが、そのインスタンスを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 つの googly レイヤーを持つ基本的な OL マップが作成されます。ギアスが選択されている場合を除いて、マップレイヤーのいずれかで追加したマーカーを見ることができます。Google Earth マップをロードするとすぐに、div 全体が「引き継がれます」。LayerSwitcher などのすべての OL コントロールがなくなり、OL から Google Earth インスタンスにアクセスする方法がわかりません。

マーカーはまだ存在していると思いますが、ベースマップの背後にあります。ベースマップで不透明度を設定しても効果はありません。

質問:

  1. これは文書化された制限ですか? それが不可能であることを示すものは何も見つかりません。
  2. OpenLayers マップ/レイヤー インスタンスを Google Earth の getEarthInstance 呼び出しに渡すことができる回避策はありますか? それともその逆?必要に応じて GE API にアクセスできるようにすることは、両方の長所のように思えますが、OL のすべての WFS 処理をほとんどのタスクに使用できました。

中途半端なアイデア大歓迎。

4

3 に答える 3

2

一般に、OpenLayers は Google Earth 3D モードをまったくサポートしていません。(私は OpenLayers の開発者ですが、これが可能であることをこの質問で初めて知りました。) 3D 表示コードが (サードパーティのプラグインを介して) 動作する方法のため、デフォルトのOpenLayers ツール (描画など) は機能する予定です。OpenLayers が統合する必要のある部分は、3D API には存在しません。

OpenLayers (主に 2D 描画クライアント) は、さまざまな呼び出しのすべてを Google Maps/Earth API 呼び出しに変換するものを実装する可能性はほとんどありません。

OpenLayers はプロトコルとフォーマットをサポートしています。理論的には、これにより、Google Earth API などのサードパーティ API とやり取りするときに、OpenLayers WFS 処理ツールチェーンをある程度使用できます。ただし、この場合、問題を解決するのに十分ではないと思います。

要するに、これは機能せず、簡単な解決策はありません。3D が必要な場合は、おそらく自分でさらに多くのものを作成する必要があります。

于 2010-07-21T04:39:49.283 に答える
1

タイプがないと思うので、この質問はGoogleマップv2に関連していたと思います:v3のG_SATELLITE_3D_MAP。

Google マップ v3 用の Google Earth プラグインは、google-maps-utility-library-v3 (googleearth.js) のスクリプトを介して (ベータ版) サポートされています。

著者@jlivniが取ったアプローチは、Google マップ v3 の追加/削除イベントをリッスンし、対応する Google Earth Api オブジェクトを追加することです。OpenLayers でも同様のアプローチを使用できると思います。私は OpenLayers を初めて使用し、これを調査し始めたばかりですが、ここに更新を投稿します。

今追加できる唯一のことは、v3 で異なる Google Earth プラグインの初期化についてです。

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 Earth の新しいマップ タイプを定義し、このタイプを Google マップ オブジェクトに追加する必要があることです。しかし、最初に google.maps.MapTypeId.SATELLITE に設定したタイプのレイヤーを作成しないと、Google マップ オブジェクトは存在しません。あまりきれいではありませんが、少なくとも、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;
    }
  }
};

LayerSwitcher の z インデックスは正しく設定されており、div は google.earth.createInstance() が呼び出されるまで上に表示され、その後消えます。もう少し時間をかけますが、解決するのは難しくないようです。

【アップデート2】

LayerSwitcher パネルの問題を回避しました。トリックは、Google Earth プラグイン div を適切な div にアタッチすることでした (GMaps の元のコードは、それを Map Controls 配列にアタッチします)。もう 1 つの問題は、LayerSwitcher が一番上にあることを確認するために zIndex を設定することでした。OpenLayers.Event.stop() を呼び出すと、GE プラグインがクラッシュする (Chrome) か、LayerSwitcher が消える (IE8) ようになります。Google から元のコードをフォークして、OpenLayers で動作する GE Plugin Layer を作成したいと考えています。誰かがそれを行う方法を提案できますか? ありがとう。

とにかく、ここに私の最新の変更があります:

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/ZiglioUK/GoogleEarth-for-OpenLayers

于 2011-06-22T02:30:26.433 に答える
0

私は OpenLayers のさまざまなレイヤー タイプに慣れていませんが、重要なのは、Google Earth API と Google Maps API はまったく別物だということです。一見しただけでは、Google マップのタイプに追加する必要がある理由がわかりません (私がそう思っていると仮定して)。

Chris が既に示唆しているように、Earth API の統合を、既存の Google レイヤとはまったく別のものとして扱います。これらの API の構文と概念は、少なくとも私が知る限り、OpenLayers で既存の Google マップ統合をサブクラス化する利点を得るには十分に類似していません。

そうは言っても、Maps V3/Earth 統合のコードが役に立ち、OpenLayers と統合するために必要なことに類似していることを願っています。その間、私はあなたが役に立つと思うかもしれないこのgeoExtの例のように、他の人々もこれを試しているのを見てきました: http://dev.geoext.org/sandbox/cmoullet/ux/GoogleEarthPanel/examples/GoogleEarthPanelExample.html

于 2011-06-23T00:14:10.783 に答える