从 Java 中的 KML 文件中提取坐标

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15636303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 20:21:05  来源:igfitidea点击:

Extract coordinates from KML file in Java

javaparsingcoordinateskmljak

提问by Shudy

I'm trying to parse a Kml file in Java. Cause I need to take the coordinates of a Placemark, to generate a poligon in java, and use it.

我正在尝试用 Java 解析 Kml 文件。因为我需要获取地标的坐标,在 java 中生成一个 poligon 并使用它。

But my problem , is that i'm using JAKthis library to parse it, and i'm not able to extract the information that i want.(I read the "help" in the official page, but I didn't found any help abut my problem)

但我的问题是,我使用JAK这个库来解析它,我无法提取我想要的信息。(我阅读了官方页面中的“帮助”,但我没有找到任何帮助解决我的问题)

I'm trying to do something like that:

我正在尝试做这样的事情:

final Kml kml = Kml.unmarshal(new File("C:/Users/A556520/Documents/Proyectos/GeoFencing/res/labasa.kml"));
final Document document = (Document)kml.getFeature();       
List<Feature> listafeatures = document.getFeature();        

But in this point I don't know how to extract the coordinates.

但在这一点上我不知道如何提取坐标。

The file I'm trying to parse is this one: la basa

我试图解析的文件是这个:la basa

回答by A4L

Following the javadocs(unofficial) you need to check - using instanceof- each Featurewhether is is a Placemark, if yes cast to it and get the Geometrywhich itself needs to be checked whether it is a Polygon, if yes then cast to it. After that the path to the coordinates is the following (just as it come in the kml-file):

遵循javadocs非官方),您需要检查 - 使用instanceof- 每个Feature是否是 a Placemark,如果是,则转换为它并获取Geometry本身需要检查它是否为 a Polygon,如果是,则转换为它。之后,坐标路径如下(就像它在 kml 文件中一样):

getOuterBoundaryIs > getlinearRing > getCoordinates

Here is how it looks like in code:

这是它在代码中的样子:

@Test
public void parseKml() {
    String src = "misctests/stackoverflow/kml/labasa.kml";
    try(InputStream is = getClass().getClassLoader().getResourceAsStream(src)) {
        Assert.assertNotNull(is);
        Kml kml = Kml.unmarshal(is);
        Feature feature = kml.getFeature();
        parseFeature(feature);
    }
}

private void parseFeature(Feature feature) {
    if(feature != null) {
        if(feature instanceof Document) {
            Document document = (Document) feature;
            List<Feature> featureList = document.getFeature();
            for(Feature documentFeature : featureList) {
                if(documentFeature instanceof Placemark) {
                    Placemark placemark = (Placemark) documentFeature;
                    Geometry geometry = placemark.getGeometry();
                    parseGeometry(geometry);
                }
            }
        }
    }
}

private void parseGeometry(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) {
                        for(Coordinate coordinate : coordinates) {
                            parseCoordinate(coordinate);
                        }
                    }
                }
            }
        }
    }
}

private void parseCoordinate(Coordinate coordinate) {
    if(coordinate != null) {
        System.out.println("Longitude: " +  coordinate.getLongitude());
        System.out.println("Latitude : " +  coordinate.getLatitude());
        System.out.println("Altitude : " +  coordinate.getAltitude());
        System.out.println("");
    }
}

回答by Parameshwar

With respect to A4L answer , thank you so much while i have added some more extraction methods which will get data from folder and document with point line and polygon extraction with spring MVC using javaapi4kml using package

关于 A4L 答案,非常感谢您,同时我添加了更多提取方法,这些方法将使用 javaapi4kml 使用包从带有点线和多边形提取的 Spring MVC 文件夹和文档中获取数据

<dependency>
<groupId>de.micromata.jak</groupId>
<artifactId>JavaAPIforKml</artifactId>
<version>2.2.0</version>
</dependency> 

