Commit 533350b6 authored by Eric Duminil's avatar Eric Duminil
Browse files

Async region extractor. Doesn't block the GUI anymore.

parent 3f7fb108
No related merge requests found
Showing with 48 additions and 61 deletions
+48 -61
...@@ -49,12 +49,8 @@ public JavaScriptFXBridge() { ...@@ -49,12 +49,8 @@ public JavaScriptFXBridge() {
/** /**
* Launches a background thread in which the hull gets extracted for every CityGML file. The hull gets sent back * Launches a background thread in which the hull gets extracted for every CityGML file. The hull gets sent back
* to the JS app in order to be displayed. * to the JS app in order to be displayed.
*
* NOTE: To be very honest, I don't really understand concurrency in JavaFX. Eric
*
*/ */
public void refreshHulls() { public void refreshHulls() {
//NOTE: Could add progress bar?
Task<Void> task = new Task<Void>() { Task<Void> task = new Task<Void>() {
@Override @Override
public Void call() throws IOException { public Void call() throws IOException {
...@@ -76,27 +72,35 @@ public Void call() throws IOException { ...@@ -76,27 +72,35 @@ public Void call() throws IOException {
} }
/** /**
* This method is called from Javascript, with a prepared wktPolygon written in local coordinates. * This method is called from Javascript, with a prepared wktPolygon written in local coordinates. Executes it in
* the background to avoid freezing the GUI
*/ */
public int downloadRegionFromCityGMLs(String wktPolygon, String project, String csvCitygmls, String srsName) public void downloadRegionFromCityGMLs(String wktPolygon, String project, String csvCitygmls, String srsName) {
throws IOException, ParseException, XPathParseException, NavException {
// It doesn't seem possible to pass arrays or list from JS to Java. So csvCitygmls contains names separated by ; // It doesn't seem possible to pass arrays or list from JS to Java. So csvCitygmls contains names separated by ;
Path[] paths = Stream.of(csvCitygmls.split(";")).map(s -> citygmlPath(project, s)).toArray(Path[]::new); Path[] paths = Stream.of(csvCitygmls.split(";")).map(s -> citygmlPath(project, s)).toArray(Path[]::new);
String proposedName = csvCitygmls.replace(";", "_").replace(".gml", "") + ".gml"; String proposedName = csvCitygmls.replace(";", "_").replace(".gml", "") + ".gml";
File outputFile = selectSaveFileWithDialog(project, proposedName, "part"); File outputFile = selectSaveFileWithDialog(project, proposedName, "part");
if (outputFile == null) { if (outputFile == null) {
return -1; return;
} }
int count; Task<Integer> downloadTask = new Task<Integer>() {
try (BufferedWriter gmlWriter = Files.newBufferedWriter(outputFile.toPath())) { @Override
count = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, srsName, gmlWriter, paths); public Integer call() throws IOException, XPathParseException, NavException, ParseException {
} int count = -1;
LOGGER.info(outputFile + " has been written"); try (BufferedWriter gmlWriter = Files.newBufferedWriter(outputFile.toPath())) {
return count; count = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, srsName, gmlWriter, paths);
}
LOGGER.info(outputFile + " has been written");
return count;
}
};
downloadTask.setOnRunning(e -> jsApp.call("downloadStart"));
downloadTask.setOnSucceeded(e -> jsApp.call("downloadFinished"));
new Thread(downloadTask).start();
} }
......
...@@ -150,8 +150,6 @@ const regionChooser = (function(){ ...@@ -150,8 +150,6 @@ const regionChooser = (function(){
var sketch_percentage = Math.round(intersectionArea / polygonArea * 100); var sketch_percentage = Math.round(intersectionArea / polygonArea * 100);
intersections.addFeature(intersection); intersections.addFeature(intersection);
//TODO: Clean this mess. No jquery
li = document.createElement('li'); li = document.createElement('li');
li.feature = feature; li.feature = feature;
...@@ -175,6 +173,7 @@ const regionChooser = (function(){ ...@@ -175,6 +173,7 @@ const regionChooser = (function(){
label.textContent = text + ")\n"; label.textContent = text + ")\n";
label.prepend(checkbox); label.prepend(checkbox);
// append to DOM element, not to jQuery object
dataPanel[0].appendChild(li); dataPanel[0].appendChild(li);
} }
...@@ -244,8 +243,24 @@ const regionChooser = (function(){ ...@@ -244,8 +243,24 @@ const regionChooser = (function(){
dataPanel.append(text + "<br/>\n"); dataPanel.append(text + "<br/>\n");
} }
publicScope.downloadRegionFromCityGMLs = function(features) { publicScope.downloadStart = function(){
//FIXME: Somehow, no feedback comes after large files are downloaded. :( document.getElementById("download_region_button").disabled = true;
document.documentElement.className = 'wait';
dataPanel.prepend("<h2 id='download_start' class='ok'>Starting to extract region.</h2><br/>\n");
}
publicScope.downloadFinished = function(){
document.documentElement.className = ''; // Stop waiting
document.getElementById("download_start").remove();
dataPanel.prepend("<h2 class='ok'>Region has been extracted</h2><br/>\n");
var button = document.getElementById("download_region_button");
if (button){ // Region might have been modified since download start
button.disabled = false;
}
}
publicScope.downloadFromSelectedCityGMLs = function() {
var features = getSelectedGMLs();
var project = features[0].get("project"); var project = features[0].get("project");
var srsName = features[0].get("srsName"); var srsName = features[0].get("srsName");
...@@ -258,38 +273,15 @@ const regionChooser = (function(){ ...@@ -258,38 +273,15 @@ const regionChooser = (function(){
dataPanel.prepend("<h2 class='error'>Sorry, the CityGML files should all be written with the same coordinate system.</h2><br/>\n"); dataPanel.prepend("<h2 class='error'>Sorry, the CityGML files should all be written with the same coordinate system.</h2><br/>\n");
} }
document.documentElement.className = 'wait';
var citygmlNames = features.map(f => f.get("name")); var citygmlNames = features.map(f => f.get("name"));
// Waiting 100ms in order to let the cursor change if (proj4.defs(srsName)){
setTimeout(function() { console.log("Selected region is written in " + srsName + " coordinate system.");
var start = new Date().getTime(); fxapp.downloadRegionFromCityGMLs(sketchAsWKT(srsName), project, citygmlNames.join(";"), srsName);
if (proj4.defs(srsName)){ } else {
console.log("Selected region is written in " + srsName + " coordinate system."); var msg = "ERROR : Unknown coordinate system : \"" + srsName + "\". Cannot extract any region";
try { console.log(msg);
var count = fxapp.downloadRegionFromCityGMLs(sketchAsWKT(srsName), project, citygmlNames.join(";"), srsName); dataPanel.append(msg + "<br/>\n");
if (count == -1){ }
console.log("No output file has been selected.");
} else {
dataPanel.prepend("<h2 class='ok'>Done! (" + count + " buildings found) </h2><br/>\n");
}
} catch (e) {
console.warn("ERROR : " + e);
dataPanel.prepend("<h2 class='error'>Some problem occured!</h2><br/>\n");
}
var end = new Date().getTime();
var time = end - start;
console.log('Download Execution time: ' + (time / 1000).toFixed(3) + 's');
setTimeout(function() {
document.getElementById("download_region_button").disabled = false;
document.documentElement.className = ''; // Stop waiting
}, 100);
} else {
var msg = "ERROR : Unknown coordinate system : \"" + srsName + "\". Cannot extract any region";
console.log(msg);
dataPanel.append(msg + "<br/>\n");
}
}, 100);
} }
function displayInfo() { function displayInfo() {
...@@ -388,15 +380,6 @@ const regionChooser = (function(){ ...@@ -388,15 +380,6 @@ const regionChooser = (function(){
console.log("Ready!"); console.log("Ready!");
} }
publicScope.downloadFromSelectedCityGMLs = function() {
document.getElementById("download_region_button").disabled = true;
let selectedGMLs = getSelectedGMLs();
selectedGMLs.forEach(f => f.setStyle(utils.polygon_style("#ffff00", 0.8)));
publicScope.downloadRegionFromCityGMLs(selectedGMLs);
}
publicScope.selectAllOrNone = function(allOrNone) { publicScope.selectAllOrNone = function(allOrNone) {
document.querySelectorAll("input.select_citygml").forEach(c => c.checked = allOrNone); document.querySelectorAll("input.select_citygml").forEach(c => c.checked = allOrNone);
publicScope.isDownloadPossible(); publicScope.isDownloadPossible();
......
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