2013-03-26 5 views
5

J'essaye d'analyser un fichier Kml en Java. Parce que je dois prendre les coordonnées d'un repère, pour générer un poligon en Java, et l'utiliser.Extraire les coordonnées du fichier KML en Java

Mais mon problème, c'est que j'utilise JAK cette bibliothèque pour l'analyser, et je ne suis pas en mesure d'extraire l'information que je veux. (J'ai lu le "aide" dans la page officielle, mais je didn didn « t trouvé aucune aide buter mon problème)

Je suis en train de faire quelque chose comme ça:

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

Mais dans ce point, je ne sais pas comment extraire les coordonnées.

Le fichier que je suis en train d'analyser est celui-ci: la basa

Répondre

9

Après la javadocs (unofficial) vous devez vérifier - en utilisant instanceof - chaque Feature si est un Placemark, si oui CAST pour et obtenir le Geometry qui lui-même doit être vérifié s'il s'agit d'un Polygon, si oui, alors cast à lui. Après que le chemin aux coordonnées est la suivante (comme il vient dans le fichier kml):

getOuterBoundaryIs > getlinearRing > getCoordinates 

Voici comment il ressemble dans le code:

@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

Incroyable! ça marche parfait! Je n'ai pas vu les Javadocs,: S (désolé!) Mais je le télécharge, et je vais le lire. Je suis "nouveau" en Java, et il y a des choses que je ne comprends pas du tout, mais, je vais lire ces jdocs, pour comprendre l'API;) Et encore ...... MERCI! !!! – Shudy

+0

De rien! Je dois dire que c'est une API bizarre puisque vous devez lancer un 'Feature 'pour voir ce que c'est réellement,' instanceof' est en fait la pratique de base dans 'OOP', je suppose que ces gars savent ce qu'ils ont à faire quand ils voulait faire une API pour 'kml' et le schéma' xml' de kml les forçait à le faire de cette façon. Une bonne aide pour vous, serait de regarder une fonctionnalité dans le débogueur pour voir ce qu'il contient. Notez également que d'autres espaces de noms xml peuvent être inclus dans un document kml, tels que 'gs',' xal' et ainsi de suite ... Ils sont également documentés dans le javadoc. – A4L

1

suis tombé sur ce poste, donc voici une partie du code de fonction que j'ai utilisé dans mon application pour extraire les coordonnées de la marque de lieu & à partir d'un String 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

Merci @ A4L Ceci est vraiment une mise à jour et plus groovy façon de faire la même chose donc changé pour Groovy et tente également de plusieurs types que l'exemple donné que creuse un puits profond dans une couche de document:

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