Как нарисовать функции openlayers с помощью базовой карты Google Earth - PullRequest
1 голос
/ 20 июля 2010

Попытка использовать OpenLayers для (в конечном итоге) загрузки маркеров, векторов и WMS поверх базовой карты плагина Google Earth. Google Планета Земля "не очень хорошо играет с другими".

Если я создаю карту в «google way»: 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();

Это создает базовую карту OL с 5 слоями Google. Я вижу маркер, который добавляю, когда любой из слоев карты , за исключением , когда выбран gearth. Как только я загружаю карту Google Earth, она «захватывает» весь div. Все элементы управления OL, такие как LayerSwitcher, исчезли, и я не смог выяснить, как получить доступ к экземпляру Google Планета Земля из OL.

Я предполагаю, что маркеры все еще присутствуют, но за базовой картой. Установка непрозрачности на базовой карте не имеет никакого эффекта.

Вопросы:

  1. Это задокументированное ограничение? Я не могу найти ничего, что указывало бы, что это не должно быть возможно.
  2. Есть ли обходной путь, когда я могу передать экземпляр карты / слоя OpenLayers в вызов getEarthInstance Google Планета Земля? Или наоборот? Кажется, что это было бы лучшим из обоих миров, предоставляя мне доступ к GE API при необходимости, но я мог бы использовать всю обработку WFS в OL для большинства задач.

Приветствуются недоделанные идеи.

Ответы [ 3 ]

1 голос
/ 22 июня 2011

Я думаю, что этот вопрос был связан с Google Maps v2, так как я не думаю, что есть тип: G_SATELLITE_3D_MAP в v3.

Плагин Google Планета Земля для Google Maps v3 (бета) поддерживается через скрипт из google-maps-utility-library-v3 (googleearth.js)

Подход, использованный автором @ jlivni , заключается в прослушивании Google Maps v3 add/ удалить события и добавить соответствующие объекты Google Earth Api.Я считаю, что аналогичный подход может быть использован с OpenLayers.Я новичок в OpenLayers и только начал изучать это, но я опубликую обновленный здесь.

Единственное, что я могу добавить сейчас, это об инициализации плагина Google Планета Земля, который отличается от 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 Earth и добавить этот тип к объекту Google Map.Но объект Google Map не существует, если мы не создадим слой с типом, который я изначально установил как google.maps.MapTypeId.SATELLITE.Не очень чистый, но, по крайней мере, он приводит меня в то же состояние, что и автор этого поста, с Google Maps v3.Наконец, может быть способ сделать элементы управления OpenLayers видимыми, изменив функцию findMapTypeControlDiv _ ():

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

[Update]

Я изменил функцию 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;
    }
  }
};

Правильно установлен индекс z LayerSwitcher, и div отображается сверху, пока не будет вызван google.earth.createInstance (), а затем исчезнет.Я потрачу на это больше времени, это не сложно решить.

[Обновление 2]

Я работал над проблемой панели LayerSwitcher.Хитрость заключалась в том, чтобы прикрепить div плагина Google Earth к соответствующему div (оригинальный код для GMaps прикрепляет его к массиву Map Controls).Другой проблемой была установка zIndex, чтобы убедиться, что LayerSwitcher находится сверху.У меня все еще есть проблема, когда плагин GE работает, и я пытаюсь свести к минимуму LayerSwitcher, вызов OpenLayers.Event.stop () приводит к сбою плагина GE (Chrome) или к исчезновению LayerSwitcher (IE8).Я хотел бы раскошелиться на оригинальный код от Google и создать слой плагинов GE, который работает на OpenLayers.Кто-нибудь может подсказать, как это сделать?спасибо.

В любом случае, вот мои последние изменения:

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

1 голос
/ 21 июля 2010

В целом, OpenLayers абсолютно не поддерживает режим Google Earth 3D. (Я разработчик для OpenLayers, и я только осознал, что это было возможно с помощью этого вопроса.) Из-за способа, которым работает код 3D-отображения (с помощью стороннего плагина), я не могу Представьте себе, как будут работать стандартные инструменты OpenLayers - для рисования и т. д.: части, с которыми OpenLayers нужно будет интегрировать, просто не существуют в 3D API.

OpenLayers - в первую очередь клиент 2D-рисования - вряд ли когда-либо реализует что-либо, что переведет все его различные вызовы в вызовы Google Maps / Earth API.

OpenLayers действительно поддерживает протоколы и форматы: теоретически это позволит вам в некоторой степени использовать цепочку обработки OpenFSayers WFS при взаимодействии со сторонними API, такими как Google Earth API. Однако я ожидаю, что в этом случае вы недостаточно выиграете от этого, чтобы решить свою проблему.

Короче говоря: это не работает, и не существует простого решения. Если вы хотите 3D, вам, вероятно, придется создавать намного больше самостоятельно.

0 голосов
/ 23 июня 2011

Я больше не знаком с различными типами слоев в OpenLayers, но главное в том, что API Google Планета Земля и API Карт Google действительно разные звери. На первый взгляд, я не понимаю, почему вам нужно было бы добавить его к типу Google Maps (если я так думаю).

Как уже предполагал Крис, просто относитесь к интеграции Earth API как совершенно новую и отдельную вещь от любых существующих слоев Google; Синтаксис и концепции в этих API не настолько схожи, чтобы вы могли получить какое-либо преимущество от подклассов существующей интеграции Google Карт в OpenLayers, по крайней мере, насколько я могу судить.

Тем не менее, я надеюсь, что код для интеграции Maps V3 / Earth будет полезен и аналогичен тому, что вам нужно сделать, чтобы интегрировать его с OpenLayers. В то же время я видел, что некоторые другие люди тоже делали это, например, этот пример geoExt, который вы также можете найти полезным: http://dev.geoext.org/sandbox/cmoullet/ux/GoogleEarthPanel/examples/GoogleEarthPanelExample.html

...