Java解析KML文件

KML(Keyhole Markup Language,Keyhole 标记语言)最初是由Google 旗下的Keyhole 公司开发和维护的一种基于XML 的标记语言,利用XML 语法格式描述地理空间数据(如点、线、面、多边形和模型等),适合网络环境下的地理信息协作与共享。

解决方案:获取到kml文件的根节点(kml),接下来获取第二级节点这里的情况目前看来只有两种节点(Document或Folder),接下来的情况就比较多了,可以为以上两种及PlaceMark以及其他的一些用户坐标点修饰的样式节点(style),其中PlaceMark节点,依次去解析这些节点下的子节点就可以获取到你所需的信息。

java解析kml文件只要使用了JAK(Java API For KML) 。JAK包可以通过https://github.com/yzjxiaoyue/JavaParseKMLForJAK/raw/master/lib/JavaAPIforKml-2.2.0.jar获取。

点:
 

import de.micromata.opengis.kml.v_2_2_0.Coordinate;
 
import java.util.List;
 
public class KmlPoint {
    private List<Coordinate> points;
    private String name;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public List<Coordinate> getPoints() {
        return points;
    }
 
    public void setPoints(List<Coordinate> points) {
        this.points = points;
    }
}

线:

import de.micromata.opengis.kml.v_2_2_0.Coordinate;
 
import java.util.List;
 
public class KmlLine {
    private List<Coordinate> points;
    private String name;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public List<Coordinate> getPoints() {
        return points;
    }
 
    public void setPoints(List<Coordinate> points) {
        this.points = points;
    }
}

面:

import de.micromata.opengis.kml.v_2_2_0.Coordinate;
 
import java.util.List;
 
/**
 * @program: ParseKMLForJava
 * @description:
 * @author: Mr.Yue
 * @create: 2018-12-04 21:12
 **/
public class KmlPolygon {
    private List<Coordinate> points;
    private String name;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public List<Coordinate> getPoints() {
        return points;
    }
 
    public void setPoints(List<Coordinate> points) {
        this.points = points;
    }
}

 封装类KmlProperty :用于获取点线面。

import java.util.List;
 
class KmlProperty {
    private List<KmlPoint> kmlPoints;
    private List<KmlLine> kmlLines;
    private List<KmlPolygon> kmlPolygons;
 
    public List<KmlPoint> getKmlPoints() {
        return kmlPoints;
    }
 
    public void setKmlPoints(List<KmlPoint> kmlPoints) {
        this.kmlPoints = kmlPoints;
    }
 
    public List<KmlLine> getKmlLines() {
        return kmlLines;
    }
 
    public void setKmlLines(List<KmlLine> kmlLines) {
        this.kmlLines = kmlLines;
    }
 
    public List<KmlPolygon> getKmlPolygons() {
        return kmlPolygons;
    }
 
    public void setKmlPolygons(List<KmlPolygon> kmlPolygons) {
        this.kmlPolygons = kmlPolygons;
    }
}

KML文件解析方法:

import de.micromata.opengis.kml.v_2_2_0.*;
 
import java.io.File;
import java.util.ArrayList;
import java.util.List;
 
/**
 * @program: my_project
 * @description: KML文件解析:先获取kml文件的根节点,依次遍历当前节点的子节点的信息,
 * 如果遇到节点属于Folder、Document则继续解析其子节点;反之则解析PlaceMark节点(主要解析LineString、Point、Polygon)。
 * @author: Yue
 * @create: 2018-12-01 12:39
 **/
public class ParsingKmlUtil {
    //以下三行都是自定义的KML类,用于获取名称name、所有点points、样式颜色color
    private List<KmlPoint> kmlPointList = new ArrayList<>();
    private List<KmlLine> kmlLineList = new ArrayList<>();
    private List<KmlPolygon> kmlPolygonList = new ArrayList<>();
    private KmlProperty kmlProperty = new KmlProperty();
 
