导出轨迹为kml文件(java和vue实现)

前言

KML文件是一种存储点数据xml文件格式,可以在地理信息系统中展示地理数据,本文实现了Java生成KML文件以及前端浏览器下载文件。

KML文件结构

KML文件是一个XML文档,包含了用于描述地理信息的标记和元素,可用于定义的地理特征包括地点、描述、叠层、路径和多边形等。

轨迹KML文件基本结构如下:

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">
<Document>
<name>track name</name>
<Placemark>
<LineString>
<coordinates>lon,lat lon,lat</coordinates>
</LineString>
</Placemark>
</Document>
</kml>

使用JAK库生成KML文件

Java中有多种方式创建KML,这里使用的是JavaAPIforKml库创建和操作KML文件。

首先在pom.xml文件中引入添加JavaAPIforKml依赖:

1
2
3
4
5
<dependency>
<groupId>de.micromata.jak</groupId>
<artifactId>JavaAPIforKml</artifactId>
<version>2.2.0</version>
</dependency>

核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import de.micromata.opengis.kml.v_2_2_0.*;

public ResponseEntity<InputStreamResource> exportTrack(String trackLine){
//解析json字符串
JSONObject trackData = JSONObject.parseObject(trackLine);
// 坐标数组
JSONArray coordinatesArr = trackData.getJSONArray("coordinates");
//创建一个kml对象
Kml kml = new Kml();
Document document = kml.createAndSetDocument().withName("Track");

List<Coordinate> coordinates = new ArrayList<>();

for (int i = 0; i < coordinatesArr.size(); i++) {
JSONArray coordinate = coordinatesArr.getJSONArray(i);
double longitude = coordinate.getDoubleValue(0);
double latitude = coordinate.getDoubleValue(1);
coordinates.add(new Coordinate(longitude, latitude));
}

// 创建线数据,并将 LineString 添加到 Placemark 中
LineString lineString =document.createAndAddPlacemark().createAndSetLineString();
lineString.setCoordinates(coordinates);

// 生成KML文件
ByteArrayOutputStream out = new ByteArrayOutputStream();
kml.marshal(out);

// 设置响应头
byte[] kmlBytes = out.toByteArray();
InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(kmlBytes));

return ResponseEntity.ok()
.contentLength(kmlBytes.length)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(resource);
}

前端下载KML文件

核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function downloadTask(url, params, filename, config) {
// 发送Post请求,blob类型数据
return service.post(url, params, {
responseType: "blob", // 设置响应类型为arraybuffer
...config
}).then(async (data) => {
// 验证是否为blob格式
const isBlob = blobValidate(data);
if (isBlob) {
const blob = new Blob([data])
saveAs(blob, filename)
} else {
const resText = await data.text();
const rspObj = JSON.parse(resText);
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
Message.error(errMsg);
}
}).catch((error) => {
Message.error('下载文件错误!')
});
}

除了JAK库,还有其它一些Java工具可以用来导出KML文件,如GIS中常用的GeoTools库。