从Java中的KML文件中提取坐标
我正在尝试用Java解析Kml文件。 因为我需要获取地标的坐标,在java中生成一个poligon并使用它。
但我的问题是,我正在使用JAK这个库来解析它,而我无法提取我想要的信息。(我在官方页面中阅读了“帮助”,但我没有找到任何帮助解决我的问题)
我正在尝试做类似的事情:
final Kml kml = Kml.unmarshal(new File("C:/Users/A556520/Documents/Proyectos/GeoFencing/res/labasa.kml")); final Document document = (Document)kml.getFeature(); List listafeatures = document.getFeature();
但在这一点上我不知道如何提取坐标。
我试图解析的文件就是这个: la basa
在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 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 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(""); } }
看过这篇文章,所以这里是我在我的应用程序中使用的函数代码的一部分,用于从String kmlText中提取Place标记名称和坐标。
if (kmlText != null & kmlText.length() > 0) { // Change case of relevant tags to match our search string case kmlText = kmlText.replaceAll("(?i)", " ") .replaceAll("(?i) ", "") .replaceAll("(?i)", " ") .replaceAll("(?i) ", "") .replaceAll("(?i)", " ") .replaceAll("(?i) ", ""); // Get tag String[] kmlPlacemarks = kmlText.split(" "); if (kmlPlacemarks.length > 0) { for (Integer i = 0; i < kmlPlacemarks.length; i++) { // Add '' to the end - actually not necessary kmlPlacemarks[i] += ""; if (kmlPlacemarks[i].indexOf("") > -1) /* Trim front to start from ' ' Otherwise additional tags may be in between leading to parsing of incorrect values especially Name */ kmlPlacemarks[i] = kmlPlacemarks[i].substring(kmlPlacemarks[i].indexOf(" ")); } String tmpPlacemarkName; String tmpPlacemarkCoordinates; for (String kmlPlacemark: kmlPlacemarks) if ((kmlPlacemark.indexOf("") > -1 && kmlPlacemark.indexOf(" ") > -1) && (kmlPlacemark.indexOf("") > -1 && kmlPlacemark.indexOf(" ") > -1)) { tmpPlacemarkCoordinates = kmlPlacemark.substring(kmlPlacemark.indexOf("") + 13, kmlPlacemark.indexOf(" ")); tmpPlacemarkName = kmlPlacemark.substring(kmlPlacemark.indexOf("") + 6, kmlPlacemark.indexOf(" ")); } } }
谢谢@ 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 getFeatureList(List 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 coordinates = linearRing.getCoordinates(); if(coordinates != null) { for(Coordinate coordinate : coordinates) { results << parseCoordinate(coordinate); } } } } } else if (geometry instanceof LineString) { LineString lineString = (LineString) geometry; List 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 }