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

Allow Vegetation to be extracted too.

parent b2536456
No related merge requests found
Showing with 38 additions and 27 deletions
+38 -27
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
import com.ximpleware.NavException; import com.ximpleware.NavException;
import com.ximpleware.XPathEvalException; import com.ximpleware.XPathEvalException;
import com.ximpleware.XPathParseException; 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.CityGmlIterator;
import eu.simstadt.regionchooser.fast_xml_parser.CityObjectMember;
public class RegionExtractor public class RegionExtractor
...@@ -51,8 +51,9 @@ ...@@ -51,8 +51,9 @@
static int selectRegionDirectlyFromCityGML(String wktPolygon, String srsName, Writer sb, static int selectRegionDirectlyFromCityGML(String wktPolygon, String srsName, Writer sb,
Path... citygmlPaths) throws ParseException, XPathParseException, NavException, IOException { Path... citygmlPaths) throws ParseException, XPathParseException, NavException, IOException {
int buildingsCount = 0; int cityObjectsCount = 0;
int foundBuildingsCount = 0; int foundBuildingsCount = 0;
// int foundVegetationCount = 0;
Geometry poly = WKT_READER.read(wktPolygon); Geometry poly = WKT_READER.read(wktPolygon);
CityGmlIterator citygml = null; CityGmlIterator citygml = null;
...@@ -61,11 +62,11 @@ static int selectRegionDirectlyFromCityGML(String wktPolygon, String srsName, Wr ...@@ -61,11 +62,11 @@ static int selectRegionDirectlyFromCityGML(String wktPolygon, String srsName, Wr
LOGGER.info("Parsing " + citygmlPath); LOGGER.info("Parsing " + citygmlPath);
//TODO: Allow citygmlPath for folders too, and iterate over gmls? //TODO: Allow citygmlPath for folders too, and iterate over gmls?
citygml = new CityGmlIterator(citygmlPath); citygml = new CityGmlIterator(citygmlPath);
for (BuildingXmlNode buildingXmlNode : citygml) { for (CityObjectMember buildingXmlNode : citygml) {
if (buildingsCount == 0) { if (cityObjectsCount == 0) {
sb.append(replaceEnvelopeInHeader(citygml.getHeader(), poly.getEnvelopeInternal(), srsName)); sb.append(replaceEnvelopeInHeader(citygml.getHeader(), poly.getEnvelopeInternal(), srsName));
} }
buildingsCount += 1; cityObjectsCount += 1;
if (buildingXmlNode.hasCoordinates()) { if (buildingXmlNode.hasCoordinates()) {
Coordinate coord = new Coordinate(buildingXmlNode.x, buildingXmlNode.y); Coordinate coord = new Coordinate(buildingXmlNode.x, buildingXmlNode.y);
Point point = GEOMETRY_FACTORY.createPoint(coord); Point point = GEOMETRY_FACTORY.createPoint(coord);
...@@ -74,7 +75,7 @@ static int selectRegionDirectlyFromCityGML(String wktPolygon, String srsName, Wr ...@@ -74,7 +75,7 @@ static int selectRegionDirectlyFromCityGML(String wktPolygon, String srsName, Wr
sb.append(buildingXmlNode.toString()); sb.append(buildingXmlNode.toString());
} }
} }
if (buildingsCount % 1000 == 0) { if (cityObjectsCount % 1000 == 0) {
LOGGER.info("1000 buildings parsed"); LOGGER.info("1000 buildings parsed");
} }
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
import com.ximpleware.XPathParseException; 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()); private static final Logger LOGGER = Logger.getLogger(CityGmlIterator.class.getName());
...@@ -42,12 +42,12 @@ public CityGmlIterator(Path citygmlPath) throws XPathParseException { ...@@ -42,12 +42,12 @@ public CityGmlIterator(Path citygmlPath) throws XPathParseException {
parser.parseFile(citygmlPath.toString(), false); parser.parseFile(citygmlPath.toString(), false);
this.navigator = parser.getNav(); this.navigator = parser.getNav();
this.buildingsFinder = new AutoPilot(navigator); 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 @Override
public Iterator<BuildingXmlNode> iterator() { public Iterator<CityObjectMember> iterator() {
return new Iterator<BuildingXmlNode>() { return new Iterator<CityObjectMember>() {
@Override @Override
public boolean hasNext() { public boolean hasNext() {
...@@ -60,12 +60,12 @@ public boolean hasNext() { ...@@ -60,12 +60,12 @@ public boolean hasNext() {
} }
@Override @Override
public BuildingXmlNode next() { public CityObjectMember next() {
try { try {
long offsetAndLength = navigator.getElementFragment(); long offsetAndLength = navigator.getElementFragment();
buildingOffset = (int) offsetAndLength; buildingOffset = (int) offsetAndLength;
buildingLength = (int) (offsetAndLength >> 32); buildingLength = (int) (offsetAndLength >> 32);
return new BuildingXmlNode(navigator, buildingOffset, buildingLength); return new CityObjectMember(navigator, buildingOffset, buildingLength);
} catch (NavException | NumberFormatException | XPathParseException | XPathEvalException ex) { } catch (NavException | NumberFormatException | XPathParseException | XPathEvalException ex) {
LOGGER.warning("Error while parsing " + citygmlPath); LOGGER.warning("Error while parsing " + citygmlPath);
} }
......
...@@ -7,11 +7,19 @@ ...@@ -7,11 +7,19 @@
import com.ximpleware.XPathParseException; 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 nodeOffset;
private int buildingLength; private int nodeLength;
private VTDNav navigator; private VTDNav navigator;
private AutoPilot coordinatesFinder; private AutoPilot coordinatesFinder;
public Double x; public Double x;
...@@ -22,14 +30,15 @@ ...@@ -22,14 +30,15 @@
public Double y; public Double y;
private int coordinatesCount = 0; private int coordinatesCount = 0;
public BuildingXmlNode(VTDNav navigator, int buildingOffset, int buildingLength) public CityObjectMember(VTDNav navigator, int nodeOffset, int nodeLength)
throws XPathParseException, XPathEvalException, NavException { throws XPathParseException, XPathEvalException, NavException {
this.navigator = navigator; this.navigator = navigator;
this.coordinatesFinder = new AutoPilot(navigator); this.coordinatesFinder = new AutoPilot(navigator);
this.buildingLength = buildingLength; this.nodeLength = nodeLength;
this.buildingOffset = buildingOffset; this.nodeOffset = nodeOffset;
extractCoordinates(); 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() { public boolean hasCoordinates() {
...@@ -84,7 +93,7 @@ private void extractCoordinates() ...@@ -84,7 +93,7 @@ private void extractCoordinates()
public String toString() { public String toString() {
try { try {
return navigator.toRawString(buildingOffset, buildingLength); return navigator.toRawString(nodeOffset, nodeLength);
} catch (NavException ex) { } catch (NavException ex) {
return ""; return "";
} }
......
...@@ -55,7 +55,7 @@ public static Geometry calculateFromCityGML(Path citygmlPath) throws XPathParseE ...@@ -55,7 +55,7 @@ public static Geometry calculateFromCityGML(Path citygmlPath) throws XPathParseE
GeometryFactory geometryFactory = new GeometryFactory(); GeometryFactory geometryFactory = new GeometryFactory();
ArrayList<Coordinate> allPoints = new ArrayList<>(); ArrayList<Coordinate> allPoints = new ArrayList<>();
CityGmlIterator citygml = new CityGmlIterator(citygmlPath); CityGmlIterator citygml = new CityGmlIterator(citygmlPath);
for (BuildingXmlNode buildingXmlNode : citygml) { for (CityObjectMember buildingXmlNode : citygml) {
if (buildingXmlNode.hasCoordinates()) { if (buildingXmlNode.hasCoordinates()) {
allPoints.add(new Coordinate(buildingXmlNode.xMin, buildingXmlNode.yMin)); allPoints.add(new Coordinate(buildingXmlNode.xMin, buildingXmlNode.yMin));
allPoints.add(new Coordinate(buildingXmlNode.xMin, buildingXmlNode.yMax)); allPoints.add(new Coordinate(buildingXmlNode.xMin, buildingXmlNode.yMax));
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
private void testNoNanInCoordinates(Path citygmlPath) throws XPathParseException { private void testNoNanInCoordinates(Path citygmlPath) throws XPathParseException {
CityGmlIterator buildingXmlNodes = new CityGmlIterator(citygmlPath); CityGmlIterator buildingXmlNodes = new CityGmlIterator(citygmlPath);
for (BuildingXmlNode buildingXmlNode : buildingXmlNodes) { for (CityObjectMember buildingXmlNode : buildingXmlNodes) {
assertTrue(buildingXmlNode.hasCoordinates(), "Buildings should have coordinates"); assertTrue(buildingXmlNode.hasCoordinates(), "Buildings should have coordinates");
assertFalse(Double.isNaN(buildingXmlNode.x), COORDINATE_SHOULD_BE_A_DOUBLE); assertFalse(Double.isNaN(buildingXmlNode.x), COORDINATE_SHOULD_BE_A_DOUBLE);
assertFalse(Double.isNaN(buildingXmlNode.y), 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 ...@@ -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.yMax), COORDINATE_SHOULD_BE_A_DOUBLE);
assertFalse(Double.isNaN(buildingXmlNode.xMin), 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); assertFalse(Double.isNaN(buildingXmlNode.yMin), COORDINATE_SHOULD_BE_A_DOUBLE);
assertTrue(buildingXmlNode.xMax > buildingXmlNode.x, COORDINATES_SHOULD_BE_PLAUSIBLE); // Some SolitaryVegetationObjects are defined with a single point.
assertTrue(buildingXmlNode.yMax > buildingXmlNode.y, COORDINATES_SHOULD_BE_PLAUSIBLE); assertTrue(buildingXmlNode.xMax >= buildingXmlNode.x, COORDINATES_SHOULD_BE_PLAUSIBLE);
assertTrue(buildingXmlNode.xMin < buildingXmlNode.x, COORDINATES_SHOULD_BE_PLAUSIBLE); assertTrue(buildingXmlNode.yMax >= buildingXmlNode.y, COORDINATES_SHOULD_BE_PLAUSIBLE);
assertTrue(buildingXmlNode.yMin < 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 { ...@@ -66,7 +67,7 @@ public void testExtractNoCoordsFromEmptyBuilding() throws XPathParseException {
Path citygmlPath = repo.resolve("Stöckach_empty_buildings.gml"); Path citygmlPath = repo.resolve("Stöckach_empty_buildings.gml");
CityGmlIterator buildingXmlNodes = new CityGmlIterator(citygmlPath); CityGmlIterator buildingXmlNodes = new CityGmlIterator(citygmlPath);
int counter = 0; int counter = 0;
for (BuildingXmlNode buildingXmlNode : buildingXmlNodes) { for (CityObjectMember buildingXmlNode : buildingXmlNodes) {
assertFalse(buildingXmlNode.hasCoordinates(), "Empty Buildings shouldn't have coordinates"); assertFalse(buildingXmlNode.hasCoordinates(), "Empty Buildings shouldn't have coordinates");
assertTrue(Double.isNaN(buildingXmlNode.x), "Coordinate should be a Nan"); assertTrue(Double.isNaN(buildingXmlNode.x), "Coordinate should be a Nan");
assertTrue(Double.isNaN(buildingXmlNode.y), "Coordinate should be a Nan"); assertTrue(Double.isNaN(buildingXmlNode.y), "Coordinate should be a Nan");
......
Supports Markdown
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