diff --git a/src/eu/simstadt/lowlevelgmlparser/BuildingXmlNode.java b/src/eu/simstadt/lowlevelgmlparser/BuildingXmlNode.java index 973867bf55cd13e54dacdbcb3c00d72171da1b85..791cc7197720dcfdb80cb2808581e87d64e14054 100644 --- a/src/eu/simstadt/lowlevelgmlparser/BuildingXmlNode.java +++ b/src/eu/simstadt/lowlevelgmlparser/BuildingXmlNode.java @@ -21,7 +21,7 @@ public BuildingXmlNode(VTDNav navigator, int buildingOffset, int buildingLength) { this.navigator = navigator; - this.coordinatesFinder = new AutoPilot(navigator); //COULD BE STATIC? + this.coordinatesFinder = new AutoPilot(navigator); this.buildingLength = buildingLength; this.buildingOffset = buildingOffset; } diff --git a/src/eu/simstadt/lowlevelgmlparser/CityGmlIterator.java b/src/eu/simstadt/lowlevelgmlparser/CityGmlIterator.java index 8c46ca11918ae9ab1918353b81e3d7d23fc5607b..d38f75c7a94c00b79d4fa4c6f2d3b4537981e81d 100644 --- a/src/eu/simstadt/lowlevelgmlparser/CityGmlIterator.java +++ b/src/eu/simstadt/lowlevelgmlparser/CityGmlIterator.java @@ -1,6 +1,7 @@ package eu.simstadt.lowlevelgmlparser; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.util.Iterator; import java.util.logging.Logger; @@ -20,12 +21,21 @@ public class CityGmlIterator implements Iterable<BuildingXmlNode> private AutoPilot buildingsFinder; private VTDNav navigator; private long offsetAndLength; - private int buildingsCount = 0; private int buildingOffset = 0; private int buildingLength = 0; + private Path citygmlPath; + /* + * Simple class to parse a CityGML and extract cityObjectMember XML nodes and their coordinates. Since the + * coordinates are extracted for RegionChooser, it's okay to not be perfectly robust, but it should be fast and not + * use much memory. + * + * Based on VTD XML, it provides a Building iterator. + * + */ public CityGmlIterator(Path citygmlPath) throws XPathParseException, NavException, NumberFormatException, XPathEvalException, IOException { + this.citygmlPath = citygmlPath; VTDGen parser = new VTDGen(); parser.parseFile(citygmlPath.toString(), false); this.navigator = parser.getNav(); @@ -41,22 +51,22 @@ public Iterator<BuildingXmlNode> iterator() { public boolean hasNext() { try { return buildingsFinder.evalXPath() != -1; - } catch (XPathEvalException | NavException ex) {} - return false; + } catch (XPathEvalException | NavException ex) { + LOGGER.warning("Error while parsing " + citygmlPath); + return false; + } } @Override public BuildingXmlNode next() { try { - buildingsCount += 1; - if (buildingsCount % 1000 == 0) { - LOGGER.info("1000 buildings parsed"); - } offsetAndLength = navigator.getElementFragment(); buildingOffset = (int) offsetAndLength; buildingLength = (int) (offsetAndLength >> 32); return new BuildingXmlNode(navigator, buildingOffset, buildingLength); - } catch (NavException ex) {} + } catch (NavException ex) { + LOGGER.warning("Error while parsing " + citygmlPath); + } return null; } @@ -68,4 +78,14 @@ public void remove() { return it; } + public String getHeader() throws NavException { + return navigator.toRawString(0, buildingOffset); + } + + public Object getFooter() throws IOException, NavException { + int footerOffset = buildingOffset + buildingLength; + int footerLength = (int) (Files.size(citygmlPath) - footerOffset); + return navigator.toRawString(footerOffset, footerLength); + } + } diff --git a/src/eu/simstadt/regionchooser/RegionExtractor.java b/src/eu/simstadt/regionchooser/RegionExtractor.java index 29912ca36a900ca06706b1fa784bfc617dc68ba4..1bff19fcdd8a9de814ceb142f9f5c4fd40d0d7d1 100644 --- a/src/eu/simstadt/regionchooser/RegionExtractor.java +++ b/src/eu/simstadt/regionchooser/RegionExtractor.java @@ -33,21 +33,22 @@ static public StringBuffer selectRegionDirectlyFromCityGML(Path citygmlPath, Str CityGmlIterator citygml = new CityGmlIterator(citygmlPath); for (BuildingXmlNode buildingXmlNode : citygml) { - buildingsCount += 1; - if (buildingsCount % 1000 == 0) { - LOGGER.info("1000 buildings parsed"); + if (buildingsCount == 0) { + sb.append(citygml.getHeader()); } + buildingsCount += 1; Point point = buildingXmlNode.getCenterOfMass(); if (point.within(poly)) { foundBuildingsCount++; sb.append(buildingXmlNode.toString()); } + if (buildingsCount % 1000 == 0) { + LOGGER.info("1000 buildings parsed"); + } } LOGGER.info("Buildings found in selected region " + foundBuildingsCount); - // int footerOffset = buildingOffset + buildingLength; - // int footerLength = (int) (Files.size(citygmlPath) - footerOffset); - // sb.append(navigator.toRawString(footerOffset, footerLength)); + sb.append(citygml.getFooter()); return sb; }