最近项目中用到了记录轨迹功能,我使用数据库将很多的轨迹点保存了起来,需要的时候直接从数据库中查找出来按照时间进行排序。因为涉及到了轨迹,所以我的这些轨迹点连接起来具体是个什么样的路线实在是看不出来。

这时候我是用了市面上的其他轨迹软件,例如:户外助手、奥维地图等。发现他们的软件可以加载Kml、Gpx文件。我选择使用KML文件。

下面是KML文件的介绍:


KML,是标记语言(Keyhole Markup Language)的缩写,最初由Keyhole公司开发,是一种基于XML 语法与格式的、用于 描述和保存地理信息(如点、线、图像、多边形和模型等)的编码规范,可以被 Google Earth 和 Google Maps 识别并显 示。Google Earth 和 Google Maps 处理 KML 文件的方式与网页浏览器 处理 HTML 和 XML 文件的方式类似。像 HTML 一 样,KML 使用包含名称、属性的标签(tag)来确定显示方式。因此,您可将 Google E arth 和 Google Maps 视为 KML文件 浏览器 。2008年4月微软的OOXML成为国际标准后,Google公司宣布放弃对KML的控制权,由开放地理信息联盟(OGC)接 管KML语言,并将“Google Earth”及“Google Maps”中使用的KML语言变成为一个国际标准。




关于KML文件的格式可以看一下这一位的博客:KML文件格式讲解 




从户外助手导出的Kml文件里面包含的数据有很多,但是我认为有许多的数据,是户外助手自己生成自己解析获取的数据。对于我只要看到轨迹数据的需求来说,这些数据是不必要的。


一下截图是我对户外助手Kml文件数据的理解:


kml生成python kml生成轨迹_Android

这些对我并不是多么的重要,我不需要样式、名字或者其他什么的,下面的图才是我想要看到的:

kml生成python kml生成轨迹_kml生成python_02

整条轨迹的数据都在这里。底下还有一堆数据,是轨迹点的时间:

<when>2017-12-20T09:45:13Z</when>
           <when>2017-12-20T09:45:17Z</when>
           <when>2017-12-20T09:45:21Z</when>
           <when>2017-12-20T09:45:27Z</when>
           <when>2017-12-20T09:45:33Z</when>
           <when>2017-12-20T09:45:39Z</when>
           <when>2017-12-20T09:45:43Z</when>
           <when>2017-12-20T09:45:47Z</when>
           <when>2017-12-20T09:45:51Z</when>
           <when>2017-12-20T09:45:55Z</when>
           <when>2017-12-20T09:45:59Z</when>
           <when>2017-12-20T09:46:01Z</when>
           <when>2017-12-20T09:46:05Z</when>
           <when>2017-12-20T09:46:09Z</when>从里面找出重要的节点属性:



<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>这个就不用说什么了,因为Kml最终还是xml文件。



<kml ></kml>这个就是kml文件的根级节点了。


<Document></Document>这个就比较熟了吧
<Folder id=""> 轨迹数据的根级节点
 
       <name>轨迹</name>
 
       <Placemark>
 
         <name>轨迹片段1</name>
 
         <styleUrl>#TrackStyle</styleUrl>
 
         <description>  //这里是描述属性
 
           <div>通过“两步路户外助手”生成,http://www.2bulu.com</div>
 
           <div>上传者:</div>
 
           <div>开始时间:2017-12-20 17:45:13</div>
 
           <div>结束时间:2017-12-20 18:35:35</div>
 
           <div>轨迹点数:288</div>
 
           <div>本段里程:4025.8867557130948米</div>
 
           <div>最高海拔:149.5米</div>
 
           <div>最低海拔:25.5米</div>
 
           <div>累计爬升:122.30000000000001米</div>
 
           <div>累计下降:20.4米</div> 
         </description>
</Folder> 
<gx:Track>重点来了  就是它  所有的轨迹点的经纬度属性都在这个节点下。
<gx:coord> 包含经纬度和高度的节点。
<when>  轨迹点时间的节点。

有了这些属性节点基本上就够满足我的需求了。下面开始撸代码!!!!!!!

public static void createKml(String filePath, Task task) {
    Element root = DocumentHelper.createElement("kml");  //根节点是kml
    Document document = DocumentHelper.createDocument(root);
    document.setXMLEncoding("UTF-8");
    //给根节点kml添加属性
    root.addNamespace("xmlns", "http://www.opengis.net/kml/2.2");
    root.addNamespace("gx", "http://www.google.com/kml/ext/2.2");
    //给根节点kml添加子节点  Document
    Element documentElement = root.addElement("Document");
    Element folderDe = documentElement.addElement("Folder");
    Element PlacemarkDe = folderDe.addElement("Placemark");

    Element styleE = PlacemarkDe.addElement("Style");
    Element LineStyle = styleE.addElement("LineStyle");
    LineStyle.addElement("color").addText("ed0000ff");
    LineStyle.addElement("width").addText("5");

    List<TrackPoint> tps = task.getTrackPoints();
    Element trackE = PlacemarkDe.addElement("gx:Track");

    for (TrackPoint tp : tps) {
        trackE.addElement("gx:coord").addText(tp.getLongitude() + " " + tp.getLatitude() + " " + tp.getAltitude());
        trackE.addElement("when").setText(DateUtils.specialDateString(tp.getTime()));
    }
    try {
        Writer fileWriter = new FileWriter(filePath);
        //换行
        OutputFormat format = new OutputFormat();
        format.setEncoding("UTF-8");
        format.setNewlines(true);
        // 生成缩进
        format.setIndent(true);
        //dom4j提供了专门写入文件的对象XMLWriter
        XMLWriter xmlWriter = new XMLWriter(fileWriter, format);
        xmlWriter.write(document);
        xmlWriter.flush();
        xmlWriter.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

难点:

上面的代码这个位置:

root.addNamespace("gx", "http://www.google.com/kml/ext/2.2");

在之前我是这么写的:

root.addAttribute("gx", "http://www.opengis.net/kml/2.2");

结果报错了。报错地方是:

trackE.addElement("gx:coord").addText(tp.getLongitude() + ""+tp.getLatitude() + " " + tp.getAltitude()); 
  这里,提示非正常语法。网上的解决方法是添加gx命名空间。

我把设置addAttribute认为是添加命名空间,结果并不是。耽搁了一点时间,找到解决方法:addNamespace。


实体类Task是一条轨迹,TrackPoint是轨迹上的轨迹点。这里用到了dom4j包。这个包可以在网上自行查找。

就写到这这吧!!!!这特么格式是怎么调的,怎么看怎么不对劲,就这样吧。能看的就看,看不懂的......我也很绝望啊,可是我有什么办法!!!!!