@RequestMapping(value = "/testKml", method = RequestMethod.POST)
public Map<String, Object> parseKml(@RequestBody Map<String, Object> data){
    Map<String, Object> response = new HashMap<String, Object>();
    List<Map<String, Object>> wktObjrow = new ArrayList<Map<String, Object>>();
    String src = data.get("kmlfile").toString();
    try {
        URL url;
        url = new URL(src);
        URLConnection conn = url.openConnection();
        InputStream is = url.openStream();
        Assert.notNull(is);
        Kml kml = Kml.unmarshal(is);
        Feature feature = kml.getFeature();
        Map<String, Object> geodata = new HashMap<String, Object>();

        if(feature != null) {
            if(feature instanceof Document) {
                Document document = (Document) feature;
                List<Feature> featureList = document.getFeature();
                for(Feature documentFeature : featureList) {
                    if(documentFeature instanceof Placemark) {
                        geodata = new HashMap<String, Object>();
                        Placemark placemark = (Placemark) documentFeature;
                        Geometry geometry = placemark.getGeometry();
                        geodata = parseGeometry(geometry, documentFeature.getName().toString());
                        if(!geodata.isEmpty())
                        {
                            wktObjrow.add(geodata);
                        }
                    }
                    else if(documentFeature instanceof Folder) 
                    {
                        Folder folder = (Folder) documentFeature;
                        List<Feature> folderfeaturList = folder.getFeature();
                        for(Feature folderfeature : folderfeaturList) 
                        {
                            geodata = new HashMap<String, Object>();
                            if(folderfeature instanceof Placemark) {
                                Placemark placemark = (Placemark) folderfeature;
                                Geometry geometry = placemark.getGeometry();
                                //push each of return store in list
                                geodata = parseGeometry(geometry, placemark.getName().toString());
                                if(!geodata.isEmpty())
                                {
                                    wktObjrow.add(geodata);
                                }
                            }
                            else
                            {
                                System.err.println("folderfeatures was not of type Placemark"); 
                            }
                        }
                    }
                    else
                    {
                        System.err.println("Was not instance of Placemark or Folder");
                    }
                }
                System.out.println("wktObjrow : "+wktObjrow);
            }
            else
            {
                System.err.println("instance of feature was Not Document");
                if(feature instanceof Folder) {
                    Folder folder = (Folder) feature;
                    List<Feature> featureList = folder.getFeature();

                    geodata = new HashMap<String, Object>();

                    for(Feature documentFeature : featureList) {

                        if(documentFeature instanceof Placemark) {
                            Placemark placemark = (Placemark) documentFeature;
                            Geometry geometry = placemark.getGeometry();
                            if(documentFeature.getName().toString().length() > 0)
                            {
                                geodata =  parseGeometry(geometry, documentFeature.getName().toString());
                                if(!geodata.isEmpty())
                                {
                                    wktObjrow.add(geodata);
                                }
                            }
                            else 
                            {
                                geodata = parseGeometry(geometry, placemark.getName().toString());
                                if(!geodata.isEmpty())
                                {
                                    wktObjrow.add(geodata);
                                }
                            }

                        }else
                        {
                            System.err.println("Was not instance of Placemark");
                        }
                    }
                    System.out.println("wktObjrow : "+wktObjrow);

                }
            }
        }
        else
        {
            System.err.println("Feature was null");
            response.put("Null", "Feature was null");
        }
    }
    catch (Exception e) {
        // TODO: handle exception
        System.err.println("Exception @ : "+ e);
    }

    if(!wktObjrow.isEmpty() && wktObjrow != null)
    {
        response.put("data", wktObjrow);
    }

    return response;
}

