Commit 66b4fd21 authored by Eric Duminil's avatar Eric Duminil
Browse files

Allows RegionChooserCLI to export hull as WKT

parent a1a1a997
No related merge requests found
Pipeline #10994 passed with stage
in 40 seconds
Showing with 73 additions and 26 deletions
+73 -26
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import org.locationtech.proj4j.CoordinateReferenceSystem; import org.locationtech.proj4j.CoordinateReferenceSystem;
import eu.simstadt.regionchooser.RegionChooserCLI.GetVersion; import eu.simstadt.regionchooser.RegionChooserCLI.GetVersion;
import eu.simstadt.regionchooser.fast_xml_parser.ConvexHullCalculator;
import picocli.CommandLine; import picocli.CommandLine;
import picocli.CommandLine.Command; import picocli.CommandLine.Command;
import picocli.CommandLine.IVersionProvider; import picocli.CommandLine.IVersionProvider;
...@@ -24,26 +25,22 @@ ...@@ -24,26 +25,22 @@
* *
*/ */
// Usage: region_chooser [-hlV] [-e=31467] -o=output.gml -w=polygon.wkt -i=input. // Usage: region_chooser [-hlV] [--get-hull] [-e=31467] [-o=output.gml]
// gml[,input.gml...] [-i=input.gml[,input.gml...]]... // [-w=polygon.wkt] -i=input.gml[,input.gml...] [-i=input.gml
// Extracts a region from one or more citygmls. // [,input.gml...]]...
// -i, --input=input.gml[,input.gml...] // Extracts a region from one or more citygmls, or calculates the convex hull.
// Citygml files to extract from // -i, --input=input.gml[,input.gml...]
// -o, --output=output.gml Output file // Citygml files to extract from
// -e, --epsg=31467 EPSG id for coordinate reference system // -o, --output=output.gml Output file
// -l, --local Are WKT coordinates in local CRS? // -e, --epsg=31467 EPSG id for coordinate reference system.
// -w, --wkt=polygon.wkt File containing WKT polygon, or - for stdin // Will use the one from input.gml if unspecified.
// -h, --help Show this help message and exit. // -l, --local Are WKT coordinates in local CRS?
// -V, --version Print version information and exit. // Coordinates are in WGS84 if unspecified.
// -w, --wkt=polygon.wkt File containing WKT polygon, or - for stdin
// --get-hull Calculate the convex hull of the input CityGML files
// Example: // -h, --help Show this help message and exit.
// --input CGSC_Repository/Würzburg.proj/LoD2_566_5516_2_BY.gml,CGSC_Repository/Würzburg.proj/LoD2_568_5516_2_BY.gml // -V, --version Print version information and exit.
// --output ./output.gml @Command(name = "region_chooser", mixinStandardHelpOptions = true, description = "Extracts a region from one or more citygmls, or calculates the convex hull.", sortOptions = false, versionProvider = GetVersion.class)
// --wkt ./grombuhl.txt
@Command(name = "region_chooser", mixinStandardHelpOptions = true, description = "Extracts a region from one or more citygmls.", sortOptions = false, versionProvider = GetVersion.class)
class RegionChooserCLI implements Callable<Integer> class RegionChooserCLI implements Callable<Integer>
{ {
@Spec @Spec
...@@ -53,8 +50,7 @@ class RegionChooserCLI implements Callable<Integer> ...@@ -53,8 +50,7 @@ class RegionChooserCLI implements Callable<Integer>
"--input" }, required = true, split = ",", description = "Citygml files to extract from", paramLabel = "input.gml") "--input" }, required = true, split = ",", description = "Citygml files to extract from", paramLabel = "input.gml")
Path[] citygmls; Path[] citygmls;
@Option(names = { "-o", @Option(names = { "-o", "--output" }, required = false, description = "Output file", paramLabel = "output.gml")
"--output" }, required = true, description = "Output file", paramLabel = "output.gml")
Path outputCityGML; Path outputCityGML;
@Option(names = { "-e", @Option(names = { "-e",
...@@ -66,11 +62,28 @@ class RegionChooserCLI implements Callable<Integer> ...@@ -66,11 +62,28 @@ class RegionChooserCLI implements Callable<Integer>
boolean localCoordinates; boolean localCoordinates;
@Option(names = { "-w", @Option(names = { "-w",
"--wkt" }, required = true, description = "File containing WKT polygon, or - for stdin", paramLabel = "polygon.wkt") "--wkt" }, required = false, description = "File containing WKT polygon, or - for stdin", paramLabel = "polygon.wkt")
String wktFile = "-"; String wktFile;
@Option(names = { "--get-hull" }, description = "Calculate the convex hull of the input CityGML files")
boolean getHull;
@Override @Override
public Integer call() throws Exception { public Integer call() throws Exception {
// Validate that either get-hull is used alone or proper extraction parameters are provided
if (!getHull && (outputCityGML == null || wktFile == null)) {
throw new CommandLine.ParameterException(spec.commandLine(),
"Either --get-hull or both --output and --wkt must be specified");
}
if (getHull) {
// Call the hull calculation function and output the result
String hull = ConvexHullCalculator.calculateFromCityGML(citygmls[0]).toString();
spec.commandLine().getOut().println(hull);
return 0;
}
// Original region extraction logic
CoordinateReferenceSystem localCRS; CoordinateReferenceSystem localCRS;
if (espgId == null) { if (espgId == null) {
...@@ -146,5 +159,4 @@ public String[] getVersion() throws Exception { ...@@ -146,5 +159,4 @@ public String[] getVersion() throws Exception {
return new String[] { RegionChooserUtils.getApplicationVersion() }; return new String[] { RegionChooserUtils.getApplicationVersion() };
} }
} }
} }
\ No newline at end of file
...@@ -53,10 +53,31 @@ public void restore() throws IOException { ...@@ -53,10 +53,31 @@ public void restore() throws IOException {
@Test @Test
void testNoInput() { void testNoInput() {
new CommandLine(new RegionChooserCLI()).execute(""); new CommandLine(new RegionChooserCLI()).execute("");
String expectedErr = "Missing required options: '--input=input.gml', '--output=output.gml', '--wkt=polygon.wkt'"; String expectedErr = "Missing required option: '--input=input.gml'";
assertTrue(err.toString().contains(expectedErr), err.toString() + " should contain " + expectedErr); assertTrue(err.toString().contains(expectedErr), err.toString() + " should contain " + expectedErr);
} }
@Test
void testIncompleteInput() {
new CommandLine(new RegionChooserCLI()).execute("--input=whatever.gml --output=whatever2.gml");
String expectedErr = "Either --get-hull or both --output and --wkt";
assertTrue(err.toString().contains(expectedErr), err.toString() + " should contain " + expectedErr);
}
@Test
void testIncompleteInput2() {
new CommandLine(new RegionChooserCLI()).execute("--input=whatever.gml --wkt=whatever.wkt");
String expectedErr = "Either --get-hull or both --output and --wkt";
assertTrue(err.toString().contains(expectedErr), err.toString() + " should contain " + expectedErr);
}
@Test
void testHelp() {
new CommandLine(new RegionChooserCLI()).execute("--help");
String expectedOut = "Extracts a region from one or more citygmls, or calculates the convex hull.";
assertTrue(out.toString().contains(expectedOut), err.toString() + " should contain " + expectedOut);
}
@Test @Test
void testGetVersion() { void testGetVersion() {
new CommandLine(new RegionChooserCLI()).execute("--version"); new CommandLine(new RegionChooserCLI()).execute("--version");
...@@ -153,6 +174,20 @@ void testExtractRegionWithMissingInput() throws IOException { ...@@ -153,6 +174,20 @@ void testExtractRegionWithMissingInput() throws IOException {
assertFalse(Files.exists(outGML)); assertFalse(Files.exists(outGML));
} }
@Test
void testGetHull() throws IOException {
Path citygml = TEST_REPOSITORY.resolve("Stuttgart.proj/Stuttgart_LOD0_LOD1_small.gml");
new CommandLine(new RegionChooserCLI()).execute("--input=" + citygml, "--get-hull");
String expectedCoords = "POLYGON ((9.17288";
assertTrue(out.toString().contains(expectedCoords), out.toString() + " should contain " + expectedCoords);
out.reset();
citygml = TEST_REPOSITORY.resolve("NewYork.proj/ManhattanSmall.gml");
new CommandLine(new RegionChooserCLI()).execute("--input=" + citygml, "--get-hull");
expectedCoords = "POLYGON ((-73.9977";
assertTrue(out.toString().contains(expectedCoords), out.toString() + " should contain " + expectedCoords);
}
private long countBuildings(Path outGML) throws IOException { private long countBuildings(Path outGML) throws IOException {
return Files.readAllLines(outGML).stream().filter(line -> line.contains("bldg:Building gml:id=")).count(); return Files.readAllLines(outGML).stream().filter(line -> line.contains("bldg:Building gml:id=")).count();
} }
......
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