ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

五、地图、谷歌地球加载kml文件,java解析实现

2021-11-11 18:00:53  阅读:246  来源: 互联网

标签:java String kml List feature private import new 加载


使用:

<!-- 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;
}

 

标签:java,String,kml,List,feature,private,import,new,加载
来源: https://www.cnblogs.com/lin-bunny/p/15540983.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有