Commit 10446f7c authored by duminil's avatar duminil
Browse files

RegionChooser: Fast extractor of CoordinateReferenceSystem

parent 5c0578fe
......@@ -4,13 +4,18 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.Optional;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.osgeo.proj4j.CoordinateReferenceSystem;
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.geo.GeoUtils;
public class CityGmlIterator implements Iterable<BuildingXmlNode>
......@@ -23,6 +28,7 @@ public class CityGmlIterator implements Iterable<BuildingXmlNode>
private int buildingOffset = 0;
private int buildingLength = 0;
private Path citygmlPath;
private Pattern srsNamePattern = Pattern.compile("(?i)(?<=srsName=\")[^\"]+(?=\")");
/*
* Simple class to parse a CityGML and extract cityObjectMember XML nodes and their coordinates. Since the
......@@ -39,7 +45,7 @@ public CityGmlIterator(Path citygmlPath)
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
buildingsFinder.selectXPath("/CityModel/cityObjectMember[Building]"); //TODO: Check it's the only correct possibility. //FIXME: BuildingPart too!
}
@Override
......@@ -87,4 +93,18 @@ public Object getFooter() throws IOException, NavException {
return navigator.toRawString(footerOffset, footerLength);
}
/*
* Fast scan of the 50 first lines to look for srsName
*
*/
public CoordinateReferenceSystem getCRS() throws IOException {
Optional<String> line = Files.lines(citygmlPath).limit(50).filter(srsNamePattern.asPredicate()).findFirst();
if (line.isPresent()) {
Matcher matcher = srsNamePattern.matcher(line.get());
matcher.find();
return GeoUtils.crsFromSrsName(matcher.group());
} else {
throw new IllegalArgumentException("No srsName found in the header of " + citygmlPath);
}
}
}
package eu.simstadt.regionchooser.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
......@@ -15,9 +16,10 @@
public class CitygmlParserTests
{
private void testNoNanInCoordinates(Path citygmlPath)
private void testCRSandNoNanInCoordinates(Path citygmlPath, String crsName)
throws NumberFormatException, XPathParseException, NavException, XPathEvalException, IOException {
CityGmlIterator buildingXmlNodes = new CityGmlIterator(citygmlPath);
assertEquals(crsName, buildingXmlNodes.getCRS().toString());
for (BuildingXmlNode buildingXmlNode : buildingXmlNodes) {
assertFalse("Coordinate should be a double", Double.isNaN(buildingXmlNode.x));
assertFalse("Coordinate should be a double", Double.isNaN(buildingXmlNode.y));
......@@ -30,7 +32,6 @@ private void testNoNanInCoordinates(Path citygmlPath)
assertTrue("Coordinates Min/Max should be plausible", buildingXmlNode.xMin < buildingXmlNode.x);
assertTrue("Coordinates Min/Max should be plausible", buildingXmlNode.yMin < buildingXmlNode.y);
}
}
@Test
......@@ -38,20 +39,27 @@ public void testExtractCoordsFromStuttgart()
throws NumberFormatException, XPathParseException, NavException, XPathEvalException, IOException {
Path repo = Paths.get("../TestRepository");
Path citygmlPath = repo.resolve("Stuttgart.proj/Stuttgart_LOD0_LOD1_buildings_and_trees.gml");
testNoNanInCoordinates(citygmlPath);
testCRSandNoNanInCoordinates(citygmlPath, "EPSG:31467");
}
@Test
public void testExtractCoordsFromGruenbuehl() throws Throwable {
Path repo = Paths.get("../TestRepository");
Path citygmlPath = repo.resolve("Gruenbuehl.proj/20140218_Gruenbuehl_LOD2_1building.gml");
testNoNanInCoordinates(citygmlPath);
testCRSandNoNanInCoordinates(citygmlPath, "EPSG:31467");
}
@Test
public void testExtractCoordsFromMunich() throws Throwable {
Path repo = Paths.get("../TestRepository");
Path citygmlPath = repo.resolve("Muenchen.proj/Munich_v_1_0_0.gml");
testNoNanInCoordinates(citygmlPath);
testCRSandNoNanInCoordinates(citygmlPath, "EPSG:32632");
}
@Test
public void testExtractCoordsFromNYC() throws Throwable {
Path repo = Paths.get("../TestRepository");
Path citygmlPath = repo.resolve("NewYork.proj/ManhattanSmall.gml");
testCRSandNoNanInCoordinates(citygmlPath, "EPSG:32118");
}
}
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