<!-- https://mvnrepository.com/artifact/de.micromata.jak/JavaAPIforKml -->
<dependency>
<groupId>de.micromata.jak</groupId>
<artifactId>JavaAPIforKml</artifactId>
<version>2.2.0</version>
</dependency>
这个包里封装了java实现的解析谷歌地球kml文件的方法
我使用到的地方,代码如下:
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.building.entity.BuildingKmlGeo;
import com.building.entity.vo.KmlBuilding;
import com.building.entity.vo.KmlDoc;
import com.building.entity.vo.KmlLookAt;
import com.building.entity.vo.KmlNetworkLink;
import de.micromata.opengis.kml.v_2_2_0.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
* kml转geoJson文件
* @author cheney
public class KmlToGeoJsonUtils {
public static List<BuildingKmlGeo> unzipKmzToKml(String filePath) throws Exception {
List<BuildingKmlGeo> geos = new ArrayList<>();
File file = new File(filePath);
ZipFile zipFile = new ZipFile(file);
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(file));
InputStream inputStream;
ZipEntry entry = zipFile.getEntry("_doc.kml");
inputStream = zipFile.getInputStream(entry);
Kml docKml = Kml.unmarshal(inputStream);
Feature feature = docKml.getFeature();
String name = zipFile.getName();
int startIndex = name.lastIndexOf("\\");
int endIndex = name.lastIndexOf(".");
String kmzFileName = name.substring(startIndex + 1, endIndex);
KmlDoc kmlDoc = new KmlDoc();
kmlDoc.setDocName(kmzFileName);
setKmlDoc(feature, kmlDoc);
ZipEntry linkHrefEntry = zipFile.getEntry(kmlDoc.getLink().getLinkHref());
inputStream = zipFile.getInputStream(linkHrefEntry);
Kml linkHrefKml = Kml.unmarshal(inputStream);
Feature linkHrefKmlFeature = linkHrefKml.getFeature();
KmlBuilding kmlBuilding = new KmlBuilding();
List<KmlNetworkLink> kmlNetworkLinks = new ArrayList<>();
setKmlBuilding(linkHrefKmlFeature, kmlNetworkLinks);
kmlBuilding.setNetworkLinks(kmlNetworkLinks);
List<String> entryNames = new ArrayList<>();
while ((entry = zipInputStream.getNextEntry()) != null) {
String zipEntryName = entry.getName();
entryNames.add(zipEntryName);
kmlNetworkLinks.forEach(kmlNetworkLink -> {
String entryName = getEntryName(kmlNetworkLink.getLinkHref(), entryNames);
ZipEntry zipEntry = zipFile.getEntry(entryName);
int i = entryName.lastIndexOf("/");
int endI = entryName.lastIndexOf(".");
String kmlFileName = entryName.substring(i + 1, endI);
InputStream kmlInputStream = null;
try {
kmlInputStream = zipFile.getInputStream(zipEntry);
} catch (IOException e) {
e.printStackTrace();
geos.addAll(parseKml(null, kmlInputStream, kmlFileName));
geos.forEach(geo -> geo.setKmzName(kmzFileName));
assert kmlInputStream != null;
try {
kmlInputStream.close();
} catch (IOException e) {
e.printStackTrace();
inputStream.close();
zipFile.close();
zipInputStream.close();
return geos;
private static String getEntryName(String entryName, List<String> absEntryNames){
return absEntryNames.stream().filter(item -> item.contains(entryName)).findFirst().get();
* 设置kmlBuilding
private static void setKmlBuilding(Feature feature, List<KmlNetworkLink> kmlNetworkLinks) {
if(feature != null){
if (feature instanceof Document) {
List<Feature> featureList = ((Document) feature).getFeature();
setKmlBuildingFeature(featureList, kmlNetworkLinks);
} else if (feature instanceof Folder) {
List<Feature> featureList = ((Folder) feature).getFeature();
setKmlBuildingFeature(featureList, kmlNetworkLinks);
private static void setKmlBuildingFeature(List<Feature> featureList, List<KmlNetworkLink> kmlNetworkLinks) {
featureList.forEach(documentFeature -> {
if (documentFeature instanceof NetworkLink) {
kmlNetworkLinks.add(setKmlBuildingNetworkLinkData((NetworkLink) documentFeature));
private static KmlNetworkLink setKmlBuildingNetworkLinkData(NetworkLink networkLink) {
String name = networkLink.getName();
Link link = networkLink.getLink();
String href = link.getHref();
KmlNetworkLink kmlNetworkLink = new KmlNetworkLink();
kmlNetworkLink.setNetworkName(name);
kmlNetworkLink.setLinkHref(href);
return kmlNetworkLink;
* 设置KmlDoc
private static void setKmlDoc(Feature feature, KmlDoc kmlDoc) {
if (feature != null) {
if (feature instanceof Document) {
List<Feature> featureList = ((Document) feature).getFeature();
setKmlDocFeature(feature, featureList, kmlDoc);
} else if (feature instanceof Folder) {
List<Feature> featureList = ((Folder) feature).getFeature();
setKmlDocFeature(feature, featureList, kmlDoc);
private static void setKmlDocFeature(Feature feature, List<Feature> featureList, KmlDoc kmlDoc) {
LookAt lookAt = (LookAt) feature.getAbstractView();
if(lookAt != null){
KmlLookAt kmlLookAt = new KmlLookAt();
BeanUtil.copyProperties(lookAt,kmlLookAt);
kmlDoc.setLook(kmlLookAt);
featureList.forEach(documentFeature -> {
if (documentFeature instanceof NetworkLink) {
NetworkLink networkLink = (NetworkLink) documentFeature;
String name = networkLink.getName();
Link link = networkLink.getLink();
String href = link.getHref();
KmlNetworkLink kmlNetworkLink = new KmlNetworkLink();
kmlNetworkLink.setNetworkName(name);
kmlNetworkLink.setLinkHref(href);
kmlDoc.setLink(kmlNetworkLink);
} else {
setKmlDoc(documentFeature, kmlDoc);
* 解析Kml文件
public static List<BuildingKmlGeo> parseKml(File file, InputStream inputStream, String kmlFileName) {
Kml kml;
if(file != null){
kml = Kml.unmarshal(file);
} else {
kml = Kml.unmarshal(inputStream);
Feature feature = kml.getFeature();
return parseFeature(feature, kmlFileName);
private static List<BuildingKmlGeo> parseFeature(Feature feature, String kmlFileName) {
if (feature != null) {
List<BuildingKmlGeo> geos = new ArrayList<>();
//判断根节点是否为Document
if (feature instanceof Document) {
List<Feature> featureList = ((Document) feature).getFeature();
//只解析folder->geo
featureList.forEach(documentFeature -> {
if (documentFeature instanceof Folder) {
geos.add(folderToGeoJson(documentFeature, kmlFileName));
return geos;
return null;
* folder -> geo
private static BuildingKmlGeo folderToGeoJson(Feature feature, String kmlFileName){
BuildingKmlGeo kmlGeo = new BuildingKmlGeo();
Folder folder = (Folder) feature;
String name = feature.getName();
List<Feature> folderFeature = folder.getFeature();
JSONObject result = new JSONObject();
result.put("type","FeatureCollection");
result.put("name", name);
JSONArray features = new JSONArray();
result.put("features", features);
folderFeature.forEach(item -> {
if (item instanceof Placemark) {
features.add(getPlaceMark((Placemark) item));
kmlGeo.setContent(result.toJSONString());
kmlGeo.setGeoName(name);
kmlGeo.setKmlName(kmlFileName);
return kmlGeo;
* 设置单个placeMark
private static JSONObject getPlaceMark(Placemark placemark) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("type","Feature");
JSONObject propertyJson = new JSONObject();
propertyJson.put("Name",placemark.getName());
propertyJson.put("description",placemark.getDescription());
jsonObject.put("properties", propertyJson);
JSONObject geometryJson = new JSONObject();
jsonObject.put("geometry", geometryJson);
Geometry geometry = placemark.getGeometry();
if (geometry != null) {
if (geometry instanceof Polygon) {
geometryJson.put("type","Polygon");
Polygon polygon = (Polygon) geometry;
Boundary outerBoundaryIs = polygon.getOuterBoundaryIs();
if (outerBoundaryIs != null) {
LinearRing linearRing = outerBoundaryIs.getLinearRing();
if (linearRing != null) {
List<Coordinate> coordinates = linearRing.getCoordinates();
if (coordinates != null) {
setCoordinates(coordinates, geometryJson);
} else if (geometry instanceof LineString) {
geometryJson.put("type","LineString");
LineString lineString = (LineString) geometry;
List<Coordinate> coordinates = lineString.getCoordinates();
if (coordinates != null) {
coordinates = ((LineString) geometry).getCoordinates();
setCoordinates(coordinates, geometryJson);
} else if (geometry instanceof Point) {
geometryJson.put("type","Point");
Point point = (Point) geometry;
List<Coordinate> coordinates = point.getCoordinates();
if (coordinates != null) {
coordinates = ((Point) geometry).getCoordinates();
setCoordinates(coordinates, geometryJson);
return jsonObject;
private static void setCoordinates(List<Coordinate> coordinates, JSONObject geometryJson) {
JSONArray array3 = new JSONArray();
JSONArray array2 = new JSONArray();
coordinates.forEach(coordinate -> {
JSONArray array1 = new JSONArray();
array1.add(coordinate.getLongitude());
array1.add(coordinate.getLatitude());
array1.add(coordinate.getAltitude());
array2.add(array1);
array3.add(array2);
geometryJson.put("coordinates", array3);
对应的使用到的vo对象有以下几个:
1.BuildingKmlGeo
@Data
@TableName(value = "building_kml_geo")
public class BuildingKmlGeo extends Model<BuildingKmlGeo> implements Serializable {
private static final long serialVersionUID = 4129983261567443938L;
private String id;
private String content;
private String geoName;
private String kmlName;
private String kmzName;
private String entryName;
public BuildingKmlGeo() {
this.id = UuidUtils.randomUUID();
@Override
protected Serializable pkVal() {
return this.id;
2.KmlBuilding
* Kmz文件里Kml文件的href的Kml文件对应的实体
* @author cheney
@Data
public class KmlBuilding {
private List<KmlNetworkLink> networkLinks;
3.KmlDoc
* _doc.kml文件对应的实体
* @author cheney
@Data
public class KmlDoc {
private String docId;
private String docName;
private String folderName;
private KmlNetworkLink link;
private KmlLookAt look;
4.KmlLookAt
* kml的LookAt对应的实体
* @author cheney
@Data
public class KmlLookAt {
private double longitude;
private double latitude;
private double altitude;
private double tilt;
private double range;
5.KmlNetworkLink
* kml文件的networkLink对应的实体
* @author cheney
@Data
public class KmlNetworkLink {
private String networkName;
private String linkHref;