diff --git a/src/eu/simstadt/regionchooser/ConvexHullCalculator.java b/src/eu/simstadt/regionchooser/ConvexHullCalculator.java index ccb016df87e2e99feeb58232267f3c4574ac5654..45358edf4f4a46af74efabffda9bc4cf1ddabb4e 100644 --- a/src/eu/simstadt/regionchooser/ConvexHullCalculator.java +++ b/src/eu/simstadt/regionchooser/ConvexHullCalculator.java @@ -3,6 +3,10 @@ import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; +import org.osgeo.proj4j.BasicCoordinateTransform; +import org.osgeo.proj4j.CRSFactory; +import org.osgeo.proj4j.CoordinateReferenceSystem; +import org.osgeo.proj4j.ProjCoordinate; import com.vividsolutions.jts.algorithm.ConvexHull; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; @@ -16,10 +20,10 @@ public class ConvexHullCalculator { - //TODO: Convert coordinates to WGS84 public static Geometry calculateFromCityGML(Path citygmlPath) throws NumberFormatException, XPathParseException, NavException, XPathEvalException, IOException { + GeometryFactory geometryFactory = new GeometryFactory(); ArrayList<Coordinate> allPoints = new ArrayList<Coordinate>(); CityGmlIterator citygml = new CityGmlIterator(citygmlPath); for (BuildingXmlNode buildingXmlNode : citygml) { @@ -30,8 +34,25 @@ public static Geometry calculateFromCityGML(Path citygmlPath) } ConvexHull ch = new com.vividsolutions.jts.algorithm.ConvexHull( - allPoints.toArray(new Coordinate[allPoints.size()]), new GeometryFactory()); - return ch.getConvexHull(); - } + allPoints.toArray(new Coordinate[allPoints.size()]), geometryFactory); + + // Convert convex hull in original coordinates to WGS84 coordinates. + // NOTE: It would be much easier with import org.geotools.referencing.CRS; instead of Proj4J + // NOTE: It's faster to convert to WGS84 once the convex hull is calculated, because there are fewer points + Coordinate[] convexHullcoordinates = ch.getConvexHull().getCoordinates(); + + CRSFactory CRS_FACTORY = new CRSFactory(); + CoordinateReferenceSystem wgs84 = CRS_FACTORY.createFromName("EPSG:4326"); + CoordinateReferenceSystem originalCRS = citygml.getCRS(); + BasicCoordinateTransform transformToWgs84 = new BasicCoordinateTransform(originalCRS, wgs84); + for (int i = 0; i < convexHullcoordinates.length; i++) { + ProjCoordinate wgs84Coordinate = transformToWgs84.transform( + new ProjCoordinate(convexHullcoordinates[i].x, convexHullcoordinates[i].y), + new ProjCoordinate()); + convexHullcoordinates[i] = new Coordinate(wgs84Coordinate.x, wgs84Coordinate.y); + } + + return geometryFactory.createPolygon(convexHullcoordinates); + } } diff --git a/test/eu/simstadt/regionchooser/test/ConvexHullCalculatorTests.java b/test/eu/simstadt/regionchooser/test/ConvexHullCalculatorTests.java index 72485f7306ba0e0b833a14cd7e84a0492edf3849..59fa855384de52183626a08af0a26ada35ed5e46 100644 --- a/test/eu/simstadt/regionchooser/test/ConvexHullCalculatorTests.java +++ b/test/eu/simstadt/regionchooser/test/ConvexHullCalculatorTests.java @@ -22,8 +22,7 @@ public void testExtractConvexHullFromOneBuilding() throws Throwable { Path citygmlPath = repo.resolve("Gruenbuehl.proj/20140218_Gruenbuehl_LOD2_1building.gml"); Geometry hull = ConvexHullCalculator.calculateFromCityGML(citygmlPath); assertEquals(hull.getCoordinates().length, 4 + 1); // Convex hull of a building should be a closed rectangle - // Point someBuildingPoint = gf.createPoint(new Coordinate(3515960.36, 5415667.91)); // Original coordinates, GSK3 - Point someBuildingPoint = gf.createPoint(new Coordinate(9.21656126408, 48.8782253597)); // WGS84 + Point someBuildingPoint = gf.createPoint(new Coordinate(9.216845, 48.878196)); // WGS84 assertTrue("Hull should contain every building point", hull.contains(someBuildingPoint)); }