6

JavaでKmlファイルを解析しようとしています。原因Javaでポリゴンを生成し、それを使用するには、目印の座標を取得する必要があります。

しかし、私の問題は、このライブラリをJAKを使用して解析しているため、必要な情報を抽出できないことです(公式ページの「ヘルプ」を読みましたが、見つかりませんでした)。私の問題に取り組むのを手伝ってください)

私はそのようなことをしようとしています:

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();        

しかし、この時点では、座標を抽出する方法がわかりません。

私が解析しようとしているファイルはこれです:la basa

4

5 に答える 5

10

javadocs非公式)に続いて、チェックする必要があります-使用してinstanceof-それぞれFeatureがであるかどうかPlacemark、はいの場合はそれにキャストし、Geometryそれ自体がであるかどうかをチェックする必要があるPolygon場合は、はいの場合はそれにキャストします。その後、座標へのパスは次のようになります(kmlファイルにあるのと同じです)。

getOuterBoundaryIs > getlinearRing > getCoordinates

コードでは次のようになります。

@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("");
    }
}
于 2013-03-26T13:24:11.730 に答える
2

A4Lの回答に関しては、フォルダとドキュメントからデータを取得する抽出方法をいくつか追加しましたが、javaapi4kmlを使用してパッケージを使用してSpringMVCでポイントラインとポリゴンを抽出していただきありがとうございます。

<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;
}
于 2019-12-16T12:33:03.360 に答える
1

この投稿に出くわしたので、これは、文字列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>"));
            }
        }
}
于 2014-03-30T15:17:28.177 に答える
0

ありがとう@A4Lこれは実際には更新であり、同じことを行うためのよりグルーヴィーな方法です。グルーヴィー用に変更され、与えられた例よりも多くのタイプを試行し、ドキュメントレイヤー内を深く掘り下げます。

 /**
     * 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
    }
于 2017-11-30T15:22:06.090 に答える
0

上記の回答は、現在サポートされていないように見えるライブラリde.micromata.opengis.kmlを利用しています。新しいライブラリ、優れたKmlDocumentクラスを持つOSMボーナスパックがあります。これを使用して、以下のように座標を抽出しました。ポリゴンではなく、線(道路)のみを抽出しますが、変更可能である必要があります。

List<List<GeoPoint>> roads = new ArrayList<List<GeoPoint>>();

public void parseKmlDocument(KmlDocument doc) {
    int index = 0;
    for (KmlFeature kmlf: doc.mKmlRoot.mItems) {
        if ((kmlf instanceof KmlPlacemark))
        {
            KmlPlacemark placemark = (KmlPlacemark)kmlf;
            KmlGeometry kmlg = placemark.mGeometry;
            if (kmlg instanceof KmlMultiGeometry)
            {
                KmlMultiGeometry kmlmg = (KmlMultiGeometry)kmlg;
                for (KmlGeometry thisKmlg: kmlmg.mItems)
                {
                    ArrayList<GeoPoint> mCoordinates = thisKmlg.mCoordinates;
                    roads.add(index++, mCoordinates);

                }
            }
        }
        else {
                // kmlg is a LineString
                    ArrayList<GeoPoint> mCoordinates = kmlg.mCoordinates;
                    Road road = new Road(mCoordinates);
                    roads.add(road);
                    ++rIndex;
             
            }
    }
    // checking the result
    int road = 0 ;
    int gpoint = 0;
    for (List<GeoPoint> listGp: roads) {
        Log.d("road ", String.valueOf(road++));
        for (GeoPoint gp: listGp) {
            gpoint++;
            Log.d("    coords ",gp.getLatitude() + " " + gp.getLongitude());
        }
    }
    Log.d("Summary ",road + " roads containing " + gpoint + " geopoints");
}
于 2020-12-29T09:36:30.687 に答える