2013-03-26 82 views
5

我想解析Java中的Kml文件。因爲我需要獲取地標的座標,在java中生成poligon並使用它。從Java中的KML文件中提取座標

但我的問題是,我正在使用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

回答

9

javadocsunofficial),您需要檢查 - 用instanceof - 每個Feature是否是Placemark,如果是投給它,並得到Geometry本身需要檢查它是否是Polygon,如果是的話就投給它。此後,路徑座標如下(就像它進來的KML文件):

getOuterBoundaryIs > getlinearRing > getCoordinates 

這裏是如何看起來像代碼:

@Test 
public void parseKml() { 
    String src = "misctests/stackoverflow/kml/labasa.kml"; 
    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(""); 
    } 
} 
+1

令人驚歎!它工作完美!我沒有看到Javadocs,:S(對不起!) 但我下載它,然後我會讀它。 我在Java中是「新」,有些東西我根本聽不懂,但是,我會閱讀這些jdoc,瞭解api;) 再次......謝謝! ! – Shudy 2013-03-26 14:11:43

+0

不客氣!我不得不說這是一個奇怪的API,因爲你必須投入一個'Feature'來查看它實際上是什麼,'instanceof'實際上是在'OOP'中的實踐,我猜那些人知道他們什麼時候應該處理什麼想要爲'kml'和kml'xml schema'製作一個API,強制他們這樣做。對你來說一個很好的幫助就是在調試器中查看一個特性來查看它裏面的內容。你還必須注意,在kml文檔中可能包含其他xml命名空間,例如'gs','xal'等......它們也記錄在javadoc中。 – A4L 2013-03-26 16:54:29

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>")); 
      } 
     } 
} 
0

感謝@ 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 
    }