2013-03-26 13 views
5

Próbuję parsować plik Kml w Javie. Bo muszę wziąć współrzędne oznaczenia miejsca, aby wygenerować poligon w java i użyć go.Wyodrębnij współrzędne z pliku KML w Javie

Ale mój problem polega na tym, że używam tej biblioteki, aby ją przetworzyć, i nie jestem w stanie wyodrębnić informacji, które chcę. (Przeczytałem "pomoc" na oficjalnej stronie, ale zrobiłem „t znaleziono żadnej pomocy przylegały mojego problemu)

Próbuję zrobić coś takiego:

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

Ale w tym momencie nie wiem, jak wydobyć współrzędne.

Plik próbuję analizować to jest jeden: la basa

Odpowiedz

9

Po javadocs (unofficial) trzeba sprawdzić - korzystając instanceof - każdy Feature czy jest to Placemark, jeśli tak oddanych do niego i uzyskać Geometry, który sam musi zostać sprawdzony, czy jest to Polygon, jeśli tak, to zostanie do niego rzucony. Po że droga do współrzędnych jest następujący (tak jak to się w plikach KML pliku):

getOuterBoundaryIs > getlinearRing > getCoordinates 

Oto jak to wygląda w kodzie:

@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

Amazing! działa idealnie! Nie widziałem Javadocs,: S (przepraszam!) Ale ja to ściągam, a ja to przeczytam. Jestem "nowy" w Javie i są rzeczy, których w ogóle nie rozumiem, ale przeczytam te jdoki, żeby zrozumieć api;) I znowu ...... DZIĘKI! !!! – Shudy

+0

Nie ma za co! Muszę powiedzieć, że to dziwne API, ponieważ musisz rzucić "Feature", aby zobaczyć, co to jest, 'instanceof' jest tak naprawdę podstawową praktyką w' OOP', myślę, że ci faceci wiedzą, z czym mają do czynienia, kiedy chciałem zrobić API dla 'kml', a schemat' xml 'kml zmusił ich do zrobienia tego w ten sposób. Dobrą pomocą dla Ciebie byłoby spojrzenie na Cechę w debugerze, aby zobaczyć, co w środku. Należy również zauważyć, że mogą istnieć inne przestrzenie xml zawarte w dokumencie kml, takie jak 'gs',' xal' i tak dalej ... Są one również dokumentowane w javadoc. – A4L

1

Natknąłem tym poście więc tutaj jest częścią kodu funkcji używanego w mojej aplikacji, aby wyodrębnić współrzędne miejsca znacznika Nazwa & z ciągu znaków 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

Dzięki @ A4L To naprawdę jest aktualizacja i bardziej groovier sposób robi to samo więc zmienione dla Groovy i próbuje także więcej typów niż podanym przykładzie, jak również kopie głęboko w warstwie dokumentu:

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