RegionChooserCommandLineInterface.java 3.85 KB
Newer Older
Eric Duminil's avatar
Eric Duminil committed
1
2
package eu.simstadt.regionchooser;

Eric Duminil's avatar
Eric Duminil committed
3
import java.nio.charset.StandardCharsets;
Eric Duminil's avatar
Eric Duminil committed
4
import java.nio.file.Files;
Eric Duminil's avatar
Eric Duminil committed
5
import java.nio.file.Path;
Eric Duminil's avatar
Eric Duminil committed
6
import java.nio.file.Paths;
Eric Duminil's avatar
Eric Duminil committed
7
import java.util.Scanner;
Eric Duminil's avatar
Eric Duminil committed
8
import java.util.concurrent.Callable;
Eric Duminil's avatar
Notes.    
Eric Duminil committed
9
import java.util.logging.Logger;
Eric Duminil's avatar
Eric Duminil committed
10
11
12
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.io.WKTWriter;
Eric Duminil's avatar
Eric Duminil committed
13
import org.osgeo.proj4j.CoordinateReferenceSystem;
Eric Duminil's avatar
Eric Duminil committed
14
15
import picocli.CommandLine;
import picocli.CommandLine.Command;
Eric Duminil's avatar
Eric Duminil committed
16
import picocli.CommandLine.Option;
Eric Duminil's avatar
Eric Duminil committed
17

Eric Duminil's avatar
Eric Duminil committed
18
19
20
21
22
// Example usage:
// --input /home/ricou/Desktop/CGSC_Repository/Würzburg.proj/LoD2_566_5516_2_BY.gml,/home/ricou/Desktop/CGSC_Repository/Würzburg.proj/LoD2_568_5516_2_BY.gml
// --output /home/ricou/Desktop/output.gml
// --wkt /home/ricou/Desktop/grombuhl.txt

Eric Duminil's avatar
Eric Duminil committed
23

