Commit 9e3cdd50 authored by Eric Duminil's avatar Eric Duminil
Browse files

Write data directly to a file.

parent 9f282455
package eu.simstadt.regionchooser;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Logger;
......@@ -76,16 +78,22 @@ public Void call() throws IOException {
/**
* This method is called from Javascript, with a prepared wktPolygon written in local coordinates.
*/
public void downloadRegionFromCityGMLs(String wktPolygon, String project, String csvCitygmls, String srsName)
public int 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 ;
Path[] paths = Stream.of(csvCitygmls.split(";")).map(s -> citygmlPath(project, s)).toArray(Path[]::new);
StringBuilder sb = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, srsName, paths);
File buildingIdsFile = selectSaveFileWithDialog(project,
File outputFile = selectSaveFileWithDialog(project,
csvCitygmls.replace(";", "_").replace(".gml", ""), "selected_region");
RegionChooserUtils.writeStringBuilderToFile(sb, buildingIdsFile.toPath());
int count;
try (BufferedWriter gmlWriter = Files.newBufferedWriter(outputFile.toPath())) {
count = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, srsName, gmlWriter, paths);
}
return count;
}
......
package eu.simstadt.regionchooser;
import java.io.BufferedWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
......@@ -101,9 +102,10 @@ public Integer call() throws Exception {
logInfo("WKT Polygon expressed in local coordinates: " + wktPolygon);
StringBuilder sb = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, localCRS.toString(), citygmls);
RegionChooserUtils.writeStringBuilderToFile(sb, outputCityGML);
try (BufferedWriter gmlWriter = Files.newBufferedWriter(outputCityGML)) {
int count = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, localCRS.toString(), gmlWriter, citygmls);
logInfo("Found buildings : " + count);
}
return 0;
}
......
package eu.simstadt.regionchooser;
import java.io.IOException;
import java.io.Writer;
import java.nio.file.Path;
import java.util.logging.Logger;
import java.util.regex.Matcher;
......@@ -34,10 +35,12 @@
*
* @param wktPolygon
* @param srsName
* @param output
* @param citygmlPaths
*
*
* @return a StringBuffer, full with the extracted Citygml, including header, buildings and footer.
* @writes the extracted Citygml, including header, buildings and footer to output
* @return counts of found building.
* @throws ParseException
* @throws IOException
* @throws XPathEvalException
......@@ -45,15 +48,11 @@
* @throws XPathParseException
* @throws NumberFormatException
*/
static StringBuilder selectRegionDirectlyFromCityGML(String wktPolygon, String srsName, Path... citygmlPaths)
throws ParseException, XPathParseException, NavException, IOException {
//TODO: Should actually write directly to a bufferedwriter
//TODO: Should return the number of found buildings.
static int selectRegionDirectlyFromCityGML(String wktPolygon, String srsName, Writer sb,
Path... citygmlPaths) throws ParseException, XPathParseException, NavException, IOException {
int buildingsCount = 0;
int foundBuildingsCount = 0;
StringBuilder sb = new StringBuilder();
Geometry poly = WKT_READER.read(wktPolygon);
CityGmlIterator citygml = null;
......@@ -90,7 +89,7 @@ static StringBuilder selectRegionDirectlyFromCityGML(String wktPolygon, String s
LOGGER.info("Buildings found in selected region " + foundBuildingsCount);
sb.append(citygml.getFooter());
return sb;
return foundBuildingsCount;
}
/**
......
......@@ -97,7 +97,7 @@ public String getHeader() throws NavException {
* @return Citygml footer
* @throws NavException
*/
public Object getFooter() throws IOException, NavException {
public String getFooter() throws IOException, NavException {
int footerOffset = buildingOffset + buildingLength;
int footerLength = (int) (Files.size(citygmlPath) - footerOffset);
return navigator.toRawString(footerOffset, footerLength);
......
......@@ -243,8 +243,9 @@ var regionChooser = (function(){
if (proj4.defs(srsName)){
console.log("Selected region is written in " + srsName + " coordinate system.");
try {
fxapp.downloadRegionFromCityGMLs(sketchAsWKT(srsName), project, citygmlNames.join(";"), srsName);
dataPanel.prepend("<h2 class='ok'>Done!</h2><br/>\n");
var count = fxapp.downloadRegionFromCityGMLs(sketchAsWKT(srsName), project, citygmlNames.join(";"), srsName);
//FIXME: count looks wrong. too high.
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");
......
......@@ -94,10 +94,6 @@ void testExtractRegionFromTwoCitygmlsInWGS84() throws IOException {
assertEquals(22, countBuildings(outGML));
}
private long countBuildings(Path outGML) throws IOException {
return Files.readAllLines(outGML).stream().filter(line -> line.contains("bldg:Building gml:id=")).count();
}
@Test
void testExtractRegionWithStandardInput() throws IOException {
String wktPolygon = "POLYGON((-73.9959209576448 40.73286384885367, -73.996317924579 40.732359794090684, -73.9947515145143 40.7315061442504, -73.99422580154739 40.73214841515045, -73.9959209576448 40.73286384885367))";
......@@ -129,5 +125,9 @@ void testExtractRegionWithMissingInput() throws IOException {
assertTrue(err.toString().contains(expectedLog), err.toString() + " should contain " + expectedLog);
assertFalse(Files.exists(outGML));
}
private long countBuildings(Path outGML) throws IOException {
return Files.readAllLines(outGML).stream().filter(line -> line.contains("bldg:Building gml:id=")).count();
}
}
......@@ -3,6 +3,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.StringWriter;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Matcher;
......@@ -35,8 +36,10 @@ void testExtract3BuildingsFromGSK3Model() throws Throwable {
//NOTE: Small region around Martinskirche in Grünbühl
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 citygmlPath = TEST_REPOSITORY.resolve("Gruenbuehl.proj/20140218_Gruenbuehl_LOD2.gml");
String churchGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, "EPSG:31467", citygmlPath)
.toString();
StringWriter gmlWriter = new StringWriter();
int count = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, "EPSG:31467", gmlWriter, citygmlPath);
String churchGMLString = gmlWriter.toString();
assertEquals(3, count);
assertEquals(3, countRegexMatches(churchGMLString, CITY_OBJECT_MEMBER_REGEX));
assertTrue(churchGMLString.contains("Donaustr"));
assertTrue(churchGMLString.contains("DEBW_LOD2_203056"));
......@@ -56,9 +59,11 @@ void testExtract3BuildingsFromGSK3Model() throws Throwable {
void testExtractBuildingsWithCommentsInBetween() throws Throwable {
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 citygmlPath = TEST_REPOSITORY.resolve("NewYork.proj/ManhattanSmall.gml");
String archGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, EPSG_32118, citygmlPath)
.toString();
assertEquals(countRegexMatches(archGMLString, CITY_OBJECT_MEMBER_REGEX), 2);
StringWriter gmlWriter = new StringWriter();
int count = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, EPSG_32118, gmlWriter, citygmlPath);
String archGMLString = gmlWriter.toString();
assertEquals(2, count);
assertEquals(2, countRegexMatches(archGMLString, CITY_OBJECT_MEMBER_REGEX));
assertTrue(archGMLString.contains("WASHINGTON SQUARE"));
assertTrue(archGMLString.contains("uuid_c0980a6e-05ea-4d09-bc83-efab226945a1"));
assertTrue(archGMLString.contains("uuid_0985cebb-922d-4b3e-95e5-15dc6089cd28"));
......@@ -70,8 +75,10 @@ void testExtractBuildingsWithCommentsInBetween() throws Throwable {
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 citygmlPath = TEST_REPOSITORY.resolve("NewYork.proj/FamilyCourt_LOD2_with_PLUTO_attributes.gml");
String familyCourtBuilding = RegionExtractor
.selectRegionDirectlyFromCityGML(wktPolygon, EPSG_32118, citygmlPath).toString();
StringWriter gmlWriter = new StringWriter();
int count = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, EPSG_32118, gmlWriter, citygmlPath);
String familyCourtBuilding = gmlWriter.toString();
assertEquals(1, count);
assertEquals(1, countRegexMatches(familyCourtBuilding, CITY_OBJECT_MEMBER_REGEX));
assertTrue(familyCourtBuilding.contains("Bldg_12210021066"));
assertFalse(
......@@ -95,8 +102,10 @@ void testExtract0BuildingsWithWrongCoordinates() throws Throwable {
//NOTE: Small region, far away from NYC
String wktPolygon = "POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))";
Path citygmlPath = TEST_REPOSITORY.resolve("NewYork.proj/ManhattanSmall.gml");
String emptyGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, EPSG_32118, citygmlPath)
.toString();
StringWriter gmlWriter = new StringWriter();
int count = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, EPSG_32118, gmlWriter, citygmlPath);
String emptyGMLString = gmlWriter.toString();
assertEquals(0, count);
assertEquals(0, countRegexMatches(emptyGMLString, CITY_OBJECT_MEMBER_REGEX));
assertTrue(emptyGMLString.contains(CITY_MODEL_HEADER));
assertTrue(emptyGMLString.contains(CITY_MODEL_FOOTER));
......@@ -107,8 +116,10 @@ void testExtract0BuildingsFromEmptyGML() throws Throwable {
//NOTE: Small region, with too many spaces between coordinates
String wktPolygon = "POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))";
Path citygmlPath = TEST_REPOSITORY.resolve("NewYork.proj/empty_model.gml");
String emptyGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, EPSG_32118, citygmlPath)
.toString();
StringWriter gmlWriter = new StringWriter();
int count = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, EPSG_32118, gmlWriter, citygmlPath);
String emptyGMLString = gmlWriter.toString();
assertEquals(0, count);
assertEquals(0, countRegexMatches(emptyGMLString, CITY_OBJECT_MEMBER_REGEX));
assertTrue(emptyGMLString.contains(CORE_CITY_MODEL_HEADER));
assertTrue(emptyGMLString.contains(CORE_CITY_MODEL_FOOTER));
......@@ -119,8 +130,10 @@ void testExtract0BuildingsFromWeirdGML() throws Throwable {
//NOTE: Small region, with too many spaces between coordinates
String wktPolygon = "POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))";
Path citygmlPath = TEST_REPOSITORY.resolve("NewYork.proj/broken_nyc_lod2.gml");
String emptyGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, EPSG_32118, citygmlPath)
.toString();
StringWriter gmlWriter = new StringWriter();
int count = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, EPSG_32118, gmlWriter, citygmlPath);
String emptyGMLString = gmlWriter.toString();
assertEquals(0, count);
assertEquals(0, countRegexMatches(emptyGMLString, CITY_OBJECT_MEMBER_REGEX));
assertTrue(emptyGMLString.contains(CORE_CITY_MODEL_HEADER));
assertTrue(emptyGMLString.contains(CORE_CITY_MODEL_FOOTER));
......@@ -130,9 +143,11 @@ void testExtract0BuildingsFromWeirdGML() throws Throwable {
void testExtractBuildingsFromCitygmlWithoutZinEnvelope() throws Throwable {
String wktPolygon = "POLYGON((3512683.1280912133 5404783.732132129,3512719.1608604863 5404714.627650777,3512831.40076119 5404768.344155442,3512790.239106708 5404838.614891164,3512683.1280912133 5404783.732132129))";
Path citygmlPath = TEST_REPOSITORY.resolve("Stuttgart.proj/Stuttgart_LOD0_LOD1_small.gml");
String emptyGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, "EPSG:31463", citygmlPath)
.toString();
assertEquals(2, countRegexMatches(emptyGMLString, "<bldg:Building gml:id"));
StringWriter gmlWriter = new StringWriter();
int count = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, "EPSG:31463", gmlWriter, citygmlPath);
String twoBuildings = gmlWriter.toString();
assertEquals(2, count);
assertEquals(2, countRegexMatches(twoBuildings, "<bldg:Building gml:id"));
}
@Test
......@@ -141,9 +156,12 @@ void testExtractBuildingsFrom2Citygmls() throws Throwable {
Path citygml1 = TEST_REPOSITORY.resolve("Stuttgart.proj/Stuttgart_LOD0_LOD1_small.gml");
Path citygml2 = TEST_REPOSITORY.resolve("Stuttgart.proj/Stöckach_überarbeitete GML-NoBuildingPart.gml");
String emptyGMLString = RegionExtractor
.selectRegionDirectlyFromCityGML(wktPolygon, "EPSG:31463", citygml1, citygml2).toString();
assertEquals(17 + 3, countRegexMatches(emptyGMLString, "<bldg:Building gml:id"));
StringWriter gmlWriter = new StringWriter();
int count = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, "EPSG:31463", gmlWriter, citygml1,
citygml2);
String gmlFromTwoGMLs = gmlWriter.toString();
assertEquals(17 + 3, count);
assertEquals(17 + 3, countRegexMatches(gmlFromTwoGMLs, "<bldg:Building gml:id"));
}
......
......@@ -2,6 +2,7 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
......@@ -28,8 +29,9 @@ void testExtractRegionWithLocalCRS()
Path citygmlPath = project.resolve(citygml);
CoordinateReferenceSystem localCRS = RegionChooserUtils.crsFromCityGMLHeader(citygmlPath);
StringBuilder sb = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, localCRS.getName(), citygmlPath);
assertTrue(sb.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"),
StringWriter gmlWriter = new StringWriter();
RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, localCRS.getName(), gmlWriter, citygmlPath);
assertTrue(gmlWriter.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"),
"One weird shaped roof should be inside the region");
}
......@@ -44,9 +46,9 @@ void testExtractRegionWithWGS84()
CoordinateReferenceSystem localCRS = RegionChooserUtils.crsFromCityGMLHeader(citygmlPath);
String localWktPolygon = RegionChooserUtils.wktPolygonToLocalCRS(wgs84WktPolygon, localCRS);
StringBuilder sb = RegionExtractor.selectRegionDirectlyFromCityGML(localWktPolygon, localCRS.getName(),
citygmlPath);
assertTrue(sb.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"),
StringWriter gmlWriter = new StringWriter();
RegionExtractor.selectRegionDirectlyFromCityGML(localWktPolygon, localCRS.getName(), gmlWriter, citygmlPath);
assertTrue(gmlWriter.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"),
"One weird shaped roof should be inside the region");
}
......@@ -90,10 +92,10 @@ void testExtractRegionWithOldCoordinates()
CoordinateReferenceSystem localCRS = RegionChooserUtils.crsFromCityGMLHeader(citygmlPath);
String localWktPolygon = RegionChooserUtils.wktPolygonToLocalCRS(wgs84WktPolygon, localCRS);
StringBuilder sb = RegionExtractor.selectRegionDirectlyFromCityGML(localWktPolygon, localCRS.getName(),
citygmlPath);
StringWriter gmlWriter = new StringWriter();
RegionExtractor.selectRegionDirectlyFromCityGML(localWktPolygon, localCRS.getName(), gmlWriter, citygmlPath);
assertTrue(sb.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"),
assertTrue(gmlWriter.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"),
"One weird shaped roof should be inside the region");
}
}
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