Question

I want to put inside a GoogleEarth instance, new 3D Region - objects, at the ground level. These objects should be clickable. At this live demo page:

https://code.google.com/apis/ajax/playground/?exp=earth#creating_3d_models

.. I tried to modify executable code, to add simple mouse-event listener, to handle mouse clicks on 3D_Box object (placemark variables).

I can't get the code works. I believe that it is possible:

google.earth.addEventListener(placemark, 'mousedown', function(event) {
    console.log(event);    
    console.log(event.getTarget().getType());
});

How??

Was it helpful?

Solution

Custom 3D models appended to GE don't trigger those kind of events (unfortunately). You have some workarounds to make that kind of behaviour work, depending on the level of precision you want:

  • Draw a Placemark in the same place of the 3D model with just the name of the element and capture clicks - the user must know he has to click on the name, might not be intuitive
  • Draw a Polygon in the same place of the 3D model - depending on the angle of the model you might not detect clicks
  • Draw multiple Polygons around the 3D model - heavier, but more precise

Regarding performance, if you only draw it once, it is just another element in GE, so it shouldn't be noticeable any issues, but if you have to constantly update its position than you will lose a bit of performance, but it will depend on the frequency of updates and the number of elements to manipulate.

This is an example of creating a "Cube" around a 3D Model position:

function createCube(lat, lon, offset, alt, altOffset, name) {
    var altitudeMode = window.ge.ALTITUDE_ABSOLUTE;
    //create the back polygon of the cube
    var backPoly = window.ge.createPolygon('');
    backPoly.setAltitudeMode(altitudeMode);

    var cubeBack = window.ge.createLinearRing('');
    cubeBack.setAltitudeMode(altitudeMode);
    // Square outer boundary.
    cubeBack.getCoordinates().pushLatLngAlt(lat - offset, lon - offset, alt); 
    cubeBack.getCoordinates().pushLatLngAlt(lat - offset, lon - offset, alt+altOffset); 
    cubeBack.getCoordinates().pushLatLngAlt(lat - offset, lon + offset, alt+altOffset); 
    cubeBack.getCoordinates().pushLatLngAlt(lat - offset, lon + offset, alt);
    backPoly.setOuterBoundary(cubeBack);

    //create the front polygon of the cube
    var frontPoly = window.ge.createPolygon('');
    frontPoly.setAltitudeMode(altitudeMode);

    var cubeFront = window.ge.createLinearRing('');
    cubeFront.setAltitudeMode(altitudeMode);
    // Square outer boundary.
    cubeFront.getCoordinates().pushLatLngAlt(lat + offset, lon - offset, alt);
    cubeFront.getCoordinates().pushLatLngAlt(lat + offset, lon - offset, alt+altOffset);
    cubeFront.getCoordinates().pushLatLngAlt(lat + offset, lon + offset, alt+altOffset);
    cubeFront.getCoordinates().pushLatLngAlt(lat + offset, lon + offset, alt);
    frontPoly.setOuterBoundary(cubeFront);

    //create the left polygon of the cube
    var leftPoly = window.ge.createPolygon('');
    leftPoly.setAltitudeMode(altitudeMode);

    var cubeLeft = window.ge.createLinearRing('');
    cubeLeft.setAltitudeMode(altitudeMode);
    // Square outer boundary.
    cubeLeft.getCoordinates().pushLatLngAlt(lat - offset, lon - offset, alt);
    cubeLeft.getCoordinates().pushLatLngAlt(lat - offset, lon - offset, alt+altOffset);
    cubeLeft.getCoordinates().pushLatLngAlt(lat + offset, lon - offset, alt+altOffset);
    cubeLeft.getCoordinates().pushLatLngAlt(lat + offset, lon - offset, alt);
    leftPoly.setOuterBoundary(cubeLeft);

    //create the right polygon of the cube
    var rightPoly = window.ge.createPolygon('');
    rightPoly.setAltitudeMode(altitudeMode);

    var cubeRight = window.ge.createLinearRing('');
    cubeRight.setAltitudeMode(altitudeMode);
    // Square outer boundary.
    cubeRight.getCoordinates().pushLatLngAlt(lat - offset, lon + offset, alt);
    cubeRight.getCoordinates().pushLatLngAlt(lat - offset, lon + offset, alt+altOffset);
    cubeRight.getCoordinates().pushLatLngAlt(lat + offset, lon + offset, alt+altOffset);
    cubeRight.getCoordinates().pushLatLngAlt(lat + offset, lon + offset, alt);
    rightPoly.setOuterBoundary(cubeRight);

    //create the multigeometry object
    var multiGeometry = window.ge.createMultiGeometry(''); 
    multiGeometry.getGeometries().appendChild(backPoly); 
    multiGeometry.getGeometries().appendChild(frontPoly); 
    multiGeometry.getGeometries().appendChild(leftPoly); 
    multiGeometry.getGeometries().appendChild(rightPoly);

    //create the cube placemark
    var cubePlacemark = window.ge.createPlacemark('');
    cubePlacemark.setGeometry(multiGeometry);

    //Create a style and set width and color of line and polygons 
    cubePlacemark.setStyleSelector(window.ge.createStyle('')); 
    var polyStyle = cubePlacemark.getStyleSelector().getPolyStyle(); 
    polyStyle.setFill(0);
    var lineStyle = cubePlacemark.getStyleSelector().getLineStyle(); 
    lineStyle.setWidth(1);

    lineStyle.getColor().set('012F2F2F');

    //append the placemark to the geplugin
    ge.getFeatures().appendChild(cubePlacemark);

    //set the cube name
    cubePlacemark.setName(name);

    /*
     * Click event listener
     * Show a menu with some nice options - For now its ugly
     */
    google.earth.addEventListener(cubePlacemark, 'click', function(event) {
        event.preventDefault();

        setTimeout(function() {
            if(console) console.log("Cube click");
            else alert("Cube click");
        },0);
    });//click
}

I hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top