Commit 782889f0 authored by Eric Duminil's avatar Eric Duminil
Browse files

Refactor and tests

parent af8031da
...@@ -7,9 +7,6 @@ ...@@ -7,9 +7,6 @@
import java.util.Scanner; import java.util.Scanner;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.io.WKTWriter;
import org.osgeo.proj4j.CoordinateReferenceSystem; import org.osgeo.proj4j.CoordinateReferenceSystem;
import picocli.CommandLine; import picocli.CommandLine;
import picocli.CommandLine.Command; import picocli.CommandLine.Command;
...@@ -49,7 +46,6 @@ class RegionChooserCommandLineInterface implements Callable<Integer> ...@@ -49,7 +46,6 @@ class RegionChooserCommandLineInterface implements Callable<Integer>
@Override @Override
public Integer call() throws Exception { public Integer call() throws Exception {
//TODO: Move as much logic to utils as possible
//TODO: Test //TODO: Test
CoordinateReferenceSystem localCRS; CoordinateReferenceSystem localCRS;
...@@ -76,12 +72,8 @@ public Integer call() throws Exception { ...@@ -76,12 +72,8 @@ public Integer call() throws Exception {
} }
if (!localCoordinates) { if (!localCoordinates) {
final WKTReader WKT_READER = new WKTReader();
final WKTWriter WKT_WRITER = new WKTWriter();
// WKT coordinates are in WGS84, so should be first converted to srsName // WKT coordinates are in WGS84, so should be first converted to srsName
Polygon wgs84Polygon = (Polygon) WKT_READER.read(wktPolygon); wktPolygon = RegionChooserUtils.wktPolygonToLocalCRS(wktPolygon, localCRS);
wktPolygon = WKT_WRITER
.write(RegionChooserUtils.changePolygonCRS(wgs84Polygon, RegionChooserUtils.WGS84, localCRS));
} }
LOGGER.info("WKT Polygon expressed in local coordinates: " + wktPolygon); LOGGER.info("WKT Polygon expressed in local coordinates: " + wktPolygon);
......
...@@ -13,6 +13,9 @@ ...@@ -13,6 +13,9 @@
import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Polygon; import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.io.WKTWriter;
import org.osgeo.proj4j.BasicCoordinateTransform; import org.osgeo.proj4j.BasicCoordinateTransform;
import org.osgeo.proj4j.CRSFactory; import org.osgeo.proj4j.CRSFactory;
import org.osgeo.proj4j.CoordinateReferenceSystem; import org.osgeo.proj4j.CoordinateReferenceSystem;
...@@ -111,6 +114,15 @@ public static Polygon changePolygonCRS(Polygon polygonInOriginalCRS, CoordinateR ...@@ -111,6 +114,15 @@ public static Polygon changePolygonCRS(Polygon polygonInOriginalCRS, CoordinateR
return geometryFactory.createPolygon(convexHullcoordinates); return geometryFactory.createPolygon(convexHullcoordinates);
} }
public static String wktPolygonToLocalCRS(String wktPolygonInWGS84, CoordinateReferenceSystem localCRS)
throws ParseException {
final WKTReader wktReader = new WKTReader();
final WKTWriter wktWriter = new WKTWriter();
// WKT coordinates are in WGS84, so should be first converted to srsName
Polygon wgs84Polygon = (Polygon) wktReader.read(wktPolygonInWGS84);
return wktWriter.write(changePolygonCRS(wgs84Polygon, WGS84, localCRS));
}
/** /**
* *
* Fast scan of the 50 first lines of a Citygml file to look for srsName. It might not be as reliable as parsing the * Fast scan of the 50 first lines of a Citygml file to look for srsName. It might not be as reliable as parsing the
......
...@@ -21,10 +21,10 @@ ...@@ -21,10 +21,10 @@
public class RegionExtractor public class RegionExtractor
{ {
private static final WKTReader wktReader = new WKTReader(); private static final WKTReader WKT_READER = new WKTReader();
private static final Logger LOGGER = Logger.getLogger(RegionExtractor.class.getName()); private static final Logger LOGGER = Logger.getLogger(RegionExtractor.class.getName());
private static final GeometryFactory gf = new GeometryFactory(); private static final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory();
/** /**
* Main method behind RegionChooser. Given CityGMLs (as Path[]) and a geometry (as Well-known text POLYGON, in the * Main method behind RegionChooser. Given CityGMLs (as Path[]) and a geometry (as Well-known text POLYGON, in the
...@@ -54,7 +54,7 @@ static StringBuilder selectRegionDirectlyFromCityGML(String wktPolygon, String s ...@@ -54,7 +54,7 @@ static StringBuilder selectRegionDirectlyFromCityGML(String wktPolygon, String s
int buildingsCount = 0; int buildingsCount = 0;
int foundBuildingsCount = 0; int foundBuildingsCount = 0;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
Geometry poly = wktReader.read(wktPolygon); Geometry poly = WKT_READER.read(wktPolygon);
CityGmlIterator citygml = null; CityGmlIterator citygml = null;
for (int i = 0; i < citygmlPaths.length; i++) { for (int i = 0; i < citygmlPaths.length; i++) {
...@@ -68,7 +68,7 @@ static StringBuilder selectRegionDirectlyFromCityGML(String wktPolygon, String s ...@@ -68,7 +68,7 @@ static StringBuilder selectRegionDirectlyFromCityGML(String wktPolygon, String s
buildingsCount += 1; buildingsCount += 1;
if (buildingXmlNode.hasCoordinates()) { if (buildingXmlNode.hasCoordinates()) {
Coordinate coord = new Coordinate(buildingXmlNode.x, buildingXmlNode.y); Coordinate coord = new Coordinate(buildingXmlNode.x, buildingXmlNode.y);
Point point = gf.createPoint(coord); Point point = GEOMETRY_FACTORY.createPoint(coord);
if (point.within(poly)) { if (point.within(poly)) {
foundBuildingsCount++; foundBuildingsCount++;
sb.append(buildingXmlNode.toString()); sb.append(buildingXmlNode.toString());
......
...@@ -7,25 +7,19 @@ ...@@ -7,25 +7,19 @@
import java.util.Arrays; import java.util.Arrays;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.io.ParseException; import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.io.WKTWriter;
import org.osgeo.proj4j.CoordinateReferenceSystem; import org.osgeo.proj4j.CoordinateReferenceSystem;
import com.ximpleware.NavException; import com.ximpleware.NavException;
import com.ximpleware.XPathEvalException; import com.ximpleware.XPathEvalException;
import com.ximpleware.XPathParseException; import com.ximpleware.XPathParseException;
public class RegionExtractorWithDifferentInputTests class RegionExtractorWithDifferentInputTests
{ {
private static final WKTReader WKT_READER = new WKTReader();
private static final WKTWriter WKT_WRITER = new WKTWriter();
private static final Path TEST_REPOSITORY = Paths.get("src/test/resources/testdata/"); private static final Path TEST_REPOSITORY = Paths.get("src/test/resources/testdata/");
//NOTE: This test can be adapted to download a region which is too large for the server. Here with local coordinates
@Test @Test
public void testExtractRegionWithLocalCRS() void testExtractRegionWithLocalCRS()
throws IOException, XPathParseException, NavException, XPathEvalException, ParseException { throws IOException, XPathParseException, NavException, XPathEvalException, ParseException {
String citygml = "DA13_DA14_3D_Buildings_Port_Morris.gml"; String citygml = "DA13_DA14_3D_Buildings_Port_Morris.gml";
String projectName = "NewYork"; String projectName = "NewYork";
...@@ -39,9 +33,8 @@ public void testExtractRegionWithLocalCRS() ...@@ -39,9 +33,8 @@ public void testExtractRegionWithLocalCRS()
"One weird shaped roof should be inside the region"); "One weird shaped roof should be inside the region");
} }
//NOTE: This test can be adapted to download a region which is too large for the server. Here with WGS84 coordinates
@Test @Test
public void testExtractRegionWithWGS84() void testExtractRegionWithWGS84()
throws ParseException, IOException, XPathParseException, NavException, XPathEvalException { throws ParseException, IOException, XPathParseException, NavException, XPathEvalException {
String wgs84WktPolygon = "POLYGON((-73.91140940026597 40.804246732157196,-73.91424181298568 40.80025100302325,-73.90934946374252 40.79755456207104,-73.90561582879378 40.80116062104605,-73.90960695580794 40.80340212653638,-73.91140940026597 40.804246732157196))"; String wgs84WktPolygon = "POLYGON((-73.91140940026597 40.804246732157196,-73.91424181298568 40.80025100302325,-73.90934946374252 40.79755456207104,-73.90561582879378 40.80116062104605,-73.90960695580794 40.80340212653638,-73.91140940026597 40.804246732157196))";
String citygml = "DA13_DA14_3D_Buildings_Port_Morris.gml"; String citygml = "DA13_DA14_3D_Buildings_Port_Morris.gml";
...@@ -49,10 +42,8 @@ public void testExtractRegionWithWGS84() ...@@ -49,10 +42,8 @@ public void testExtractRegionWithWGS84()
Path project = TEST_REPOSITORY.resolve(projectName + ".proj"); Path project = TEST_REPOSITORY.resolve(projectName + ".proj");
Path citygmlPath = project.resolve(citygml); Path citygmlPath = project.resolve(citygml);
Polygon wgs84Polygon = (Polygon) WKT_READER.read(wgs84WktPolygon);
CoordinateReferenceSystem localCRS = RegionChooserUtils.crsFromCityGMLHeader(citygmlPath); CoordinateReferenceSystem localCRS = RegionChooserUtils.crsFromCityGMLHeader(citygmlPath);
String localWktPolygon = WKT_WRITER String localWktPolygon = RegionChooserUtils.wktPolygonToLocalCRS(wgs84WktPolygon, localCRS);
.write(RegionChooserUtils.changePolygonCRS(wgs84Polygon, RegionChooserUtils.WGS84, localCRS));
StringBuilder sb = RegionExtractor.selectRegionDirectlyFromCityGML(localWktPolygon, localCRS.getName(), StringBuilder sb = RegionExtractor.selectRegionDirectlyFromCityGML(localWktPolygon, localCRS.getName(),
citygmlPath); citygmlPath);
assertTrue(sb.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"), assertTrue(sb.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"),
...@@ -61,7 +52,7 @@ public void testExtractRegionWithWGS84() ...@@ -61,7 +52,7 @@ public void testExtractRegionWithWGS84()
//NOTE: This test can be adapted to download a region which is too large for the server. Here with old coordinates from WebSimstadt //NOTE: This test can be adapted to download a region which is too large for the server. Here with old coordinates from WebSimstadt
@Test @Test
public void testExtractRegionWithOldCoordinates() void testExtractRegionWithOldCoordinates()
throws ParseException, IOException, XPathParseException, NavException, XPathEvalException { throws ParseException, IOException, XPathParseException, NavException, XPathEvalException {
String oldFormatPolygon = "(40.81173171854368,-73.93268437431763)\r\n" + String oldFormatPolygon = "(40.81173171854368,-73.93268437431763)\r\n" +
"(40.81069231965162,-73.93068165999941)\r\n" + "(40.81069231965162,-73.93068165999941)\r\n" +
...@@ -98,16 +89,12 @@ public void testExtractRegionWithOldCoordinates() ...@@ -98,16 +89,12 @@ public void testExtractRegionWithOldCoordinates()
Path project = TEST_REPOSITORY.resolve(projectName + ".proj"); Path project = TEST_REPOSITORY.resolve(projectName + ".proj");
Path citygmlPath = project.resolve(citygml); Path citygmlPath = project.resolve(citygml);
Polygon wgs84Polygon = (Polygon) WKT_READER.read(wgs84WktPolygon);
CoordinateReferenceSystem localCRS = RegionChooserUtils.crsFromCityGMLHeader(citygmlPath); CoordinateReferenceSystem localCRS = RegionChooserUtils.crsFromCityGMLHeader(citygmlPath);
String localWktPolygon = WKT_WRITER String localWktPolygon = RegionChooserUtils.wktPolygonToLocalCRS(wgs84WktPolygon, localCRS);
.write(RegionChooserUtils.changePolygonCRS(wgs84Polygon, RegionChooserUtils.WGS84, localCRS));
StringBuilder sb = RegionExtractor.selectRegionDirectlyFromCityGML(localWktPolygon, localCRS.getName(), StringBuilder sb = RegionExtractor.selectRegionDirectlyFromCityGML(localWktPolygon, localCRS.getName(),
citygmlPath); citygmlPath);
assertTrue(sb.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"), assertTrue(sb.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"),
"One weird shaped roof should be inside the region"); "One weird shaped roof should be inside the region");
} }
//TODO: Write a method to merge RegionChooser results from multiple gmls
} }
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