diff --git a/src/eu/simstadt/lowlevelgmlparser/BuildingXmlNode.java b/src/eu/simstadt/lowlevelgmlparser/BuildingXmlNode.java index ecbd58c522d0c709db6fbb412fc1f1d2797586c6..973867bf55cd13e54dacdbcb3c00d72171da1b85 100644 --- a/src/eu/simstadt/lowlevelgmlparser/BuildingXmlNode.java +++ b/src/eu/simstadt/lowlevelgmlparser/BuildingXmlNode.java @@ -1,8 +1,13 @@ package eu.simstadt.lowlevelgmlparser; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.Point; import com.ximpleware.AutoPilot; import com.ximpleware.NavException; import com.ximpleware.VTDNav; +import com.ximpleware.XPathEvalException; +import com.ximpleware.XPathParseException; public class BuildingXmlNode @@ -12,6 +17,7 @@ private int buildingLength; private VTDNav navigator; private AutoPilot coordinatesFinder; + private static final GeometryFactory gf = new GeometryFactory(); public BuildingXmlNode(VTDNav navigator, int buildingOffset, int buildingLength) { this.navigator = navigator; @@ -20,6 +26,31 @@ public BuildingXmlNode(VTDNav navigator, int buildingOffset, int buildingLength) this.buildingOffset = buildingOffset; } + public Point getCenterOfMass() throws XPathParseException, NumberFormatException, XPathEvalException, NavException { + int coordinatesCount = 0; + double xTotal = 0; + double yTotal = 0; + + coordinatesFinder.selectXPath(".//posList"); + while (coordinatesFinder.evalXPath() != -1) { + long offsetAndLength = navigator.getContentFragment(); + int coordinatesOffset = (int) offsetAndLength; + int coordinatesLength = (int) (offsetAndLength >> 32); + String posList = navigator.toRawString(coordinatesOffset, coordinatesLength); + String[] coordinates = posList.split(" "); + for (int k = 0; k < coordinates.length; k = k + 3) { + coordinatesCount++; + xTotal += Double.valueOf(coordinates[k]); + yTotal += Double.valueOf(coordinates[k + 1]); + } + } + + double x = xTotal / coordinatesCount; + double y = yTotal / coordinatesCount; + Coordinate coord = new Coordinate(x, y); + return gf.createPoint(coord); + } + public String toString() { try { return navigator.toRawString(buildingOffset, buildingLength); diff --git a/src/eu/simstadt/lowlevelgmlparser/CityGmlIterator.java b/src/eu/simstadt/lowlevelgmlparser/CityGmlIterator.java index 599ba052cac18f8af74dec79c3ae5696e7677b7a..8c46ca11918ae9ab1918353b81e3d7d23fc5607b 100644 --- a/src/eu/simstadt/lowlevelgmlparser/CityGmlIterator.java +++ b/src/eu/simstadt/lowlevelgmlparser/CityGmlIterator.java @@ -12,7 +12,7 @@ import com.ximpleware.XPathParseException; -public class CityGmlIterator implements Iterable<String> +public class CityGmlIterator implements Iterable<BuildingXmlNode> { private static final Logger LOGGER = Logger.getLogger(CityGmlIterator.class.getName()); @@ -34,8 +34,8 @@ public CityGmlIterator(Path citygmlPath) } @Override - public Iterator<String> iterator() { - Iterator<String> it = new Iterator<String>() { + public Iterator<BuildingXmlNode> iterator() { + Iterator<BuildingXmlNode> it = new Iterator<BuildingXmlNode>() { @Override public boolean hasNext() { @@ -46,7 +46,7 @@ public boolean hasNext() { } @Override - public String next() { + public BuildingXmlNode next() { try { buildingsCount += 1; if (buildingsCount % 1000 == 0) { @@ -55,8 +55,7 @@ public String next() { offsetAndLength = navigator.getElementFragment(); buildingOffset = (int) offsetAndLength; buildingLength = (int) (offsetAndLength >> 32); - BuildingXmlNode b = new BuildingXmlNode(navigator, buildingOffset, buildingLength); - return b.toString(); + return new BuildingXmlNode(navigator, buildingOffset, buildingLength); } catch (NavException ex) {} return null; } diff --git a/src/eu/simstadt/regionchooser/RegionExtractor.java b/src/eu/simstadt/regionchooser/RegionExtractor.java index 33e3e64783b11443982351d3b842003465585911..29912ca36a900ca06706b1fa784bfc617dc68ba4 100644 --- a/src/eu/simstadt/regionchooser/RegionExtractor.java +++ b/src/eu/simstadt/regionchooser/RegionExtractor.java @@ -1,23 +1,18 @@ package eu.simstadt.regionchooser; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import java.util.logging.Logger; import javax.xml.stream.XMLStreamException; import org.xml.sax.SAXParseException; -import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; -import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.io.ParseException; import com.vividsolutions.jts.io.WKTReader; -import com.ximpleware.AutoPilot; import com.ximpleware.NavException; -import com.ximpleware.VTDGen; -import com.ximpleware.VTDNav; import com.ximpleware.XPathEvalException; import com.ximpleware.XPathParseException; +import eu.simstadt.lowlevelgmlparser.BuildingXmlNode; import eu.simstadt.lowlevelgmlparser.CityGmlIterator; @@ -31,77 +26,29 @@ static public StringBuffer selectRegionDirectlyFromCityGML(Path citygmlPath, Str throws SAXParseException, XMLStreamException, ParseException, XPathParseException, NavException, NumberFormatException, XPathEvalException, IOException { - CityGmlIterator citygml = new CityGmlIterator(citygmlPath); - - for (String lowLevelBuildingXML : citygml) { - System.out.println(lowLevelBuildingXML.length()); - } - - Geometry poly = wktReader.read(wktPolygon); - final GeometryFactory gf = new GeometryFactory(); - StringBuffer sb = new StringBuffer(); - - int foundBuildingsCount = 0; int buildingsCount = 0; - long offsetAndLength; - int buildingOffset = 0; - int buildingLength = 0; - int coordinatesOffset = 0; - int coordinatesLength = 0; - VTDGen parser = new VTDGen(); - if (parser.parseFile(citygmlPath.toString(), false)) { - - VTDNav navigator = parser.getNav(); - AutoPilot buildingsFinder = new AutoPilot(navigator); - buildingsFinder.selectXPath("//cityObjectMember"); - while ((buildingsFinder.evalXPath()) != -1) { - AutoPilot coordinatesFinder = new AutoPilot(navigator); - coordinatesFinder.selectXPath(".//posList"); - offsetAndLength = navigator.getElementFragment(); - buildingOffset = (int) offsetAndLength; - buildingLength = (int) (offsetAndLength >> 32); - String cityObject = navigator.toRawString(buildingOffset, buildingLength); - // Add header - if (buildingsCount == 0) { - sb.append(navigator.toRawString(0, buildingOffset)); - } - buildingsCount += 1; - if (buildingsCount % 1000 == 0) { - LOGGER.info("1000 buildings parsed"); - } - - int coordinatesCount = 0; - double xTotal = 0; - double yTotal = 0; - - while (coordinatesFinder.evalXPath() != -1) { - offsetAndLength = navigator.getContentFragment(); - coordinatesOffset = (int) offsetAndLength; - coordinatesLength = (int) (offsetAndLength >> 32); - String posList = navigator.toRawString(coordinatesOffset, coordinatesLength); - String[] coordinates = posList.split(" "); - for (int k = 0; k < coordinates.length; k = k + 3) { - coordinatesCount++; - xTotal += Double.valueOf(coordinates[k]); - yTotal += Double.valueOf(coordinates[k + 1]); - } - } + int foundBuildingsCount = 0; + StringBuffer sb = new StringBuffer(); + Geometry poly = wktReader.read(wktPolygon); - double x = xTotal / coordinatesCount; - double y = yTotal / coordinatesCount; - Coordinate coord = new Coordinate(x, y); - Point point = gf.createPoint(coord); - if (point.within(poly)) { - foundBuildingsCount++; - sb.append(cityObject); - } + CityGmlIterator citygml = new CityGmlIterator(citygmlPath); + for (BuildingXmlNode buildingXmlNode : citygml) { + buildingsCount += 1; + if (buildingsCount % 1000 == 0) { + LOGGER.info("1000 buildings parsed"); + } + Point point = buildingXmlNode.getCenterOfMass(); + if (point.within(poly)) { + foundBuildingsCount++; + sb.append(buildingXmlNode.toString()); } - 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)); } + 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)); + return sb; } }