public Map<String, Object> parseGeometry(Geometry geometry,String name) {
    // <Point> <LinearRing> <Geometry> <Model> <LineString> <Polygon> <MultiGeometry>

    Map<String, Object> response = new HashMap<String, Object>();
    List<Map<String, Object>> wktObjrow = new ArrayList<Map<String, Object>>();

    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) {
                        Map<String, Object> map = new HashMap<String, Object>();
                        ArrayList<String> wkt_lonlat = new ArrayList<String>();
                        for(Coordinate coordinate : coordinates) {
                            wkt_lonlat.add(coordinate.getLongitude()+" "+coordinate.getLatitude());
                        }
                        response.put("name",name);
                        response.put("category","POLYGON");
                        response.put("row","POLYGON(("+String.join(",", wkt_lonlat)+"))");
                    }
                    else
                    {
                        System.err.println("coordinate was null");
                    }
                }
            }
        }
        else if(geometry instanceof Point)
        {
            Point point = (Point) geometry;
            List<Coordinate> coordinates = point.getCoordinates();
            if(coordinates != null  && !coordinates.isEmpty())
            {
                if(coordinates != null) {

                    for(Coordinate coordinate : coordinates) {
                        Map<String, Object> map = new HashMap<String, Object>();
                        response.put("lon",coordinate.getLongitude());
                        response.put("lat",coordinate.getLatitude());
                        response.put("name",name);
                        response.put("category","POINT");
                    }
                }
            }
        }
        else if(geometry instanceof LineString)
        {
            LineString line = (LineString) geometry;
            List<Coordinate> coordinates = line.getCoordinates();
            if(coordinates != null  && !coordinates.isEmpty())
            {
                if(coordinates != null) {
                    Map<String, Object> map = new HashMap<String, Object>();
                    ArrayList<String> wkt_lonlat = new ArrayList<String>();
                    for(Coordinate coordinate : coordinates) {
                        wkt_lonlat.add(coordinate.getLongitude()+" "+coordinate.getLatitude());
                    }
                    response.put("name",name);
                    response.put("category","LINESTRING");
                    response.put("row","LINESTRING("+String.join(",", wkt_lonlat)+")");
                }
            }
       }
       else if(geometry instanceof MultiGeometry)
       {

            MultiGeometry multigeometry = (MultiGeometry) geometry;
               for (int j = 0; j < multigeometry.getGeometry().size(); j++) {
                    if(multigeometry.getGeometry().get(j) instanceof LineString)
                    {
                        LineString line = (LineString) multigeometry.getGeometry().get(j);
                        List<Coordinate> coordinates = line.getCoordinates();
                        if(coordinates != null  && !coordinates.isEmpty())
                        {
                            if(coordinates != null) {
                                Map<String, Object> map = new HashMap<String, Object>();

                                ArrayList<String> wkt_lonlat = new ArrayList<String>();

                                for(Coordinate coordinate : coordinates) {
                                    wkt_lonlat.add(coordinate.getLongitude()+" "+coordinate.getLatitude());
                                }
                                response.put("name",name);
                                response.put("category","LINESTRING");
                                response.put("row","LINESTRING("+String.join(",", wkt_lonlat)+")");
                            }
                        }
                    }
                    else if(multigeometry.getGeometry().get(j) instanceof Point)
                    {
                        Point point = (Point) multigeometry.getGeometry().get(j);
                        List<Coordinate> coordinates = point.getCoordinates();
                           if(coordinates != null  && !coordinates.isEmpty())
                           {
                               if(coordinates != null) {
                                   for(Coordinate coordinate : coordinates) {
                                    Map<String, Object> map = new HashMap<String, Object>();
                                    response.put("lon",coordinate.getLongitude());
                                    response.put("lat",coordinate.getLatitude());
                                    response.put("name",name);
                                    response.put("category","POINT");
                                   }
                               }
                           }
                    }
                    else if(multigeometry.getGeometry().get(j) instanceof Polygon)
                    {
                        Polygon polygon = (Polygon) multigeometry.getGeometry().get(j);
                        Boundary outerBoundaryIs = polygon.getOuterBoundaryIs();
                        if(outerBoundaryIs != null) {
                            LinearRing linearRing = outerBoundaryIs.getLinearRing();
                            if(linearRing != null) {
                                List<Coordinate> coordinates = linearRing.getCoordinates();
                                if(coordinates != null) {

                                    Map<String, Object> map = new HashMap<String, Object>();

                                    ArrayList<String> wkt_lonlat = new ArrayList<String>();

                                    for(Coordinate coordinate : coordinates) {
                                        wkt_lonlat.add(coordinate.getLongitude()+" "+coordinate.getLatitude());
                                    }
                                    response.put("name",name);
                                    response.put("category","POLYGON");
                                    response.put("row","POLYGON(("+String.join(",", wkt_lonlat)+"))");
                                }
                                else
                                {
                                    System.err.println("coordinate was null");
                                }
                            }
                        }
                    }
               }

       }
    }
    else
    {
        System.err.println("geometry was null");
        response.put("Null", "geometry was null");
    }
    return response;
}

回答by Kanchu

Came across this post, so here is part of the code of function I have been using in my app to extract Place mark name & coordinates from a String kmlText.

