diff --git a/src/eu/simstadt/regionchooser/RegionChooserFX.java b/src/eu/simstadt/regionchooser/RegionChooserFX.java index c90cb07242708e43b81d9d8d666dce3a1aa6dc1a..bebad725ee80bd78d0396f28a35eb2e5023117f4 100644 --- a/src/eu/simstadt/regionchooser/RegionChooserFX.java +++ b/src/eu/simstadt/regionchooser/RegionChooserFX.java @@ -3,10 +3,15 @@ import java.io.BufferedWriter; import java.io.File; import java.io.IOException; +import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.time.Duration; +import java.time.Instant; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javafx.application.Application; import javafx.beans.value.ObservableValue; import javafx.concurrent.Worker.State; @@ -69,41 +74,60 @@ public void downloadRegion(String wktPolygon) { System.out.println("FROM JAVA : DO SOMETHING with " + wktPolygon); } - public int downloadRegionFromCityGML(String wktPolygon, String project, String citygml, JSObject featureOverlay) - throws SAXParseException, XMLStreamException, ParseException, IOException { - //FIXME: Why is this so slow? - SimStadtModel model = SimStadtProject.loadModelWithoutSchemaValidation(citygmlPath(project, citygml).toFile()); - Geometry poly = wktReader.read(wktPolygon); - final GeometryFactory gf = new GeometryFactory(); + public void downloadRegionFromCityGML(String wktPolygon, String project, String citygml, JSObject featureOverlay) + throws IOException, ParseException + { + StringBuffer sb = selectRegionDirectlyFromCityGML(citygmlPath(project, citygml), wktPolygon); File buildingIdsFile = selectSaveFileWithDialog(project, citygml); if (buildingIdsFile != null) { BufferedWriter writer = Files.newBufferedWriter(buildingIdsFile.toPath()); + writer.write(sb.toString()); + writer.close(); + } + } - //TODO: What's the easiest way to get WGS84 coordinates of building center? - for (Building building : model.getCityDoctorBuildings()) { - BoundingShape boundedBy = building.getCitygmlBuilding().getBoundedBy(); - if (boundedBy != null) { - Envelope envelope = boundedBy.getEnvelope(); - if (envelope != null) { - List<Double> l = envelope.getLowerCorner().getValue(); - List<Double> h = envelope.getUpperCorner().getValue(); - double x = (l.get(0) + h.get(0)) * 0.5; - double y = (l.get(1) + h.get(1)) * 0.5; - Coordinate coord = new Coordinate(x, y); - Point point = gf.createPoint(coord); - if (point.within(poly)) { - //featureOverlay.call("addMarker", x, y, building.getGmlId()); - writer.write(building.getGmlId() + "\r\n"); - System.out.println(building.getGmlId()); - } - } - } + public StringBuffer selectRegionDirectlyFromCityGML(Path citygmlPath, String wktPolygon) throws IOException, + ParseException { + //TODO: Write directly to file + // Instant start = Instant.now(); + Geometry poly = wktReader.read(wktPolygon); + final GeometryFactory gf = new GeometryFactory(); + String s = new String(Files.readAllBytes(citygmlPath), Charset.defaultCharset()); + + Pattern cityObjectPattern = Pattern + .compile("(?s)<(core:)?cityObjectMember>.*?<\\/(core:)?cityObjectMember>\\s*"); + Pattern gsk3CoordinatesPattern = Pattern + .compile("(?<![\\d\\.])(3\\d\\d\\d\\d\\d\\d[\\.\\d]*) (5\\d\\d\\d\\d\\d\\d[\\.\\d]*)"); + Matcher cityObjectMatcher = cityObjectPattern.matcher(s); + StringBuffer sb = new StringBuffer(); + int i = 0; + while (cityObjectMatcher.find()) { + cityObjectMatcher.appendReplacement(sb, ""); + String cityObject = cityObjectMatcher.group(); + Matcher gsk3CoordinatesMatcher = gsk3CoordinatesPattern.matcher(cityObject); + int coordinatesCount = 0; + double xTotal = 0; + double yTotal = 0; + while (gsk3CoordinatesMatcher.find()) { + coordinatesCount++; + xTotal += Double.valueOf(gsk3CoordinatesMatcher.group(1)); + yTotal += Double.valueOf(gsk3CoordinatesMatcher.group(2)); + } + double x = xTotal / coordinatesCount; + double y = yTotal / coordinatesCount; + Coordinate coord = new Coordinate(x, y); + Point point = gf.createPoint(coord); + if (point.within(poly)) { + i++; + sb.append(cityObject); } - writer.close(); } + System.out.println("Buildings found in selected region " + i); + cityObjectMatcher.appendTail(sb); + // System.out.println(Duration.between(start, Instant.now())); + return sb; - return model.getCityDoctorBuildings().size(); } private File selectSaveFileWithDialog(String project, String citygml) { @@ -111,14 +135,15 @@ private File selectSaveFileWithDialog(String project, String citygml) { FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("Save CITYGML ids"); fileChooser.setInitialDirectory(repo.resolve(project + ".simstadt").toFile()); - fileChooser.setInitialFileName(citygml.split("\\.")[0] + "_selected_region"); - FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("TXT files (*.txt)", "*.txt"); + fileChooser.setInitialFileName(citygml.replace(".", "_selected_region.")); + FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("GML files (*.gml)", "*.gml"); fileChooser.getExtensionFilters().add(extFilter); return fileChooser.showSaveDialog(mainStage); } public boolean checkIfCityGMLSAreAvailable(String project, String citygml) { - return Files.isReadable(citygmlPath(project, citygml)); + Path p = citygmlPath(project, citygml); + return Files.isReadable(p); } public void log(String text) @@ -145,13 +170,25 @@ public Browser() { (ObservableValue<? extends State> ov, State oldState, State newState) -> { if (newState == State.SUCCEEDED) { JSObject win = (JSObject) webEngine.executeScript("window"); - win.setMember("fxapp", new JavaScriptFXBridge()); + JavaScriptFXBridge fxapp = new JavaScriptFXBridge(); + win.setMember("fxapp", fxapp); webEngine.executeScript("console.log = function(message)\n" + "{\n" + " fxapp.log(message);\n" + "};"); - } - }); + // try { + // fxapp.selectRegionDirectlyFromCityGML( + // Paths.get("../TestRepository").resolve("Gruenbuehl.simstadt") + // .resolve("Gruenbuehl_LOD2_validated+ADE.gml"), + // "POLYGON((3515896.6132767177 5415942.563662692,3516013.1135652466 5415930.341095623,3516035.1608944996 5415925.696283888,3516052.531667652 5415905.3452489935,3516053.640043498 5415793.1428597355,3516092.996199113 5415790.117097386,3516086.9957373445 5415687.30812527,3515953.2106800284 5415687.710348818,3515893.4419519473 5415673.416324939,3515876.73573549 5415736.92758554,3515896.6132767177 5415942.563662692))" + // ); + // } catch (Exception ex) { + // ex.printStackTrace(); + // + // } + // System.exit(0); + } + }); //add the web view to the scene getChildren().add(browser); } diff --git a/website/script/simstadt_openlayers.js b/website/script/simstadt_openlayers.js index 6d2aec48dc77a3502f880dbb07089dcd14608766..207753a443ab83b7830ab2b19eee3e218f9b7932 100644 --- a/website/script/simstadt_openlayers.js +++ b/website/script/simstadt_openlayers.js @@ -240,8 +240,7 @@ function downloadRegionFromCityGML(i) { // Waiting 100ms in order to let the cursor change setTimeout(function() { var start = new Date().getTime(); - var buildings_count = fxapp.downloadRegionFromCityGML(sketchAsWKT(), feature.get("project"), feature - .get("name"), vectorSource); + fxapp.downloadRegionFromCityGML(sketchAsWKT(), feature.get("project"), feature.get("name"), vectorSource); var end = new Date().getTime(); var time = end - start; console.log('DL Execution time: ' + time);