سؤال

Using Google Earth I have a loaded kml layer that displays polygons of every county in the US. On click a balloon pop's up with some relevant info about the state (name, which state, area, etc) When a user clicks the polygon I want the information to also pop up on a DIV element somewhere else.

This is my code so far.

var ge;
google.load("earth", "1");

function init() {
    google.earth.createInstance('map3d', initCB, failureCB);
}

function initCB(instance) {
    ge = instance;
    ge.getWindow().setVisibility(true);
    ge.getNavigationControl().setVisibility(ge.VISIBILITY_AUTO);
    ge.getNavigationControl().setStreetViewEnabled(true);
    ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, true);

    //here is where im loading the kml file 
    google.earth.fetchKml(ge, href, function (kmlObject) {
        if (kmlObject) {
            // show it on Earth
            ge.getFeatures().appendChild(kmlObject);
        } else {
            setTimeout(function () {
                alert('Bad or null KML.');
            }, 0);
        }
    });

    function recordEvent(event) {
        alert("click");
    }

    // Listen to the mousemove event on the globe.
    google.earth.addEventListener(ge.getGlobe(), 'click', recordEvent);
}

function failureCB(errorCode) {}

google.setOnLoadCallback(init);

My problem is that when I change ge.getGlobe() to kmlObject or ge.getFeatures() it doesn't work.

My first question is what should I change ge.getGlobe() to to be able to get a click listener when a user clicks on a kml layer's polygon?

After that I was planning on using getDescription() or getBalloonHtml() to get the polygons balloons information. Am I even on the right track?

هل كانت مفيدة؟

المحلول

...what should I change ge.getGlobe() to...

You don't need to change the event object from GEGlobe. Indeed it is the best option as you can use it to capture all the events and then check the target object in the handler. This means you only have to set up a single event listener in the API.

The other option would be to somehow parse the KML and attach specific event handlers to specific objects. This means you have to create an event listener for each object.

Am I even on the right track?

So, yes you are on the right track. I would keep the generic GEGlobe event listener but extend your recordEvent method to check for the types of KML object you are interested in. You don't show your KML so it is hard to know how you have structured it (are your <Polygon>s nested in <Placemarks> or ` elements for example).

In the simple case if your Polygons are in Placemarks then you could just do the following. Essentially listening for clicks on all objects, then filtering for all Placmark's (either created via the API or loaded in via KML).

function recordEvent(event) {
  var target = event.getTarget();
  var type = target.getType();
  if(type == "KmlPolygon") {
  } else if(type == "KmlPlacemark") {
    // get the data you want from the target.
    var description = target.getDescription();
    var balloon = target.getBalloonHtml();
  } else if(type == "KmlLineString") {
    //etc...
  }
};

google.earth.addEventListener(ge.getGlobe(), 'click', recordEvent);

If you wanted to go for the other option you would iterate over the KML Dom once it has loaded and then add events to specific objects. You can do this using something like kmldomwalk.js. Although I wouldn't really recommend this approach here as you will create a large number of event listeners in the api (one for each Placemark in this case). The up side is that the events are attached to each specific object from the kml file, so if you have other Plaemarks, etc, that shouldn't have the same 'click' behaviour then it can be useful.

function placeMarkClick(event) { 
  var target = event.getTarget();
  // get the data you want from the target.
  var description = target.getDescription();
  var balloon = target.getBalloonHtml();
}

google.earth.fetchKml(ge, href, function (kml) {
    if (kml) {
        parseKml(kml);
    } else {
        setTimeout(function () {
            alert('Bad or null KML.');
        }, 0);
    }
});

function parseKml(kml) {
    ge.getFeatures().appendChild(kml);
    walkKmlDom(kml, function () {
        var type = this.getType();
        if (type == 'KmlPlacemark') {
          // add event listener to `this`
          google.earth.addEventListener(this, 'click', placeMarkClick);
        }
    });
};

نصائح أخرى

Long time since i have worked with this.. but i can try to help you or to give you some tracks...

About your question on "google.earth.addEventListener(ge.getGlobe(), 'click', recordEvent);" ge.getGlobe can not be replaced with ge.getFeatures() : if you look in the documentation ( https://developers.google.com/earth/documentation/reference/interface_g_e_feature_container-members) for GEFeatureContainer ( which is the output type of getFeatures() , the click Event is not defined!

ge.getGlobe replaced with kmlObject: waht is kmlObject here??

About using getDescription, can you have a look on the getTarget, getCurrentTarget ... (https://developers.google.com/earth/documentation/reference/interface_kml_event)

As I told you, i haven't work with this since a long time.. so I'm not sure this can help you but at least, it's a first track on which you can look!

Please keep me informed! :-)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top