Commit d118c3ac authored by duminil's avatar duminil
Browse files

RegionChooser: Documentation, refactoring and tests.

parent 671dfe38
......@@ -95,12 +95,10 @@ public void extractZIPtoGML(String zipFilename) throws IOException {
zipFile.close();
}
public void downloadRegionFromCityGML(String wktPolygon, String project, String citygml, String srsName)
throws IOException,
ParseException, SAXParseException, XMLStreamException, NumberFormatException, XPathParseException,
NavException, XPathEvalException {
StringBuffer sb = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath(project, citygml), wktPolygon,
srsName);
public void downloadRegionFromCityGML(String wktPolygon, String project, String citygml)
throws IOException, ParseException, SAXParseException, XMLStreamException, NumberFormatException,
XPathParseException, NavException, XPathEvalException {
StringBuffer sb = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath(project, citygml), wktPolygon);
File buildingIdsFile = selectSaveFileWithDialog(project, citygml, "selected_region");
if (buildingIdsFile != null) {
......
......@@ -12,9 +12,15 @@ public class RegionChooserFX extends Application
private Scene scene;
protected final static Logger LOGGER = Logger.getLogger(RegionChooserFX.class.getName());
/**
* Start point of RegionChooser application. Either "Run as Java" from Eclipse or run
* "RegionChooser.bat/.sh/.command" from deployed SimStadt folder.
*
* This application is basically just a scene and a browser for the RegionChooser website (HTML + Javascript frontend
* + Java backend). The Java part is written in RegionChooserBrowser.
*/
@Override
public void start(Stage stage) {
// create the scene
stage.setTitle("RegionChooserJavaFX");
scene = new Scene(new RegionChooserBrowser(), 1024, 768, Color.web("#666970"));
stage.setScene(scene);
......
......@@ -25,7 +25,19 @@
private static final Logger LOGGER = Logger.getLogger(RegionExtractor.class.getName());
private static final GeometryFactory gf = new GeometryFactory();
static public StringBuffer selectRegionDirectlyFromCityGML(Path citygmlPath, String wktPolygon, String srsName)
/**
* Main method behind RegionChooser. Given a CityGML (as Path) and a geometry (as Well-known text POLYGON, in the
* same coordinate system as the CityGML), it iterates over each Building and checks if the building is inside the
* geometry. It only works with CityGML files smaller than 2GB. It uses VTD-XML parser instead of a whole
* Simstadt/Citydoctor/Citygml model.
*
*
* @param citygmlPath
* @param wktPolygon
* @return
* @throws Exception
*/
static public StringBuffer selectRegionDirectlyFromCityGML(Path citygmlPath, String wktPolygon)
throws SAXParseException, XMLStreamException, ParseException, XPathParseException, NavException,
NumberFormatException, XPathEvalException, IOException {
......@@ -37,11 +49,14 @@ static public StringBuffer selectRegionDirectlyFromCityGML(Path citygmlPath, Str
CityGmlIterator citygml = new CityGmlIterator(citygmlPath);
for (BuildingXmlNode buildingXmlNode : citygml) {
if (buildingsCount == 0) {
//TODO: Replace original CityGML envelope with a smaller one, corresponding to wktPolygon
// Envelope env = poly.getEnvelopeInternal();
// System.out.println(env);
sb.append(citygml.getHeader());
}
buildingsCount += 1;
Coordinate coord = new Coordinate(buildingXmlNode.x, buildingXmlNode.y);
Point point = gf.createPoint(coord); //NOTE: Should it be in buildingXmlNode?
Point point = gf.createPoint(coord);
if (point.within(poly)) {
foundBuildingsCount++;
sb.append(buildingXmlNode.toString());
......
......@@ -221,20 +221,27 @@ function findIntersections() {
function downloadRegionFromCityGML(i) {
// TODO: Disable all links
// TODO: DRY
$("html").addClass("wait");
var feature = kml_source.getFeatures()[i];
// Waiting 100ms in order to let the cursor change
setTimeout(function() {
// var start = new Date().getTime();
var start = new Date().getTime();
var srsName = feature.get("srsName") || "EPSG:31467";
fxapp.downloadRegionFromCityGML(sketchAsWKT(srsName), feature.get("project"), feature.get("name"), srsName);
// var end = new Date().getTime();
// var time = end - start;
// console.log('DL Execution time: ' + time);
setTimeout(function() {
$("html").removeClass("wait");
dataPanel.append("Done<br/>\n");
}, 100);
if (proj4.defs(srsName)){
$("html").addClass("wait");
console.log("Selected region is written in " + srsName + " coordinate system.");
fxapp.downloadRegionFromCityGML(sketchAsWKT(srsName), feature.get("project"), feature.get("name"));
var end = new Date().getTime();
var time = end - start;
console.log('DL Execution time: ' + time);
setTimeout(function() {
$("html").removeClass("wait");
dataPanel.append("Done<br/>\n");
}, 100);
} else {
var msg = "ERROR : Unknown coordinate system : \"" + srsName + "\". Cannot extract any region";
console.log(msg);
dataPanel.append(msg + "<br/>\n");
}
}, 100);
}
......@@ -313,7 +320,6 @@ function downloadRegionFromNovaFACTORY(i) {
}
function sketchAsWKT(srsName) {
console.log(srsName); //TODO: Check if proj4 knows this coordinate system
srsName = (typeof srsName === 'undefined') ? 'EPSG:4326' : srsName;
var wktFormat = new ol.format.WKT();
return wktFormat.writeFeature(sketch, {
......
package eu.simstadt.nf4j.async.test;
package eu.simstadt.nf4j.async;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
......
package eu.simstadt.nf4j.async.test;
package eu.simstadt.nf4j.async;
import static org.junit.Assert.assertTrue;
......
package eu.simstadt.regionchooser.test;
package eu.simstadt.regionchooser;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
......@@ -8,7 +8,6 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Test;
import eu.simstadt.regionchooser.RegionExtractor;
public class RegionExtractorTests
......@@ -26,11 +25,11 @@ public static int countRegexMatches(String str, String subStr) {
@Test
public void testExtract3BuildingsFromGSK3Model() throws Throwable {
//NOTE: Small region around Martinskirche in Grünbühl
// "EPSG:31467"
String wktPolygon = "POLYGON((3515848.896028535 5415823.108586172,3515848.9512289143 5415803.590347393,3515829.0815150724 5415803.338023346,3515830.9784850604 5415793.437034622,3515842.0946056456 5415793.272282251,3515843.3515515197 5415766.204935087,3515864.1064344468 5415766.557899496,3515876.489172751 5415805.433782301,3515876.343844858 5415822.009293416,3515848.896028535 5415823.108586172))";
Path repo = Paths.get("../TestRepository");
Path citygmlPath = repo.resolve("Gruenbuehl.proj/20140218_Gruenbuehl_LOD2.gml");
String churchGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon, "EPSG:31467")
.toString();
String churchGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon).toString();
assertEquals(countRegexMatches(churchGMLString, "<(core:)?cityObjectMember"), 3);
assertTrue(churchGMLString.contains("Donaustr"));
assertTrue(churchGMLString.contains("DEBW_LOD2_203056"));
......@@ -41,13 +40,13 @@ public void testExtract3BuildingsFromGSK3Model() throws Throwable {
}
@Test
public void testExtract3BuildingsFromNAD83Model() throws Throwable {
public void testExtractBuildingsWithoutCommentsInBetween() throws Throwable {
//NOTE: Small region around WashingtonSquare
// "EPSG:32118"
String wktPolygon = "POLYGON((300259.78663489706 62835.835907766595,300230.33294975647 62792.0482567884,300213.5667431851 62770.83143720031,300183.6592861123 62730.20347659383,300252.9947486632 62676.938468840905,300273.3862256562 62701.767105345614,300257.5250407747 62715.760413539596,300308.2754543957 62805.14198211394,300259.78663489706 62835.835907766595))";
Path repo = Paths.get("../TestRepository");
Path citygmlPath = repo.resolve("NewYork.proj/ManhattanSmall.gml");
String archGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon, "EPSG:32118")
.toString();
String archGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon).toString();
assertEquals(countRegexMatches(archGMLString, "<(core:)?cityObjectMember"), 2);
assertTrue(archGMLString.contains("WASHINGTON SQUARE"));
assertTrue(archGMLString.contains("uuid_c0980a6e-05ea-4d09-bc83-efab226945a1"));
......@@ -58,14 +57,28 @@ public void testExtract3BuildingsFromNAD83Model() throws Throwable {
assertFalse(archGMLString.contains("comment after last building")); // Comment
}
@Test
public void testExtractBuildingsAndChangeEnvelope() throws Throwable {
String wktPolygon = "POLYGON((299761.8123557725 61122.68126771413,299721.46983062755 61058.11626595352,299780.84627343423 61021.99295737501,299823.9079725632 61083.3979344517,299761.8123557725 61122.68126771413))";
Path repo = Paths.get("../TestRepository");
Path citygmlPath = repo.resolve("NewYork.proj/FamilyCourt_LOD2_with_PLUTO_attributes.gml");
String familyCourtBuilding = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon).toString();
assertEquals(countRegexMatches(familyCourtBuilding, "<(core:)?cityObjectMember"), 1);
assertTrue(familyCourtBuilding.contains("Bldg_12210021066"));
assertFalse("The exported CityGML shouldn't contain the original envelope", familyCourtBuilding
.contains("<gml:lowerCorner>298393.46959639067 59277.34021543693 -11.892070104139751</gml:lowerCorner>"));
assertFalse("The exported CityGML shouldn't contain the original envelope", familyCourtBuilding
.contains("<gml:upperCorner>305641.79529639013 67101.44881543722 547.7591871983744</gml:upperCorner>"));
}
@Test
public void testExtract0BuildingsWithWrongCoordinates() throws Throwable {
//NOTE: Small region, far away from NYC
// "EPSG:32118"
String wktPolygon = "POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))";
Path repo = Paths.get("../TestRepository");
Path citygmlPath = repo.resolve("NewYork.proj/ManhattanSmall.gml");
String emptyGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon, "EPSG:32118")
.toString();
String emptyGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon).toString();
assertEquals(countRegexMatches(emptyGMLString, "<(core:)?cityObjectMember"), 0);
assertTrue(emptyGMLString.contains("<CityModel")); // Header
assertTrue(emptyGMLString.contains("</CityModel")); // Footer
......@@ -74,11 +87,11 @@ public void testExtract0BuildingsWithWrongCoordinates() throws Throwable {
@Test
public void testExtract0BuildingsFromEmptyGML() throws Throwable {
//NOTE: Small region, with too many spaces between coordinates
// "EPSG:32118"
String wktPolygon = "POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))";
Path repo = Paths.get("../TestRepository");
Path citygmlPath = repo.resolve("NewYork.proj/empty_model.gml");
String emptyGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon, "EPSG:32118")
.toString();
String emptyGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon).toString();
assertEquals(countRegexMatches(emptyGMLString, "<(core:)?cityObjectMember"), 0);
assertTrue(emptyGMLString.contains("<core:CityModel")); // Header
assertTrue(emptyGMLString.contains("</core:CityModel")); // Footer
......@@ -90,8 +103,7 @@ public void testExtract0BuildingsFromWeirdGML() throws Throwable {
String wktPolygon = "POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))";
Path repo = Paths.get("../TestRepository");
Path citygmlPath = repo.resolve("NewYork.proj/broken_nyc_lod2.gml");
String emptyGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon, "EPSG:32118")
.toString();
String emptyGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon).toString();
assertEquals(countRegexMatches(emptyGMLString, "<(core:)?cityObjectMember"), 0);
assertTrue(emptyGMLString.contains("<core:CityModel")); // Header
assertTrue(emptyGMLString.contains("</core:CityModel")); // Footer
......
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