    /**
     * 保存kml数据到临时表
     *
     * @param file 上传的文件实体
     * @return 自定义的KML文件实体
     */
    public KmlProperty parseKmlForJAK(File file) {
        Kml kml = Kml.unmarshal(file);
        Feature feature = kml.getFeature();
        parseFeature(feature);
        kmlProperty.setKmlPoints(kmlPointList);
        kmlProperty.setKmlLines(kmlLineList);
        kmlProperty.setKmlPolygons(kmlPolygonList);
        return kmlProperty;
    }
 
    /**
     * 解析kml节点信息
     *
     * @param feature 需要解析到要素信息
     * @return
     */
    private void parseFeature(Feature feature) {
        if (feature != null) {
            //判断根节点是否为Document
            if (feature instanceof Document) {
                List<Feature> featureList = ((Document) feature).getFeature();
                //遍历已获取的节点信息(节点信息为List),将list使用forEach进行遍历(同for、while)
                featureList.forEach(documentFeature -> {
                            //判断遍历节点是否为PlaceMark,否则迭代解析
                            if (documentFeature instanceof Placemark) {
                                getPlaceMark((Placemark) documentFeature);
                            } else {
                                parseFeature(documentFeature);
                            }
                        }
                );
            } else if (feature instanceof Folder) {
                //原理同上
                List<Feature> featureList = ((Folder) feature).getFeature();
                featureList.forEach(documentFeature -> {
                            if (documentFeature instanceof Placemark) {
                                getPlaceMark((Placemark) documentFeature);
                            }
                            {
                                parseFeature(documentFeature);
                            }
                        }
                );
            }
        }
    }
 
    /**
     * 解析PlaceMark节点下的信息
     *
     * @return
     */
    private void getPlaceMark(Placemark placemark) {
        Geometry geometry = placemark.getGeometry();
        String name = placemark.getName();
        parseGeometry(name, geometry);
    }
 
    /**
     * 解析PlaceMark节点下的信息
     *
     * @return
     */
    private void parseGeometry(String name, Geometry geometry) {
        if (geometry != null) {
            if (geometry instanceof 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) {
                            outerBoundaryIs = ((Polygon) geometry).getOuterBoundaryIs();
                            addPolygonToList(kmlPolygonList, name, outerBoundaryIs);
                        }
                    }
                }
            } else if (geometry instanceof LineString) {
                LineString lineString = (LineString) geometry;
                List<Coordinate> coordinates = lineString.getCoordinates();
                if (coordinates != null) {
                    coordinates = ((LineString) geometry).getCoordinates();
                    addLineStringToList(kmlLineList, coordinates, name);
                }
            } else if (geometry instanceof Point) {
                Point point = (Point) geometry;
                List<Coordinate> coordinates = point.getCoordinates();
                if (coordinates != null) {
                    coordinates = ((Point) geometry).getCoordinates();
                    addPointToList(kmlPointList, coordinates, name);
                }
            } else if (geometry instanceof MultiGeometry) {
                List<Geometry> geometries = ((MultiGeometry) geometry).getGeometry();
                for (Geometry geometryToMult : geometries) {
                    Boundary outerBoundaryIs;
                    List<Coordinate> coordinates;
                    if (geometryToMult instanceof Point) {
                        coordinates = ((Point) geometryToMult).getCoordinates();
                        addPointToList(kmlPointList, coordinates, name);
                    } else if (geometryToMult instanceof LineString) {
                        coordinates = ((LineString) geometryToMult).getCoordinates();
                        addLineStringToList(kmlLineList, coordinates, name);
                    } else if (geometryToMult instanceof Polygon) {
                        outerBoundaryIs = ((Polygon) geometryToMult).getOuterBoundaryIs();
                        addPolygonToList(kmlPolygonList, name, outerBoundaryIs);
                    }
                }
            }
        }
    }
 
    /**
     * 将kml中所有面添加到一个list
     *
     * @return
     */
    private void addPolygonToList(List<KmlPolygon> kmlPolygonList, String name, Boundary outerBoundaryIs) {
        LinearRing linearRing;
        List<Coordinate> coordinates;
        linearRing = outerBoundaryIs.getLinearRing();//面
        coordinates = linearRing.getCoordinates();
        KmlPolygon kmlPolygon = new KmlPolygon();
        kmlPolygon.setPoints(coordinates);
        kmlPolygon.setName(name);
        kmlPolygonList.add(kmlPolygon);
    }
 
    /**
     * 将kml中所有线添加到一个list
     *
     * @return
     */
    private void addLineStringToList(List<KmlLine> kmlLineList, List<Coordinate> coordinates, String name) {
        KmlLine kmlLine = new KmlLine();
        kmlLine.setPoints(coordinates);
        kmlLine.setName(name);
        kmlLineList.add(kmlLine);
    }
 
    /**
     * 将kml中所有点添加到一个list
     *
     * @return
     */
    private void addPointToList(List<KmlPoint> kmlPointList, List<Coordinate> coordinates, String name) {
        KmlPoint kmlPoint = new KmlPoint();
        kmlPoint.setName(name);
        kmlPoint.setPoints(coordinates);
        kmlPointList.add(kmlPoint);
    }
}

