Commit c49391c1 authored by Eric Duminil's avatar Eric Duminil
Browse files

Allow Vegetation to be extracted too.

parent b2536456
......@@ -16,8 +16,8 @@
import com.ximpleware.NavException;
import com.ximpleware.XPathEvalException;
import com.ximpleware.XPathParseException;
import eu.simstadt.regionchooser.fast_xml_parser.BuildingXmlNode;
import eu.simstadt.regionchooser.fast_xml_parser.CityGmlIterator;
import eu.simstadt.regionchooser.fast_xml_parser.CityObjectMember;
public class RegionExtractor
......@@ -51,8 +51,9 @@
static int selectRegionDirectlyFromCityGML(String wktPolygon, String srsName, Writer sb,
Path... citygmlPaths) throws ParseException, XPathParseException, NavException, IOException {
int buildingsCount = 0;
int cityObjectsCount = 0;
int foundBuildingsCount = 0;
// int foundVegetationCount = 0;
Geometry poly = WKT_READER.read(wktPolygon);
CityGmlIterator citygml = null;
......@@ -61,11 +62,11 @@ static int selectRegionDirectlyFromCityGML(String wktPolygon, String srsName, Wr
LOGGER.info("Parsing " + citygmlPath);
//TODO: Allow citygmlPath for folders too, and iterate over gmls?
citygml = new CityGmlIterator(citygmlPath);
for (BuildingXmlNode buildingXmlNode : citygml) {
if (buildingsCount == 0) {
for (CityObjectMember buildingXmlNode : citygml) {
if (cityObjectsCount == 0) {
sb.append(replaceEnvelopeInHeader(citygml.getHeader(), poly.getEnvelopeInternal(), srsName));
}
buildingsCount += 1;
cityObjectsCount += 1;
if (buildingXmlNode.hasCoordinates()) {
Coordinate coord = new Coordinate(buildingXmlNode.x, buildingXmlNode.y);
Point point = GEOMETRY_FACTORY.createPoint(coord);
......@@ -74,7 +75,7 @@ static int selectRegionDirectlyFromCityGML(String wktPolygon, String srsName, Wr
sb.append(buildingXmlNode.toString());
}
}
if (buildingsCount % 1000 == 0) {
if (cityObjectsCount % 1000 == 0) {
LOGGER.info("1000 buildings parsed");
}
}
......
......@@ -13,7 +13,7 @@
import com.ximpleware.XPathParseException;
public class CityGmlIterator implements Iterable<BuildingXmlNode>
public class CityGmlIterator implements Iterable<CityObjectMember>
{
private static final Logger LOGGER = Logger.getLogger(CityGmlIterator.class.getName());
......@@ -42,12 +42,12 @@ public CityGmlIterator(Path citygmlPath) throws XPathParseException {
parser.parseFile(citygmlPath.toString(), false);
this.navigator = parser.getNav();
this.buildingsFinder = new AutoPilot(navigator);
buildingsFinder.selectXPath("/CityModel/cityObjectMember[Building]"); //TODO: Check it's the only correct possibility. //FIXME: BuildingPart too!
buildingsFinder.selectXPath(CityObjectMember.XPATH_PATTERN);
}
@Override
public Iterator<BuildingXmlNode> iterator() {
return new Iterator<BuildingXmlNode>() {
public Iterator<CityObjectMember> iterator() {
return new Iterator<CityObjectMember>() {
@Override
public boolean hasNext() {
......@@ -60,12 +60,12 @@ public boolean hasNext() {
}
@Override
public BuildingXmlNode next() {
public CityObjectMember next() {
try {
long offsetAndLength = navigator.getElementFragment();
buildingOffset = (int) offsetAndLength;
buildingLength = (int) (offsetAndLength >> 32);
return new BuildingXmlNode(navigator, buildingOffset, buildingLength);
return new CityObjectMember(navigator, buildingOffset, buildingLength);
} catch (NavException | NumberFormatException | XPathParseException | XPathEvalException ex) {
LOGGER.warning("Error while parsing " + citygmlPath);
}
......
......@@ -7,11 +7,19 @@
import com.ximpleware.XPathParseException;
public class BuildingXmlNode
/**
* XML Node representing a CityObjectMember
*
*/
public class CityObjectMember
{
//TODO: Check it's the only correct possibility.
//FIXME: BuildingPart too!
static final String XPATH_PATTERN = "/CityModel/cityObjectMember[Building or SolitaryVegetationObject or PlantCover]";
private int buildingOffset;
private int buildingLength;
private int nodeOffset;
private int nodeLength;
private VTDNav navigator;
private AutoPilot coordinatesFinder;
public Double x;
......@@ -22,14 +30,15 @@
public Double y;
private int coordinatesCount = 0;
public BuildingXmlNode(VTDNav navigator, int buildingOffset, int buildingLength)
public CityObjectMember(VTDNav navigator, int nodeOffset, int nodeLength)
throws XPathParseException, XPathEvalException, NavException {
this.navigator = navigator;
this.coordinatesFinder = new AutoPilot(navigator);
this.buildingLength = buildingLength;
this.buildingOffset = buildingOffset;
this.nodeLength = nodeLength;
this.nodeOffset = nodeOffset;
extractCoordinates();
//TODO: Get Building ID too, in order to avoid duplicates?
//TODO: Get Node ID too, in order to avoid duplicates?
//TODO: Now that "Building" can be Vegetation too, define a method to check class?
}
public boolean hasCoordinates() {
......@@ -84,7 +93,7 @@ private void extractCoordinates()
public String toString() {
try {
return navigator.toRawString(buildingOffset, buildingLength);
return navigator.toRawString(nodeOffset, nodeLength);
} catch (NavException ex) {
return "";
}
......
......@@ -55,7 +55,7 @@ public static Geometry calculateFromCityGML(Path citygmlPath) throws XPathParseE
GeometryFactory geometryFactory = new GeometryFactory();
ArrayList<Coordinate> allPoints = new ArrayList<>();
CityGmlIterator citygml = new CityGmlIterator(citygmlPath);
for (BuildingXmlNode buildingXmlNode : citygml) {
for (CityObjectMember buildingXmlNode : citygml) {
if (buildingXmlNode.hasCoordinates()) {
allPoints.add(new Coordinate(buildingXmlNode.xMin, buildingXmlNode.yMin));
allPoints.add(new Coordinate(buildingXmlNode.xMin, buildingXmlNode.yMax));
......
......@@ -17,7 +17,7 @@
private void testNoNanInCoordinates(Path citygmlPath) throws XPathParseException {
CityGmlIterator buildingXmlNodes = new CityGmlIterator(citygmlPath);
for (BuildingXmlNode buildingXmlNode : buildingXmlNodes) {
for (CityObjectMember buildingXmlNode : buildingXmlNodes) {
assertTrue(buildingXmlNode.hasCoordinates(), "Buildings should have coordinates");
assertFalse(Double.isNaN(buildingXmlNode.x), COORDINATE_SHOULD_BE_A_DOUBLE);
assertFalse(Double.isNaN(buildingXmlNode.y), COORDINATE_SHOULD_BE_A_DOUBLE);
......@@ -25,10 +25,11 @@ private void testNoNanInCoordinates(Path citygmlPath) throws XPathParseException
assertFalse(Double.isNaN(buildingXmlNode.yMax), COORDINATE_SHOULD_BE_A_DOUBLE);
assertFalse(Double.isNaN(buildingXmlNode.xMin), COORDINATE_SHOULD_BE_A_DOUBLE);
assertFalse(Double.isNaN(buildingXmlNode.yMin), COORDINATE_SHOULD_BE_A_DOUBLE);
assertTrue(buildingXmlNode.xMax > buildingXmlNode.x, COORDINATES_SHOULD_BE_PLAUSIBLE);
assertTrue(buildingXmlNode.yMax > buildingXmlNode.y, COORDINATES_SHOULD_BE_PLAUSIBLE);
assertTrue(buildingXmlNode.xMin < buildingXmlNode.x, COORDINATES_SHOULD_BE_PLAUSIBLE);
assertTrue(buildingXmlNode.yMin < buildingXmlNode.y, COORDINATES_SHOULD_BE_PLAUSIBLE);
// Some SolitaryVegetationObjects are defined with a single point.
assertTrue(buildingXmlNode.xMax >= buildingXmlNode.x, COORDINATES_SHOULD_BE_PLAUSIBLE);
assertTrue(buildingXmlNode.yMax >= buildingXmlNode.y, COORDINATES_SHOULD_BE_PLAUSIBLE);
assertTrue(buildingXmlNode.xMin <= buildingXmlNode.x, COORDINATES_SHOULD_BE_PLAUSIBLE);
assertTrue(buildingXmlNode.yMin <= buildingXmlNode.y, COORDINATES_SHOULD_BE_PLAUSIBLE);
}
}
......@@ -66,7 +67,7 @@ public void testExtractNoCoordsFromEmptyBuilding() throws XPathParseException {
Path citygmlPath = repo.resolve("Stöckach_empty_buildings.gml");
CityGmlIterator buildingXmlNodes = new CityGmlIterator(citygmlPath);
int counter = 0;
for (BuildingXmlNode buildingXmlNode : buildingXmlNodes) {
for (CityObjectMember buildingXmlNode : buildingXmlNodes) {
assertFalse(buildingXmlNode.hasCoordinates(), "Empty Buildings shouldn't have coordinates");
assertTrue(Double.isNaN(buildingXmlNode.x), "Coordinate should be a Nan");
assertTrue(Double.isNaN(buildingXmlNode.y), "Coordinate should be a Nan");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment