将事件侦听器附加到kml图层的多边形时遇到问题

时间:2013-07-24 17:38:14

标签: google-earth google-earth-plugin

使用Google地球我有一个加载的kml图层,显示美国每个县的多边形。点击一个气球弹出窗口,其中包含有关状态的一些相关信息(名称,状态,区域等)当用户点击多边形时,我希望信息也会弹出在其他地方的DIV元素上。

到目前为止,这是我的代码。

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);

我的问题是,当我将ge.getGlobe()更改为kmlObject或ge.getFeatures()时,它无效。

我的第一个问题是,当用户点击kml图层的多边形时,我应该将ge.getGlobe()更改为能够获得点击侦听器吗?

之后,我计划使用getDescription()getBalloonHtml()来获取多边形气球信息。我甚至走在正确的轨道上吗?

2 个答案:

答案 0 :(得分:1)

  

...我应该将ge.getGlobe()更改为...

您无需从GEGlobe更改事件对象。实际上它是最好的选项,因为您可以使用它来捕获所有事件,然后检查处理程序中的目标对象。这意味着您只需在API中设置单个事件侦听器。

另一种选择是以某种方式解析KML并将特定事件处理程序附加到特定对象。这意味着您必须为每个对象创建一个事件侦听器。

  

我是否在正确的轨道上?

所以,是的,你是在正确的轨道上。我会保留通用的GEGlobe事件监听器,但扩展你的recordEvent方法来检查你感兴趣的KML对象的类型。你没有显示你的KML所以很难知道你是怎么做的结构化的(你的<Polygon>嵌套在<Placemarks>或`元素中)。

在简单的情况下,如果您的多边形位于地标中,那么您可以执行以下操作。基本上听取所有对象的点击,然后过滤所有Placmark(通过API创建或通过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);

如果你想选择另一个选项,你可以在加载后迭代KML Dom,然后将事件添加到特定对象。您可以使用kmldomwalk.js之类的内容执行此操作。虽然我不会在这里推荐这种方法,因为你将在api中创建大量的事件监听器(在这种情况下,每个Placemark都有一个)。好的一面是事件附加到kml文件中的每个特定对象,所以如果你有其他的Plaemarks等不应该有相同的'click'行为,那么它就会很有用。

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);
        }
    });
};

答案 1 :(得分:0)

很长一段时间以来我一直在努力...但我可以尝试帮助你或给你一些曲目......

关于“google.earth.addEventListener(ge.getGlobe(),'click',recordEvent)的问题;” ge.getGlobe不能替换为ge.getFeatures():如果您查看GEFeatureContainer的文档(https://developers.google.com/earth/documentation/reference/interface_g_e_feature_container-members)(这是getFeatures()的输出类型,则不会定义click事件!

ge.getGlobe替换为kmlObject:waht是kmlObject here ??

关于使用getDescription,你能看看getTarget,getCurrentTarget ...... (https://developers.google.com/earth/documentation/reference/interface_kml_event

正如我告诉过你的那样,我很长时间没有使用过这个...所以我不确定这对你有什么帮助,但至少,这是你可以看到的第一首曲目!

请随时通知我! : - )