From 6ec8f7eaa75ac7215010985c48136651a4150936 Mon Sep 17 00:00:00 2001 From: duminil <duminil@2c044af0-2e85-064f-a0c3-7471430cffcd> Date: Fri, 19 May 2017 13:18:58 +0000 Subject: [PATCH] RegionChooser: Relatively fast and efficient convex hull extractor from CityGML files. --- .../regionchooser/ConvexHullCalculator.java | 29 ++++++++++++++++--- .../test/ConvexHullCalculatorTests.java | 3 +- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/eu/simstadt/regionchooser/ConvexHullCalculator.java b/src/eu/simstadt/regionchooser/ConvexHullCalculator.java index ccb016d..45358ed 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 72485f7..59fa855 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)); } -- GitLab