KML解析方法调用:

 
import java.io.File;
public class Main {
    public static void main(String[] args) {
        KmlProperty kmlProperty;
        ParsingKmlUtil parsingKmlUtil =new ParsingKmlUtil();
        File file = new File("src/point.kml");
        kmlProperty = parsingKmlUtil.parseKmlForJAK(file);
        assert kmlProperty != null;
 
        if (kmlProperty.getKmlPoints().size() > 0) {
            for (KmlPoint k : kmlProperty.getKmlPoints()) {
                System.out.println(k.getName());
            }
            System.out.println("点");
        }
        if (kmlProperty.getKmlLines().size() > 0) {
            for (KmlLine k : kmlProperty.getKmlLines()) {
                System.out.println(k.getName());
            }
            System.out.println("线");
        }
        if (kmlProperty.getKmlPoints().size() > 0) {
            for (KmlPoint k : kmlProperty.getKmlPoints()) {
                System.out.println(k.getPoints());
            }
            System.out.println("面");
        }
    }
}

 

项目源代码:https://github.com/yzjxiaoyue/JavaParseKMLForJAK

代码参考于:https://stackoverrun.com/cn/q/4243988#47576837,之前写的使用Groovy,经过理解和修改得到以上代码。

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android解析KML文件的步骤如下: 1. 创建SAXParserFactory实例。 2. 创建SAXParser实例。 3. 创建DefaultHandler的子类实例,覆盖startElement()、characters()、endElement()等方法。 4. 调用SAXParser的parse()方法,传入KML文件的InputStream和DefaultHandler实例,开始解析。 5. 在startElement()方法中,可以获取到每个标签的名称和属性值。 6. 在characters()方法中,可以获取到每个标签中的文本内容。 7. 在endElement()方法中,可以处理当前标签的子标签和属性值。 以下是一个简单的例子,演示如何解析KML文件: ```java public class KmlParser { public static void parse(InputStream inputStream) { try { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); DefaultHandler handler = new DefaultHandler() { boolean inCoordinates = false; public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("coordinates")) { inCoordinates = true; } } public void characters(char[] ch, int start, int length) throws SAXException { if (inCoordinates) { String coords = new String(ch, start, length); // 坐标处理逻辑 inCoordinates = false; } } }; parser.parse(inputStream, handler); } catch (Exception e) { e.printStackTrace(); } } } ``` 在上面的例子中,我们只处理了KML文件中的coordinates标签,读取其中的坐标信息。如果需要处理其他标签或属性,可以在DefaultHandler子类中覆盖相应的方法进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值