看到这篇文章,所以这里是我在我的应用程序中使用的函数代码的一部分,用于从字符串 kmlText 中提取地标名称和坐标。

    if (kmlText != null & kmlText.length() > 0) {
    // Change case of relevant tags to match our search string case
    kmlText = kmlText.replaceAll("(?i)<Placemark>", "<Placemark>")
        .replaceAll("(?i)</Placemark>", "</Placemark>")
        .replaceAll("(?i)<name>", "<name>")
        .replaceAll("(?i)</name>", "</name>")
        .replaceAll("(?i)<coordinates>", "<coordinates>")
        .replaceAll("(?i)</coordinates>", "</coordinates>");
    // Get <Placemark> tag
    String[] kmlPlacemarks = kmlText.split("</Placemark>");
    if (kmlPlacemarks.length > 0) {
        for (Integer i = 0; i < kmlPlacemarks.length; i++) {
            // Add '</Placemark>' to the end - actually not necessary
            kmlPlacemarks[i] += "</Placemark>";
            if (kmlPlacemarks[i].indexOf("<Placemark>") > -1)
                /* Trim front to start from '<Placemark>'
                Otherwise additional tags may be in between leading
                to parsing of incorrect values especially Name */
                kmlPlacemarks[i] = kmlPlacemarks[i].substring(kmlPlacemarks[i].indexOf("<Placemark>"));
        }
        String tmpPlacemarkName;
        String tmpPlacemarkCoordinates;
        for (String kmlPlacemark: kmlPlacemarks)
            if ((kmlPlacemark.indexOf("<name>") > -1 && kmlPlacemark.indexOf("</name>") > -1) &&
                    (kmlPlacemark.indexOf("<coordinates>") > -1 && kmlPlacemark.indexOf("</coordinates>") > -1)) {
                tmpPlacemarkCoordinates = kmlPlacemark.substring(kmlPlacemark.indexOf("<coordinates>") + 13, kmlPlacemark.indexOf("</coordinates>"));
                tmpPlacemarkName = kmlPlacemark.substring(kmlPlacemark.indexOf("<name>") + 6, kmlPlacemark.indexOf("</name>"));
            }
        }
}

回答by V H

Thanks @A4L This is really an update and a more groovier way of doing the same So changed for Groovy and also attempts more types than the example given as well digs deep within a document layer:

谢谢@A4L 这真的是一个更新,也是一种更优雅的方式来做同样的事情所以对 Groovy 进行了更改,并且还尝试了比给出的示例更多的类型以及深入文档层的挖掘:

 /**
     * This starts the process and reads in the uk file
     */
    public static void parseKml() {
        def src = ServletContextHolder.servletContext.getRealPath("/KML/doc.kml")
        InputStream is = new FileInputStream(src);
        Kml kml = Kml.unmarshal(is);
        Feature feature = kml.getFeature();
        parseFeature(feature);
    }

    /**
     * This is step 2 of the process it figures out if it has a direct placemark mapping on kml
     * or if this is part of some big folder structure
     * @param feature
     */
    public static void parseFeature(Feature feature) {
        if(feature) {
            if(feature instanceof Document) {
                feature?.feature?.each { documentFeature->
                    if(documentFeature instanceof Placemark) {
                        getPlacemark((Placemark) documentFeature)
                    } else if (documentFeature instanceof Folder) {
                        getFeatureList(documentFeature.feature)
                    }
                }
            }
        }
    }


    /**
     * This iterates over itself over and over again to gain access to placemarks within folders
     * The uk map boundary was nested folders within folders
     * @param features
     * @return
     */
    public static List<Feature> getFeatureList(List<Feature> features) {
        features?.each { Feature  f ->
            if (f instanceof Folder) {
                getFeatureList(f.getFeature())
            } else if (f instanceof Placemark) {
                getPlacemark((Placemark) f)
            }
        }
    }

    /**
     * This in short kicks off looking at a placemark it's name then parsing through each of its geometry points
     * This controls the listener content or should I say builds it up from within this helper
     * @param placemark
     */
    public static void getPlacemark(Placemark placemark) {
        Geometry geometry = placemark.getGeometry()
        List results = parseGeometry(geometry)
        GeoMapListener.update(placemark.name, results)
    }


    private static List parseGeometry(Geometry geometry) {
        List results=[]
        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) {
                            for(Coordinate coordinate : coordinates) {
                                results << parseCoordinate(coordinate);
                            }
                        }
                    }
                }
            } else  if (geometry instanceof LineString) {
                LineString lineString = (LineString) geometry;
                List<Coordinate> coordinates = lineString.getCoordinates();
                if (coordinates != null) {
                    for (Coordinate coordinate : coordinates) {
                        results <<  parseCoordinate(coordinate);
                    }
                }
            }
        }
        return results
    }

    private static Map parseCoordinate(Coordinate coordinate) {
        Map results=[:]
        if(coordinate) {
            results.longitude= coordinate.longitude
            results.latitude= coordinate.latitude
            results.altitude= coordinate.altitude
        }
        return results
    }