Eric Duminil's avatar
Eric Duminil committed
24
@Command(name = "region_chooser", mixinStandardHelpOptions = true, version = "regionChooser x.x", description = "Extracts a region from one or more citygmls.", sortOptions = false)
Eric Duminil's avatar
Eric Duminil committed
25
class RegionChooserCommandLineInterface implements Callable<Integer>
Eric Duminil's avatar
Eric Duminil committed
26
{
Eric Duminil's avatar
Notes.    
Eric Duminil committed
27
28
29

	private static final Logger LOGGER = Logger.getLogger(RegionChooserCommandLineInterface.class.getName());

Eric Duminil's avatar
Eric Duminil committed
30
31
	@Option(names = { "-i",
			"--input" }, required = true, split = ",", description = "Citygml files to extract from", paramLabel = "input.gml")
Eric Duminil's avatar
todo    
Eric Duminil committed
32
	//TODO: Allow folders too?
Eric Duminil's avatar
Eric Duminil committed
33
	Path[] citygmls;
Eric Duminil's avatar
Eric Duminil committed
34

Eric Duminil's avatar
Eric Duminil committed
35
36
	@Option(names = { "-o",
			"--output" }, required = true, description = "Output file", paramLabel = "output.gml")
Eric Duminil's avatar
Eric Duminil committed
37
	Path outputCityGML;
Eric Duminil's avatar
Eric Duminil committed
38

Eric Duminil's avatar
Eric Duminil committed
39
40
	@Option(names = { "-e", "--epsg" }, description = "EPSG id for coordinate reference system", paramLabel = "31467")
	Integer espgId;
Eric Duminil's avatar
Eric Duminil committed
41

Eric Duminil's avatar
Eric Duminil committed
42
43
44
	@Option(names = { "-l",
			"--local" }, description = "Are WKT coordinates in local CRS?", paramLabel = "local_coordinates?")
	boolean localCoordinates;
Eric Duminil's avatar
Eric Duminil committed
45

Eric Duminil's avatar
Eric Duminil committed
46
	@Option(names = { "-w",
Eric Duminil's avatar
Eric Duminil committed
47
			"--wkt" }, required = true, description = "File containing WKT polygon, or - for stdin", paramLabel = "polygon.wkt")
Eric Duminil's avatar
Eric Duminil committed
48
49
	String wktFile = "-";

Eric Duminil's avatar
Eric Duminil committed
50
	@Override
Eric Duminil's avatar
Eric Duminil committed
51
	public Integer call() throws Exception {
Eric Duminil's avatar
todo    
Eric Duminil committed
52
53
		//TODO: Move as much logic to utils as possible
		//TODO: Test
Eric Duminil's avatar
Eric Duminil committed
54
		CoordinateReferenceSystem localCRS;
Eric Duminil's avatar
Eric Duminil committed
55

Eric Duminil's avatar
Eric Duminil committed
56
		if (espgId == null) {
Eric Duminil's avatar
Eric Duminil committed
57
			localCRS = RegionChooserUtils.crsFromCityGMLHeader(citygmls[0]);
Eric Duminil's avatar
Eric Duminil committed
58
		} else {
Eric Duminil's avatar
Eric Duminil committed
59
			localCRS = RegionChooserUtils.crsFromSrsName("EPSG:" + espgId);
Eric Duminil's avatar
Eric Duminil committed
60
		}
Eric Duminil's avatar
Notes.    
Eric Duminil committed
61
		LOGGER.info("Coordinate system: " + localCRS);
Eric Duminil's avatar
Eric Duminil committed
62

Eric Duminil's avatar
Eric Duminil committed
63
		String wktPolygon;
Eric Duminil's avatar
Eric Duminil committed
64

Eric Duminil's avatar
Eric Duminil committed
65
66
		if (wktFile.equals("-")) {
			if (System.in.available() == 0) {
Eric Duminil's avatar
Eric Duminil committed
67
				throw new IllegalArgumentException("Please provide \"POLYGON((x1 y1, x2 y2, ...))\" to standard input.");
Eric Duminil's avatar
Eric Duminil committed
68
			} else {
Eric Duminil's avatar
Eric Duminil committed
69
				wktPolygon = getInput();
Eric Duminil's avatar
Eric Duminil committed
70
			}
Eric Duminil's avatar
Eric Duminil committed
71
		} else {
Eric Duminil's avatar
Eric Duminil committed
72
73
74
75
			wktPolygon = new String(Files.readAllBytes(Paths.get(wktFile)), StandardCharsets.UTF_8);
			if (wktPolygon.isEmpty()) {
				throw new IllegalArgumentException("Please write \"POLYGON((x1 y1, x2 y2, ...))\" inside " + wktFile);
			}
Eric Duminil's avatar
Eric Duminil committed
76
		}
Eric Duminil's avatar
Eric Duminil committed
77

Eric Duminil's avatar
Eric Duminil committed
78
		if (!localCoordinates) {
Eric Duminil's avatar
Eric Duminil committed
79
80
			final WKTReader WKT_READER = new WKTReader();
			final WKTWriter WKT_WRITER = new WKTWriter();
Eric Duminil's avatar
Eric Duminil committed
81
			// WKT coordinates are in WGS84, so should be first converted to srsName
Eric Duminil's avatar
Eric Duminil committed
82
83
84
			Polygon wgs84Polygon = (Polygon) WKT_READER.read(wktPolygon);
			wktPolygon = WKT_WRITER
					.write(RegionChooserUtils.changePolygonCRS(wgs84Polygon, RegionChooserUtils.WGS84, localCRS));
Eric Duminil's avatar
Eric Duminil committed
85
86
		}

Eric Duminil's avatar
Notes.    
Eric Duminil committed
87
		LOGGER.info("WKT Polygon expressed in local coordinates: " + wktPolygon);
Eric Duminil's avatar
Eric Duminil committed
88

Eric Duminil's avatar
Eric Duminil committed
89
		StringBuilder sb = RegionExtractor.selectRegionDirectlyFromCityGML(wktPolygon, localCRS.toString(), citygmls);
Eric Duminil's avatar
Eric Duminil committed
90
91
92

		RegionChooserUtils.writeStringBuilderToFile(sb, outputCityGML);

Eric Duminil's avatar
Eric Duminil committed
93
		return 0;
Eric Duminil's avatar
Eric Duminil committed
94
95
	}

Eric Duminil's avatar
Eric Duminil committed
96
	private static String getInput() {
Eric Duminil's avatar
Eric Duminil committed
97
98
99
		try (Scanner myObj = new Scanner(System.in)) {
			return myObj.nextLine();
		}
Eric Duminil's avatar
Eric Duminil committed
100
101
	}

Eric Duminil's avatar
Eric Duminil committed
102
103
104
105
106
	// this example implements Callable, so parsing, error handling and handling user
	// requests for usage help or version help can be done with one line of code.
	public static void main(String... args) {
		int exitCode = new CommandLine(new RegionChooserCommandLineInterface()).execute(args);
		System.exit(exitCode);
Eric Duminil's avatar
Eric Duminil committed
107
	}
Eric Duminil's avatar
Eric Duminil committed
108
}