2013-03-26 21 views
5

Sto provando ad analizzare un file Kml in Java. Perché ho bisogno di prendere le coordinate di un segnaposto, di generare un poligono in java e usarlo.Estrai le coordinate dal file KML in Java

Ma il mio problema è che sto usando la libreria JAK per analizzarla, e non sono in grado di estrarre le informazioni che voglio. (Ho letto l'aiuto nella pagina ufficiale, ma non l'ho 't trovato alcun aiuto intestano il mio problema)

sto cercando di fare qualcosa di simile:

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

Ma in questo punto non so come estrarre le coordinate.

Il file che sto cercando di analizzare è questo: la basa

risposta

9

Dopo la javadocs (unofficial) è necessario verificare - con instanceof - ogni Feature se è un Placemark, se sì, cast e ottenere il Geometry che deve essere controllato se si tratta di un Polygon, se sì, eseguire il cast su di esso. Dopo che il percorso alle coordinate è la seguente (proprio come è venuto nel kml-file):

getOuterBoundaryIs > getlinearRing > getCoordinates 

Ecco come sembra in codice:

@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

Incredibile! funziona perfettamente! Non ho visto i Javadoc,: S (mi dispiace!) Ma io lo scarico e lo leggerò. Sono "nuovo" in Java, e ci sono cose che non capisco affatto, ma, leggerò questi jdocs, per capire l'API;) E ancora ...... GRAZIE! !!! – Shudy

+0

Prego! Devo dire che questa è un'API strana dato che devi lanciare un 'Feature' per vedere di cosa si tratta,' instanceof' è in pratica pratica in 'OOP', immagino che quei ragazzi sappiano cosa devono affrontare quando volevo creare un'API per 'kml' e lo' xml schema' di kml li obbligava a farlo in questo modo. Un buon aiuto per te, sarebbe quello di guardare una caratteristica nel debugger per vedere cosa c'è dentro. Inoltre, è necessario notare che possono esistere altri spazi dei nomi xml inclusi in un documento kml come 'gs',' xal' e così via ... Sono anche documentati in javadoc. – A4L

1

imbattuto in questo post, quindi ecco parte del codice di funzione che ho utilizzato nella mia app per estrarre le coordinate del nome del punto & da una stringa 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

Grazie @ A4L Questo è davvero un aggiornamento e un modo più groovier di fare lo stesso così cambiato per Groovy e tenta anche più tipi di l'esempio dato così scava in profondità all'interno di un livello documento:

/** 
    * 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 
    }