使用Javascript从KML中提取扩展数据

时间:2013-10-03 13:33:20

标签: kml google-earth-plugin

我在KML中有一个看起来像这样的地标

<Placemark> 
 <id>test345</id>
<name>Images from KML file</name>
<ExtendedData>
<Data name="type">
    <value>images</value>
</Data>
</ExtendedData>
<Point>
  <coordinates>-122.448425,37.802907,0</coordinates>
</Point>

我试图在点击事件中从此地标标记中提取ExtendedData信息:

google.earth.addEventListener(kmlObject, 'click', function(event) {
    event.preventDefault();
    var kmlPlacemark = event.getTarget();
});

另一种解决方案是从kmlPlacemarker获取kmlObject,任何想法?

3 个答案:

答案 0 :(得分:1)

鉴于地标,Google地球API提供了两种方法来访问ExtendedData元素。

  • getBalloonHtml()
  • getBalloonHtmlUnsafe可()

API参考:
https://developers.google.com/earth/documentation/reference/interface_kml_feature

您可以在Google Code Playground中找到一个有效的例子:
https://code.google.com/apis/ajax/playground/?exp=earth#extended_data_in_balloons

如果您想获取扩展数据的原始KML,那么您可以获取KML表示并将其解析为XML文档。

var output = placemark.getKml();

答案 1 :(得分:0)

只是说我在插件支持论坛上发布了这个问题:https://code.google.com/p/earth-api-samples/issues/detail?id=16

这是我拼凑在一起为getExtendedData提供支持的方法。它通过'feature.getKml();接受一串Kml作为参数。它返回任何在key [value]对象中具有值的扩展数据元素。它希望扩展数据采用以下格式:

<Data name="Foo">
  <value>bar</value>
</Data>

在XP中测试 - FF3.0,IE7,Chrome

function getExtendedData(kmlString) { 
  var xmlDoc = null; 
  var keyValue = []; 
  //Parse the kml 
  try { 
    //Internet Explorer 
    xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 
    xmlDoc.async="false"; 
    xmlDoc.loadXML(kmlString); 
  } catch(e) { 
    try { 
      //Firefox, etc. 
      var parser = new DOMParser(); 
      xmlDoc = parser.parseFromString(kmlString,"text/xml"); 
    } 
    catch(e) { 
      //Failed to parse 
      alert(e.message); 
      return; 
    } 
  } 
  // Get all the named elements 
  var data = xmlDoc.getElementsByTagName("Data"); 
  // Iterate through the data elements 
  for(var i=0; i<data.length; i++) { 
    if(data[i].getAttribute("name") &&
      data[i].getElementsByTagName("value").length > 0) { 
      // Get the name and value 
      var name = data[i].getAttribute("name"); 
      var value = data[i].getElementsByTagName("value")[0].firstChild.data; 
      // Assign them to the keyValue object 
      keyValue[name] = value; 
    } 
  } 
  return keyValue; 
} 

用法

// where 'feature' is the object with the extended data
var data = getExtendedData(feature.getKml()); 

for (var name in data) { 
  var value = data[name]; 
  alert(name + '=' + value); // e.g. type=images
} 

答案 2 :(得分:0)

实际上可以通过DOM API访问ExtendedData元素,尽管它们在任何地方都没有特别好的记录。 我在使用插件打包的一些资源(.rcc)文件中搜索时找到了它们。

假设一个与您的相似的简单地标样本:

  <Placemark id="testmark">
    <!-- other stuff... -->
    <ExtendedData>
      <Data name="someDataUrl">
        <displayName>URL Representing some Data</displayName>
        <value>http://example.com/#hello</value> 
      </Data>
    </ExtendedData>
  </Placemark>

然后(一旦它被提取/解析/加载到地球,您可以访问它类似于:

var mark = ge.getElementById('testmark');
var extDataObj = mark.getExtendedData();
var extDataOut = Array(extDataObj.getDataCount());

for (var i = 0; i < extDataObj.getDataCount(); i++) {
    var item = extDataObj.getData(i);
    var details = { name: item.getName(),
                    displayName: item.getDisplayName(),
                    value: item.getValue() 
                   };
    extDataOut[i] = details;
}
console.dir(extDataOut);

没有针对性能与.getKml()进行测试并提供给外部解析器方法,缺乏官方文档可能意味着它没有完全正常或支持,但到目前为止所有测试似乎都没有好。我还没有找到一种方法来访问任何更复杂的SchemaData类型结构,只有简单的<data name=''><value>...形式。