Commit ee1c5dbc authored by Eric Duminil's avatar Eric Duminil
Browse files

Merge branch 'master' into gitlab

parents de9e8bfa eda8d586
Pipeline #625 failed with stage
......@@ -18,8 +18,9 @@ RegionChooser was developed during [SimStadt & SimStadt II](http://simstadt.eu/e
## Usage
* `start.bat` in Windows
* `./start.sh` in Linux
`RegionChooser.bat` in Windows
`./RegionChooser.sh` in Linux
`./RegionChooser.command` in macOS
## Author
......
java -classpath lib/* -Xms512m -Xmx2g -Djava.util.logging.config.file=logging.properties eu.simstadt.regionchooser.RegionChooserFX
\ No newline at end of file
#!/bin/bash
cd "$(dirname "$0")" # set the current working directory to the directory this script is in
java -d64 -classpath lib/*: -Xms512m -Xmx2g -Djava.util.logging.config.file=logging.properties eu.simstadt.regionchooser.RegionChooserFX
#!/bin/bash
java -classpath 'lib/*' -Xms512m -Xmx2g -Djava.util.logging.config.file=logging.properties eu.simstadt.regionchooser.RegionChooserFX
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
......@@ -6,15 +6,23 @@
<formats>
<format>zip</format>
</formats>
<dependencySets>
<dependencySet>
<outputDirectory>/lib</outputDirectory>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.basedir}/buildConfig</directory>
<outputDirectory></outputDirectory>
<filtered>true</filtered>
<includes>
<include>start.bat</include>
<include>start.sh</include>
<include>RegionChooser.bat</include>
<include>RegionChooser.command</include>
<include>RegionChooser.sh</include>
</includes>
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>${project.basedir}</directory>
......@@ -27,14 +35,14 @@
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory></outputDirectory>
<outputDirectory>./lib</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/libs</directory>
<outputDirectory>./libs</outputDirectory>
<directory>${project.build.directory}/lib</directory>
<outputDirectory>./lib</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
......
java -jar ${project.artifactId}-${project.version}.jar
\ No newline at end of file
#!/bin/bash
java -jar ${project.artifactId}-${project.version}.jar
\ No newline at end of file
......@@ -3,19 +3,30 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>eu.simstadt</groupId>
<artifactId>RegionChooser</artifactId>
<version>0.2.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
<junit-jupiter.version>5.6.0</junit-jupiter.version>
</properties>
<scm>
<connection>scm:git:file://${project.baseUri}/.git</connection>
<developerConnection>scm:git:file://${project.baseUri}/.git</developerConnection>
</scm>
<dependencies>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.osgeo/proj4j -->
<dependency>
<groupId>org.osgeo</groupId>
......@@ -37,43 +48,45 @@
</dependencies>
<build>
<plugins>
<!-- Gets info from git, e.g. hash and datetime -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<phase>validate</phase>
<goals>
<goal>copy-dependencies</goal>
<goal>create</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
</configuration>
</execution>
</executions>
<configuration>
<timestampFormat>{0,date,yyyyMMdd}</timestampFormat>
<shortRevisionLength>7</shortRevisionLength>
<doCheck>false</doCheck>
<doUpdate>false</doUpdate>
</configuration>
</plugin>
<!-- Packs everything in a zip -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>eu.simstadt.regionchooser.RegionChooserFX</mainClass>
</manifest>
</archive>
<descriptors>
<descriptor>${basedir}/buildConfig/assemblyDesc.xml</descriptor>
</descriptors>
</configuration>
<version>3.2.0</version>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<id>regionchooser</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>${basedir}/buildConfig/assemblyDesc.xml</descriptor>
</descriptors>
<finalName>RegionChooser_${project.version}_${scmBranch}_${timestamp}_${buildNumber}</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
......@@ -84,10 +97,13 @@
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<mainClass>eu.simstadt.regionchooser.RegionChooserFX</mainClass>
</manifest>
<manifestEntries>
<Implementation-URL>http://simstadt.hft-stuttgart.de/</Implementation-URL>
<Implementation-Version>${project.version} (${scmBranch}, rev. ${buildNumber}, ${timestamp})</Implementation-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>
......
......@@ -21,6 +21,7 @@
private static final CRSFactory CRS_FACTORY = new CRSFactory();
public static final CoordinateReferenceSystem WGS84 = CRS_FACTORY.createFromName("EPSG:4326");
private static final Pattern srsNamePattern = Pattern.compile("(?i)(?<=srsName=[\"'])[^\"']+(?=[\"'])");
private static final int CITYGML_HEADER_LENGTH = 50;
private RegionChooserUtils() {
// only static use
......@@ -41,7 +42,7 @@ private RegionChooserUtils() {
* @param srsName
* @return CoordinateReferenceSystem
*/
public static CoordinateReferenceSystem crsFromSrsName(String srsName) {
private static CoordinateReferenceSystem crsFromSrsName(String srsName) {
// EPSG:31467
Pattern pEPSG = Pattern.compile("^(EPSG:\\d+)$");
Matcher mEPSG = pEPSG.matcher(srsName);
......@@ -116,13 +117,15 @@ public static Polygon changePolygonCRS(Polygon polygonInOriginalCRS, CoordinateR
* @throws IOException
*/
public static CoordinateReferenceSystem crsFromCityGMLHeader(Path citygmlPath) throws IOException {
Optional<String> line = Files.lines(citygmlPath).limit(50).filter(srsNamePattern.asPredicate()).findFirst();
if (line.isPresent()) {
Matcher matcher = srsNamePattern.matcher(line.get());
matcher.find();
return crsFromSrsName(matcher.group());
} else {
throw new IllegalArgumentException("No srsName found in the header of " + citygmlPath);
try (Stream<String> lines = Files.lines(citygmlPath).limit(CITYGML_HEADER_LENGTH)) {
Optional<String> line = lines.filter(srsNamePattern.asPredicate()).findFirst();
if (line.isPresent()) {
Matcher matcher = srsNamePattern.matcher(line.get());
matcher.find();
return crsFromSrsName(matcher.group());
} else {
throw new IllegalArgumentException("No srsName found in the header of " + citygmlPath);
}
}
}
......
package eu.simstadt.geo.fast_xml_parser;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import com.ximpleware.XPathParseException;
......@@ -18,17 +18,17 @@
private void testNoNanInCoordinates(Path citygmlPath) throws XPathParseException {
CityGmlIterator buildingXmlNodes = new CityGmlIterator(citygmlPath);
for (BuildingXmlNode buildingXmlNode : buildingXmlNodes) {
assertTrue("Buildings should have coordinates", buildingXmlNode.hasCoordinates());
assertFalse(COORDINATE_SHOULD_BE_A_DOUBLE, Double.isNaN(buildingXmlNode.x));
assertFalse(COORDINATE_SHOULD_BE_A_DOUBLE, Double.isNaN(buildingXmlNode.y));
assertFalse(COORDINATE_SHOULD_BE_A_DOUBLE, Double.isNaN(buildingXmlNode.xMax));
assertFalse(COORDINATE_SHOULD_BE_A_DOUBLE, Double.isNaN(buildingXmlNode.yMax));
assertFalse(COORDINATE_SHOULD_BE_A_DOUBLE, Double.isNaN(buildingXmlNode.xMin));
assertFalse(COORDINATE_SHOULD_BE_A_DOUBLE, Double.isNaN(buildingXmlNode.yMin));
assertTrue(COORDINATES_SHOULD_BE_PLAUSIBLE, buildingXmlNode.xMax > buildingXmlNode.x);
assertTrue(COORDINATES_SHOULD_BE_PLAUSIBLE, buildingXmlNode.yMax > buildingXmlNode.y);
assertTrue(COORDINATES_SHOULD_BE_PLAUSIBLE, buildingXmlNode.xMin < buildingXmlNode.x);
assertTrue(COORDINATES_SHOULD_BE_PLAUSIBLE, buildingXmlNode.yMin < buildingXmlNode.y);
assertTrue(buildingXmlNode.hasCoordinates(), "Buildings should have coordinates");
assertFalse(Double.isNaN(buildingXmlNode.x), COORDINATE_SHOULD_BE_A_DOUBLE);
assertFalse(Double.isNaN(buildingXmlNode.y), COORDINATE_SHOULD_BE_A_DOUBLE);
assertFalse(Double.isNaN(buildingXmlNode.xMax), COORDINATE_SHOULD_BE_A_DOUBLE);
assertFalse(Double.isNaN(buildingXmlNode.yMax), COORDINATE_SHOULD_BE_A_DOUBLE);
assertFalse(Double.isNaN(buildingXmlNode.xMin), COORDINATE_SHOULD_BE_A_DOUBLE);
assertFalse(Double.isNaN(buildingXmlNode.yMin), COORDINATE_SHOULD_BE_A_DOUBLE);
assertTrue(buildingXmlNode.xMax > buildingXmlNode.x, COORDINATES_SHOULD_BE_PLAUSIBLE);
assertTrue(buildingXmlNode.yMax > buildingXmlNode.y, COORDINATES_SHOULD_BE_PLAUSIBLE);
assertTrue(buildingXmlNode.xMin < buildingXmlNode.x, COORDINATES_SHOULD_BE_PLAUSIBLE);
assertTrue(buildingXmlNode.yMin < buildingXmlNode.y, COORDINATES_SHOULD_BE_PLAUSIBLE);
}
}
......@@ -67,11 +67,11 @@ public void testExtractNoCoordsFromEmptyBuilding() throws XPathParseException {
CityGmlIterator buildingXmlNodes = new CityGmlIterator(citygmlPath);
int counter = 0;
for (BuildingXmlNode buildingXmlNode : buildingXmlNodes) {
assertFalse("Empty Buildings shouldn't have coordinates", buildingXmlNode.hasCoordinates());
assertTrue("Coordinate should be a Nan", Double.isNaN(buildingXmlNode.x));
assertTrue("Coordinate should be a Nan", Double.isNaN(buildingXmlNode.y));
assertFalse(buildingXmlNode.hasCoordinates(), "Empty Buildings shouldn't have coordinates");
assertTrue(Double.isNaN(buildingXmlNode.x), "Coordinate should be a Nan");
assertTrue(Double.isNaN(buildingXmlNode.y), "Coordinate should be a Nan");
counter++;
}
assertEquals("3 buildings should have been analyzed", counter, 3);
assertEquals(3, counter, "3 buildings should have been analyzed");
}
}
package eu.simstadt.geo.fast_xml_parser;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
......@@ -9,7 +9,7 @@
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
......@@ -27,9 +27,9 @@
public void testExtractConvexHullFromOneBuilding() throws IOException, XPathParseException {
Path citygmlPath = repository.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
assertEquals(4 + 1, hull.getCoordinates().length); // Convex hull of a building should be a closed rectangle
Point someBuildingPoint = gf.createPoint(new Coordinate(9.216845, 48.878196)); // WGS84
assertTrue("Hull should contain every building point", hull.contains(someBuildingPoint));
assertTrue(hull.contains(someBuildingPoint), "Hull should contain every building point");
}
@Test
......@@ -39,7 +39,7 @@ public void testExtractConvexHullFromOneSmallRegion() throws IOException, XPathP
assertTrue(hull.getCoordinates().length > 4); // Convex hull should have at least 4 corners
// Point somewhereBetweenBuildings = gf.createPoint(new Coordinate(3515883.6668538367, 5415843.300640578)); // Original coordinates, GSK3
Point somewhereBetweenBuildings = gf.createPoint(new Coordinate(9.21552249084, 48.87980446)); // WGS84
assertTrue("Hull should contain region between buildings", hull.contains(somewhereBetweenBuildings));
assertTrue(hull.contains(somewhereBetweenBuildings), "Hull should contain region between buildings");
}
@Test
......@@ -48,7 +48,7 @@ public void testExtractConvexHullFromStoeckachNoBuildingPart() throws IOExceptio
Geometry hull = ConvexHullCalculator.calculateFromCityGML(citygmlPath);
assertTrue(hull.getCoordinates().length > 4); // Convex hull should have at least 4 corners
Point somewhereBetweenBuildings = gf.createPoint(new Coordinate(9.195212, 48.789062)); // WGS84
assertTrue("Hull should contain region between buildings", hull.contains(somewhereBetweenBuildings));
assertTrue(hull.contains(somewhereBetweenBuildings), "Hull should contain region between buildings");
}
@Test
......@@ -63,13 +63,13 @@ public void testExtractConvexHullFromEveryCitygmlInRepository() throws IOExcepti
long gmlCount = RegionChooserUtils.everyCityGML(repository).count();
AtomicInteger hullCount = new AtomicInteger(0);
ConvexHullCalculator.extractHullsForEveryCityGML(repository, kmlHull -> {
assertTrue("KML hull should contain project name", kmlHull.contains("Data name=\"project\""));
assertTrue("KML hull should contain srs name", kmlHull.contains("Data name=\"srsName\""));
assertTrue("KML hull should contain epsg id", kmlHull.contains("<value>EPSG:"));
assertTrue("KML hull should contain coordinates", kmlHull.contains("<coordinates>"));
assertTrue(kmlHull.contains("Data name=\"project\""), "KML hull should contain project name");
assertTrue(kmlHull.contains("Data name=\"srsName\""), "KML hull should contain srs name");
assertTrue(kmlHull.contains("<value>EPSG:"), "KML hull should contain epsg id");
assertTrue(kmlHull.contains("<coordinates>"), "KML hull should contain coordinates");
hullCount.getAndIncrement();
});
assertTrue("At least " + minHullCount + " citygmls should be present in repository", gmlCount >= minHullCount);
assertTrue("At least " + minHullCount + " hulls should have been calculated", hullCount.get() >= minHullCount);
assertTrue(gmlCount >= minHullCount, "At least " + minHullCount + " citygmls should be present in repository");
assertTrue(hullCount.get() >= minHullCount, "At least " + minHullCount + " hulls should have been calculated");
}
}
package eu.simstadt.regionchooser;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.Test;
import eu.simstadt.geo.RegionChooserUtils;
public class CRSfromCityGMLHeaderTests
{
private Path repo = Paths.get("src/test/resources/testdata");
private void testExtractCSRNameFromHeader(Path citygmlPath, String crsName) throws IOException {
assertEquals(RegionChooserUtils.crsFromCityGMLHeader(citygmlPath).toString(), crsName);
}
@Test
public void testExtractCRSFromStuttgart() throws IOException {
testExtractCSRNameFromHeader(repo.resolve("Stuttgart.proj/Stuttgart_LOD0_LOD1_buildings_and_trees.gml"),
"EPSG:31463");
}
@Test
public void testExtractCRSFromGruenbuehl() throws IOException {
testExtractCSRNameFromHeader(repo.resolve("Gruenbuehl.proj/20140218_Gruenbuehl_LOD2_1building.gml"),
"EPSG:31467");
}
@Test
public void testExtractCRSFromMunich() throws IOException {
testExtractCSRNameFromHeader(repo.resolve("Muenchen.proj/Munich_v_1_0_0.gml"), "EPSG:32632");
}
@Test
public void testExtractCRSFromNYC() throws IOException {
testExtractCSRNameFromHeader(repo.resolve("NewYork.proj/ManhattanSmall.gml"), "EPSG:32118");
}
@Test
public void testExtractCRSFromAachen() throws IOException {
testExtractCSRNameFromHeader(repo.resolve("Others.proj/Aachen_LoD2_293_5623_1_NW.gml"), "EPSG:25832");
}
@Test
public void testExtractCRSFromValladolid() throws IOException {
testExtractCSRNameFromHeader(repo.resolve("Others.proj/Valladolid_Spain_only_header.gml"), "EPSG:25830");
}
@Test
public void testDontExtractCRSFromBrokenCityGML() throws IOException {
Path citygmlPath = repo.resolve("Others.proj/SimpleSolid_MSBS.gml");
assertThrows(IllegalArgumentException.class, () -> {
testExtractCSRNameFromHeader(citygmlPath, "Nothing found. Should throw an exception");
});
}
}
package eu.simstadt.regionchooser;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Test;
import org.junit.jupiter.api.Test;
public class RegionExtractorTests
......@@ -37,19 +37,19 @@ public void testExtract3BuildingsFromGSK3Model() throws Throwable {
Path citygmlPath = TEST_REPOSITORY.resolve("Gruenbuehl.proj/20140218_Gruenbuehl_LOD2.gml");
String churchGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon, "EPSG:31467")
.toString();
assertEquals(countRegexMatches(churchGMLString, CITY_OBJECT_MEMBER_REGEX), 3);
assertEquals(3, countRegexMatches(churchGMLString, CITY_OBJECT_MEMBER_REGEX));
assertTrue(churchGMLString.contains("Donaustr"));
assertTrue(churchGMLString.contains("DEBW_LOD2_203056"));
assertTrue(churchGMLString.contains("DEBW_LOD2_2869"));
assertTrue(churchGMLString.contains("DEBW_LOD2_2909"));
assertTrue(churchGMLString.contains(CORE_CITY_MODEL_HEADER));
assertTrue(churchGMLString.contains(CORE_CITY_MODEL_FOOTER));
assertTrue("The exported CityGML should contain a new envelope with the correct EPSG", churchGMLString
.contains("<gml:Envelope srsName=\"EPSG:31467\" srsDimension=\"3\">"));
assertTrue("The exported CityGML should contain a new envelope", churchGMLString
.contains("<gml:lowerCorner>3515829.0815150724 5415766.204935087 "));
assertTrue("The exported CityGML should contain a new envelope", churchGMLString
.contains("<gml:upperCorner>3515876.489172751 5415823.108586172 "));
assertTrue(churchGMLString.contains("<gml:Envelope srsName=\"EPSG:31467\" srsDimension=\"3\">"),
"The exported CityGML should contain a new envelope with the correct EPSG");
assertTrue(churchGMLString.contains("<gml:lowerCorner>3515829.0815150724 5415766.204935087 "),
"The exported CityGML should contain a new envelope");
assertTrue(churchGMLString.contains("<gml:upperCorner>3515876.489172751 5415823.108586172 "),
"The exported CityGML should contain a new envelope");
}
@Test
......@@ -65,10 +65,10 @@ public void testExtractBuildingsWithoutCommentsInBetween() throws Throwable {
assertTrue(archGMLString.contains("uuid_0985cebb-922d-4b3e-95e5-15dc6089cd28"));
assertTrue(archGMLString.contains(CITY_MODEL_HEADER));
assertTrue(archGMLString.contains(CITY_MODEL_FOOTER));
assertFalse("Comments between buildings shouldn't be extracted",
archGMLString.contains("comment between buildings")); // Comment
assertFalse("Comments after buildings shouldn't be extracted",
archGMLString.contains("comment after last building")); // Comment
assertFalse(archGMLString.contains("comment between buildings"),
"Comments between buildings shouldn't be extracted");
assertFalse(archGMLString.contains("comment after last building"),
"Comments after buildings shouldn't be extracted");
}
@Test
......@@ -77,18 +77,22 @@ public void testExtractBuildingsAndChangeEnvelope() throws Throwable {
Path citygmlPath = TEST_REPOSITORY.resolve("NewYork.proj/FamilyCourt_LOD2_with_PLUTO_attributes.gml");
String familyCourtBuilding = RegionExtractor
.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon, EPSG_32118).toString();
assertEquals(countRegexMatches(familyCourtBuilding, CITY_OBJECT_MEMBER_REGEX), 1);
assertEquals(1, countRegexMatches(familyCourtBuilding, CITY_OBJECT_MEMBER_REGEX));
assertTrue(familyCourtBuilding.contains("Bldg_12210021066"));
assertFalse("The exported CityGML shouldn't contain the original envelope", familyCourtBuilding
.contains("<gml:lowerCorner>298393.46959639067 59277.34021543693 -11.892070104139751</gml:lowerCorner>"));
assertFalse("The exported CityGML shouldn't contain the original envelope", familyCourtBuilding
.contains("<gml:upperCorner>305641.79529639013 67101.44881543722 547.7591871983744</gml:upperCorner>"));
assertTrue("The exported CityGML should contain a new envelope with the original altitudes", familyCourtBuilding
.contains("<gml:lowerCorner>299721.46983062755 61021.99295737501 -11.89"));
assertTrue("The exported CityGML should contain a new envelope with the original altitudes", familyCourtBuilding
.contains("<gml:upperCorner>299823.9079725632 61122.68126771413 547.75"));
assertTrue("The exported CityGML should contain a new envelope with the correct EPSG", familyCourtBuilding
.contains("<gml:Envelope srsName=\"EPSG:32118\" srsDimension=\"3\">"));
assertFalse(
familyCourtBuilding.contains(
"<gml:lowerCorner>298393.46959639067 59277.34021543693 -11.892070104139751</gml:lowerCorner>"),
"The exported CityGML shouldn't contain the original envelope");
assertFalse(
familyCourtBuilding.contains(
"<gml:upperCorner>305641.79529639013 67101.44881543722 547.7591871983744</gml:upperCorner>"),
"The exported CityGML shouldn't contain the original envelope");
assertTrue(familyCourtBuilding.contains("<gml:lowerCorner>299721.46983062755 61021.99295737501 -11.89"),
"The exported CityGML should contain a new envelope with the original altitudes");
assertTrue(familyCourtBuilding.contains("<gml:upperCorner>299823.9079725632 61122.68126771413 547.75"),
"The exported CityGML should contain a new envelope with the original altitudes");
assertTrue(familyCourtBuilding.contains("<gml:Envelope srsName=\"EPSG:32118\" srsDimension=\"3\">"),
"The exported CityGML should contain a new envelope with the correct EPSG");
}
@Test
......@@ -98,7 +102,7 @@ public void testExtract0BuildingsWithWrongCoordinates() throws Throwable {
Path citygmlPath = TEST_REPOSITORY.resolve("NewYork.proj/ManhattanSmall.gml");
String emptyGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon, EPSG_32118)
.toString();
assertEquals(countRegexMatches(emptyGMLString, CITY_OBJECT_MEMBER_REGEX), 0);
assertEquals(0, countRegexMatches(emptyGMLString, CITY_OBJECT_MEMBER_REGEX));
assertTrue(emptyGMLString.contains(CITY_MODEL_HEADER));
assertTrue(emptyGMLString.contains(CITY_MODEL_FOOTER));
}
......@@ -110,7 +114,7 @@ public void testExtract0BuildingsFromEmptyGML() throws Throwable {
Path citygmlPath = TEST_REPOSITORY.resolve("NewYork.proj/empty_model.gml");
String emptyGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon, EPSG_32118)
.toString();
assertEquals(countRegexMatches(emptyGMLString, CITY_OBJECT_MEMBER_REGEX), 0);
assertEquals(0, countRegexMatches(emptyGMLString, CITY_OBJECT_MEMBER_REGEX));
assertTrue(emptyGMLString.contains(CORE_CITY_MODEL_HEADER));
assertTrue(emptyGMLString.contains(CORE_CITY_MODEL_FOOTER));
}
......@@ -122,7 +126,7 @@ public void testExtract0BuildingsFromWeirdGML() throws Throwable {
Path citygmlPath = TEST_REPOSITORY.resolve("NewYork.proj/broken_nyc_lod2.gml");
String emptyGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon, EPSG_32118)
.toString();
assertEquals(countRegexMatches(emptyGMLString, CITY_OBJECT_MEMBER_REGEX), 0);
assertEquals(0, countRegexMatches(emptyGMLString, CITY_OBJECT_MEMBER_REGEX));
assertTrue(emptyGMLString.contains(CORE_CITY_MODEL_HEADER));
assertTrue(emptyGMLString.contains(CORE_CITY_MODEL_FOOTER));
}
......@@ -133,6 +137,6 @@ public void testExtractBuildingsFromCitygmlWithoutZinEnvelope() throws Throwable
Path citygmlPath = TEST_REPOSITORY.resolve("Stuttgart.proj/Stuttgart_LOD0_LOD1_small.gml");
String emptyGMLString = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon, "EPSG:31463")
.toString();
assertEquals(countRegexMatches(emptyGMLString, "<bldg:Building gml:id"), 2);
assertEquals(2, countRegexMatches(emptyGMLString, "<bldg:Building gml:id"));
}
}
package eu.simstadt.regionchooser;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
......@@ -36,8 +36,8 @@ public void testExtractRegionWithLocalCRS()
CoordinateReferenceSystem localCRS = RegionChooserUtils.crsFromCityGMLHeader(citygmlPath);
StringBuilder sb = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon, localCRS.getName());
assertTrue("One weird shaped roof should be inside the region",
sb.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"));
assertTrue(sb.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"),
"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
......@@ -52,11 +52,12 @@ public void testExtractRegionWithWGS84()
Polygon wgs84Polygon = (Polygon) WKT_READER.read(wgs84WktPolygon);
CoordinateReferenceSystem localCRS = RegionChooserUtils.crsFromCityGMLHeader(citygmlPath);
String localWktPolygon = WKT_WRITER.write(RegionChooserUtils.changePolygonCRS(wgs84Polygon, RegionChooserUtils.WGS84, localCRS));
String localWktPolygon = WKT_WRITER
.write(RegionChooserUtils.changePolygonCRS(wgs84Polygon, RegionChooserUtils.WGS84, localCRS));
StringBuilder sb = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, localWktPolygon,
localCRS.getName());
assertTrue("One weird shaped roof should be inside the region",
sb.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"));
assertTrue(sb.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"),
"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 old coordinates from WebSimstadt
......@@ -100,12 +101,13 @@ public void testExtractRegionWithOldCoordinates()
Polygon wgs84Polygon = (Polygon) WKT_READER.read(wgs84WktPolygon);
CoordinateReferenceSystem localCRS = RegionChooserUtils.crsFromCityGMLHeader(citygmlPath);
String localWktPolygon = WKT_WRITER.write(RegionChooserUtils.changePolygonCRS(wgs84Polygon, RegionChooserUtils.WGS84, localCRS));
String localWktPolygon = WKT_WRITER
.write(RegionChooserUtils.changePolygonCRS(wgs84Polygon, RegionChooserUtils.WGS84, localCRS));
StringBuilder sb = RegionExtractor.selectRegionDirectlyFromCityGML(citygmlPath, localWktPolygon,
localCRS.getName());
assertTrue("One weird shaped roof should be inside the region",
sb.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"));
assertTrue(sb.toString().contains("gml_ZVHMQQ6BZGRT0O3Q6RGXF12BDOV49QIZ58XB"),
"One weird shaped roof should be inside the region");
}
//TODO: Write a method to merge RegionChooser results from multiple gmls
......
<?xml version="1.0" encoding="windows-1252" standalone="yes"?>
<core:CityModel xmlns:xal="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0" xmlns:gml="http://www.opengis.net/gml" xmlns:app="http://www.opengis.net/citygml/appearance/1.0" xmlns:core="http://www.opengis.net/citygml/1.0" xmlns:tex="http://www.opengis.net/citygml/texturedsurface/1.0" xmlns:dem="http://www.opengis.net/citygml/relief/1.0" xmlns:veg="http://www.opengis.net/citygml/vegetation/1.0" xmlns:wtr="http://www.opengis.net/citygml/waterbody/1.0" xmlns:tran="http://www.opengis.net/citygml/transportation/1.0" xmlns:bldg="http://www.opengis.net/citygml/building/1.0" xmlns:frn="http://www.opengis.net/citygml/cityfurniture/1.0" xmlns:grp="http://www.opengis.net/citygml/cityobjectgroup/1.0" xmlns:gen="http://www.opengis.net/citygml/generics/1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:luse="http://www.opengis.net/citygml/landuse/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/citygml/building/1.0 http://schemas.opengis.net/citygml/building/1.0/building.xsd http://www.opengis.net/citygml/cityfurniture/1.0 http://schemas.opengis.net/citygml/cityfurniture/1.0/cityFurniture.xsd http://www.opengis.net/citygml/appearance/1.0 http://schemas.opengis.net/citygml/appearance/1.0/appearance.xsd http://www.opengis.net/citygml/cityobjectgroup/1.0 http://schemas.opengis.net/citygml/cityobjectgroup/1.0/cityObjectGroup.xsd http://www.opengis.net/citygml/generics/1.0 http://schemas.opengis.net/citygml/generics/1.0/generics.xsd http://www.opengis.net/citygml/texturedsurface/1.0 http://schemas.opengis.net/citygml/texturedsurface/1.0/texturedSurface.xsd http://www.opengis.net/citygml/relief/1.0 http://schemas.opengis.net/citygml/relief/1.0/relief.xsd http://www.opengis.net/citygml/vegetation/1.0 http://schemas.opengis.net/citygml/vegetation/1.0/vegetation.xsd http://www.opengis.net/citygml/waterbody/1.0 http://schemas.opengis.net/citygml/waterbody/1.0/waterBody.xsd http://www.opengis.net/citygml/transportation/1.0 http://schemas.opengis.net/citygml/transportation/1.0/transportation.xsd http://www.opengis.net/citygml/landuse/1.0 http://schemas.opengis.net/citygml/landuse/1.0/landUse.xsd">
<gml:name>LoD1_293_5623_1_NW</gml:name>
<gml:boundedBy>
<gml:Envelope srsName="urn:adv:crs:ETRS89_UTM32*DE_DHHN92_NH">
<gml:lowerCorner srsDimension="3">293000.0 5623000.0 291.37</gml:lowerCorner>
<gml:upperCorner srsDimension="3">294000.0 5624000.0 294.37</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<core:cityObjectMember>
<bldg:Building gml:id="DENW39AL10003jfi">
<core:creationDate>2015-12-18</core:creationDate>
<core:externalReference>
<core:informationSystem>http://repository.gdi-de.org/schemas/adv/citygml/fdv/art.htm</core:informationSystem>
<core:externalObject>
<core:name>DENW39AL10003jfi</core:name>
</core:externalObject>
</core:externalReference>
<gen:stringAttribute name="DatenquelleDachhoehe">
<gen:value>3000</gen:value>
</gen:stringAttribute>
<gen:stringAttribute name="DatenquelleLage">
<gen:value>1000</gen:value>
</gen:stringAttribute>
<gen:stringAttribute name="Gemeindeschluessel">
<gen:value>05334002</gen:value>
</gen:stringAttribute>
<gen:stringAttribute name="DatenquelleBodenhoehe">
<gen:value>1100</gen:value>
</gen:stringAttribute>
<bldg:function>31001_2000</bldg:function>
<bldg:measuredHeight uom="urn:adv:uom:m">3.0</bldg:measuredHeight>
<bldg:lod1Solid>
<gml:Solid gml:id="UUID_5975d8a4-ac67-451c-ac07-94b17249c272">
<gml:exterior>
<gml:CompositeSurface gml:id="UUID_09896245-a517-4309-8009-6aa452c83241">
<gml:surfaceMember>
<gml:Polygon gml:id="UUID_b9db823d-cc7e-41ed-9dd3-0edae5e35968">
<gml:exterior>
<gml:LinearRing gml:id="UUID_b9db823d-cc7e-41ed-9dd3-0edae5e35968_0_">
<gml:posList srsDimension="3">293419.864 5623614.091 294.37 293420.389 5623616.431 294.37 293420.389 5623616.431 291.37 293419.864 5623614.091 291.37 293419.864 5623614.091 294.37</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="UUID_6ab56fed-c69d-4ca7-ab10-4e1df778ba42">
<gml:exterior>
<gml:LinearRing gml:id="UUID_6ab56fed-c69d-4ca7-ab10-4e1df778ba42_0_">
<gml:posList srsDimension="3">293420.389 5623616.431 294.37 293422.915 5623617.223 294.37 293422.915 5623617.223 291.37 293420.389 5623616.431 291.37 293420.389 5623616.431 294.37</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="UUID_9f7551d0-a458-4959-9b48-75a7bd2eb1a3">
<gml:exterior>
<gml:LinearRing gml:id="UUID_9f7551d0-a458-4959-9b48-75a7bd2eb1a3_0_">
<gml:posList srsDimension="3">293422.915 5623617.223 294.37 293424.598 5623615.468 294.37 293424.598 5623615.468 291.37 293422.915 5623617.223 291.37 293422.915 5623617.223 294.37</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="UUID_6f1c4986-26fd-44bb-9962-d12321915256">
<gml:exterior>
<gml:LinearRing gml:id="UUID_6f1c4986-26fd-44bb-9962-d12321915256_0_">
<gml:posList srsDimension="3">293424.598 5623615.468 294.37 293424.06 5623613.068 294.37 293424.06 5623613.068 291.37 293424.598 5623615.468 291.37 293424.598 5623615.468 294.37</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="UUID_dd97b9a6-a10e-44e6-895d-e94ab9d802b2">
<gml:exterior>
<gml:LinearRing gml:id="UUID_dd97b9a6-a10e-44e6-895d-e94ab9d802b2_0_">
<gml:posList srsDimension="3">293424.06 5623613.068 294.37 293421.595 5623612.293 294.37 293421.595 5623612.293 291.37 293424.06 5623613.068 291.37 293424.06 5623613.068 294.37</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="UUID_d2373d80-6e27-4604-863d-fa730626ffcc">
<gml:exterior>
<gml:LinearRing gml:id="UUID_d2373d80-6e27-4604-863d-fa730626ffcc_0_">
<gml:posList srsDimension="3">293421.595 5623612.293 294.37 293419.864 5623614.091 294.37 293419.864 5623614.091 291.37 293421.595 5623612.293 291.37 293421.595 5623612.293 294.37</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="UUID_b201ece1-17f9-4769-8b45-51e08e763dae">
<gml:exterior>
<gml:LinearRing gml:id="UUID_b201ece1-17f9-4769-8b45-51e08e763dae_0_">
<gml:posList srsDimension="3">293421.595 5623612.293 294.37 293424.06 5623613.068 294.37 293424.598 5623615.468 294.37 293422.915 5623617.223 294.37 293420.389 5623616.431 294.37 293419.864 5623614.091 294.37 293421.595 5623612.293 294.37</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="UUID_5fdc05ef-025a-4212-903c-8bc3d637829d">
<gml:exterior>
<gml:LinearRing gml:id="UUID_5fdc05ef-025a-4212-903c-8bc3d637829d_0_">
<gml:posList srsDimension="3">293419.864 5623614.091 291.37 293420.389 5623616.431 291.37 293422.915 5623617.223 291.37 293424.598 5623615.468 291.37 293424.06 5623613.068 291.37 293421.595 5623612.293 291.37 293419.864 5623614.091 291.37</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:CompositeSurface>
</gml:exterior>
</gml:Solid>
</bldg:lod1Solid>
<bldg:lod1TerrainIntersection>
<gml:MultiCurve>
<gml:curveMember>
<gml:LineString>
<gml:posList srsDimension="3">293419.864 5623614.091 291.706 293420.0 5623614.697 291.676 293420.068 5623615.0 291.665 293420.088 5623615.088 291.663 293420.292 5623616.0 291.64 293420.377 5623616.377 291.634 293420.389 5623616.431 291.633</gml:posList>
</gml:LineString>
</gml:curveMember>
<gml:curveMember>
<gml:LineString>
<gml:posList srsDimension="3">293420.389 5623616.431 291.633 293420.45 5623616.45 291.628 293421.0 5623616.623 291.59 293421.907 5623616.907 291.545 293422.0 5623616.936 291.541 293422.204 5623617.0 291.528 293422.915 5623617.223 291.474</gml:posList>
</gml:LineString>
</gml:curveMember>
<gml:curveMember>
<gml:LineString>
<gml:posList srsDimension="3">293422.915 5623617.223 291.474 293423.0 5623617.134 291.473 293423.066 5623617.066 291.473 293423.129 5623617.0 291.468 293423.555 5623616.555 291.448 293424.0 5623616.092 291.426 293424.045 5623616.045 291.424 293424.088 5623616.0 291.419 293424.534 5623615.534 291.375 293424.598 5623615.468 291.37</gml:posList>
</gml:LineString>
</gml:curveMember>
<gml:curveMember>
<gml:LineString>
<gml:posList srsDimension="3">293424.06 5623613.068 291.407 293424.269 5623614.0 291.418 293424.347 5623614.347 291.405 293424.493 5623615.0 291.401 293424.598 5623615.468 291.37</gml:posList>
</gml:LineString>
</gml:curveMember>
<gml:curveMember>
<gml:LineString>
<gml:posList srsDimension="3">293421.595 5623612.293 291.554 293422.0 5623612.42 291.527 293422.613 5623612.613 291.492 293423.0 5623612.735 291.467 293423.844 5623613.0 291.421 293424.0 5623613.049 291.411 293424.06 5623613.068 291.407</gml:posList>
</gml:LineString>
</gml:curveMember>
<gml:curveMember>
<gml:LineString>
<gml:posList srsDimension="3">293419.864 5623614.091 291.706 293419.952 5623614.0 291.696 293419.975 5623613.975 291.693 293420.0 5623613.95 291.691 293420.466 5623613.466 291.658 293420.914 5623613.0 291.618 293420.956 5623612.956 291.614 293421.0 5623612.911 291.608 293421.447 5623612.447 291.572 293421.595 5623612.293 291.554</gml:posList>
</gml:LineString>
</gml:curveMember>
</gml:MultiCurve>
</bldg:lod1TerrainIntersection>
</bldg:Building>
</core:cityObjectMember>
</core:CityModel>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<core:CityModel xmlns:core="http://www.opengis.net/citygml/1.0" xmlns:gen="http://www.opengis.net/citygml/generics/1.0" xmlns:bldg="http://www.opengis.net/citygml/building/1.0" xmlns:app="http://www.opengis.net/citygml/appearance/1.0" xmlns:dem="http://www.opengis.net/citygml/relief/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/citygml/building/1.0 http://schemas.opengis.net/citygml/building/1.0/building.xsd http://www.opengis.net/citygml/appearance/1.0 http://schemas.opengis.net/citygml/appearance/1.0/appearance.xsd http://www.opengis.net/citygml/relief/1.0 http://schemas.opengis.net/citygml/relief/1.0/relief.xsd http://www.opengis.net/citygml/1.0 http://schemas.opengis.net/citygml/1.0/cityGMLBase.xsd http://www.opengis.net/citygml/generics/1.0 http://schemas.opengis.net/citygml/generics/1.0/generics.xsd">
<core:cityObjectMember>
<bldg:Building gml:id="_Simple_BD.1">
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon gml:id="_Simple_BD.1_PG.1ms">
<gml:exterior>
<gml:LinearRing gml:id="_Simple_BD.1_PG.1_LR.1ms">
<gml:posList srsDimension="3">
10.0 10.0 0.0
10.0 15.0 0.0
13.0 15.0 0.0
13.0 10.0 0.0
10.0 10.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="_Simple_BD.1_PG.2ms">
<gml:exterior>
<gml:LinearRing gml:id="_Simple_BD.1_PG.2_LR.1ms">
<gml:posList srsDimension="3">
13.0 15.0 0.0
13.0 15.0 3.0
13.0 10.0 3.0
13.0 10.0 0.0
13.0 15.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="_Simple_BD.1_PG.3ms">
<gml:exterior>
<gml:LinearRing gml:id="_Simple_BD.1_PG.3_LR.1ms">
<gml:posList srsDimension="3">
10.0 15.0 0.0
10.0 15.0 3.0
11.5 15.0 4.5
13.0 15.0 3.0
13.0 15.0 0.0
10.0 15.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="_Simple_BD.1_PG.4ms">
<gml:exterior>
<gml:LinearRing gml:id="_Simple_BD.1_PG.4_LR.1ms">
<gml:posList srsDimension="3">
10.0 10.0 3.0
10.0 15.0 3.0
10.0 15.0 0.0
10.0 10.0 0.0
10.0 10.0 3.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="_Simple_BD.1_PG.5ms">
<gml:exterior>
<gml:LinearRing gml:id="_Simple_BD.1_PG.5_LR.1ms">
<gml:posList srsDimension="3">
13.0 10.0 0.0
13.0 10.0 3.0
11.5 10.0 4.5
10.0 10.0 3.0
10.0 10.0 0.0
13.0 10.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="_Simple_BD.1_PG.6ms">
<gml:exterior>
<gml:LinearRing gml:id="_Simple_BD.1_PG.6_LR.1ms">
<gml:posList srsDimension="3">
10.0 10.0 3.0
11.5 10.0 4.5
11.5 15.0 4.5
10.0 15.0 3.0
10.0 10.0 3.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="_Simple_BD.1_PG.7ms">
<gml:exterior>
<gml:LinearRing gml:id="_Simple_BD.1_PG.7_LR.1ms">
<gml:posList srsDimension="3">
11.5 10.0 4.5
13.0 10.0 3.0
13.0 15.0 3.0
11.5 15.0 4.5
11.5 10.0 4.5
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
<bldg:boundedBy>
<bldg:WallSurface gml:id="_Simple_BD.1_WallSurface_1">
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon gml:id="_Simple_BD.1_PG.2">
<gml:exterior>
<gml:LinearRing gml:id="_Simple_BD.1_PG.2_LR.1">
<gml:posList srsDimension="3">
13.0 15.0 0.0
13.0 15.0 3.0
13.0 10.0 3.0
13.0 10.0 0.0
13.0 15.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:WallSurface>
</bldg:boundedBy>
<bldg:boundedBy>
<bldg:WallSurface gml:id="_Simple_BD.1_WallSurface_2">
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon gml:id="_Simple_BD.1_PG.3">
<gml:exterior>
<gml:LinearRing gml:id="_Simple_BD.1_PG.3_LR.1">
<gml:posList srsDimension="3">
10.0 15.0 0.0
10.0 15.0 3.0
11.5 15.0 4.5
13.0 15.0 3.0
13.0 15.0 0.0
10.0 15.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:WallSurface>
</bldg:boundedBy>
<bldg:boundedBy>
<bldg:WallSurface gml:id="_Simple_BD.1_WallSurface_3">
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon gml:id="_Simple_BD.1_PG.4">
<gml:exterior>
<gml:LinearRing gml:id="_Simple_BD.1_PG.4_LR.1">
<gml:posList srsDimension="3">
10.0 10.0 3.0
10.0 15.0 3.0
10.0 15.0 0.0
10.0 10.0 0.0
10.0 10.0 3.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:WallSurface>
</bldg:boundedBy>
<bldg:boundedBy>
<bldg:WallSurface gml:id="_Simple_BD.1_WallSurface_4">
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon gml:id="_Simple_BD.1_PG.5">
<gml:exterior>
<gml:LinearRing gml:id="_Simple_BD.1_PG.5_LR.1">
<gml:posList srsDimension="3">
13.0 10.0 0.0
13.0 10.0 3.0
11.5 10.0 4.5
10.0 10.0 3.0
10.0 10.0 0.0
13.0 10.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:WallSurface>
</bldg:boundedBy>
<bldg:boundedBy>
<bldg:RoofSurface gml:id="_Simple_BD.1_RoofSurface_1">
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon gml:id="_Simple_BD.1_PG.6">
<gml:exterior>
<gml:LinearRing gml:id="_Simple_BD.1_PG.6_LR.1">
<gml:posList srsDimension="3">
10.0 10.0 3.0
11.5 10.0 4.5
11.5 15.0 4.5
10.0 15.0 3.0
10.0 10.0 3.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="_Simple_BD.1_PG.7">
<gml:exterior>
<gml:LinearRing gml:id="_Simple_BD.1_PG.7_LR.1">
<gml:posList srsDimension="3">
11.5 10.0 4.5
13.0 10.0 3.0
13.0 15.0 3.0
11.5 15.0 4.5
11.5 10.0 4.5
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:RoofSurface>
</bldg:boundedBy>
<bldg:boundedBy>
<bldg:GroundSurface gml:id="_Simple_BD.1_GroundSurface_1">
<bldg:lod2MultiSurface>
<gml:MultiSurface>
<gml:surfaceMember>
<gml:Polygon gml:id="_Simple_BD.1_PG.1">
<gml:exterior>
<gml:LinearRing gml:id="_Simple_BD.1_PG.1_LR.1">
<gml:posList srsDimension="3">
10.0 10.0 0.0
10.0 15.0 0.0
13.0 15.0 0.0
13.0 10.0 0.0
10.0 10.0 0.0
</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:MultiSurface>
</bldg:lod2MultiSurface>
</bldg:GroundSurface>
</bldg:boundedBy>
</bldg:Building>
</core:cityObjectMember>
</core:CityModel>
\ No newline at end of file
<?xml version='1.0' encoding='utf-8'?>
<core:CityModel xmlns:core='http://www.opengis.net/citygml/2.0' xmlns:app='http://www.opengis.net/citygml/appearance/2.0' xmlns:brid='http://www.opengis.net/citygml/bridge/2.0' xmlns:bldg='http://www.opengis.net/citygml/building/2.0' xmlns:frn='http://www.opengis.net/citygml/cityfurniture/2.0' xmlns:grp='http://www.opengis.net/citygml/cityobjectgroup/2.0' xmlns:gen='http://www.opengis.net/citygml/generics/2.0' xmlns:luse='http://www.opengis.net/citygml/landuse/2.0' xmlns:dem='http://www.opengis.net/citygml/relief/2.0' xmlns:tran='http://www.opengis.net/citygml/transportation/2.0' xmlns:tun='http://www.opengis.net/citygml/tunnel/2.0' xmlns:veg='http://www.opengis.net/citygml/vegetation/2.0' xmlns:wtr='http://www.opengis.net/citygml/waterbody/2.0' xmlns:tex='http://www.opengis.net/citygml/texturedsurface/2.0' xmlns:gml='http://www.opengis.net/gml' xmlns:xal='urn:oasis:names:tc:ciq:xsdschema:xAL:2.0' xmlns:smil20lang='http://www.w3.org/2001/SMIL20/Language' xmlns:smil20='http://www.w3.org/2001/SMIL20/' xmlns:wfs='http://www.opengis.net/wfs' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:noise='http://www.citygml.org/ade/noise_de/2.0' xsi:schemaLocation='http://www.opengis.net/citygml/2.0 http://schemas.opengis.net/citygml/2.0/cityGMLBase.xsd http://www.opengis.net/citygml/appearance/2.0 http://schemas.opengis.net/citygml/appearance/2.0/appearance.xsd http://www.opengis.net/citygml/bridge/2.0 http://schemas.opengis.net/citygml/bridge/2.0/bridge.xsd http://www.opengis.net/citygml/building/2.0 http://schemas.opengis.net/citygml/building/2.0/building.xsd http://www.opengis.net/citygml/cityfurniture/2.0 http://schemas.opengis.net/citygml/cityfurniture/2.0/cityFurniture.xsd http://www.opengis.net/citygml/cityobjectgroup/2.0 http://schemas.opengis.net/citygml/cityobjectgroup/2.0/cityObjectGroup.xsd http://www.opengis.net/citygml/generics/2.0 http://schemas.opengis.net/citygml/generics/2.0/generics.xsd http://www.opengis.net/citygml/landuse/2.0 http://schemas.opengis.net/citygml/landuse/2.0/landUse.xsd http://www.opengis.net/citygml/relief/2.0 http://schemas.opengis.net/citygml/relief/2.0/relief.xsd http://www.opengis.net/citygml/transportation/2.0 http://schemas.opengis.net/citygml/transportation/2.0/transportation.xsd http://www.opengis.net/citygml/tunnel/2.0 http://schemas.opengis.net/citygml/tunnel/2.0/tunnel.xsd http://www.opengis.net/citygml/vegetation/2.0 http://schemas.opengis.net/citygml/vegetation/2.0/vegetation.xsd http://www.opengis.net/citygml/waterbody/2.0 http://schemas.opengis.net/citygml/waterbody/2.0/waterBody.xsd http://www.opengis.net/citygml/texturedsurface/2.0 http://schemas.opengis.net/citygml/texturedsurface/2.0/texturedSurface.xsd http://www.citygml.org/ade/noise_de/2.0 http://schemas.opengis.net/citygml/examples/2.0/ade/noise-ade/CityGML-NoiseADE.xsd '>
<gml:name>4 DE MARZO, VALLADOLID (SPAIN) LOD2</gml:name>
<gml:boundedBy>
<gml:Envelope srsName='urn:ogc:def:crs:EPSG::25830' srsDimension='3'>
<gml:lowerCorner>354759.866 4610778.142 680.66</gml:lowerCorner>
<gml:upperCorner>355145.627 4611001.435 728.36</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
</core:CityModel>
\ No newline at end of file
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