Commit b8bac3e6 authored by Luna Riegel's avatar Luna Riegel
Browse files

Merge branch 'dev' into 'master'

CityDoctor Version 3.18.2

See merge request !40
parents 947020ff 4b27a7e4
Pipeline #12385 passed with stage
in 2 minutes and 4 seconds
...@@ -32,6 +32,5 @@ public interface CityGmlConsumer { ...@@ -32,6 +32,5 @@ public interface CityGmlConsumer {
} }
// public void endOfFile();
} }
...@@ -28,6 +28,7 @@ import java.nio.file.Path; ...@@ -28,6 +28,7 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
...@@ -43,8 +44,6 @@ import javax.xml.validation.Schema; ...@@ -43,8 +44,6 @@ import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory; import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator; import javax.xml.validation.Validator;
import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
import de.hft.stuttgart.citydoctor2.datastructure.ImplicitGeometryHolder;
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
...@@ -84,8 +83,11 @@ import org.xmlobjects.schema.SchemaHandlerException; ...@@ -84,8 +83,11 @@ import org.xmlobjects.schema.SchemaHandlerException;
import org.xmlobjects.stream.XMLReader; import org.xmlobjects.stream.XMLReader;
import org.xmlobjects.stream.XMLReaderFactory; import org.xmlobjects.stream.XMLReaderFactory;
import de.hft.stuttgart.citydoctor2.check.error.XMLValidationError;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel; import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject; import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
import de.hft.stuttgart.citydoctor2.datastructure.ImplicitGeometryHolder;
import de.hft.stuttgart.citydoctor2.mapper.citygml3.Citygml3FeatureMapper; import de.hft.stuttgart.citydoctor2.mapper.citygml3.Citygml3FeatureMapper;
import de.hft.stuttgart.citydoctor2.mapper.citygml3.GMLValidationHandler; import de.hft.stuttgart.citydoctor2.mapper.citygml3.GMLValidationHandler;
import de.hft.stuttgart.citydoctor2.math.Vector3d; import de.hft.stuttgart.citydoctor2.math.Vector3d;
...@@ -129,9 +131,9 @@ public class CityGmlParser { ...@@ -129,9 +131,9 @@ public class CityGmlParser {
private static CityGMLContext context; private static CityGMLContext context;
private static List<QName> chunkProperties = new ArrayList<>(); private static List<QName> chunkProperties = new ArrayList<>();
static { static {
System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"); System.setProperty("javax.xml.transform.TransformerFactory",
"com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
FACTORY = SAXParserFactory.newInstance(); FACTORY = SAXParserFactory.newInstance();
try { try {
FACTORY.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); FACTORY.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false);
...@@ -147,7 +149,7 @@ public class CityGmlParser { ...@@ -147,7 +149,7 @@ public class CityGmlParser {
private CityGmlParser() { private CityGmlParser() {
} }
public static synchronized CityGMLContext getContext() { public static synchronized CityGMLContext setupContext() {
if (context == null) { if (context == null) {
try { try {
context = CityGMLContext.newInstance(CityGmlParser.class.getClassLoader()); context = CityGMLContext.newInstance(CityGmlParser.class.getClassLoader());
...@@ -166,13 +168,17 @@ public class CityGmlParser { ...@@ -166,13 +168,17 @@ public class CityGmlParser {
} }
/** /**
* Parses a given CityGML file and collects the contained CityObject Features in a {@link CityDoctorModel}. * Parses a given CityGML file and collects the contained CityObject Features in
* a {@link CityDoctorModel}.
* <p/> * <p/>
* The nested parse uses an {@link de.hft.stuttgart.citydoctor2.database.UnconnectedCache UnconnectedCache}, which * The nested parse uses an
* is not connected to the database. * {@link de.hft.stuttgart.citydoctor2.database.UnconnectedCache
* UnconnectedCache}, which is not connected to the database.
* <p/> * <p/>
* Nested parsing should only be used for accessing Features in auxiliary, small CityGML files, e.g. parsing of * Nested parsing should only be used for accessing Features in auxiliary, small
* {@link de.hft.stuttgart.citydoctor2.datastructure.LibraryObject LibraryObject} files. * CityGML files, e.g. parsing of
* {@link de.hft.stuttgart.citydoctor2.datastructure.LibraryObject
* LibraryObject} files.
* *
* @param filePath String path to the file * @param filePath String path to the file
* @param config Configuration of the parser * @param config Configuration of the parser
...@@ -186,10 +192,12 @@ public class CityGmlParser { ...@@ -186,10 +192,12 @@ public class CityGmlParser {
} }
/** /**
* Parses a given CityGML file and collects the contained CityObject Features in a {@link CityDoctorModel}. * Parses a given CityGML file and collects the contained CityObject Features in
* a {@link CityDoctorModel}.
* <p/> * <p/>
* Features are held in a non-persistent, embedded Database with an in-memory upstream cache. Thus, strong references * Features are held in a non-persistent, embedded Database with an in-memory
* to {@link CityObject} are to be avoided, to allow for the memory management of the cache. * upstream cache. Thus, strong references to {@link CityObject} are to be
* avoided, to allow for the memory management of the cache.
* *
* @param filePath String path to the file * @param filePath String path to the file
* @param config Configuration of the parser * @param config Configuration of the parser
...@@ -202,12 +210,13 @@ public class CityGmlParser { ...@@ -202,12 +210,13 @@ public class CityGmlParser {
return parseCityGmlFile(filePath, config, null, null); return parseCityGmlFile(filePath, config, null, null);
} }
/** /**
* Parses a given CityGML file and collects the contained CityObject Features in a {@link CityDoctorModel}. * Parses a given CityGML file and collects the contained CityObject Features in
* a {@link CityDoctorModel}.
* <p/> * <p/>
* Features are held in a non-persistent, embedded Database with an in-memory upstream cache. Thus, strong references * Features are held in a non-persistent, embedded Database with an in-memory
* to {@link CityObject} are to be avoided, to allow for the memory management of the cache. * upstream cache. Thus, strong references to {@link CityObject} are to be
* avoided, to allow for the memory management of the cache.
* *
* @param filePath String path to the file * @param filePath String path to the file
* @param config Configuration of the parser * @param config Configuration of the parser
...@@ -222,10 +231,12 @@ public class CityGmlParser { ...@@ -222,10 +231,12 @@ public class CityGmlParser {
} }
/** /**
* Parses a given CityGML file and collects the contained CityObject Features in a {@link CityDoctorModel}. * Parses a given CityGML file and collects the contained CityObject Features in
* a {@link CityDoctorModel}.
* <p/> * <p/>
* Features are held in a non-persistent, embedded Database with an in-memory upstream cache. Thus, strong references * Features are held in a non-persistent, embedded Database with an in-memory
* to {@link CityObject} are to be avoided, to allow for the memory management of the cache. * upstream cache. Thus, strong references to {@link CityObject} are to be
* avoided, to allow for the memory management of the cache.
* *
* @param filePath String path to the file * @param filePath String path to the file
* @param config Configuration of the parser * @param config Configuration of the parser
...@@ -241,18 +252,22 @@ public class CityGmlParser { ...@@ -241,18 +252,22 @@ public class CityGmlParser {
} }
/** /**
* Parses a given CityGML file and collects the contained CityObject Features in a {@link CityDoctorModel}. * Parses a given CityGML file and collects the contained CityObject Features in
* a {@link CityDoctorModel}.
* <p/> * <p/>
* Features are held in a non-persistent, embedded Database with an in-memory upstream cache. Thus, strong references * Features are held in a non-persistent, embedded Database with an in-memory
* to {@link CityObject} are to be avoided, to allow for the memory management of the cache. * upstream cache. Thus, strong references to {@link CityObject} are to be
* avoided, to allow for the memory management of the cache.
* *
* @param filePath String path to the file * @param filePath String path to the file
* @param config Configuration of the parser * @param config Configuration of the parser
* @param l Listener hook for tracking of parsing progress * @param l Listener hook for tracking of parsing progress
* @param handler Validation handler for GML-file validation * @param handler Validation handler for GML-file validation
* @param verbose If verbosity is enabled the parser will write info logs to the logger * @param verbose If verbosity is enabled the parser will write info logs to
* @param unconnected If true the parser will use an {@link de.hft.stuttgart.citydoctor2.database.UnconnectedCache UnconnectedCache} * the logger
* to collect the parsed CityObjects * @param unconnected If true the parser will use an
* {@link de.hft.stuttgart.citydoctor2.database.UnconnectedCache
* UnconnectedCache} to collect the parsed CityObjects
* @return A {@link CityDoctorModel} object with the parsed Features * @return A {@link CityDoctorModel} object with the parsed Features
* @throws CityGmlParseException if parsing of the CityGML-file failed * @throws CityGmlParseException if parsing of the CityGML-file failed
* @throws InvalidGmlFileException if the GMLValidationHandler found an error * @throws InvalidGmlFileException if the GMLValidationHandler found an error
...@@ -260,15 +275,12 @@ public class CityGmlParser { ...@@ -260,15 +275,12 @@ public class CityGmlParser {
private static CityDoctorModel parseCityGmlFile(String filePath, ParserConfiguration config, ProgressListener l, private static CityDoctorModel parseCityGmlFile(String filePath, ParserConfiguration config, ProgressListener l,
GMLValidationHandler handler, boolean verbose, boolean unconnected) GMLValidationHandler handler, boolean verbose, boolean unconnected)
throws CityGmlParseException, InvalidGmlFileException { throws CityGmlParseException, InvalidGmlFileException {
CityGMLContext context = getContext(); CityGMLContext context = setupContext();
Path file = Paths.get(filePath); Path file = Paths.get(filePath);
List<String> validationIssues = Collections.emptyList();
if (config.getValidate()) { if (config.getValidate()) {
List<String> messages = validateFile(context, handler, file); validationIssues = validateFile(handler, file);
if (!messages.isEmpty()) {
throw new InvalidGmlFileException("Invalid GML File. First error: \n" + messages.get(0));
}
} }
try { try {
parseEpsgCodeFromFile(file, config, verbose); parseEpsgCodeFromFile(file, config, verbose);
CityGMLInputFactory in = context.createCityGMLInputFactory() CityGMLInputFactory in = context.createCityGMLInputFactory()
...@@ -277,21 +289,17 @@ public class CityGmlParser { ...@@ -277,21 +289,17 @@ public class CityGmlParser {
if (l != null) { if (l != null) {
ois.addListener(l::updateProgress); ois.addListener(l::updateProgress);
} }
return readAndKeepFeatures(config, file, in, ois, verbose, unconnected); CityDoctorModel model = readAndKeepFeatures(config, file, in, ois, verbose, unconnected);
for (String xmlError : validationIssues) {
model.addGlobalError(new XMLValidationError(xmlError));
}
return model;
} }
} catch (CityGMLReadException | IOException e) { } catch (CityGMLReadException | IOException e) {
throw new CityGmlParseException("Failed to read CityGML file", e); throw new CityGmlParseException("Failed to read CityGML file", e);
} }
} }
public static void streamCityGml(String file, ParserConfiguration config, CityGmlConsumer cityObjectConsumer,
String outputFile) throws CityGmlParseException {
Path f = Paths.get(file);
streamCityGml(f, config, null, cityObjectConsumer, outputFile);
}
public static void streamCityGml(File file, ParserConfiguration parserConfig, CityGmlConsumer cityObjectConsumer, public static void streamCityGml(File file, ParserConfiguration parserConfig, CityGmlConsumer cityObjectConsumer,
String outputFile) throws CityGmlParseException { String outputFile) throws CityGmlParseException {
streamCityGml(file.toPath(), parserConfig, null, cityObjectConsumer, outputFile); streamCityGml(file.toPath(), parserConfig, null, cityObjectConsumer, outputFile);
...@@ -338,18 +346,18 @@ public class CityGmlParser { ...@@ -338,18 +346,18 @@ public class CityGmlParser {
private static void readAndDiscardFeatures(Path file, ParserConfiguration config, ObservedInputStream ois, private static void readAndDiscardFeatures(Path file, ParserConfiguration config, ObservedInputStream ois,
CityGmlConsumer cityObjectConsumer, String outputFile) throws CityGMLReadException { CityGmlConsumer cityObjectConsumer, String outputFile) throws CityGMLReadException {
Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(config, file, false); Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(config, file, false);
readAndDiscardModel(mapper, ois, cityObjectConsumer, outputFile); readAndDiscardModel(mapper, ois, cityObjectConsumer, outputFile, config, file);
} }
private static void readAndDiscardModel(Citygml3FeatureMapper mapper, ObservedInputStream ois, private static void readAndDiscardModel(Citygml3FeatureMapper mapper, ObservedInputStream ois,
CityGmlConsumer cityObjectConsumer, String outputFile) throws CityGMLReadException { CityGmlConsumer cityObjectConsumer, String outputFile, ParserConfiguration config, Path file)
getContext(); throws CityGMLReadException {
setupContext();
CityGMLInputFactory inputFactory = context.createCityGMLInputFactory() CityGMLInputFactory inputFactory = context.createCityGMLInputFactory()
.withChunking(ChunkOptions.chunkByProperties(chunkProperties).skipCityModel(false)); .withChunking(ChunkOptions.chunkByProperties(chunkProperties).skipCityModel(false));
CityGMLChunkWriter writer = null; CityGMLChunkWriter writer = null;
try (CityGMLReader reader = inputFactory.createCityGMLReader(ois)) { try (CityGMLReader reader = inputFactory.createCityGMLReader(ois)) {
CityDoctorModel model = mapper.getModel(); CityDoctorModel model = mapper.getModel();
boolean isInitialized = false; boolean isInitialized = false;
while (reader.hasNext()) { while (reader.hasNext()) {
...@@ -414,7 +422,7 @@ public class CityGmlParser { ...@@ -414,7 +422,7 @@ public class CityGmlParser {
if (outputFile == null) { if (outputFile == null) {
return null; return null;
} }
CityGMLContext gmlContext = CityGmlParser.getContext(); CityGMLContext gmlContext = CityGmlParser.setupContext();
CityGMLVersion version = CityGMLModules.getCityGMLVersion(reader.getName().getNamespaceURI()); CityGMLVersion version = CityGMLModules.getCityGMLVersion(reader.getName().getNamespaceURI());
CityGMLOutputFactory factory = gmlContext.createCityGMLOutputFactory(version); CityGMLOutputFactory factory = gmlContext.createCityGMLOutputFactory(version);
CityGMLChunkWriter writer = factory.createCityGMLChunkWriter(new File(outputFile), CityGMLChunkWriter writer = factory.createCityGMLChunkWriter(new File(outputFile),
...@@ -428,8 +436,8 @@ public class CityGmlParser { ...@@ -428,8 +436,8 @@ public class CityGmlParser {
} }
private static CityDoctorModel readAndKeepFeatures(ParserConfiguration config, Path file, private static CityDoctorModel readAndKeepFeatures(ParserConfiguration config, Path file,
CityGMLInputFactory inputFactory, ObservedInputStream ois, CityGMLInputFactory inputFactory, ObservedInputStream ois, boolean verbose, boolean unconnected)
boolean verbose, boolean unconnected) throws CityGMLReadException { throws CityGMLReadException {
return readAndKeepModel(new Citygml3FeatureMapper(config, file, unconnected), inputFactory, ois, verbose); return readAndKeepModel(new Citygml3FeatureMapper(config, file, unconnected), inputFactory, ois, verbose);
} }
...@@ -444,7 +452,7 @@ public class CityGmlParser { ...@@ -444,7 +452,7 @@ public class CityGmlParser {
CityModel cgmlModel = null; CityModel cgmlModel = null;
CityDoctorModel cdModel = mapper.getModel(); CityDoctorModel cdModel = mapper.getModel();
AutoCloseable parsingContext = cdModel.getCache().startParsingMode(); AutoCloseable parsingContext = cdModel.getCache().startParsingMode();
try (parsingContext){ try (parsingContext) {
List<AbstractCityObject> queuedObjects = new ArrayList<>(); List<AbstractCityObject> queuedObjects = new ArrayList<>();
while (reader.hasNext()) { while (reader.hasNext()) {
AbstractFeature chunk = reader.next(); AbstractFeature chunk = reader.next();
...@@ -469,7 +477,7 @@ public class CityGmlParser { ...@@ -469,7 +477,7 @@ public class CityGmlParser {
if (cgmlModel == null) { if (cgmlModel == null) {
// Add object to queue till the CityModel has been parsed // Add object to queue till the CityModel has been parsed
queuedObjects.add(aco); queuedObjects.add(aco);
}else if (!cdModel.containsGmlId(id)){ } else if (!cdModel.containsGmlId(id)) {
cgmlModel.getCityObjectMembers().add(new AbstractCityObjectProperty(aco)); cgmlModel.getCityObjectMembers().add(new AbstractCityObjectProperty(aco));
} }
} }
...@@ -482,7 +490,8 @@ public class CityGmlParser { ...@@ -482,7 +490,8 @@ public class CityGmlParser {
mapper.setCityModel(new CityModel()); mapper.setCityModel(new CityModel());
for (AbstractCityObject aco : queuedObjects) { for (AbstractCityObject aco : queuedObjects) {
if (!cdModel.containsGmlId(aco.getId())) { if (!cdModel.containsGmlId(aco.getId())) {
mapper.getModel().getCityModel().getCityObjectMembers().add(new AbstractCityObjectProperty(aco)); mapper.getModel().getCityModel().getCityObjectMembers()
.add(new AbstractCityObjectProperty(aco));
} }
} }
} }
...@@ -492,6 +501,7 @@ public class CityGmlParser { ...@@ -492,6 +501,7 @@ public class CityGmlParser {
logger.info(Localization.getText("CityGmlParser.parsedObjects"), logger.info(Localization.getText("CityGmlParser.parsedObjects"),
mapper.getModel().getNumberOfFeatures()); mapper.getModel().getNumberOfFeatures());
} }
mapper.checkUnresolvedReferences();
mapper.setCityGMLVersion(version); mapper.setCityGMLVersion(version);
return mapper.getModel(); return mapper.getModel();
} catch (Exception e) { } catch (Exception e) {
...@@ -501,7 +511,8 @@ public class CityGmlParser { ...@@ -501,7 +511,8 @@ public class CityGmlParser {
} }
} }
private static void parseEpsgCodeFromFile(Path file, ParserConfiguration config, boolean verbose) throws CityGmlParseException { private static void parseEpsgCodeFromFile(Path file, ParserConfiguration config, boolean verbose)
throws CityGmlParseException {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file.toFile()))) { try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file.toFile()))) {
parseEpsgCodeFromStream(bis, config, verbose); parseEpsgCodeFromStream(bis, config, verbose);
} catch (ParserConfigurationException | SAXException | IOException e) { } catch (ParserConfigurationException | SAXException | IOException e) {
...@@ -668,11 +679,12 @@ public class CityGmlParser { ...@@ -668,11 +679,12 @@ public class CityGmlParser {
return CRS_FACTORY.createFromParameters(crsName, params.toArray(new String[0])); return CRS_FACTORY.createFromParameters(crsName, params.toArray(new String[0]));
} }
private static List<String> validateFile(CityGMLContext context, GMLValidationHandler handler, Path file) public static List<String> validateFile(GMLValidationHandler handler, Path file)
throws CityGmlParseException { throws CityGmlParseException {
if (handler == null) { if (handler == null) {
handler = new GMLValidationHandler(); handler = new GMLValidationHandler();
} }
setupContext();
try { try {
SchemaHandler schemaHandler = new ValidationSchemaHandler(context.getDefaultSchemaHandler()); SchemaHandler schemaHandler = new ValidationSchemaHandler(context.getDefaultSchemaHandler());
readAdditionalSchemaDefinitions(context, file, schemaHandler); readAdditionalSchemaDefinitions(context, file, schemaHandler);
...@@ -691,8 +703,7 @@ public class CityGmlParser { ...@@ -691,8 +703,7 @@ public class CityGmlParser {
private static void readAdditionalSchemaDefinitions(CityGMLContext context, Path file, SchemaHandler schemaHandler) private static void readAdditionalSchemaDefinitions(CityGMLContext context, Path file, SchemaHandler schemaHandler)
throws CityGmlParseException { throws CityGmlParseException {
try (XMLReader reader = XMLReaderFactory.newInstance(context.getXMLObjects()) try (XMLReader reader = XMLReaderFactory.newInstance(context.getXMLObjects()).withSchemaHandler(schemaHandler)
.withSchemaHandler(schemaHandler)
.createReader(file)) { .createReader(file)) {
reader.nextTag(); reader.nextTag();
} catch (Exception e) { } catch (Exception e) {
...@@ -710,5 +721,4 @@ public class CityGmlParser { ...@@ -710,5 +721,4 @@ public class CityGmlParser {
} }
} }
...@@ -41,7 +41,6 @@ import java.util.Set; ...@@ -41,7 +41,6 @@ import java.util.Set;
*/ */
public final class CityGmlUtils { public final class CityGmlUtils {
private CityGmlUtils() { private CityGmlUtils() {
// util class // util class
} }
...@@ -91,7 +90,6 @@ public final class CityGmlUtils { ...@@ -91,7 +90,6 @@ public final class CityGmlUtils {
return new CompositeSurface(surfaces); return new CompositeSurface(surfaces);
} }
public static org.xmlobjects.gml.model.geometry.primitives.LinearRing createGmlRing(GeometryFactory factory, public static org.xmlobjects.gml.model.geometry.primitives.LinearRing createGmlRing(GeometryFactory factory,
ParserConfiguration config, LinearRing lr) { ParserConfiguration config, LinearRing lr) {
...@@ -130,7 +128,8 @@ public final class CityGmlUtils { ...@@ -130,7 +128,8 @@ public final class CityGmlUtils {
List<SurfaceProperty> surfaceMember = comp.getSurfaceMembers(); List<SurfaceProperty> surfaceMember = comp.getSurfaceMembers();
for (Polygon cdPoly : geom.getPolygons()) { for (Polygon cdPoly : geom.getPolygons()) {
if (!cdPoly.isLink()) { if (!cdPoly.isLink()) {
org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config); org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly,
config);
if (gmlPoly != null) { if (gmlPoly != null) {
surfaceMember.add(new SurfaceProperty(gmlPoly)); surfaceMember.add(new SurfaceProperty(gmlPoly));
} }
...@@ -150,8 +149,7 @@ public final class CityGmlUtils { ...@@ -150,8 +149,7 @@ public final class CityGmlUtils {
return solid; return solid;
} }
public static MultiSurface createMultiSurface(Geometry geom, GeometryFactory factory, public static MultiSurface createMultiSurface(Geometry geom, GeometryFactory factory, ParserConfiguration config) {
ParserConfiguration config) {
if (geom.getType() != GeometryType.MULTI_SURFACE && geom.getType() != GeometryType.COMPOSITE_SURFACE) { if (geom.getType() != GeometryType.MULTI_SURFACE && geom.getType() != GeometryType.COMPOSITE_SURFACE) {
throw new IllegalArgumentException("This can only handle MultiSurfaces"); throw new IllegalArgumentException("This can only handle MultiSurfaces");
} }
...@@ -162,7 +160,8 @@ public final class CityGmlUtils { ...@@ -162,7 +160,8 @@ public final class CityGmlUtils {
compositeCollections.add(conc.getPartOfComposite()); compositeCollections.add(conc.getPartOfComposite());
} else if (!cdPoly.isLink()) { } else if (!cdPoly.isLink()) {
// is not part of a boundary surface // is not part of a boundary surface
org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config); org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly,
config);
if (gmlPoly != null) { if (gmlPoly != null) {
surfaces.add(new SurfaceProperty(gmlPoly)); surfaces.add(new SurfaceProperty(gmlPoly));
} }
......
...@@ -6,7 +6,7 @@ import de.hft.stuttgart.citydoctor2.check.Checkable; ...@@ -6,7 +6,7 @@ import de.hft.stuttgart.citydoctor2.check.Checkable;
/** /**
* This Visitor removes the check results from a CityObject and the objects in its datastructure. * This Visitor removes the check results from a CityObject and the objects in its datastructure.
*/ */
public class ClearVisitorResultsVisitor extends CheckableUtilsVisitor { public class ClearResultsVisitor extends CheckableUtilsVisitor {
@Override @Override
public void check(Checkable checkable) { public void check(Checkable checkable) {
......
...@@ -65,7 +65,7 @@ public class CityGMLWriterUtils { ...@@ -65,7 +65,7 @@ public class CityGMLWriterUtils {
} }
public static void writeCityModel(String file, CityDoctorModel model) throws CityDoctorWriteException { public static void writeCityModel(String file, CityDoctorModel model) throws CityDoctorWriteException {
CityGMLContext gmlContext = CityGmlParser.getContext(); CityGMLContext gmlContext = CityGmlParser.setupContext();
CityModel cModel = model.getCityModel(); CityModel cModel = model.getCityModel();
CityGMLOutputFactory factory = gmlContext.createCityGMLOutputFactory(model.getCityGMLVersion()); CityGMLOutputFactory factory = gmlContext.createCityGMLOutputFactory(model.getCityGMLVersion());
try (CityGMLWriter writer = factory.createCityGMLWriter(new File(file))) { try (CityGMLWriter writer = factory.createCityGMLWriter(new File(file))) {
......
package org.xmlobjects.xml;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
public class Attributes implements Serializable {
private static final long serialVersionUID = 8942583366234714632L;
private final Map<String, Map<String, TextContent>> attributes = new HashMap<>();
public boolean isEmpty() {
return attributes.isEmpty();
}
public void add(String namespaceURI, String localName, TextContent value) {
attributes.computeIfAbsent(namespaceURI, v -> new HashMap<>()).put(localName, value);
}
public void add(String namespaceURI, String localName, String value) {
add(namespaceURI, localName, TextContent.of(value));
}
public void add(String localName, TextContent value) {
add(XMLConstants.NULL_NS_URI, localName, value);
}
public void add(String localName, String value) {
add(localName, TextContent.of(value));
}
public void add(QName name, TextContent value) {
add(name.getNamespaceURI(), name.getLocalPart(), value);
}
public void add(QName name, String value) {
add(name, TextContent.of(value));
}
public void addAll(String namespaceURI, Map<String, TextContent> attributes) {
this.attributes.computeIfAbsent(namespaceURI, v -> new HashMap<>()).putAll(attributes);
}
public Map<String, Map<String, TextContent>> get() {
return attributes;
}
public Map<String, TextContent> get(String namespaceURI) {
return attributes.getOrDefault(namespaceURI, Collections.emptyMap());
}
public TextContent getValue(String localName) {
return getValue(XMLConstants.NULL_NS_URI, localName);
}
public TextContent getValue(String namespaceURI, String localName) {
return get(namespaceURI).getOrDefault(localName, TextContent.empty());
}
public TextContent getValue(QName name) {
return getValue(name.getNamespaceURI(), name.getLocalPart());
}
public Attributes copy() {
Attributes copy = new Attributes();
copy.attributes.putAll(attributes);
return copy;
}
}
...@@ -6,15 +6,18 @@ CheckContainer.error=Unexpected exception while executing check: {} ...@@ -6,15 +6,18 @@ CheckContainer.error=Unexpected exception while executing check: {}
CheckDialog.availableChecksLabel=Available Checks CheckDialog.availableChecksLabel=Available Checks
CheckDialog.cancelBtn=Cancel CheckDialog.cancelBtn=Cancel
CheckDialog.checkBtn=Check CheckDialog.checkBtn=Check
CheckDialog.checkDescriptionsLabel=Explanations for the requirements are available on CityDoctor's homepage
CheckDialog.checkEnabled=Enabled CheckDialog.checkEnabled=Enabled
CheckDialog.checkName=Name CheckDialog.checkName=Name
CheckDialog.checksDone=Checks done CheckDialog.checksDone=Checks done
CheckDialog.checksReenabledAlert=Some checks have been reenabled so that other wanted checks can be executed\nSee the log for more information. CheckDialog.checksReenabledAlert=Some checks have been reenabled so that other wanted checks can be executed\nSee the log for more information.
CheckDialog.checksTab=Checks CheckDialog.checksTab=Checks
CheckDialog.clickHereToOpen=[Click here to open]
CheckDialog.failedChecks=Failed to execute checks CheckDialog.failedChecks=Failed to execute checks
CheckDialog.filterTab=Filter CheckDialog.filterTab=Filter
CheckDialog.geometricChecksLabel=Geometric Checks CheckDialog.geometricChecksLabel=Geometric Checks
CheckDialog.globalParametersLabel=Global Parameters CheckDialog.globalParametersLabel=Global Parameters
CheckDialog.homepageHyperlink=https://transfer.hft-stuttgart.de/pages/citydoctor/citydoctorhomepage/en/requirements/
CheckDialog.noPathError=Output path is missing! CheckDialog.noPathError=Output path is missing!
CheckDialog.outputPathBtn=Select CheckDialog.outputPathBtn=Select
CheckDialog.outputPathLabel=Output directory (Required): CheckDialog.outputPathLabel=Output directory (Required):
...@@ -25,12 +28,14 @@ CheckDialog.schematronChooserTitle=Choose schematron file ... ...@@ -25,12 +28,14 @@ CheckDialog.schematronChooserTitle=Choose schematron file ...
CheckDialog.schematronFileLabel=Schematron File: CheckDialog.schematronFileLabel=Schematron File:
CheckDialog.schematronFileNotExisting=Schematron file does not exist, Schematron will be skipped CheckDialog.schematronFileNotExisting=Schematron file does not exist, Schematron will be skipped
CheckDialog.schematronFiles=Schematron Files CheckDialog.schematronFiles=Schematron Files
CheckDialog.selectAllChecksBtn=Select All
CheckDialog.selectBtn=Select CheckDialog.selectBtn=Select
CheckDialog.semanticChecksLabel=Semantic Checks CheckDialog.semanticChecksLabel=Semantic Checks
CheckDialog.startingChecks=Starting checks CheckDialog.startingChecks=Starting checks
CheckDialog.streamCheckLabel=Citymodels are not loaded and kept in memory. Check results are saved to the QualityADE in copies of the input files. CheckDialog.streamCheckLabel=Citymodels are not loaded and kept in memory. Check results are saved to the QualityADE in copies of the input files.
CheckDialog.streamCheckOption=Use low memory mode CheckDialog.streamCheckOption=Use low memory mode
CheckDialog.title=Check Configuration CheckDialog.title=Check Configuration
CheckDialog.unselectAllChecksBtn=Unselect All
CheckDialog.validationConfiguration=Validation Configuration CheckDialog.validationConfiguration=Validation Configuration
CheckDialog.xmlReportsOption=Create XML reports CheckDialog.xmlReportsOption=Create XML reports
Checker.checkFeature=Checking feature: {} Checker.checkFeature=Checking feature: {}
...@@ -70,6 +75,9 @@ CityDoctorValidation.notExactlyOneOutputFile=Specify exactly one file as output. ...@@ -70,6 +75,9 @@ CityDoctorValidation.notExactlyOneOutputFile=Specify exactly one file as output.
CityDoctorValidation.notExactlyOnePDFOutput=Specify exactly one file as pdfReport CityDoctorValidation.notExactlyOnePDFOutput=Specify exactly one file as pdfReport
CityDoctorValidation.notExactlyOneXMLOutput=Specify exactly one file as xmlReport CityDoctorValidation.notExactlyOneXMLOutput=Specify exactly one file as xmlReport
CityDoctorValidation.wrongInputFileFormat=Input file '{}' does not end with .gml or .xml CityDoctorValidation.wrongInputFileFormat=Input file '{}' does not end with .gml or .xml
CityGmlFeatureMapper.crossFeatureReferencesDetected=Model has Features containing cross-feature references without their own copies of the referenced polygons
CityGmlFeatureMapper.emptyCrossFeatureReference=Polygon {} of Feature {} is being referenced in other Features: {}
CityGmlFeatureMapper.unresolvedReferencesDetected=Model contains polygon references that could not be found
CityGmlParser.chunkReadFailed=Failed to read GML file in chunks, falling back to reading the complete file CityGmlParser.chunkReadFailed=Failed to read GML file in chunks, falling back to reading the complete file
CityGmlParser.convertCrsToUtmZoneN=Converting coordinate system to UTM zone {}N CityGmlParser.convertCrsToUtmZoneN=Converting coordinate system to UTM zone {}N
CityGmlParser.convertCrsToUtmZoneS=Converting coordinate system to UTM zone {}S CityGmlParser.convertCrsToUtmZoneS=Converting coordinate system to UTM zone {}S
...@@ -99,6 +107,9 @@ DatabaseHandler.serializationFailure=Serialization of CityObject {} failed! ...@@ -99,6 +107,9 @@ DatabaseHandler.serializationFailure=Serialization of CityObject {} failed!
DatabaseHandler.setupFailure=FATAL ERROR: Creation of embedded database failed! DatabaseHandler.setupFailure=FATAL ERROR: Creation of embedded database failed!
DatabaseHandler.tableFailure=FATAL ERROR: Creation of features table failed! DatabaseHandler.tableFailure=FATAL ERROR: Creation of features table failed!
DatabaseHandler.unmarshallingFailure=Loading of CityObject {} from embedded database failed! DatabaseHandler.unmarshallingFailure=Loading of CityObject {} from embedded database failed!
DatabaseSettings.invalidPath=Properties for database directory and name do not combine to a valid path. Using default value instead
DatabaseSettings.poolSizeLessThanOne=ConnectionPoolSize property was set to be less than 1. Using default value instead
DatabaseSettings.poolSizeNaN=ConnectionPoolSize property is not an integer. Using default value instead
DistanceError.distanceFromPlane=distance from plane DistanceError.distanceFromPlane=distance from plane
ErrorItemVisitor.childId=Child id ErrorItemVisitor.childId=Child id
ErrorItemVisitor.component=Component ErrorItemVisitor.component=Component
......
...@@ -6,15 +6,18 @@ CheckContainer.error=Unerwarteter Fehler bei der Ausf\u00fchrung von Pr\u00fcfun ...@@ -6,15 +6,18 @@ CheckContainer.error=Unerwarteter Fehler bei der Ausf\u00fchrung von Pr\u00fcfun
CheckDialog.availableChecksLabel=Verf\u00fcgbare Pr\u00fcfungen CheckDialog.availableChecksLabel=Verf\u00fcgbare Pr\u00fcfungen
CheckDialog.cancelBtn=Abbrechen CheckDialog.cancelBtn=Abbrechen
CheckDialog.checkBtn=Pr\u00fcfen CheckDialog.checkBtn=Pr\u00fcfen
CheckDialog.checkDescriptionsLabel=Beschreibungen der Pr\u00fcfungen sind auf der CityDoctor Homepage verf\u00fcgbar
CheckDialog.checkEnabled=Aktiv CheckDialog.checkEnabled=Aktiv
CheckDialog.checkName=Name CheckDialog.checkName=Name
CheckDialog.checksDone=Pr\u00fcfung abgeschlossen CheckDialog.checksDone=Pr\u00fcfung abgeschlossen
CheckDialog.checksReenabledAlert=Manche Pr\u00fcfungen wurden reaktiviert damit andere gewollte Pr\u00fcfungen durchgef\u00fchrt werden k\u00f6nnen\nMehr Details sind im Log geschrieben CheckDialog.checksReenabledAlert=Manche Pr\u00fcfungen wurden reaktiviert damit andere gewollte Pr\u00fcfungen durchgef\u00fchrt werden k\u00f6nnen\nMehr Details sind im Log geschrieben
CheckDialog.checksTab=Pr\u00fcfungen CheckDialog.checksTab=Pr\u00fcfungen
CheckDialog.clickHereToOpen=[Hier Klicken zum \u00d6ffnen]
CheckDialog.failedChecks=Konnte Pr\u00fcfungen nicht ausf\u00fchren CheckDialog.failedChecks=Konnte Pr\u00fcfungen nicht ausf\u00fchren
CheckDialog.filterTab=Filter CheckDialog.filterTab=Filter
CheckDialog.geometricChecksLabel=Geometrische Pr\u00fcfungen CheckDialog.geometricChecksLabel=Geometrische Pr\u00fcfungen
CheckDialog.globalParametersLabel=Globale Parameter CheckDialog.globalParametersLabel=Globale Parameter
CheckDialog.homepageHyperlink=https://transfer.hft-stuttgart.de/pages/citydoctor/citydoctorhomepage/de/requirements/
CheckDialog.noPathError=Ausgabepfad wurde nicht gesetzt! CheckDialog.noPathError=Ausgabepfad wurde nicht gesetzt!
CheckDialog.outputPathBtn=Ausw\u00e4hlen CheckDialog.outputPathBtn=Ausw\u00e4hlen
CheckDialog.outputPathLabel=Ausgabeordner (Pflichtfeld): CheckDialog.outputPathLabel=Ausgabeordner (Pflichtfeld):
...@@ -25,12 +28,14 @@ CheckDialog.schematronChooserTitle=W\u00e4hle Schematron Datei ... ...@@ -25,12 +28,14 @@ CheckDialog.schematronChooserTitle=W\u00e4hle Schematron Datei ...
CheckDialog.schematronFileLabel=Schematron Datei: CheckDialog.schematronFileLabel=Schematron Datei:
CheckDialog.schematronFileNotExisting=Schematron Datei existiert nicht, Schematron-Pr\u00fcfung wird \u00fcbersprungen CheckDialog.schematronFileNotExisting=Schematron Datei existiert nicht, Schematron-Pr\u00fcfung wird \u00fcbersprungen
CheckDialog.schematronFiles=Schematron Dateien CheckDialog.schematronFiles=Schematron Dateien
CheckDialog.selectAllChecksBtn=Alle aktivieren
CheckDialog.selectBtn=Ausw\u00e4hlen CheckDialog.selectBtn=Ausw\u00e4hlen
CheckDialog.semanticChecksLabel=Semantische Pr\u00fcfungen CheckDialog.semanticChecksLabel=Semantische Pr\u00fcfungen
CheckDialog.startingChecks=Starte Pr\u00fcfung CheckDialog.startingChecks=Starte Pr\u00fcfung
CheckDialog.streamCheckLabel=Stadtmodelle werden nicht in den Arbeitsspeicher geladen. Ergebnisse werden in der QualityADE in Kopien der Eingangsdateien gespeichert. CheckDialog.streamCheckLabel=Stadtmodelle werden nicht in den Arbeitsspeicher geladen. Ergebnisse werden in der QualityADE in Kopien der Eingangsdateien gespeichert.
CheckDialog.streamCheckOption=Niedrigen Arbeitsspeicherverbrauchsmodus aktivieren CheckDialog.streamCheckOption=Niedrigen Arbeitsspeicherverbrauchsmodus aktivieren
CheckDialog.title=Pr\u00fcfungskonfiguration CheckDialog.title=Pr\u00fcfungskonfiguration
CheckDialog.unselectAllChecksBtn=Alle deaktivieren
CheckDialog.validationConfiguration=Validierungskonfiguration CheckDialog.validationConfiguration=Validierungskonfiguration
CheckDialog.xmlReportsOption=XML-Berichte erstellen CheckDialog.xmlReportsOption=XML-Berichte erstellen
Checker.checkFeature=Pr\u00fcfe Feature: {} Checker.checkFeature=Pr\u00fcfe Feature: {}
...@@ -70,6 +75,9 @@ CityDoctorValidation.notExactlyOneOutputFile=Es muss exakt ein Ausgabedateipfad ...@@ -70,6 +75,9 @@ CityDoctorValidation.notExactlyOneOutputFile=Es muss exakt ein Ausgabedateipfad
CityDoctorValidation.notExactlyOnePDFOutput=Es muss exakt ein Ausgabedateipfad f\u00fcr den PDF-Bericht angegeben werden. CityDoctorValidation.notExactlyOnePDFOutput=Es muss exakt ein Ausgabedateipfad f\u00fcr den PDF-Bericht angegeben werden.
CityDoctorValidation.notExactlyOneXMLOutput=Es muss exakt ein Ausgabedateipfad f\u00fcr den XML-Bericht angegeben werden. CityDoctorValidation.notExactlyOneXMLOutput=Es muss exakt ein Ausgabedateipfad f\u00fcr den XML-Bericht angegeben werden.
CityDoctorValidation.wrongInputFileFormat=Eingabedatei '{}' ist keine .gml oder .xml Datei. CityDoctorValidation.wrongInputFileFormat=Eingabedatei '{}' ist keine .gml oder .xml Datei.
CityGmlFeatureMapper.crossFeatureReferencesDetected=Modell enth\u00e4lt Features mit Feature\u00fcbergreifenden Polygonreferenzen ohne eigene Duplikate
CityGmlFeatureMapper.emptyCrossFeatureReference=Polygon {} in Feature {} wird Feature\u00fcbergreifend referenziert durch Features: {}
CityGmlFeatureMapper.unresolvedReferencesDetected=Modell enth\u00e4lt Features mit Polygonreferenzen welche nicht aufgel\u00f6st werden konnten
CityGmlParser.chunkReadFailed=Konnte Datei nicht in St\u00fccken lesen, versuche komplett zu lesen CityGmlParser.chunkReadFailed=Konnte Datei nicht in St\u00fccken lesen, versuche komplett zu lesen
CityGmlParser.convertCrsToUtmZoneN=Konvertiere Koordinatensystem zu UTM Zone {}N CityGmlParser.convertCrsToUtmZoneN=Konvertiere Koordinatensystem zu UTM Zone {}N
CityGmlParser.convertCrsToUtmZoneS=Konvertiere Koordinatensystem zu UTM Zone {}S CityGmlParser.convertCrsToUtmZoneS=Konvertiere Koordinatensystem zu UTM Zone {}S
...@@ -99,6 +107,9 @@ DatabaseHandler.serializationFailure=Serialisierung des CityObject {} fehlgeschl ...@@ -99,6 +107,9 @@ DatabaseHandler.serializationFailure=Serialisierung des CityObject {} fehlgeschl
DatabaseHandler.setupFailure=KRITISCHER FEHLER: Erstellen der eingebetteten Datenbank fehlgeschlagen! DatabaseHandler.setupFailure=KRITISCHER FEHLER: Erstellen der eingebetteten Datenbank fehlgeschlagen!
DatabaseHandler.tableFailure=KRITISCHER FEHLER: Erstellen der "features" Tabelle fehlgeschlagen! DatabaseHandler.tableFailure=KRITISCHER FEHLER: Erstellen der "features" Tabelle fehlgeschlagen!
DatabaseHandler.unmarshallingFailure=Laden des CityObject {} aus der Datenbank fehlgeschlagen! DatabaseHandler.unmarshallingFailure=Laden des CityObject {} aus der Datenbank fehlgeschlagen!
DatabaseSettings.invalidPath=Einstellungen f\u00fcr Directory und Name der Datenbank bilden keinen validen Pfad. Standardwerte werden stattdessen genutzt
DatabaseSettings.poolSizeLessThanOne=ConnectionPoolSize Einstellung wurde auf unter 1 gesetzt. Standardwert wird stattdessen genutzt
DatabaseSettings.poolSizeNaN=ConnectionPoolSize Einstellung ist kein Integer. Standardwert wird stattdessen genutzt
DistanceError.distanceFromPlane=Abstand von der Ebene DistanceError.distanceFromPlane=Abstand von der Ebene
ErrorItemVisitor.childId=Kind ID ErrorItemVisitor.childId=Kind ID
ErrorItemVisitor.component=Komponente ErrorItemVisitor.component=Komponente
......
package de.hft.stuttgart.citydoctor2.database;
import org.junit.jupiter.api.Test;
public class DatabaseSettingsTest {
public void testSetLocation(){
String tempdirectory = System.getProperty("java.io.tmpdir");
DatabaseSettings.setDBLocation(tempdirectory + "/citydoctor");
}
}
...@@ -16,7 +16,6 @@ import de.hft.stuttgart.citydoctor2.parser.CityGmlParser; ...@@ -16,7 +16,6 @@ import de.hft.stuttgart.citydoctor2.parser.CityGmlParser;
import de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException; import de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import org.citygml4j.core.model.building.AbstractBuilding; import org.citygml4j.core.model.building.AbstractBuilding;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
...@@ -25,25 +24,44 @@ import java.util.List; ...@@ -25,25 +24,44 @@ import java.util.List;
import static de.hft.stuttgart.citydoctor2.database.SerializationTest.assertCityObjectEquality; import static de.hft.stuttgart.citydoctor2.database.SerializationTest.assertCityObjectEquality;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class EmbeddedDataBaseHandlerTest { public class EmbeddedDataBaseHandlerTest {
private EmbeddedDatabaseHandler handler; private final EmbeddedDatabaseHandler handler = new EmbeddedDatabaseHandler(new EmbeddedDatabaseConfiguration());
@Test
public void testTempFileConfiguration(){
EmbeddedDatabaseConfiguration tempFileconfig = new EmbeddedDatabaseConfiguration("database",
"inTempConfig",1, false,false,
false,true);
EmbeddedDatabaseHandler tempHandler = new EmbeddedDatabaseHandler(tempFileconfig);
assertTrue(tempHandler.getTempFileDBLocation().exists());
@Before
public void resetDatabase() {
try {
handler = new EmbeddedDatabaseHandler();
handler.setupFeaturesTable();
} catch (Exception e) {
fail(e.getMessage());
}
} }
@Test
public void testInMemoryConfiguration() throws CityGmlParseException, InvalidGmlFileException {
EmbeddedDatabaseConfiguration inMemoryConfig = new EmbeddedDatabaseConfiguration("database",
"irrelevant",1, true,false,
false,false);
EmbeddedDatabaseHandler memHandler = new EmbeddedDatabaseHandler(inMemoryConfig);
assertNull(memHandler.getTempFileDBLocation());
ParserConfiguration config = new ParserConfiguration(8, false);
CityDoctorModel model = CityGmlParser.nestedCityGmlFileParse("src/test/resources/SimpleSolid_SrefBS.gml", config);
Building b = model.getBuildings().toList().get(0);
assertEquals(0, memHandler.getFeatureCount());
memHandler.marshallCityObject(b);
assertEquals(1, memHandler.getFeatureCount());
CityObject co = memHandler.unmarshallCityObject(b.getGmlId());
assertNotNull(co);
assertTrue(co instanceof Building);
}
@Test @Test
public void testGetBboxIntersectingObjects() { public void testGetBboxIntersectingObjects() {
handler.setupFeaturesTable();
Building b = new Building(); Building b = new Building();
Building b2 = new Building(); Building b2 = new Building();
b2.setGmlObject(Mockito.mock(AbstractBuilding.class)); b2.setGmlObject(Mockito.mock(AbstractBuilding.class));
...@@ -124,6 +142,7 @@ public class EmbeddedDataBaseHandlerTest { ...@@ -124,6 +142,7 @@ public class EmbeddedDataBaseHandlerTest {
@Test @Test
public void testGetBboxBufferIntersectingObjects() { public void testGetBboxBufferIntersectingObjects() {
handler.setupFeaturesTable();
Building b = new Building(); Building b = new Building();
Building b2 = new Building(); Building b2 = new Building();
b2.setGmlObject(Mockito.mock(AbstractBuilding.class)); b2.setGmlObject(Mockito.mock(AbstractBuilding.class));
...@@ -210,6 +229,7 @@ public class EmbeddedDataBaseHandlerTest { ...@@ -210,6 +229,7 @@ public class EmbeddedDataBaseHandlerTest {
Building b = model.getBuildings().toList().get(0); Building b = model.getBuildings().toList().get(0);
assertNotNull(b); assertNotNull(b);
assertEquals(1, handler.getFeatureCount());
handler.marshallCityObject(b); handler.marshallCityObject(b);
assertEquals(1, handler.getFeatureCount()); assertEquals(1, handler.getFeatureCount());
......
...@@ -30,7 +30,7 @@ import java.util.ArrayList; ...@@ -30,7 +30,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import de.hft.stuttgart.citydoctor2.utils.visitors.ClearVisitorResultsVisitor; import de.hft.stuttgart.citydoctor2.utils.visitors.ClearResultsVisitor;
import de.hft.stuttgart.citydoctor2.utils.visitors.GmlGeometryRebuilder; import de.hft.stuttgart.citydoctor2.utils.visitors.GmlGeometryRebuilder;
import de.hft.stuttgart.citydoctor2.utils.visitors.UnsetGeometriesVisitor; import de.hft.stuttgart.citydoctor2.utils.visitors.UnsetGeometriesVisitor;
import org.citygml4j.core.model.construction.AbstractConstructionSurface; import org.citygml4j.core.model.construction.AbstractConstructionSurface;
...@@ -141,7 +141,7 @@ public class BoundarySurfaceTest { ...@@ -141,7 +141,7 @@ public class BoundarySurfaceTest {
assertFalse(bs.getAllCheckResults().isEmpty()); assertFalse(bs.getAllCheckResults().isEmpty());
bs.addOpening(oMock); bs.addOpening(oMock);
bs.clearAllContainedCheckResults(); bs.clearAllContainedCheckResults();
verify(oMock).accept(any(ClearVisitorResultsVisitor.class)); verify(oMock).accept(any(ClearResultsVisitor.class));
assertTrue(bs.getAllCheckResults().isEmpty()); assertTrue(bs.getAllCheckResults().isEmpty());
} }
......
package de.hft.stuttgart.citydoctor2.datastructure;
import static org.junit.jupiter.api.Assertions.*;
import org.citygml4j.core.model.construction.WallSurface;
import org.citygml4j.core.util.geometry.GeometryFactory;
import org.junit.jupiter.api.Test;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
class BridgeConstructiveElementTest {
@Test
void testBoundarySurfaceGeometryRecreation() {
WallSurface wallSurface = new WallSurface();
BoundarySurface surface = new BoundarySurface(wallSurface);
surface.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2));
var gmlBce = new org.citygml4j.core.model.bridge.BridgeConstructiveElement();
BridgeConstructiveElement bce = new BridgeConstructiveElement(gmlBce);
bce.addBoundarySurface(surface);
assertNull(wallSurface.getLod2MultiSurface());
GeometryFactory factory = GeometryFactory.newInstance();
ParserConfiguration config = new ParserConfiguration(8, false);
bce.reCreateGeometries(factory, config);
assertNotNull(wallSurface.getLod2MultiSurface());
}
}
...@@ -52,12 +52,12 @@ public class BuildingTest { ...@@ -52,12 +52,12 @@ public class BuildingTest {
Vertex v2 = new Vertex(2, 0, 0); Vertex v2 = new Vertex(2, 0, 0);
LinearRing lr = new LinearRing(LinearRingType.EXTERIOR); LinearRing lr = new LinearRing(LinearRingType.EXTERIOR);
ConcretePolygon p = new ConcretePolygon(); ConcretePolygon p = new ConcretePolygon();
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD0, Orientation.OUTWARD);
geom.addPolygon(p);
p.setExteriorRing(lr); p.setExteriorRing(lr);
lr.addVertex(v1); lr.addVertex(v1);
lr.addVertex(v2); lr.addVertex(v2);
lr.addVertex(v1); lr.addVertex(v1);
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD0, Orientation.OUTWARD);
geom.addPolygon(p);
geom.updateEdgesAndVertices(); geom.updateEdgesAndVertices();
b.addGeometry(geom); b.addGeometry(geom);
......
...@@ -33,7 +33,7 @@ import java.util.ArrayList; ...@@ -33,7 +33,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.hft.stuttgart.citydoctor2.check.CheckableUtilsVisitor; import de.hft.stuttgart.citydoctor2.check.CheckableUtilsVisitor;
import de.hft.stuttgart.citydoctor2.utils.visitors.ClearVisitorResultsVisitor; import de.hft.stuttgart.citydoctor2.utils.visitors.ClearResultsVisitor;
import org.citygml4j.core.model.construction.AbstractConstructionSurface; import org.citygml4j.core.model.construction.AbstractConstructionSurface;
import org.citygml4j.core.model.construction.WallSurface; import org.citygml4j.core.model.construction.WallSurface;
import org.citygml4j.core.util.geometry.GeometryFactory; import org.citygml4j.core.util.geometry.GeometryFactory;
...@@ -105,9 +105,9 @@ public class GeometryTest { ...@@ -105,9 +105,9 @@ public class GeometryTest {
ConcretePolygon p = new ConcretePolygon(); ConcretePolygon p = new ConcretePolygon();
LinearRing lr = new LinearRing(LinearRingType.EXTERIOR); LinearRing lr = new LinearRing(LinearRingType.EXTERIOR);
p.setExteriorRing(lr); p.setExteriorRing(lr);
geom.addPolygon(p);
lr.addVertex(new Vertex(0, 0, 0)); lr.addVertex(new Vertex(0, 0, 0));
geom.addPolygon(p);
p.setPartOfSurface(bs); p.setPartOfSurface(bs);
p.setPartOfInstallation(bi); p.setPartOfInstallation(bi);
...@@ -139,9 +139,9 @@ public class GeometryTest { ...@@ -139,9 +139,9 @@ public class GeometryTest {
ConcretePolygon p = new ConcretePolygon(); ConcretePolygon p = new ConcretePolygon();
LinearRing lr = new LinearRing(LinearRingType.EXTERIOR); LinearRing lr = new LinearRing(LinearRingType.EXTERIOR);
p.setExteriorRing(lr); p.setExteriorRing(lr);
geom.addPolygon(p);
lr.addVertex(new Vertex(0, 0, 0)); lr.addVertex(new Vertex(0, 0, 0));
geom.addPolygon(p);
p.setPartOfSurface(bs); p.setPartOfSurface(bs);
bs.addGeometry(geom); bs.addGeometry(geom);
...@@ -165,10 +165,10 @@ public class GeometryTest { ...@@ -165,10 +165,10 @@ public class GeometryTest {
ConcretePolygon p = new ConcretePolygon(); ConcretePolygon p = new ConcretePolygon();
LinearRing lr = new LinearRing(LinearRingType.EXTERIOR); LinearRing lr = new LinearRing(LinearRingType.EXTERIOR);
p.setExteriorRing(lr); p.setExteriorRing(lr);
geom.addPolygon(p);
lr.addVertex(new Vertex(0, 0, 0)); lr.addVertex(new Vertex(0, 0, 0));
bs.addGeometry(geom); bs.addGeometry(geom);
geom.addPolygon(p);
p.setPartOfSurface(bs); p.setPartOfSurface(bs);
p.setPartOfInstallation(bi); p.setPartOfInstallation(bi);
...@@ -301,7 +301,7 @@ public class GeometryTest { ...@@ -301,7 +301,7 @@ public class GeometryTest {
Polygon p = mock(Polygon.class); Polygon p = mock(Polygon.class);
geom.addPolygon(p); geom.addPolygon(p);
geom.clearAllContainedCheckResults(); geom.clearAllContainedCheckResults();
verify(p).accept(any(ClearVisitorResultsVisitor.class)); verify(p).accept(any(ClearResultsVisitor.class));
assertFalse(geom.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); assertFalse(geom.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
} }
......
...@@ -90,8 +90,8 @@ public class ImplicitGeometryTest { ...@@ -90,8 +90,8 @@ public class ImplicitGeometryTest {
assertFalse(lib.containsError(CheckId.C_GE_P_NON_PLANAR)); assertFalse(lib.containsError(CheckId.C_GE_P_NON_PLANAR));
igh.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); igh.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertFalse("ImplicitGeometryHolder's errors should be ignored and delegate the call to the prototype geometry", assertFalse(lib.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
lib.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); assertTrue(igh.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(lib.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); assertTrue(lib.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
...@@ -105,27 +105,39 @@ public class ImplicitGeometryTest { ...@@ -105,27 +105,39 @@ public class ImplicitGeometryTest {
@Test @Test
public void testClearAllContainedCheckResults() { public void testClearAllContainedCheckResults() {
igh.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null));
lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null)); lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null));
assertEquals(1, lib.getAllCheckResults().size()); assertEquals(1, lib.getAllCheckResults().size());
assertEquals(1, igh.getAllCheckResults().size());
lib.clearAllContainedCheckResults(); lib.clearAllContainedCheckResults();
assertTrue(lib.getAllCheckResults().isEmpty()); assertTrue(lib.getAllCheckResults().isEmpty());
assertEquals(1, igh.getAllCheckResults().size());
igh.clearAllContainedCheckResults();
assertTrue(igh.getAllCheckResults().isEmpty());
} }
@Test @Test
public void testContainsAnyError() { public void testContainsAnyError() {
assertFalse(lib.containsAnyError()); assertFalse(lib.containsAnyError());
assertFalse(igh.containsAnyError());
igh.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null)); igh.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null));
assertFalse(lib.containsAnyError()); assertFalse(lib.containsAnyError());
assertFalse(igh.containsAnyError());
lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null)); lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null));
assertFalse(lib.containsAnyError()); assertFalse(lib.containsAnyError());
assertFalse(igh.containsAnyError());
igh.addCheckResult( igh.addCheckResult(
new CheckResult(CheckId.C_GE_P_INNER_RINGS_NESTED, ResultStatus.ERROR, mock(CheckError.class))); new CheckResult(CheckId.C_GE_P_INNER_RINGS_NESTED, ResultStatus.ERROR, mock(CheckError.class)));
assertFalse(lib.containsAnyError()); assertFalse(lib.containsAnyError());
assertTrue(igh.containsAnyError());
lib.addCheckResult( lib.addCheckResult(
new CheckResult(CheckId.C_GE_P_INNER_RINGS_NESTED, ResultStatus.ERROR, mock(CheckError.class))); new CheckResult(CheckId.C_GE_P_INNER_RINGS_NESTED, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(lib.containsAnyError()); assertTrue(lib.containsAnyError());
assertTrue(igh.containsAnyError());
} }
@Test @Test
...@@ -134,19 +146,18 @@ public class ImplicitGeometryTest { ...@@ -134,19 +146,18 @@ public class ImplicitGeometryTest {
igh.addCheckResult(new CheckResult(CheckId.C_GE_P_NON_PLANAR, ResultStatus.ERROR, mock(CheckError.class))); igh.addCheckResult(new CheckResult(CheckId.C_GE_P_NON_PLANAR, ResultStatus.ERROR, mock(CheckError.class)));
igh.collectContainedErrors(errors); igh.collectContainedErrors(errors);
assertEquals("ImplicitGeometryHolder's errors should be ignored and delegate the call to the prototype geometry", assertEquals(1, errors.size());
0, errors.size()); errors.clear();
lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
igh.collectContainedErrors(errors); igh.collectContainedErrors(errors);
assertEquals("ImplicitGeometryHolder's errors should be ignored and delegate the call to the prototype geometry", assertEquals(1, errors.size());
1, errors.size());
} }
@Test @Test
public void testAccept() { public void testAccept() {
int polyCount = lib.getPolygons().size(); int polyCount = igh.getPolygons().size();
AtomicInteger loCounter = new AtomicInteger(0); AtomicInteger loCounter = new AtomicInteger(0);
...@@ -157,7 +168,7 @@ public class ImplicitGeometryTest { ...@@ -157,7 +168,7 @@ public class ImplicitGeometryTest {
} }
}; };
igh.accept(c); igh.accept(c);
assertEquals("ImplicitGeometryHolder should only check polygons of prototype geometry", assertEquals("Visitors should only walk over ImplicitGeometryHolder",
polyCount, loCounter.intValue()); polyCount, loCounter.intValue());
} }
......
...@@ -22,6 +22,7 @@ import static org.junit.Assert.*; ...@@ -22,6 +22,7 @@ import static org.junit.Assert.*;
import org.junit.Test; import org.junit.Test;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType;
import de.hft.stuttgart.citydoctor2.math.UnitVector3d; import de.hft.stuttgart.citydoctor2.math.UnitVector3d;
import de.hft.stuttgart.citydoctor2.math.Vector3d; import de.hft.stuttgart.citydoctor2.math.Vector3d;
...@@ -35,7 +36,9 @@ public class LinearRingTest { ...@@ -35,7 +36,9 @@ public class LinearRingTest {
@Test @Test
public void testIsPointInside1() { public void testIsPointInside1() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD2, Orientation.OUTWARD);
Polygon p = new ConcretePolygon(); Polygon p = new ConcretePolygon();
geom.addPolygon(p);
LinearRing lr = new LinearRing(LinearRingType.EXTERIOR); LinearRing lr = new LinearRing(LinearRingType.EXTERIOR);
p.setExteriorRing(lr); p.setExteriorRing(lr);
......
...@@ -6,7 +6,7 @@ import de.hft.stuttgart.citydoctor2.check.CheckId; ...@@ -6,7 +6,7 @@ import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.ResultStatus;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.utils.visitors.ClearVisitorResultsVisitor; import de.hft.stuttgart.citydoctor2.utils.visitors.ClearResultsVisitor;
import org.citygml4j.core.model.core.AbstractSpaceBoundary; import org.citygml4j.core.model.core.AbstractSpaceBoundary;
import org.citygml4j.core.model.core.AbstractUnoccupiedSpace; import org.citygml4j.core.model.core.AbstractUnoccupiedSpace;
import org.citygml4j.core.model.deprecated.core.DeprecatedPropertiesOfAbstractCityObject; import org.citygml4j.core.model.deprecated.core.DeprecatedPropertiesOfAbstractCityObject;
...@@ -91,7 +91,7 @@ public class TrafficSpaceTest { ...@@ -91,7 +91,7 @@ public class TrafficSpaceTest {
tso.clearAllContainedCheckResults(); tso.clearAllContainedCheckResults();
assertFalse(tso.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); assertFalse(tso.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
verify(taMock).accept(any(ClearVisitorResultsVisitor.class)); verify(taMock).accept(any(ClearResultsVisitor.class));
} }
@Test @Test
......
...@@ -62,20 +62,4 @@ public class VertexTest { ...@@ -62,20 +62,4 @@ public class VertexTest {
assertEquals(1, adjacentRings.size()); assertEquals(1, adjacentRings.size());
assertTrue(adjacentRings.contains(lr)); assertTrue(adjacentRings.contains(lr));
} }
@Test(expected = IllegalStateException.class)
public void testGetAdjacentRingsGeometryNotContainingVertex() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1, Orientation.OUTWARD);
Polygon p = new ConcretePolygon();
LinearRing lr = new LinearRing(LinearRingType.EXTERIOR);
p.setExteriorRing(lr);
Vertex v0 = new Vertex(0, 0, 0);
lr.addVertex(v0);
v0.getAdjacentRings(geom);
}
} }
...@@ -37,7 +37,7 @@ public class CityGml3ParserTest { ...@@ -37,7 +37,7 @@ public class CityGml3ParserTest {
@Test @Test
public void testGetContext() { public void testGetContext() {
CityGMLContext context = CityGmlParser.getContext(); CityGMLContext context = CityGmlParser.setupContext();
List<ADE> ades = ADERegistry.getInstance().getADEs(); List<ADE> ades = ADERegistry.getInstance().getADEs();
ADE ade = ades.get(0); ADE ade = ades.get(0);
assertEquals(QualityADEContext.class, ade.getClass()); assertEquals(QualityADEContext.class, ade.getClass());
......
Supports Markdown
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