Commit 8b6cdd3b authored by Luna Riegel's avatar Luna Riegel
Browse files

Merge branch 'dev_embedded_geodb' into 'dev'

!Geodatabase implementation

See merge request !36
parents 2fe401b3 e2cce980
Pipeline #12243 passed with stage
in 2 minutes and 14 seconds
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>de.hft.stuttgart</groupId> <groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorParent</artifactId> <artifactId>CityDoctorParent</artifactId>
<version>3.17.3</version> <version>3.18.0</version>
</parent> </parent>
<artifactId>CityDoctorValidation</artifactId> <artifactId>CityDoctorValidation</artifactId>
<name>CityDoctorValidation</name> <name>CityDoctorValidation</name>
......
...@@ -21,13 +21,11 @@ package de.hft.stuttgart.citydoctor2; ...@@ -21,13 +21,11 @@ package de.hft.stuttgart.citydoctor2;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path;
import java.util.List; import java.util.List;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipArchive; import de.hft.stuttgart.citydoctor2.utils.Localization;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.citygml4j.core.ade.ADEException;
import de.hft.stuttgart.citydoctor2.check.Checker; import de.hft.stuttgart.citydoctor2.check.Checker;
import de.hft.stuttgart.citydoctor2.check.ValidationConfiguration; import de.hft.stuttgart.citydoctor2.check.ValidationConfiguration;
...@@ -83,12 +81,12 @@ public class CityDoctorValidation { ...@@ -83,12 +81,12 @@ public class CityDoctorValidation {
if (optional) { if (optional) {
return null; return null;
} }
logger.error("No output file specified. (-out [FILE])"); logger.error(Localization.getText("CityDoctorValidation.noOutputFile"));
System.exit(11); System.exit(11);
} }
List<String> outFiles = argParser.getValues("out"); List<String> outFiles = argParser.getValues("out");
if (outFiles.size() != 1) { if (outFiles.size() != 1) {
logger.error("Specify exactly one file as output."); logger.error(Localization.getText("CityDoctorValidation.notExactlyOneOutputFile"));
System.exit(12); System.exit(12);
} }
outputFile = outFiles.get(0); outputFile = outFiles.get(0);
...@@ -157,15 +155,13 @@ public class CityDoctorValidation { ...@@ -157,15 +155,13 @@ public class CityDoctorValidation {
ValidationConfiguration config, String outputFile) throws CityDoctorWriteException, CityGmlParseException, IOException, InvalidGmlFileException { ValidationConfiguration config, String outputFile) throws CityDoctorWriteException, CityGmlParseException, IOException, InvalidGmlFileException {
File inputFile = new File(input); File inputFile = new File(input);
if (!inputFile.exists()) { if (!inputFile.exists()) {
logger.error("Input file '{}' does not exist.", input); logger.error(Localization.getText("CityDoctorValidation.inputFileNotExisting"), input);
System.exit(1); System.exit(1);
} }
if (inputFile.getName().endsWith(".gml") || inputFile.getName().endsWith(".xml")) { if (inputFile.getName().endsWith(".gml") || inputFile.getName().endsWith(".xml")) {
startFileValidation(inputFile, xmlOutput, pdfOutput, config, outputFile); startFileValidation(inputFile, xmlOutput, pdfOutput, config, outputFile);
} else if (inputFile.getName().endsWith(".zip")) {
startZipValidation(input, xmlOutput, pdfOutput, config, outputFile);
} else { } else {
logger.error("Input file '{}' does not end with .gml or .xml and is not a zip archive.", input); logger.error(Localization.getText("CityDoctorValidation.wrongInputFileFormat"), input);
System.exit(1); System.exit(1);
} }
} }
...@@ -179,10 +175,11 @@ public class CityDoctorValidation { ...@@ -179,10 +175,11 @@ public class CityDoctorValidation {
* @param pdfOutput the output path for the pdf report (optional) * @param pdfOutput the output path for the pdf report (optional)
* @param config the configuration path for the validation plan * @param config the configuration path for the validation plan
* @param outputFile storing the validated gml file with quality ade * @param outputFile storing the validated gml file with quality ade
* @throws CityDoctorWriteException if something goes wrong while writing the gml *
* file * @throws IOException When an exception while writing the report files happens.
* @throws CityGMLBuilderException * @throws CityGmlParseException When an error while parsing the cityGML file happens.
* @throws ADEException * @throws InvalidGmlFileException If the cityGML file is not valid according to the cityGML schema.
* @throws CityDoctorWriteException If something goes wrong while writing the output gml file
*/ */
public static void startFileValidation(File inputFile, String xmlOutput, String pdfOutput, public static void startFileValidation(File inputFile, String xmlOutput, String pdfOutput,
ValidationConfiguration config, String outputFile) throws IOException, CityGmlParseException, ValidationConfiguration config, String outputFile) throws IOException, CityGmlParseException,
...@@ -201,34 +198,11 @@ public class CityDoctorValidation { ...@@ -201,34 +198,11 @@ public class CityDoctorValidation {
} }
} }
public static void startZipValidation(String inputZipFile, String xmlOutput, String pdfOutput,
ValidationConfiguration config, String outputFile) throws CityGmlParseException, IOException {
xmlOutput = toDirectoryPath(xmlOutput);
pdfOutput = toDirectoryPath(pdfOutput);
outputFile = toDirectoryPath(outputFile);
if (xmlOutput == null && pdfOutput == null && outputFile == null) {
logger.warn("No output locations specified, results of validation will not be saved");
}
CityGmlZipArchive archive = CityGmlZipArchive.register(inputZipFile);
Checker.streamCheck(archive, xmlOutput, pdfOutput, config, outputFile);
}
public static String toDirectoryPath(String input) {
if (input == null) {
return null;
}
String parentDirectory = Path.of(input).getParent().toString() + File.separator;
String name = Path.of(input).getFileName().toString().replaceFirst("\\..+", "") + File.separator;
File f = new File(parentDirectory + name);
f.mkdir();
return f.getPath() + File.separator;
}
public static String getPdfOutput(ArgumentParser argParser) { public static String getPdfOutput(ArgumentParser argParser) {
if (argParser.containsOption("pdfreport")) { if (argParser.containsOption("pdfreport")) {
List<String> reportFiles = argParser.getValues("pdfreport"); List<String> reportFiles = argParser.getValues("pdfreport");
if (reportFiles.size() != 1) { if (reportFiles.size() != 1) {
logger.error("Specify exactly one file as pdfReport"); logger.error(Localization.getText("CityDoctorValidation.notExactlyOnePDFOutput"));
System.exit(6); System.exit(6);
} }
return reportFiles.get(0); return reportFiles.get(0);
...@@ -240,7 +214,7 @@ public class CityDoctorValidation { ...@@ -240,7 +214,7 @@ public class CityDoctorValidation {
if (argParser.containsOption("xmlreport")) { if (argParser.containsOption("xmlreport")) {
List<String> reportFiles = argParser.getValues("xmlreport"); List<String> reportFiles = argParser.getValues("xmlreport");
if (reportFiles.size() != 1) { if (reportFiles.size() != 1) {
logger.error("Specify exactly one file as xmlReport"); logger.error(Localization.getText("CityDoctorValidation.notExactlyOneXMLOutput"));
System.exit(5); System.exit(5);
} }
return reportFiles.get(0); return reportFiles.get(0);
...@@ -257,16 +231,16 @@ public class CityDoctorValidation { ...@@ -257,16 +231,16 @@ public class CityDoctorValidation {
if (argParser.containsOption("config")) { if (argParser.containsOption("config")) {
List<String> configFiles = argParser.getValues("config"); List<String> configFiles = argParser.getValues("config");
if (configFiles.size() != 1) { if (configFiles.size() != 1) {
logger.error("Specify exactly one file as configuration"); logger.error(Localization.getText("CityDoctorValidation.notExactlyOneConfigFile"));
System.exit(4); System.exit(4);
} }
return ValidationConfiguration.loadValidationConfig(configFiles.get(0)); return ValidationConfiguration.loadValidationConfig(configFiles.get(0));
} else { } else {
if (optional) { if (optional) {
logger.warn("No configuration file given, loading default configuration"); logger.warn(Localization.getText("CityDoctorValidation.loadingDefaultConfig"));
return ValidationConfiguration.loadStandardValidationConfig(); return ValidationConfiguration.loadStandardValidationConfig();
} else { } else {
logger.error("No configuration file specified with -config [FILE]"); logger.error(Localization.getText("CityDoctorValidation.noConfig"));
System.exit(7); System.exit(7);
return null; return null;
} }
...@@ -278,7 +252,7 @@ public class CityDoctorValidation { ...@@ -278,7 +252,7 @@ public class CityDoctorValidation {
if (argParser.containsOption("out")) { if (argParser.containsOption("out")) {
List<String> outFiles = argParser.getValues("out"); List<String> outFiles = argParser.getValues("out");
if (outFiles.size() != 1) { if (outFiles.size() != 1) {
logger.error("Specify exactly one file as output."); logger.error(Localization.getText("CityDoctorValidation.multipleOutputFiles"));
System.exit(3); System.exit(3);
} }
return outFiles.get(0); return outFiles.get(0);
...@@ -297,12 +271,12 @@ public class CityDoctorValidation { ...@@ -297,12 +271,12 @@ public class CityDoctorValidation {
if (optional) { if (optional) {
return null; return null;
} }
logger.error("No input file specified. (-in [FILE])"); logger.error(Localization.getText("CityDoctorValidation.noInputFile"));
System.exit(1); System.exit(1);
} }
List<String> inFiles = argParser.getValues("in"); List<String> inFiles = argParser.getValues("in");
if (inFiles.size() != 1) { if (inFiles.size() != 1) {
logger.error("Specify exactly one file as input."); logger.error(Localization.getText("CityDoctorValidation.notExactlyOneInputFile"));
System.exit(2); System.exit(2);
} }
inputFile = inFiles.get(0); inputFile = inFiles.get(0);
......
package de.hft.stuttgart.citydoctor2; package de.hft.stuttgart.citydoctor2;
import java.util.concurrent.Callable;
import de.hft.stuttgart.citydoctor2.check.ValidationConfiguration;
import de.hft.stuttgart.citydoctor2.exceptions.CityDoctorWriteException;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException;
import de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException;
import picocli.CommandLine;
import picocli.CommandLine.Command; import picocli.CommandLine.Command;
import picocli.CommandLine.Option; import picocli.CommandLine.Option;
import java.io.File;
import java.io.IOException;
@Command(name = "citydoctor2", mixinStandardHelpOptions = true, description = "Validates CityGML files according to a provided validation-plan.") @Command(name = "citydoctor2", mixinStandardHelpOptions = true, description = "Validates CityGML files according to a provided validation-plan.")
public class CityDoctorValidationCLI implements Callable<Integer> { public class CityDoctorValidationCLI implements Runnable {
@Option(names = {"-i" , "--in" , "--input"}, @Option(names = {"-i" , "--in" , "--input"},
description = "Filepath of the CityGML file.", description = "Filepath of the CityGML file.",
...@@ -15,23 +22,41 @@ public class CityDoctorValidationCLI implements Callable<Integer> { ...@@ -15,23 +22,41 @@ public class CityDoctorValidationCLI implements Callable<Integer> {
@Option(names = {"-c" , "--config" , "--configuration", "--plan"}, @Option(names = {"-c" , "--config" , "--configuration", "--plan"},
description = "Filepath of the validation configuration .yml", description = "Filepath of the validation configuration .yml",
required = true) defaultValue = Option.NULL_VALUE)
private String config; private File config;
@Option(names = {"-x" , "--xml" , "--xmlReport"}, @Option(names = {"-x" , "--xml" , "--xmlReport"},
description = "Create a XML validation report at target location") description = "Create a XML validation report at target location",
defaultValue = Option.NULL_VALUE)
private String xmlReport; private String xmlReport;
@Option(names = {"-p" , "--pdf" , "--pdfReport"}, @Option(names = {"-p" , "--pdf" , "--pdfReport"},
description = "Create a PDF validation report at target location") description = "Create a PDF validation report at target location",
defaultValue = Option.NULL_VALUE)
private String pdfReport; private String pdfReport;
@Option(names = {"-o" , "--out" , "--output"}, @Option(names = {"-o" , "--out" , "--output"},
description = "Create a validated copy of the CityGML input with QualityADE at target location.") description = "Create a validated copy of the CityGML input with QualityADE at target location.",
defaultValue = Option.NULL_VALUE)
private String output; private String output;
@Override @Override
public Integer call() throws Exception { public void run(){
return 0; try {
ValidationConfiguration valConfig;
if(config == null){
valConfig=ValidationConfiguration.loadStandardValidationConfig();
} else{
valConfig=ValidationConfiguration.loadValidationConfig(config.getAbsolutePath());
}
CityDoctorValidation.startValidationProcess(input, xmlReport, pdfReport, valConfig,output);
} catch (CityDoctorWriteException | CityGmlParseException | IOException | InvalidGmlFileException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
int exitCode = new CommandLine(new CityDoctorValidationCLI()).execute(args);
System.exit(exitCode);
} }
} }
...@@ -28,9 +28,14 @@ import de.hft.stuttgart.citydoctor2.checks.CheckPrototype; ...@@ -28,9 +28,14 @@ import de.hft.stuttgart.citydoctor2.checks.CheckPrototype;
import de.hft.stuttgart.citydoctor2.checks.Checks; import de.hft.stuttgart.citydoctor2.checks.Checks;
import de.hft.stuttgart.citydoctor2.checks.SvrlContentHandler; import de.hft.stuttgart.citydoctor2.checks.SvrlContentHandler;
import de.hft.stuttgart.citydoctor2.checks.util.FeatureCheckedListener; import de.hft.stuttgart.citydoctor2.checks.util.FeatureCheckedListener;
import de.hft.stuttgart.citydoctor2.database.CityObjectCache;
import de.hft.stuttgart.citydoctor2.database.CityObjectCache;
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.FeatureType; import de.hft.stuttgart.citydoctor2.datastructure.FeatureType;
import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
import de.hft.stuttgart.citydoctor2.datastructure.ImplicitGeometryHolder;
import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
import de.hft.stuttgart.citydoctor2.parser.CityGmlConsumer; import de.hft.stuttgart.citydoctor2.parser.CityGmlConsumer;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException; import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParser; import de.hft.stuttgart.citydoctor2.parser.CityGmlParser;
...@@ -42,11 +47,8 @@ import de.hft.stuttgart.citydoctor2.reporting.XmlStreamReporter; ...@@ -42,11 +47,8 @@ import de.hft.stuttgart.citydoctor2.reporting.XmlStreamReporter;
import de.hft.stuttgart.citydoctor2.reporting.XmlValidationReporter; import de.hft.stuttgart.citydoctor2.reporting.XmlValidationReporter;
import de.hft.stuttgart.citydoctor2.reporting.pdf.PdfReporter; import de.hft.stuttgart.citydoctor2.reporting.pdf.PdfReporter;
import de.hft.stuttgart.citydoctor2.reporting.pdf.PdfStreamReporter; import de.hft.stuttgart.citydoctor2.reporting.pdf.PdfStreamReporter;
import de.hft.stuttgart.citydoctor2.utils.ArchivePacker;
import de.hft.stuttgart.citydoctor2.utils.Localization; import de.hft.stuttgart.citydoctor2.utils.Localization;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipArchive; import de.hft.stuttgart.citydoctor2.utils.TimeFormatter;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntryFile;
import de.hft.stuttgart.quality.model.enums.RequirementId; import de.hft.stuttgart.quality.model.enums.RequirementId;
import de.hft.stuttgart.quality.model.enums.TopLevelFeatureType; import de.hft.stuttgart.quality.model.enums.TopLevelFeatureType;
import de.hft.stuttgart.quality.model.properties.CheckingProperty; import de.hft.stuttgart.quality.model.properties.CheckingProperty;
...@@ -57,7 +59,6 @@ import de.hft.stuttgart.quality.model.properties.RequirementProperty; ...@@ -57,7 +59,6 @@ import de.hft.stuttgart.quality.model.properties.RequirementProperty;
import de.hft.stuttgart.quality.model.types.Checking; import de.hft.stuttgart.quality.model.types.Checking;
import de.hft.stuttgart.quality.model.types.Parameter; import de.hft.stuttgart.quality.model.types.Parameter;
import de.hft.stuttgart.quality.model.types.ValidationPlan; import de.hft.stuttgart.quality.model.types.ValidationPlan;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
...@@ -79,6 +80,7 @@ import java.io.FileOutputStream; ...@@ -79,6 +80,7 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.UncheckedIOException; import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
...@@ -89,7 +91,8 @@ import java.util.List; ...@@ -89,7 +91,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.stream.Stream; import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/** /**
* The main container class for checking. It contains the logic for validation, * The main container class for checking. It contains the logic for validation,
...@@ -191,18 +194,46 @@ public class Checker { ...@@ -191,18 +194,46 @@ public class Checker {
if (config == null) { if (config == null) {
config = ValidationConfiguration.loadStandardValidationConfig(); config = ValidationConfiguration.loadStandardValidationConfig();
} }
checkCityModel(model, l); AutoCloseable checkingContext = model.getCache().startCheckingMode();
if (logger.isInfoEnabled()) { try(checkingContext){
logger.info(Localization.getText("Checker.checksFinished")); Callable<SvrlContentHandler> schematronThread = () -> executeSchematronValidationIfAvailable(config, model.getFile());
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<SvrlContentHandler> handlerFuture = executor.submit(schematronThread);
executor.shutdown();
checkCityModel(model, l);
getSchematronResults(handlerFuture, l);
model.setValidated(createValidationPlan());
} catch (Exception e){
logger.error("Validation failed due to encountering error", e);
} }
SvrlContentHandler handler = executeSchematronValidationIfAvailable(config, model.getFile()); }
if (handler != null) {
handleSchematronResults(handler); private void getSchematronResults(Future<SvrlContentHandler> handlerFuture, ProgressListener l) {
if (!handlerFuture.isDone()) {
if (logger.isInfoEnabled()) {
logger.info(Localization.getText("Checker.schematronStillRunning"));
}
if(l !=null){
l.updateProgress(-0.5f);
}
}
try {
SvrlContentHandler handler = handlerFuture.get();
if (handler != null) {
handleSchematronResults(handler);
}
} catch (ExecutionException e) {
logger.error(e);
} catch (InterruptedException e) {
logger.error(Localization.getText("Checker.schematronInterrupted"), e);
Thread.currentThread().interrupt();
} }
model.setValidated(createValidationPlan());
} }
private void handleSchematronResults(SvrlContentHandler handler) { private void handleSchematronResults(SvrlContentHandler handler) {
CityObjectCache cache = model.getCache();
handleSchematronErrorsGlobal(handler.getGeneralErrors()); handleSchematronErrorsGlobal(handler.getGeneralErrors());
Map<String, CityObject> featureMap = new HashMap<>(); Map<String, CityObject> featureMap = new HashMap<>();
boolean onlySchematron = execLayers.isEmpty(); boolean onlySchematron = execLayers.isEmpty();
...@@ -222,7 +253,7 @@ public class Checker { ...@@ -222,7 +253,7 @@ public class Checker {
} }
handler.getFeatureErrors().forEach((k, v) -> { handler.getFeatureErrors().forEach((k, v) -> {
String trimmedId = k.trim(); String trimmedId = k.trim();
CityObject co = featureMap.get(trimmedId); CityObject co = cache.get(new GmlId(k));
if (co == null) { if (co == null) {
// gml id reported by schematron was not found, add to general errors // gml id reported by schematron was not found, add to general errors
handleSchematronErrorsGlobal(v); handleSchematronErrorsGlobal(v);
...@@ -468,6 +499,10 @@ public class Checker { ...@@ -468,6 +499,10 @@ public class Checker {
if (logger.isInfoEnabled()) { if (logger.isInfoEnabled()) {
logger.info(Localization.getText("Checker.schematronValidation")); logger.info(Localization.getText("Checker.schematronValidation"));
} }
if (!Files.exists(Path.of(config.getSchematronFilePath()))) {
logger.warn(Localization.getText("Checker.schematronFileNotFound"), config.getSchematronFilePath());
return null;
}
try { try {
TransformerFactory transformerFactory = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl", Checker.class.getClassLoader()); TransformerFactory transformerFactory = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl", Checker.class.getClassLoader());
...@@ -585,7 +620,7 @@ public class Checker { ...@@ -585,7 +620,7 @@ public class Checker {
for (Entry<String, RequirementConfiguration> e : config.getRequirements().entrySet()) { for (Entry<String, RequirementConfiguration> e : config.getRequirements().entrySet()) {
de.hft.stuttgart.citydoctor2.check.Requirement req = Checks.getAvailableRequirements().get(e.getKey()); de.hft.stuttgart.citydoctor2.check.Requirement req = Checks.getAvailableRequirements().get(e.getKey());
if (req == null) { if (req == null) {
logger.warn("Could not find any check that satisfies requirement {}, it will not be checked", logger.warn(Localization.getText("Checker.noCheckSatisfiesRequirement"),
e.getKey()); e.getKey());
} else { } else {
if (e.getValue().isEnabled()) { if (e.getValue().isEnabled()) {
...@@ -652,31 +687,110 @@ public class Checker { ...@@ -652,31 +687,110 @@ public class Checker {
} }
} }
private void checkCityModel(CityDoctorModel model, ProgressListener l) { private void checkCityModel(CityDoctorModel model, ProgressListener l){
Stream<CityObject> features = model.createFeatureStream(); List<GmlId> features = model.getFeatureIds();
float featureSum = model.getNumberOfFeatures();
AtomicInteger checkedCount = new AtomicInteger(0);
// clear global errors // clear global errors
model.getGlobalErrors().clear(); model.getGlobalErrors().clear();
CityObjectCache cache = model.getCache();
// stupid lamda with final variable restrictions logger.trace("Setting up ThreadPool");
int[] currentFeature = new int[1]; int threadCount = Runtime.getRuntime().availableProcessors() * 5;
features.forEach(co -> { ExecutorService exec = new ThreadPoolExecutor
if (config.getParserConfiguration().useLowMemoryConsumption()) { (threadCount, threadCount, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
// no edges have been created yet, create them try{
co.prepareForChecking(); long startTime = System.nanoTime();
ImplicitGeometryHolder.preparePrototypeGeometriesForChecking();
List<Future<GmlId>> futures = runChecksOnFeatures(exec, cache, features, checkedCount, l);
List<GmlId> missedFeatures = getMissedFeatures(futures);
ImplicitGeometryHolder.clearMetaDataOfPrototypeGeometries();
if (!missedFeatures.isEmpty()){
logger.error(Localization.getText("Checker.dbUnresponsive"));
if (logger.isDebugEnabled()){
logger.debug(missedFeatures.toString());
}
} }
// check every feature long endTime = System.nanoTime();
executeChecksForCityObject(co); if (logger.isInfoEnabled()){
long totalTime = (endTime - startTime) / 1_000_000; // Convert ns to ms
String messageString = Localization.getText("Checker.checksFinished");
String timeString = TimeFormatter.format(totalTime);
messageString = messageString.replace("{0}", timeString);
logger.info(messageString);
}
} catch (InterruptedException e){
// No interrupts implemented, so this block should actually never be entered
logger.error(Localization.getText("Checker.validationInterrupted"), e);
Thread.currentThread().interrupt();
} finally {
exec.shutdown();
try {
if(!exec.awaitTermination(1, TimeUnit.MINUTES)){
exec.shutdownNow();
}
if (config.getParserConfiguration().useLowMemoryConsumption()) { } catch (InterruptedException e) {
// low memory consumption, remove edges again Thread.currentThread().interrupt();
co.clearMetaInformation(); logger.error(Localization.getText("Checker.shutdownInterrupted"));
} }
if (l != null) { }
currentFeature[0]++; }
l.updateProgress(currentFeature[0] / featureSum);
private List<Future<GmlId>> runChecksOnFeatures(ExecutorService exec, CityObjectCache cache, List<GmlId> ids, AtomicInteger checkedCount,
ProgressListener l)
throws InterruptedException {
float featureSum = ids.size() + (float) checkedCount.get();
logger.trace("Queueing up Checker tasks");
List<Callable<GmlId>> tasks = new ArrayList<>();
for (GmlId id : ids) {
tasks.add(()->{
CityObject co = cache.get(id);
if (co == null) {
return id;
}
if(Thread.interrupted()){
Thread.currentThread().interrupt();
return null;
}
co.prepareForChecking();
executeChecksForCityObject(co);
co.clearMetaInformation();
cache.put(co);
checkedCount.incrementAndGet();
if (l!=null){
l.updateProgress((checkedCount.get()) / featureSum);
}
return null;
});
}
logger.trace("Queueing up finished, invoking all tasks");
return exec.invokeAll(tasks);
}
private List<GmlId> getMissedFeatures(List<Future<GmlId>> futures) throws InterruptedException{
List<GmlId> missedList = new ArrayList<>();
Set<ExecutionException> errors = new HashSet<>();
for (Future<GmlId> future : futures) {
try{
GmlId gmlId = future.get();
if (gmlId != null) {
missedList.add(gmlId);
}
} catch (ExecutionException e){
logger.debug("A Task failed due to an unexpected exception", e);
logger.debug(e.getCause());
errors.add(e);
} }
}); }
if (!errors.isEmpty()) {
logger.error(Localization.getText("Checker.futuresCheckFailures"));
logger.error(errors.toString());
}
return missedList;
} }
private boolean filterObject(CityObject co) { private boolean filterObject(CityObject co) {
...@@ -782,73 +896,6 @@ public class Checker { ...@@ -782,73 +896,6 @@ public class Checker {
return hasUnusedDependency; return hasUnusedDependency;
} }
public static void streamCheck(CityGmlZipArchive archive, String xmlDirectory, String pdfDirectory, ValidationConfiguration config,
String outputDirectory) throws IOException, CityGmlParseException {
streamCheck(archive, xmlDirectory, pdfDirectory, config, null, outputDirectory);
}
public static void streamCheck(CityGmlZipArchive archive, String xmlDirectory, String pdfDirectory, ValidationConfiguration config,
FeatureCheckedListener l, String outputDirectory) throws IOException, CityGmlParseException {
for (CityGmlZipEntry entry : archive.getEntries()) {
String entryName = FilenameUtils.removeExtension(entry.getDisplayName());
String xmlOutput = null;
String pdfOutput = null;
String outputFile = null;
if (xmlDirectory != null) {
xmlOutput = Path.of(xmlDirectory).resolve(entryName + "_report.xml").toString();
}
if (pdfDirectory != null) {
pdfOutput = Path.of(pdfDirectory).resolve(entryName + "_report.pdf").toString();
}
if (outputDirectory != null) {
outputFile = Path.of(outputDirectory).resolve(entryName + "_validated.gml").toString();
}
streamCheck(entry, xmlOutput, pdfOutput, config, l, outputFile);
}
if (outputDirectory != null) {
ArchivePacker.packAndDeleteDirectory(outputDirectory);
}
}
public static void streamCheck(CityGmlZipEntry entry, String xmlOutput, String pdfOutput, ValidationConfiguration config,
String outputFile) throws IOException, CityGmlParseException {
streamCheck(entry, xmlOutput, pdfOutput, config, null, outputFile);
}
public static void streamCheck(CityGmlZipEntry entry, String xmlOutput, String pdfOutput, ValidationConfiguration config,
FeatureCheckedListener l, String outputFile) throws IOException, CityGmlParseException {
try (BufferedOutputStream xmlBos = getXmlOutputMaybe(xmlOutput);
BufferedOutputStream pdfBos = getPdfOutputMaybe(pdfOutput)) {
Checker c = new Checker(config, null);
String fileName = entry.getEntrySubPath();
// create reporter if available
XmlStreamReporter xmlReporter = getXmlReporter(config, xmlBos, fileName);
PdfStreamReporter pdfReporter = getPdfReporter(config, pdfBos, fileName);
// execute schematron first
try (CityGmlZipEntryFile entryFile = new CityGmlZipEntryFile(entry)) {
SvrlContentHandler handler = executeSchematronValidationIfAvailable(config, entryFile.getInputStream());
CityGmlConsumer con = new StreamCityGmlConsumer(c, xmlReporter, pdfReporter, handler, config, l);
// parse and validate
CityGmlParser.streamCityGml(entry, config.getParserConfiguration(), con, outputFile);
// write reports if available
writeReport(xmlReporter);
writeReport(pdfReporter);
}
} catch (CheckReportWriteException e) {
logger.error(Localization.getText("Checker.failReports"), e);
}
}
public static void streamCheck(File inputFile, String xmlOutput, String pdfOutput, ValidationConfiguration config, public static void streamCheck(File inputFile, String xmlOutput, String pdfOutput, ValidationConfiguration config,
String outputFile) throws IOException, CityGmlParseException { String outputFile) throws IOException, CityGmlParseException {
streamCheck(inputFile, xmlOutput, pdfOutput, config, null, outputFile); streamCheck(inputFile, xmlOutput, pdfOutput, config, null, outputFile);
......
...@@ -134,7 +134,7 @@ public class StreamCityGmlConsumer implements CityGmlConsumer { ...@@ -134,7 +134,7 @@ public class StreamCityGmlConsumer implements CityGmlConsumer {
pdfReporter.report(co); pdfReporter.report(co);
} }
// TODO: Update QualityADE to be compatible with CityGML 3.0 or deprecate it, unhandled top-level feature types are just skipped for now // TODO: Update QualityADE to be compatible with CityGML 3.0, unhandled top-level feature types are just skipped for now
if (!(co instanceof AbstractTunnel || co instanceof CityFurniture || co instanceof GenericCityObject)) { if (!(co instanceof AbstractTunnel || co instanceof CityFurniture || co instanceof GenericCityObject)) {
// store quality ade datastructures in cityobject // store quality ade datastructures in cityobject
QualityADEUtils.writeQualityAde(co, val); QualityADEUtils.writeQualityAde(co, val);
......
...@@ -230,6 +230,24 @@ public class CheckContainer extends Check { ...@@ -230,6 +230,24 @@ public class CheckContainer extends Check {
} }
} }
@Override
public void check(TinObject to) {
try {
check.check(to);
}catch (Exception e) {
handleException(e, to);
}
}
@Override
public void check(ReliefObject ro) {
try {
check.check(ro);
}catch (Exception e) {
handleException(e, ro);
}
}
@Override @Override
public void check(CityFurniture cf){ public void check(CityFurniture cf){
try { try {
...@@ -248,6 +266,15 @@ public class CheckContainer extends Check { ...@@ -248,6 +266,15 @@ public class CheckContainer extends Check {
} }
} }
@Override
public void check(OtherConstructionObject oco) {
try {
check.check(oco);
}catch (Exception e) {
handleException(e, oco);
}
}
@Override @Override
public RequirementType getType() { public RequirementType getType() {
return check.getType(); return check.getType();
......
...@@ -45,33 +45,8 @@ public class XmlValidationReporter implements Reporter { ...@@ -45,33 +45,8 @@ public class XmlValidationReporter implements Reporter {
@Override @Override
public void writeReport(Checks checks, OutputStream filePath, CityDoctorModel model, ValidationConfiguration config) throws CheckReportWriteException { public void writeReport(Checks checks, OutputStream filePath, CityDoctorModel model, ValidationConfiguration config) throws CheckReportWriteException {
StreamReporter streamReporter = new XmlStreamReporter(filePath, model.getFileName(), config); StreamReporter streamReporter = new XmlStreamReporter(filePath, model.getFileName(), config);
for (BridgeObject bo : model.getBridges()) { model.createFeatureStream().forEach(streamReporter::report);
streamReporter.report(bo);
}
for (Building b : model.getBuildings()) {
streamReporter.report(b);
}
for (TransportationObject to : model.getTransportation()) {
streamReporter.report(to);
}
for (CityObject lo : model.getLand()) {
streamReporter.report(lo);
}
for (Vegetation v : model.getVegetation()) {
streamReporter.report(v);
}
for (WaterObject wo : model.getWater()) {
streamReporter.report(wo);
}
for (Tunnel tunnel : model.getTunnels()) {
streamReporter.report(tunnel);
}
for (CityFurniture cf : model.getCityFurniture()) {
streamReporter.report(cf);
}
for (GenericCityObject gco : model.getGenericCityObjects()) {
streamReporter.report(gco);
}
for (CheckError err : model.getGlobalErrors()) { for (CheckError err : model.getGlobalErrors()) {
streamReporter.reportGlobalError(err); streamReporter.reportGlobalError(err);
} }
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configuration>
<Configuration status="INFO">
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout
pattern="[%-5level] %d{HH:mm:ss.SSS} %c{1} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="debug" additivity="false">
<AppenderRef ref="console" />
</Root>
<Logger name="com.zaxxer.hikari" level="INFO" additivity="false">
<AppenderRef ref="console"/>
</Logger>
</Loggers>
</Configuration>
\ No newline at end of file
...@@ -24,7 +24,6 @@ import de.hft.stuttgart.citydoctor2.checkresult.GlobalErrorStatistics; ...@@ -24,7 +24,6 @@ import de.hft.stuttgart.citydoctor2.checkresult.GlobalErrorStatistics;
import de.hft.stuttgart.citydoctor2.checkresult.GlobalStatistics; import de.hft.stuttgart.citydoctor2.checkresult.GlobalStatistics;
import de.hft.stuttgart.citydoctor2.checkresult.ModelStatistics; import de.hft.stuttgart.citydoctor2.checkresult.ModelStatistics;
import de.hft.stuttgart.citydoctor2.checkresult.utility.CheckReportParseException; import de.hft.stuttgart.citydoctor2.checkresult.utility.CheckReportParseException;
import de.hft.stuttgart.citydoctor2.checks.util.FeatureCheckedListener;
import de.hft.stuttgart.citydoctor2.datastructure.Building; import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel; import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.exceptions.CityDoctorWriteException; import de.hft.stuttgart.citydoctor2.exceptions.CityDoctorWriteException;
...@@ -32,8 +31,6 @@ import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException; ...@@ -32,8 +31,6 @@ import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParser; 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 de.hft.stuttgart.citydoctor2.zip.CityGmlZipArchive;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
...@@ -68,7 +65,7 @@ public class CheckerTest { ...@@ -68,7 +65,7 @@ public class CheckerTest {
"src/test/resources/SimpleSolid_SrefBS_SchematronTest.gml", config.getParserConfiguration()); "src/test/resources/SimpleSolid_SrefBS_SchematronTest.gml", config.getParserConfiguration());
Checker checker = new Checker(config, model); Checker checker = new Checker(config, model);
checker.runChecks(); checker.runChecks();
for (Building b : model.getBuildings()) { for (Building b : model.getBuildings().toList()) {
if (b.getGmlId().getGmlString().equals("_Simple_BD.1")) { if (b.getGmlId().getGmlString().equals("_Simple_BD.1")) {
assertTrue(b.containsAnyError()); assertTrue(b.containsAnyError());
} else { } else {
...@@ -128,76 +125,6 @@ public class CheckerTest { ...@@ -128,76 +125,6 @@ public class CheckerTest {
} }
} }
@Test
public void testCliZipChecking() throws IOException, CityDoctorWriteException, CityGmlParseException, InvalidGmlFileException {
String output = folder.getRoot().toPath() + File.separator + "test";
String pdfOutput = folder.getRoot().toPath() + File.separator + "pdf" + File.separator;
String xmlOutput = folder.getRoot().toPath() + File.separator + "xml" + File.separator;
try {
String[] args = new String[10];
args[0] = "-in";
args[1] = "src/test/resources/zipArchive.zip";
args[2] = "-config";
args[3] = "src/test/resources/testConfigWithStreaming.yml";
args[4] = "-pdfReport";
args[5] = pdfOutput;
args[6] = "-xmlReport";
args[7] = xmlOutput;
args[8] = "-out";
args[9] = output + File.separator;
CityDoctorValidation.main(args);
File zipFile = new File(output + ".zip");
File pdfDir = new File(pdfOutput);
File xmlDir = new File(xmlOutput);
assertTrue(zipFile.exists());
assertTrue(pdfDir.exists());
assertTrue(xmlDir.exists());
assertTrue(pdfDir.isDirectory());
assertTrue(xmlDir.isDirectory());
assertEquals(5, pdfDir.listFiles().length);
assertEquals(5, xmlDir.listFiles().length);
CityGmlZipArchive cgmlArch = CityGmlZipArchive.register(output + ".zip");
assertNotNull(cgmlArch);
cgmlArch.mountArchive(new ParserConfiguration(8, true));
assertEquals(5, cgmlArch.getEntries().size());
for (CityGmlZipEntry entry : cgmlArch.getEntries()) {
assertNotNull(entry);
assertNull(entry.getErrorType());
}
} catch (CityGmlParseException | IOException | InvalidGmlFileException | CityDoctorWriteException e) {
throw e;
}
}
@Test
public void testZipEntryChecking() throws CityGmlParseException, IOException {
CityGmlZipArchive cgmlArch = CityGmlZipArchive.register("src/test/resources/zipArchive.zip");
assertNotNull(cgmlArch);
cgmlArch.mountArchive(new ParserConfiguration(8, false));
ValidationConfiguration config = ValidationConfiguration.loadStandardValidationConfig();
FeatureCheckedListener l = co -> {
assertTrue("CityObject should be validated", co.isValidated());
};
for (CityGmlZipEntry entry : cgmlArch.getEntries()) {
Checker.streamCheck(entry, null, null, config, l, null);
}
}
@Test
public void testZipArchiveChecking() throws CityGmlParseException, IOException {
CityGmlZipArchive cgmlArch = CityGmlZipArchive.register("src/test/resources/zipArchive.zip");
assertNotNull(cgmlArch);
cgmlArch.mountArchive(new ParserConfiguration(8, false));
ValidationConfiguration config = ValidationConfiguration.loadStandardValidationConfig();
FeatureCheckedListener l = co -> {
assertTrue(co.isValidated());
};
Checker.streamCheck(cgmlArch, null, null, config, l, null);
}
@Test @Test
public void testReportCreation() throws IOException, CityGmlParseException, InvalidGmlFileException { public void testReportCreation() throws IOException, CityGmlParseException, InvalidGmlFileException {
Path tmpDir = null; Path tmpDir = null;
...@@ -207,7 +134,7 @@ public class CheckerTest { ...@@ -207,7 +134,7 @@ public class CheckerTest {
Path xmlPath = tmpDir.resolve("report.xml"); Path xmlPath = tmpDir.resolve("report.xml");
Path pdfPath = tmpDir.resolve("report.pdf"); Path pdfPath = tmpDir.resolve("report.pdf");
File features = new File("src/test/resources/feature_types.gml"); File features = new File("src/test/resources/feature_types.gml");
CityDoctorModel model = CityGmlParser.parseCityGmlFileSilently( CityDoctorModel model = CityGmlParser.nestedCityGmlFileParse(
features.toString(), new ParserConfiguration(8, false)); features.toString(), new ParserConfiguration(8, false));
assertNotNull(model); assertNotNull(model);
Checker checker = new Checker(model); Checker checker = new Checker(model);
......
...@@ -45,12 +45,12 @@ public class FilterTest { ...@@ -45,12 +45,12 @@ public class FilterTest {
Checker c = new Checker(config, model); Checker c = new Checker(config, model);
c.runChecks(); c.runChecks();
Building b = model.getBuildings().get(0); Building b = model.getBuildings().toList().get(0);
Geometry geom = b.getGeometries().get(0); Geometry geom = b.getGeometries().get(0);
assertFalse(geom.hasCheckResults()); assertFalse(geom.hasCheckResults());
TransportationObject to = model.getTransportation().get(0); TransportationObject to = model.getTransportation().toList().get(0);
Geometry geom2 = to.getGeometries().get(0); Geometry geom2 = to.getGeometries().get(0);
assertTrue(geom2.getPolygons().get(0).hasCheckResults()); assertTrue(geom2.getPolygons().get(0).hasCheckResults());
...@@ -65,12 +65,12 @@ public class FilterTest { ...@@ -65,12 +65,12 @@ public class FilterTest {
Checker c = new Checker(config, model); Checker c = new Checker(config, model);
c.runChecks(); c.runChecks();
Building b = model.getBuildings().get(0); Building b = model.getBuildings().toList().get(0);
Geometry geom = b.getGeometries().get(0); Geometry geom = b.getGeometries().get(0);
assertFalse(geom.hasCheckResults()); assertFalse(geom.hasCheckResults());
TransportationObject to = model.getTransportation().get(0); TransportationObject to = model.getTransportation().toList().get(0);
Geometry geom2 = to.getGeometries().get(0); Geometry geom2 = to.getGeometries().get(0);
assertTrue(geom2.getPolygons().get(0).hasCheckResults()); assertTrue(geom2.getPolygons().get(0).hasCheckResults());
......
...@@ -26,6 +26,7 @@ import java.util.HashMap; ...@@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import de.hft.stuttgart.citydoctor2.database.UnconnectedCache;
import org.junit.Test; import org.junit.Test;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
...@@ -44,6 +45,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.Vertex; ...@@ -44,6 +45,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation; import de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.quality.model.enums.RequirementId; import de.hft.stuttgart.quality.model.enums.RequirementId;
import org.mockito.Mockito;
public class DegeneratedPolygonCheckTest { public class DegeneratedPolygonCheckTest {
...@@ -68,9 +70,10 @@ public class DegeneratedPolygonCheckTest { ...@@ -68,9 +70,10 @@ public class DegeneratedPolygonCheckTest {
Building b = new Building(); Building b = new Building();
b.addGeometry(geom); b.addGeometry(geom);
File file = Mockito.mock(File.class);
Mockito.when(file.getName()).thenReturn("building");
ParserConfiguration config = new ParserConfiguration(8, false); ParserConfiguration config = new ParserConfiguration(8, false);
CityDoctorModel model = new CityDoctorModel(config, new File("")); CityDoctorModel model = new CityDoctorModel(config, file, new UnconnectedCache());
model.addBuilding(b); model.addBuilding(b);
ValidationConfiguration valConfig = ValidationConfiguration.loadStandardValidationConfig(); ValidationConfiguration valConfig = ValidationConfiguration.loadStandardValidationConfig();
......
...@@ -35,7 +35,7 @@ public class SolidSelfIntCheckFalsePositiveBigMeshTest { ...@@ -35,7 +35,7 @@ public class SolidSelfIntCheckFalsePositiveBigMeshTest {
CityDoctorModel m = CityGmlParser.parseCityGmlFile(gml_filepath, config.getParserConfiguration()); CityDoctorModel m = CityGmlParser.parseCityGmlFile(gml_filepath, config.getParserConfiguration());
Checker c = new Checker(config, m); Checker c = new Checker(config, m);
c.runChecks(); c.runChecks();
Building building = m.getBuildings().get(0); Building building = m.getBuildings().toList().get(0);
/* /*
* The examples have no actual self-intersections, but can contain other actual model defects. * The examples have no actual self-intersections, but can contain other actual model defects.
* If an error is detected, it is thus required to check if the * If an error is detected, it is thus required to check if the
......
...@@ -95,7 +95,7 @@ public class SolidSelfIntCheckTest { ...@@ -95,7 +95,7 @@ public class SolidSelfIntCheckTest {
CityDoctorModel m = CityGmlParser.parseCityGmlFile("src/test/resources/SolidSelfIntTest1.gml", config.getParserConfiguration()); CityDoctorModel m = CityGmlParser.parseCityGmlFile("src/test/resources/SolidSelfIntTest1.gml", config.getParserConfiguration());
Checker c = new Checker(config, m); Checker c = new Checker(config, m);
c.runChecks(); c.runChecks();
assertFalse(m.getBuildings().get(0).containsAnyError()); assertFalse(m.getBuildings().toList().get(0).containsAnyError());
} }
...@@ -105,7 +105,7 @@ public class SolidSelfIntCheckTest { ...@@ -105,7 +105,7 @@ public class SolidSelfIntCheckTest {
CityDoctorModel m = CityGmlParser.parseCityGmlFile(gml_filepath, config.getParserConfiguration()); CityDoctorModel m = CityGmlParser.parseCityGmlFile(gml_filepath, config.getParserConfiguration());
Checker c = new Checker(config, m); Checker c = new Checker(config, m);
c.runChecks(); c.runChecks();
Building building = m.getBuildings().get(0); Building building = m.getBuildings().toList().get(0);
/* /*
* The examples have no actual self-intersections, but can contain other actual model defects. * The examples have no actual self-intersections, but can contain other actual model defects.
* If an error is detected, it is thus required to check if the * If an error is detected, it is thus required to check if the
......
...@@ -48,7 +48,7 @@ public class AllPolygonWrongOrientedTest { ...@@ -48,7 +48,7 @@ public class AllPolygonWrongOrientedTest {
Checker c = new Checker(config, model); Checker c = new Checker(config, model);
c.runChecks(); c.runChecks();
Building b = model.getBuildings().get(0); Building b = model.getBuildings().toList().get(0);
assertFalse(b.containsError(CheckId.C_GE_S_ALL_POLYGONS_WRONG_ORIENTATION)); assertFalse(b.containsError(CheckId.C_GE_S_ALL_POLYGONS_WRONG_ORIENTATION));
} }
......
...@@ -51,7 +51,7 @@ public class ConCompCheckTest extends TestCleanUp { ...@@ -51,7 +51,7 @@ public class ConCompCheckTest extends TestCleanUp {
Checker c = new Checker(m); Checker c = new Checker(m);
c.runChecks(); c.runChecks();
Geometry geom = m.getBuildings().get(0).getGeometries().get(0); Geometry geom = m.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = geom.getCheckResult(CheckId.C_GE_S_MULTIPLE_CONNECTED_COMPONENTS); CheckResult cr = geom.getCheckResult(CheckId.C_GE_S_MULTIPLE_CONNECTED_COMPONENTS);
assertNotNull(cr); assertNotNull(cr);
assertEquals(ResultStatus.ERROR, cr.getResultStatus()); assertEquals(ResultStatus.ERROR, cr.getResultStatus());
...@@ -65,7 +65,7 @@ public class ConCompCheckTest extends TestCleanUp { ...@@ -65,7 +65,7 @@ public class ConCompCheckTest extends TestCleanUp {
Checker c = new Checker(m); Checker c = new Checker(m);
c.runChecks(); c.runChecks();
Geometry geom = m.getBuildings().get(0).getGeometries().get(0); Geometry geom = m.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = geom.getCheckResult(CheckId.C_GE_S_MULTIPLE_CONNECTED_COMPONENTS); CheckResult cr = geom.getCheckResult(CheckId.C_GE_S_MULTIPLE_CONNECTED_COMPONENTS);
assertNotNull(cr); assertNotNull(cr);
assertEquals(ResultStatus.ERROR, cr.getResultStatus()); assertEquals(ResultStatus.ERROR, cr.getResultStatus());
......
...@@ -79,7 +79,7 @@ public class DupPointsCheckTest { ...@@ -79,7 +79,7 @@ public class DupPointsCheckTest {
@Test @Test
public void testDupPoints3() throws CityGmlParseException, IOException, InvalidGmlFileException { public void testDupPoints3() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel m = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS.gml"); CityDoctorModel m = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS.gml");
for (Polygon p : m.getBuildings().get(0).getGeometries().get(0).getPolygons()) { for (Polygon p : m.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
LinearRing r = p.getExteriorRing(); LinearRing r = p.getExteriorRing();
CheckResult cr = r.getCheckResult(CheckId.C_GE_R_DUPLICATE_POINT); CheckResult cr = r.getCheckResult(CheckId.C_GE_R_DUPLICATE_POINT);
assertEquals(ResultStatus.OK, cr.getResultStatus()); assertEquals(ResultStatus.OK, cr.getResultStatus());
......
...@@ -43,7 +43,7 @@ public class HoleOutsideSystemTest { ...@@ -43,7 +43,7 @@ public class HoleOutsideSystemTest {
@Test @Test
public void testHoleOutside1() throws CityGmlParseException, IOException, InvalidGmlFileException { public void testHoleOutside1() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0001-T0002.gml"); CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0001-T0002.gml");
for (Polygon p : c.getBuildings().get(0).getGeometries().get(0).getPolygons()) { for (Polygon p : c.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
CheckResult cr = p.getCheckResult(CheckId.C_GE_P_HOLE_OUTSIDE); CheckResult cr = p.getCheckResult(CheckId.C_GE_P_HOLE_OUTSIDE);
assertEquals(ResultStatus.OK, cr.getResultStatus()); assertEquals(ResultStatus.OK, cr.getResultStatus());
} }
......
...@@ -43,7 +43,7 @@ public class InnerRingsNestedSystemTest { ...@@ -43,7 +43,7 @@ public class InnerRingsNestedSystemTest {
@Test @Test
public void innerRingsNested1() throws CityGmlParseException, IOException, InvalidGmlFileException { public void innerRingsNested1() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0001-T0002.gml"); CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0001-T0002.gml");
for (Polygon p : c.getBuildings().get(0).getGeometries().get(0).getPolygons()) { for (Polygon p : c.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
CheckResult cr = p.getCheckResult(CheckId.C_GE_P_INNER_RINGS_NESTED); CheckResult cr = p.getCheckResult(CheckId.C_GE_P_INNER_RINGS_NESTED);
assertEquals(ResultStatus.OK, cr.getResultStatus()); assertEquals(ResultStatus.OK, cr.getResultStatus());
} }
......
...@@ -43,7 +43,7 @@ public class InteriorDisconnectedSystemTest { ...@@ -43,7 +43,7 @@ public class InteriorDisconnectedSystemTest {
@Test @Test
public void testInteriorDisconnected1() throws CityGmlParseException, IOException, InvalidGmlFileException { public void testInteriorDisconnected1() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0001-T0002.gml"); CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0001-T0002.gml");
for (Polygon p : c.getBuildings().get(0).getGeometries().get(0).getPolygons()) { for (Polygon p : c.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
CheckResult cr = p.getCheckResult(CheckId.C_GE_P_INTERIOR_DISCONNECTED); CheckResult cr = p.getCheckResult(CheckId.C_GE_P_INTERIOR_DISCONNECTED);
assertEquals(ResultStatus.OK, cr.getResultStatus()); assertEquals(ResultStatus.OK, cr.getResultStatus());
} }
......
...@@ -43,7 +43,7 @@ public class MultipleComponentTest { ...@@ -43,7 +43,7 @@ public class MultipleComponentTest {
@Test @Test
public void testNoMultipleComponents() throws CityGmlParseException, IOException, InvalidGmlFileException { public void testNoMultipleComponents() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS.gml"); CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS.gml");
Geometry g = c.getBuildings().get(0).getGeometries().get(0); Geometry g = c.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = g.getCheckResult(CheckId.C_GE_S_MULTIPLE_CONNECTED_COMPONENTS); CheckResult cr = g.getCheckResult(CheckId.C_GE_S_MULTIPLE_CONNECTED_COMPONENTS);
assertEquals(ResultStatus.OK, cr.getResultStatus()); assertEquals(ResultStatus.OK, cr.getResultStatus());
} }
...@@ -51,7 +51,7 @@ public class MultipleComponentTest { ...@@ -51,7 +51,7 @@ public class MultipleComponentTest {
@Test @Test
public void testMultipleComponents() throws CityGmlParseException, IOException, InvalidGmlFileException { public void testMultipleComponents() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-SO-0005-T0001.gml"); CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-SO-0005-T0001.gml");
Geometry g = c.getBuildings().get(0).getGeometries().get(0); Geometry g = c.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = g.getCheckResult(CheckId.C_GE_S_MULTIPLE_CONNECTED_COMPONENTS); CheckResult cr = g.getCheckResult(CheckId.C_GE_S_MULTIPLE_CONNECTED_COMPONENTS);
assertEquals(ResultStatus.ERROR, cr.getResultStatus()); assertEquals(ResultStatus.ERROR, cr.getResultStatus());
assertEquals(ErrorId.GE_S_MULTIPLE_CONNECTED_COMPONENTS, cr.getError().getErrorId()); assertEquals(ErrorId.GE_S_MULTIPLE_CONNECTED_COMPONENTS, cr.getError().getErrorId());
......
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