diff --git a/src/main/java/eu/simstadt/regionchooser/RegionChooserCLI.java b/src/main/java/eu/simstadt/regionchooser/RegionChooserCLI.java
index 11e1232a712b9648b791bd26562fa45cae7d0d1f..5a87b9a759d58c9864bc9cb5e58fa591fdb25b90 100644
--- a/src/main/java/eu/simstadt/regionchooser/RegionChooserCLI.java
+++ b/src/main/java/eu/simstadt/regionchooser/RegionChooserCLI.java
@@ -10,6 +10,7 @@
 import java.util.concurrent.Callable;
 import org.locationtech.proj4j.CoordinateReferenceSystem;
 import eu.simstadt.regionchooser.RegionChooserCLI.GetVersion;
+import eu.simstadt.regionchooser.fast_xml_parser.ConvexHullCalculator;
 import picocli.CommandLine;
 import picocli.CommandLine.Command;
 import picocli.CommandLine.IVersionProvider;
@@ -24,26 +25,22 @@
  *
  */
 
-// Usage: region_chooser [-hlV] [-e=31467] -o=output.gml -w=polygon.wkt -i=input.
-//                       gml[,input.gml...] [-i=input.gml[,input.gml...]]...
-// Extracts a region from one or more citygmls.
-//   -i, --input=input.gml[,input.gml...]
-//                             Citygml files to extract from
-//   -o, --output=output.gml   Output file
-//   -e, --epsg=31467          EPSG id for coordinate reference system
-//   -l, --local               Are WKT coordinates in local CRS?
-//   -w, --wkt=polygon.wkt     File containing WKT polygon, or - for stdin
-//   -h, --help                Show this help message and exit.
-//   -V, --version             Print version information and exit.
-
-
-// Example:
-// --input CGSC_Repository/Würzburg.proj/LoD2_566_5516_2_BY.gml,CGSC_Repository/Würzburg.proj/LoD2_568_5516_2_BY.gml
-// --output ./output.gml
-// --wkt ./grombuhl.txt
-
-
-@Command(name = "region_chooser", mixinStandardHelpOptions = true, description = "Extracts a region from one or more citygmls.", sortOptions = false, versionProvider = GetVersion.class)
+//	Usage: region_chooser [-hlV] [--get-hull] [-e=31467] [-o=output.gml]
+//			[-w=polygon.wkt] -i=input.gml[,input.gml...] [-i=input.gml
+//			[,input.gml...]]...
+//	Extracts a region from one or more citygmls, or calculates the convex hull.
+//	-i, --input=input.gml[,input.gml...]
+//					Citygml files to extract from
+//	-o, --output=output.gml   Output file
+//	-e, --epsg=31467          EPSG id for coordinate reference system.
+//					Will use the one from input.gml if unspecified.
+//	-l, --local               Are WKT coordinates in local CRS?
+//					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
+//	-h, --help                Show this help message and exit.
+//	-V, --version             Print version information and exit.
+@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)
 class RegionChooserCLI implements Callable<Integer>
 {
 	@Spec
@@ -53,8 +50,7 @@ class RegionChooserCLI implements Callable<Integer>
 			"--input" }, required = true, split = ",", description = "Citygml files to extract from", paramLabel = "input.gml")
 	Path[] citygmls;
 
-	@Option(names = { "-o",
-			"--output" }, required = true, description = "Output file", paramLabel = "output.gml")
+	@Option(names = { "-o", "--output" }, required = false, description = "Output file", paramLabel = "output.gml")
 	Path outputCityGML;
 
 	@Option(names = { "-e",
@@ -66,11 +62,28 @@ class RegionChooserCLI implements Callable<Integer>
 	boolean localCoordinates;
 
 	@Option(names = { "-w",
-			"--wkt" }, required = true, description = "File containing WKT polygon, or - for stdin", paramLabel = "polygon.wkt")
-	String wktFile = "-";
+			"--wkt" }, required = false, description = "File containing WKT polygon, or - for stdin", paramLabel = "polygon.wkt")
+	String wktFile;
+
+	@Option(names = { "--get-hull" }, description = "Calculate the convex hull of the input CityGML files")
+	boolean getHull;
 
 	@Override
 	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;
 
 		if (espgId == null) {
@@ -146,5 +159,4 @@ public String[] getVersion() throws Exception {
 			return new String[] { RegionChooserUtils.getApplicationVersion() };
 		}
 	}
-
 }
\ No newline at end of file
diff --git a/src/test/java/eu/simstadt/regionchooser/RegionChooserCLITests.java b/src/test/java/eu/simstadt/regionchooser/RegionChooserCLITests.java
index 20981392383676ade648864e81e9ada3bef37fec..837bbf1ad4b69d8ab8be23f531774bc64e02a49c 100644
--- a/src/test/java/eu/simstadt/regionchooser/RegionChooserCLITests.java
+++ b/src/test/java/eu/simstadt/regionchooser/RegionChooserCLITests.java
@@ -53,10 +53,31 @@ public void restore() throws IOException {
 	@Test
 	void testNoInput() {
 		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);
 	}
 
+	@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
 	void testGetVersion() {
 		new CommandLine(new RegionChooserCLI()).execute("--version");
@@ -153,6 +174,20 @@ void testExtractRegionWithMissingInput() throws IOException {
 		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 {
 		return Files.readAllLines(outGML).stream().filter(line -> line.contains("bldg:Building gml:id=")).count();
 	}