只要做地图相关的朋友,都会遇到一个功能,那就是显示点位以及轨迹回放,如果需要方便的查看轨迹回放以及点位的位置,我们可以借助Google Earth工具,当然使用的前提你得准备KML文件。
KML:KML文件就是一种在GOOGLE地图浏览器中用于交换地理数据的文件。它基于XML,并定义了一些TAG用于规定地理数据的显示方式。KML可用于定义的地理特征包括地点、描述、叠层、路径和多边形等。KML的用途主要有:
(1)指定地点的图标和注记;
(2)为每一个地理特征创建不同的视角位置;
(3)在地球上叠放图像;
(4)指定地理特征显示的样式;
(5)编写地理特征的HTML描述,包括超链接和内嵌图像;
(6)使用文件夹对地理特征进行群组;
(7)KML文件的动态获取及修改;
(8)显示三维地物;
kml一般来说是由两个文件组成,一个kml文件和一个png图标文件。但是我一般只用一个kml文件就行了,图标我使用的是在线图标。
下面我们就举一个例子来说明java怎样生成kml文件。
最终在Google Earth中效果图如下:
图中包含蓝色的图标以及黄色的路径。
首先我们需要生成一个包含位置信息的kml文件(类似xml文件),有多种方式创建kml,这里使用的是Dom4J方式。android中就导入jar包下载地址:dom4j,java中就在pom.xml文件中添加如下。
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
使用如下(懒,直接上代码,注解配合参数说明介绍很详细):
//travelRecords代表一个地理信息的对象集合(自定义) 生成kml的名称
public static boolean setTravelsKml(List<TravelRecord> travelRecords,String fileName) throws IOException {
Element root = DocumentHelper.createElement("kml");
Document document = DocumentHelper.createDocument(root);
//根节点添加属性
root.addAttribute("xmlns", "http://www.opengis.net/kml/2.2")
.addAttribute("xmlns:gx", "http://www.google.com/kml/ext/2.2")
.addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
.addAttribute("xsi:schemaLocation",
"http://www.opengis.net/kml/2.2 http://schemas.opengis.net/kml/2.2.0/ogckml22.xsd http://www.google.com/kml/ext/2.2 http://code.google.com/apis/kml/schema/kml22gx.xsd");
Element documentElement = root.addElement("Document");
documentElement.addElement("name").addText(fileName);
documentElement.addElement("Snippet").addText("");
Element folderElement = documentElement.addElement("Folder");//添加一个目录
folderElement.addAttribute("id", "FeatureLayer0");
folderElement.addElement("name").addText("轨迹点位"); //名称
folderElement.addElement("Snippet").addText(""); //显示在Google Earth之中的对description的简短概要.
//生成点位图标数据
int i = 0;
for (TravelRecord travelRecord:travelRecords) {
i++;
Element placeMarkElement = folderElement.addElement("Placemark");//在文件夹中添加一个地标
placeMarkElement.addAttribute("id", String.valueOf(i));
placeMarkElement.addElement("name").addText("点位"+String.valueOf(i));
placeMarkElement.addElement("Snippet").addText("");
placeMarkElement.addElement("description").addText("");//简介
placeMarkElement.addElement("styleUrl").addText("#MyStyle");//风格
Element pointElement = placeMarkElement.addElement("Point");
pointElement.addElement("altitudeMode").addText("clampToGround");
//添加点位的经纬度坐标以及高度(显示时绘制高度m)
pointElement.addElement("coordinates").addText(travelRecord.lng+","+travelRecord.lat+",0");//可以是是任何几何形状的子元素,定义每一个点的经度、纬度和高度(按照严格的顺序). 多个点使用空格隔开,经纬度按照WGS84标准.
}
//生成轨迹线路径数据
Element lineElement = documentElement.addElement("Placemark");//在文件夹外添加一个地标
lineElement.addElement("name").addText("轨迹线");
lineElement.addElement("description").addText("");
lineElement.addElement("styleUrl").addText("#MyStyle");
Element pointElement = lineElement.addElement("LineString");
pointElement.addElement("altitudeMode").addText("absolute");
pointElement.addElement("extrude").addText("1");
pointElement.addElement("tessellate").addText("1");
String linedata="";
//每个坐标以及高度用换行符或空格分开
for (TravelRecord travelRecord:travelRecords) {
linedata =linedata+"\n"+ travelRecord.lng+","+travelRecord.lat+",30";
}
pointElement.addElement("coordinates").addText(linedata);
//生成显示风格
Element styleElement = documentElement.addElement("Style");//Style节点
styleElement.addAttribute("id", "MyStyle");
// IconStyle 图标风格
Element iconStyleElement = styleElement.addElement("IconStyle");
Element iconElement = iconStyleElement.addElement("Icon");
// iconElement.addElement("href").addText("http://192.168.10.108:8080/images/mark_b.png");//在线图标
iconStyleElement.addElement("scale").addText("0.250000");
// LabelStyle 标签风格
Element labelStyleElement = styleElement.addElement("LabelStyle");
labelStyleElement.addElement("color").addText("00000000");
labelStyleElement.addElement("scale").addText("0.000000");
// PolyStyle 图形风格
Element polyStyleElement = styleElement.addElement("PolyStyle");
polyStyleElement.addElement("color").addText("5f00ff00");
polyStyleElement.addElement("outline").addText("0");
// LineStyle 路径线风格
Element lineStyleElement = styleElement.addElement("LineStyle");
lineStyleElement.addElement("color").addText("7f00ffff");
lineStyleElement.addElement("width").addText("4");
//创建kml到本地
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("D:/web/airportData/"+fileName+"_1.kml"),format);
xmlWriter.write(document);
xmlWriter.close();
//开始对文件进行压缩,一个kml文件其实是一个压缩文件,里面包含一个kml文件和一个png图标
String[] strs = new String[2];
strs[0]="D:/web/Travels/"+fileName+"_1.kml";
strs[1]="D:/web/Travels/images/img_mark.png";//这里写图片的路径 如果使用在线图标这段代码屏蔽
writeKml(strs,"D:/web/Travels/"+ fileName);//压缩
return true;
}
public static void writeKml(String[] strs, String kmlName) throws IOException
{
String[] files = strs;
OutputStream os = new BufferedOutputStream( new FileOutputStream(kmlName + ".kml"));
ZipOutputStream zos = new ZipOutputStream(os);
byte[] buf = new byte[8192];
int len;
for (int i=0;i < files.length;i++) {
File file = new File(files[i]);
if ( !file.isFile() )
continue;
ZipEntry ze = new ZipEntry( file.getName() );
zos.putNextEntry( ze );
BufferedInputStream bis = new BufferedInputStream( new FileInputStream( file ) );
while ( ( len = bis.read( buf ) ) > 0 ) {
zos.write( buf, 0, len );
}
zos.closeEntry();
bis.close();
}
zos.closeEntry();
zos.close();
os.close();
}
这样就在"D:/web/Travels/"中生成了一个kml文件,然后就可以进行下一步操作了,web的话,一般就是提供接口下载kml文件。android的话,路径就要改一下,直接把文件生成在手机存储中,接下来就可以在Google Earth中打开kml就行。