diff --git a/src/eu/simstadt/regionchooser/ConvexHullCalculator.java b/src/eu/simstadt/regionchooser/ConvexHullCalculator.java new file mode 100644 index 0000000000000000000000000000000000000000..ccb016df87e2e99feeb58232267f3c4574ac5654 --- /dev/null +++ b/src/eu/simstadt/regionchooser/ConvexHullCalculator.java @@ -0,0 +1,37 @@ +package eu.simstadt.regionchooser; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import com.vividsolutions.jts.algorithm.ConvexHull; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.ximpleware.NavException; +import com.ximpleware.XPathEvalException; +import com.ximpleware.XPathParseException; +import eu.simstadt.regionchooser.citygml_parser.BuildingXmlNode; +import eu.simstadt.regionchooser.citygml_parser.CityGmlIterator; + + +public class ConvexHullCalculator +{ + //TODO: Convert coordinates to WGS84 + public static Geometry calculateFromCityGML(Path citygmlPath) + throws NumberFormatException, XPathParseException, NavException, XPathEvalException, IOException { + + ArrayList allPoints = new ArrayList(); + CityGmlIterator citygml = new CityGmlIterator(citygmlPath); + for (BuildingXmlNode buildingXmlNode : citygml) { + allPoints.add(new Coordinate(buildingXmlNode.xMin, buildingXmlNode.yMin)); + allPoints.add(new Coordinate(buildingXmlNode.xMin, buildingXmlNode.yMax)); + allPoints.add(new Coordinate(buildingXmlNode.xMax, buildingXmlNode.yMin)); + allPoints.add(new Coordinate(buildingXmlNode.xMax, buildingXmlNode.yMax)); + } + + ConvexHull ch = new com.vividsolutions.jts.algorithm.ConvexHull( + allPoints.toArray(new Coordinate[allPoints.size()]), new GeometryFactory()); + return ch.getConvexHull(); + } + +} diff --git a/src/eu/simstadt/regionchooser/RegionExtractor.java b/src/eu/simstadt/regionchooser/RegionExtractor.java index 157eff011204d54a9f8fcfd69eac36edb849a64a..42f2837fa1c5a67895f4bffe5edccdacadb9478c 100644 --- a/src/eu/simstadt/regionchooser/RegionExtractor.java +++ b/src/eu/simstadt/regionchooser/RegionExtractor.java @@ -20,7 +20,7 @@ public class RegionExtractor { - static private WKTReader wktReader = new WKTReader(); + private static final WKTReader wktReader = new WKTReader(); private static final Logger LOGGER = Logger.getLogger(RegionExtractor.class.getName()); private static final GeometryFactory gf = new GeometryFactory(); diff --git a/test/eu/simstadt/regionchooser/test/ConvexHullCalculatorTests.java b/test/eu/simstadt/regionchooser/test/ConvexHullCalculatorTests.java new file mode 100644 index 0000000000000000000000000000000000000000..dc5807e2ffa2f8523ab632c95c6afaaffee8dd47 --- /dev/null +++ b/test/eu/simstadt/regionchooser/test/ConvexHullCalculatorTests.java @@ -0,0 +1,38 @@ +package eu.simstadt.regionchooser.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import java.nio.file.Path; +import java.nio.file.Paths; +import org.junit.Test; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.Point; +import eu.simstadt.regionchooser.ConvexHullCalculator; + + +public class ConvexHullCalculatorTests +{ + private static final GeometryFactory gf = new GeometryFactory(); + + @Test + public void testExtractConvexHullFromOneBuilding() throws Throwable { + Path repo = Paths.get("../TestRepository"); + 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)); + assertTrue(hull.contains(someBuildingPoint)); + } + + @Test + public void testExtractConvexHullFromOneSmallRegion() throws Throwable { + Path repo = Paths.get("../TestRepository"); + Path citygmlPath = repo.resolve("Gruenbuehl.proj/Gruenbuehl_LOD2_ALKIS_1010.gml"); + Geometry hull = ConvexHullCalculator.calculateFromCityGML(citygmlPath); + assertTrue(hull.getCoordinates().length > 4); // Convex hull should have at least 4 corners + Point somewhereBetweenBuildings = gf.createPoint(new Coordinate(3515883.6668538367, 5415843.300640578)); + assertTrue(hull.contains(somewhereBetweenBuildings)); + } +}