Source

...

Target

Commits (2)
Showing with 51 additions and 7 deletions
+51 -7
......@@ -4,7 +4,7 @@
<groupId>eu.simstadt</groupId>
<artifactId>region-chooser</artifactId>
<version>0.3.2-SNAPSHOT</version>
<version>0.3.3-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
......
......@@ -52,6 +52,26 @@ private ConvexHullCalculator() {
*/
public static Geometry calculateFromCityGML(Path citygmlPath) throws XPathParseException, IOException {
Polygon originalConvexHull = getConvexHull(citygmlPath);
CoordinateReferenceSystem originalCRS = RegionChooserUtils.crsFromCityGMLHeader(citygmlPath);
Polygon convexHull = RegionChooserUtils.changePolygonCRS(originalConvexHull, originalCRS,
RegionChooserUtils.WGS84);
convexHull.setUserData(originalCRS.toString());
return convexHull;
}
/**
* @param citygmlPath
* @return area of convex hull, in the same unit as original file. Hopefully m², but possibly ft² or even °².
* @throws XPathParseException
*/
public static double calculateArea(Path citygmlPath) throws XPathParseException {
Polygon originalConvexHull = getConvexHull(citygmlPath);
return originalConvexHull.getArea();
}
private static Polygon getConvexHull(Path citygmlPath) throws XPathParseException {
GeometryFactory geometryFactory = new GeometryFactory();
ArrayList<Coordinate> allPoints = new ArrayList<>();
CityGmlIterator citygml = new CityGmlIterator(citygmlPath);
......@@ -70,12 +90,13 @@ public static Geometry calculateFromCityGML(Path citygmlPath) throws XPathParseE
// Convert convex hull in original coordinates to WGS84 coordinates.
// NOTE: It's faster to convert to WGS84 once the convex hull is calculated, because there are fewer points
Polygon originalConvexHull = (Polygon) ch.getConvexHull();
return originalConvexHull;
}
CoordinateReferenceSystem originalCRS = RegionChooserUtils.crsFromCityGMLHeader(citygmlPath);
Polygon convexHull = RegionChooserUtils.changePolygonCRS(originalConvexHull, originalCRS,
RegionChooserUtils.WGS84);
convexHull.setUserData(originalCRS.toString());
return convexHull;
public static Geometry getArea(Path citygmlPath) throws XPathParseException, IOException {
Geometry geometry = calculateFromCityGML(citygmlPath);
RegionChooserUtils.changePolygonCRS((Polygon) geometry, RegionChooserUtils.WGS84, RegionChooserUtils.WGS84);
return geometry;
}
/**
......
......@@ -4,7 +4,6 @@
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
......@@ -46,6 +45,30 @@ public void testExtractConvexHullFromOneSmallRegion() throws IOException, XPathP
assertTrue(hull.contains(somewhereBetweenBuildings), "Hull should contain region between buildings");
}
@Test
public void testAreaFromOneSmallRegion() throws IOException, XPathParseException {
Path citygmlPath = repository.resolve("Gruenbuehl.proj/Gruenbuehl_LOD2_ALKIS_1010.gml");
double squareMeters = ConvexHullCalculator.calculateArea(citygmlPath);
double hectares = squareMeters / 10000;
assertEquals(19.0, hectares, 0.2);
citygmlPath = repository.resolve("NewYork.proj/FamilyCourt_LOD2_with_PLUTO_attributes.gml");
squareMeters = ConvexHullCalculator.calculateArea(citygmlPath);
// Checked with GoogleEarth
assertEquals(13000, squareMeters, 1000);
citygmlPath = repository.resolve("NewYork.proj/ManhattanSmall.gml");
squareMeters = ConvexHullCalculator.calculateArea(citygmlPath);
// Checked with GoogleEarth
double squareKilometers = squareMeters / 1000000;
assertEquals(1.0, squareKilometers, 0.1);
citygmlPath = repository.resolve("Stuttgart.proj/Stuttgart_LOD0_LOD1_small.gml");
squareMeters = ConvexHullCalculator.calculateArea(citygmlPath);
hectares = squareMeters / 10000;
assertEquals(47.5, hectares, 1);
}
@Test
public void testExtractConvexHullFromStoeckachNoBuildingPart() throws IOException, XPathParseException {
Path citygmlPath = repository.resolve("Stuttgart.proj/Stöckach_überarbeitete GML-NoBuildingPart.gml");
......