I think this question was related to Google Maps v2, since I don't think there's a type: G_SATELLITE_3D_MAP in v3.
The Google Earth Plugin for Google Maps v3 is (beta) supported via a script from the google-maps-utility-library-v3 (googleearth.js)
The approach the author @jlivni has taken is to listen to Google Maps v3 add/remove events and add corresponding Google Earth Api objects.
I believe a similar approach could be used with OpenLayers. I'm new to OpenLayers, and have just started looking into this but I'll post updated here.
The only thing I can add now is about the initialization of the Google Earth plugin, that is different in 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_();
});
}
The convoluted part is that we need to define a new map type for Google Earth, and add this type to a Google Map object. But the Google Map object doesn't exist if we don't create a layer with a type, that I set initially to google.maps.MapTypeId.SATELLITE.
Not very clean, but at least it gets me to the same state as the author of this post with Google Maps v3.
Finally there may be a way to make OpenLayers controls visible by modifying the function findMapTypeControlDiv_():
var mapTypeControlDiv = this.findMapTypeControlDiv_();
if (mapTypeControlDiv) {
this.setZIndexes_(mapTypeControlDiv);
this.addShim_(mapTypeControlDiv);
}
[Update]
I've modified the function findMapTypeControlDiv_() and now I look for the OpenLayers LayerSwitcher instead:
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;
}
}
};
The z index of the LayerSwitcher is correctly set and the div shows on top until google.earth.createInstance() is invoked, then it disappears. I'll spend some more time on it, it doesn't look to hard to solve.
[Update 2]
I've worked around the LayerSwitcher panel issue. The trick was attaching the Google Earth Plugin div to the proper div (the original code for GMaps attaches it to the Map Controls array). The other issue was setting the zIndex to make sure the LayerSwitcher is on top.
I'm still having a problem when the GE Plugin is running and I try to minimize the LayerSwitcher, a call to OpenLayers.Event.stop() makes the GE Plugin crash (Chrome) or the LayerSwitcher to disappear (IE8).
I'd like to fork the original code from Google and make a GE Plugin Layer that works on OpenLayers.
Could anyone suggest how to do it? thanks.
Anyway, here are my latest changes:
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;
};
[update 3]
I've set up a github project here: https://github.com/ZiglioUK/GoogleEarth-for-OpenLayers