diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/Check.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/Check.java index 2610cc122d0829cb17f7750ce902053d89e23022..85cd9cfa25c43110652c3e054568f8400fc37eeb 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/Check.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/Check.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.error.DependenciesNotMetError; import de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding; @@ -46,15 +47,16 @@ import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; * The general check class containing the methods which will be called by check * engine. To create a new check override one or more check(...) methods and * implement the {@link Check#getApplicableToClasses()} method by returning a - * list of classes you wish to check. CheckResult objects can be attached to - * every Checkable. If the check has parameters override the - * {@link Check#init(Map, ParserConfiguration)} method to get the value of a - * parameter if a user has specified one in the validation plan. It will be - * contained in the Map as a string. If you have parameters you will need to - * override the {@link Check#getDefaultParameter()} method as well to declare - * which parameters you have, which name and default value they have. The name - * will be the key for the Map in the init method previously mentioned. If your - * check has dependencies you can declare them in the + * list of classes you wish to check.
+ * CheckResult objects can be attached to every Checkable. If the check has + * parameters override the {@link Check#init(Map, ParserConfiguration)} method + * to get the value of a parameter if a user has specified one in the validation + * plan. It will be contained in the Map as a string. If you have parameters you + * will need to override the {@link Check#getDefaultParameter()} method as well + * to declare which parameters you have, which name and default value they have. + * The name will be the key for the Map in the init method previously + * mentioned.
+ * If your check has dependencies you can declare them in the * {@link Check#getDependencies()} method. Be sure not to create cyclic * dependencies as that would result in undefined behavior. * @@ -66,7 +68,7 @@ public abstract class Check { private List> applicableToClasses = new ArrayList<>(2); @SuppressWarnings("unchecked") - public Check() { + protected Check() { Method[] declaredMethods = getClass().getDeclaredMethods(); for (Method m : declaredMethods) { if ("check".equals(m.getName())) { @@ -97,6 +99,8 @@ public abstract class Check { public List getDependencies() { return Collections.emptyList(); } + + public abstract Set appliesToRequirements(); /** * Getter for the check id. @@ -110,7 +114,7 @@ public abstract class Check { * * @return the check type */ - public abstract CheckType getType(); + public abstract RequirementType getType(); /** * Checks whether the check can be executed on this checkable, meaning the @@ -145,7 +149,7 @@ public abstract class Check { } return true; } - + private boolean canBeApplied(Checkable c) { for (Class checkableClass : getApplicableToClasses()) { if (checkableClass.isAssignableFrom(c.getCheckClass())) { @@ -306,7 +310,7 @@ public abstract class Check { * * @param params the parameter map containing the parameters for the check in * String form. The key should be the same String provided by the - * {@link Check#getDefaultParameter()} method + * {@link Requirement#getDefaultParameter()} method * @param config sometimes there are global parameters which can be used by * checks. Those are be stored in this container */ @@ -314,16 +318,6 @@ public abstract class Check { } - /** - * This methods gives checks the possibility to declare default parameters, used - * primarily in the GUI. - * - * @return a list of default parameters, not null - */ - public List getDefaultParameter() { - return Collections.emptyList(); - } - @Override public String toString() { return "Check [id=" + getCheckId() + "]"; diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/CheckId.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/CheckId.java index 1fac3387e9b3beab32bc0e5dcf17f2b223e8b0d9..4dec1f148cd9506ebc0270ddcf3a7e9d1108739a 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/CheckId.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/CheckId.java @@ -44,14 +44,13 @@ public class CheckId implements Serializable { public static final CheckId C_GE_P_HOLE_OUTSIDE = new CheckId("C_GE_P_HOLE_OUTSIDE"); public static final CheckId IS_CEILING = new CheckId("IS_CEILING"); public static final CheckId C_GE_P_INNER_RINGS_NESTED = new CheckId("C_GE_P_INNER_RINGS_NESTED"); - public static final CheckId C_SEM_BS_NOT_CEILING = new CheckId("C_SEM_BS_NOT_CEILING"); - public static final CheckId C_SEM_BS_NOT_FLOOR = new CheckId("C_SEM_BS_NOT_FLOOR"); - public static final CheckId C_SEM_BS_NOT_GROUND = new CheckId("C_SEM_BS_NOT_GROUND"); - public static final CheckId C_SEM_F_MISSING_ID = new CheckId("C_SEM_F_MISSING_ID"); - public static final CheckId C_SEM_BS_GROUND_NOT_FRAGMENTED = new CheckId("C_SEM_BS_GROUND_NOT_FRAGMENTED"); - public static final CheckId C_SEM_BS_IS_WALL = new CheckId("C_SEM_BS_IS_WALL"); - public static final CheckId C_SEM_SCHEMATRON = new CheckId("C_SEM_SCHEMATRON"); - public static final CheckId C_SEM_BS_ROOF_NOT_FRAGMENTED = new CheckId("C_SEM_BS_ROOF_NOT_FRAGMENTED"); + public static final CheckId C_SE_BS_IS_CEILING = new CheckId("C_SE_BS_IS_CEILING"); + public static final CheckId C_SE_BS_IS_FLOOR = new CheckId("C_SE_BS_IS_FLOOR"); + public static final CheckId C_SE_BS_IS_GROUND = new CheckId("C_SE_BS_IS_GROUND"); + public static final CheckId C_SE_BS_GROUND_NOT_FRAGMENTED = new CheckId("C_SE_BS_GROUND_NOT_FRAGMENTED"); + public static final CheckId C_SE_BS_IS_WALL = new CheckId("C_SE_BS_IS_WALL"); + public static final CheckId C_SE_SCHEMATRON = new CheckId("C_SE_SCHEMATRON"); + public static final CheckId C_SE_BS_ROOF_UNFRAGMENTED = new CheckId("C_SE_BS_ROOF_UNFRAGMENTED"); public static final CheckId C_GE_S_NOT_CLOSED = new CheckId("C_GE_S_NOT_CLOSED"); public static final CheckId C_GE_P_ORIENTATION_RINGS_SAME = new CheckId("C_GE_P_ORIENTATION_RINGS_SAME"); diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/Checkable.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/Checkable.java index e281a64db05f146777c57c606705a5f84a4b918f..005c4b31f08123d6fe21731f2358d5befe954cae 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/Checkable.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/Checkable.java @@ -31,7 +31,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.GmlId; /** * Interface to indicate that this object can be checked by Checks. * - * @author Matthias Betz - 12bema1bif@hft-stuttgart.de + * @author Matthias Betz * */ public abstract class Checkable implements Serializable { diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/DefaultParameter.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/DefaultParameter.java index 0c48ec13c4c132113288701dc9805d6033a6540b..2bb9aee3f9134f960d2e784fa82fa8081ce80817 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/DefaultParameter.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/DefaultParameter.java @@ -18,6 +18,8 @@ */ package de.hft.stuttgart.citydoctor2.check; +import java.io.Serializable; + /** * Describes a parameter for a check including the default value as a String. * All values are a String as they are passed to the check as a Map. + */ +package de.hft.stuttgart.citydoctor2.check; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class Requirement implements Serializable { + + private static final long serialVersionUID = -590639811553512803L; + + private static final String DISTANCE_TOLERANCE = "distanceTolerance"; + private static final String ANGLE_TOLERANCE = "angleTolerance"; + private static final String TYPE_STRING = "type"; + private static final String DEGENERATED_POLYGON_TOLERANCE = "degeneratedPolygonTolerance"; + private static final String LOWER_ANGLE_NAME = "lowerAngle"; + private static final String UPPER_ANGLE_NAME = "upperAngle"; + private static final String MAX_ANGLE_DEVIATION = "maxAngleDeviation"; + + public static final Requirement R_GE_R_TOO_FEW_POINTS = new Requirement("R_GE_R_TOO_FEW_POINTS", RequirementType.GEOMETRY); + public static final Requirement R_GE_R_NOT_CLOSED = new Requirement("R_GE_R_NOT_CLOSED", RequirementType.GEOMETRY); + public static final Requirement R_GE_R_CONSECUTIVE_POINTS_SAME = new Requirement("R_GE_R_CONSECUTIVE_POINTS_SAME", RequirementType.GEOMETRY); + public static final Requirement R_GE_R_SELF_INTERSECTION = new Requirement("R_GE_R_SELF_INTERSECTION", RequirementType.GEOMETRY); + public static final Requirement R_GE_P_NON_PLANAR = new Requirement("R_GE_P_NON_PLANAR", RequirementType.GEOMETRY); + public static final Requirement R_GE_P_INTERIOR_DISCONNECTED = new Requirement("R_GE_P_INTERIOR_DISCONNECTED", RequirementType.GEOMETRY); + public static final Requirement R_GE_P_INTERSECTING_RINGS = new Requirement("R_GE_P_INTERSECTING_RINGS", RequirementType.GEOMETRY); + public static final Requirement R_GE_P_HOLE_OUTSIDE = new Requirement("R_GE_P_HOLE_OUTSIDE", RequirementType.GEOMETRY); + public static final Requirement R_GE_P_ORIENTATION_RINGS_SAME = new Requirement("R_GE_P_ORIENTATION_RINGS_SAME", RequirementType.GEOMETRY); + public static final Requirement R_GE_P_INNER_RINGS_NESTED = new Requirement("R_GE_P_INNER_RINGS_NESTED", RequirementType.GEOMETRY); + public static final Requirement R_GE_S_TOO_FEW_POLYGONS = new Requirement("R_GE_S_TOO_FEW_POLYGONS", RequirementType.GEOMETRY); + public static final Requirement R_GE_S_NOT_CLOSED = new Requirement("R_GE_S_NOT_CLOSED", RequirementType.GEOMETRY); + public static final Requirement R_GE_S_NON_MANIFOLD_EDGE = new Requirement("R_GE_S_NON_MANIFOLD_EDGE", RequirementType.GEOMETRY); + public static final Requirement R_GE_S_POLYGON_WRONG_ORIENTATION = new Requirement( + "R_GE_S_POLYGON_WRONG_ORIENTATION", RequirementType.GEOMETRY); + public static final Requirement R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION = new Requirement( + "R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION", RequirementType.GEOMETRY); + public static final Requirement R_GE_S_NON_MANIFOLD_VERTEX = new Requirement("R_GE_S_NON_MANIFOLD_VERTEX", RequirementType.GEOMETRY); + public static final Requirement R_GE_S_SELF_INTERSECTION = new Requirement("R_GE_S_SELF_INTERSECTION", RequirementType.GEOMETRY); + public static final Requirement R_GE_S_MULTIPLE_CONNECTED_COMPONENTS = new Requirement( + "R_GE_S_MULTIPLE_CONNECTED_COMPONENTS", RequirementType.GEOMETRY); + public static final Requirement R_SE_ATTRIBUTES_EXISTING = new Requirement("R_SE_ATTRIBUTES_EXISTING", RequirementType.SEMANTIC); + public static final Requirement R_SE_ATTRIBUTES_CORRECT = new Requirement("R_SE_ATTRIBUTES_CORRECT", RequirementType.SEMANTIC); + public static final Requirement R_GE_R_NULL_AREA = new Requirement("R_GE_R_NULL_AREA", RequirementType.GEOMETRY); + + public static final Requirement R_SE_BS_GROUND_UNFRAGMENTED = new Requirement("R_SE_BS_GROUND_UNFRAGMENTED", RequirementType.SEMANTIC); + public static final Requirement R_SE_BS_ROOF_UNFRAGMENTED = new Requirement("R_SE_BS_GROUND_UNFRAGMENTED", RequirementType.SEMANTIC); + public static final Requirement R_SE_BS_IS_CEILING = new Requirement("R_SE_BS_IS_CEILING", RequirementType.SEMANTIC); + public static final Requirement R_SE_BS_IS_FLOOR = new Requirement("R_SE_BS_IS_FLOOR", RequirementType.SEMANTIC); + public static final Requirement R_SE_BS_IS_WALL = new Requirement("R_SE_BS_IS_WALL", RequirementType.SEMANTIC); + public static final Requirement R_SE_BS_IS_GROUND = new Requirement("R_SE_BS_IS_GROUND", RequirementType.SEMANTIC); + + static { + // fill requirements with default parameters + ArrayList defaultParameters = new ArrayList<>(); + defaultParameters.add(new DefaultParameter(TYPE_STRING, "distance", Unit.NONE)); + defaultParameters.add(new DefaultParameter(DISTANCE_TOLERANCE, "0.01", Unit.METER)); + defaultParameters.add(new DefaultParameter(ANGLE_TOLERANCE, "1", Unit.DEGREE)); + defaultParameters.add(new DefaultParameter(DEGENERATED_POLYGON_TOLERANCE, "0.00000", Unit.METER)); + R_GE_P_NON_PLANAR.parameters = Collections.unmodifiableList(defaultParameters); + + defaultParameters = new ArrayList<>(); + defaultParameters.add(new DefaultParameter(LOWER_ANGLE_NAME, "45", Unit.DEGREE)); + defaultParameters.add(new DefaultParameter(UPPER_ANGLE_NAME, "135", Unit.DEGREE)); + R_SE_BS_IS_WALL.parameters = Collections.unmodifiableList(defaultParameters); + + defaultParameters.add(new DefaultParameter(MAX_ANGLE_DEVIATION, "1", Unit.DEGREE)); + R_SE_BS_ROOF_UNFRAGMENTED.parameters = Collections.unmodifiableList(defaultParameters); + + } + + private String id; + private RequirementType type; + private List parameters; + + public Requirement(String id, RequirementType type) { + this.id = id; + this.type = type; + parameters = Collections.emptyList(); + } + + public String getId() { + return id; + } + + public List getDefaultParameter() { + return parameters; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Requirement other = (Requirement) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + + @Override + public String toString() { + return id; + } + + public RequirementType getType() { + return type; + } + +} diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/CheckType.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/RequirementType.java similarity index 97% rename from CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/CheckType.java rename to CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/RequirementType.java index b8f2afdeb1570f70e157eab3b78182e8d2ddd24c..46d63f3f8fd3ff5cb5e3f12ec2a282fb8a125843 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/CheckType.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/RequirementType.java @@ -26,7 +26,7 @@ package de.hft.stuttgart.citydoctor2.check; * @author Matthias Betz * */ -public enum CheckType { +public enum RequirementType { GEOMETRY, SEMANTIC diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/DegeneratedPolygonError.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/DegeneratedPolygonError.java index a9671a2564ac1a435689421c0480627e463039f5..708b6a7f3f7d6e3cd361910c4cbe60a11f610989 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/DegeneratedPolygonError.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/DegeneratedPolygonError.java @@ -64,7 +64,7 @@ public class DegeneratedPolygonError implements CheckError { @Override public ErrorId getErrorId() { - return ErrorId.GE_P_TINY_EDGE; + return ErrorId.GE_P_DEGENERATED_POLYGON; } @Override diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotCeilingError.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotCeilingError.java index 4ed6bea9be3872e7e88b8f87b6d50a8d91692b62..699ad8b8549224b53bd5c6490ec6559eb24ffbe2 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotCeilingError.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotCeilingError.java @@ -79,7 +79,7 @@ public class NotCeilingError implements CheckError { @Override public ErrorId getErrorId() { - return ErrorId.SEM_BS_NOT_CEILING; + return ErrorId.SE_BS_NOT_CEILING; } @Override diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotFloorError.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotFloorError.java index 1b8198f1a8148f34037dcad01d074995fbf40fdb..7f4aea9fef8998552dbe93807ce03a7032533607 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotFloorError.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotFloorError.java @@ -77,7 +77,7 @@ public class NotFloorError implements CheckError { @Override public ErrorId getErrorId() { - return ErrorId.SEM_BS_NOT_FLOOR; + return ErrorId.SE_BS_NOT_FLOOR; } @Override diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotGroundError.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotGroundError.java index b810a6f7a04f21b90b3d76c910e3a77561214f54..90395bcf61bf8e749472bcf9d3f65fe166e710db 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotGroundError.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotGroundError.java @@ -79,7 +79,7 @@ public class NotGroundError implements CheckError { @Override public ErrorId getErrorId() { - return ErrorId.SEM_BS_NOT_GROUND; + return ErrorId.SE_BS_NOT_GROUND; } @Override diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotWallError.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotWallError.java index 44a3efa741fe553639fd034f3b2ecc6d218220aa..6eb0835f3a1d43f71e4943cde5dc6b8581d5e03b 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotWallError.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/NotWallError.java @@ -82,7 +82,7 @@ public class NotWallError implements CheckError { @Override public ErrorId getErrorId() { - return ErrorId.SEM_BS_NOT_WALL; + return ErrorId.SE_BS_NOT_WALL; } @Override diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/SchematronError.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/SchematronError.java index f12702766b4948137212b619dacabeef3ae885a6..cdc72e8fc79b5aa601fe848ad81bb72e88ccb945 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/SchematronError.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/SchematronError.java @@ -94,7 +94,7 @@ public class SchematronError implements CheckError { @Override public ErrorId getErrorId() { - return ErrorId.SEM_SCHEMATRON_ERROR; + return ErrorId.SE_SCHEMATRON_ERROR; } @Override diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/SurfaceUnfragmentedError.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/SurfaceUnfragmentedError.java index 55d02c6d25f16724fb77c5f954dc6470b3f1670e..16ceb6b34d7798c5f2917f0384991fe2c983325b 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/SurfaceUnfragmentedError.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/check/error/SurfaceUnfragmentedError.java @@ -77,7 +77,7 @@ public class SurfaceUnfragmentedError implements CheckError { @Override public ErrorId getErrorId() { - return ErrorId.SEM_BS_UNFRAGMENTED; + return ErrorId.SE_BS_UNFRAGMENTED; } @Override diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundingBox.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundingBox.java index 13889c26704856b4dd1e38ebd4bfa056a2c1e145..357f39d4db29541220cc76b63a4c15ea89961cca 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundingBox.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundingBox.java @@ -42,6 +42,10 @@ public class BoundingBox { public static BoundingBox of(List polygons) { return BoundingBoxCalculator.calculateBoundingBox(polygons); } + + public static BoundingBox ofPoints(List points) { + return BoundingBoxCalculator.calculateBoundingBoxFromPoints(points); + } /** * Creates an axis aligned bounding box of the whole model. diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/CovarianceMatrix.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/CovarianceMatrix.java index f6df612f296f7809db0d6e8ef6729d2038ab67e3..0c58931eadedc13920765de1a5b5b793e49e9b2c 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/CovarianceMatrix.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/CovarianceMatrix.java @@ -56,6 +56,12 @@ public class CovarianceMatrix { covValues[1][2] += ydiff * zdiff; covValues[2][2] += zdiff * zdiff; } + covValues[0][0] /= vertices.size(); + covValues[0][1] /= vertices.size(); + covValues[0][2] /= vertices.size(); + covValues[1][1] /= vertices.size(); + covValues[1][2] /= vertices.size(); + covValues[2][2] /= vertices.size(); // the covariance matrix is symmetric, so we can fill in the remaining values covValues[1][0] = covValues[0][1]; covValues[2][0] = covValues[0][2]; diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/Matrix3x3d.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/Matrix3x3d.java index c112ee3a59e979d7f5e3f1e198755e683c4ab1a4..5d751930d3fa8c7e04f56f907130beb5f7a16782 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/Matrix3x3d.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/Matrix3x3d.java @@ -135,7 +135,7 @@ public class Matrix3x3d { /** * Multiplies this matrix with a 3-dim vector. * - * @param other the vector + * @param the multiplied vector * @return the result stored in a new vector */ public Vector3d mult(Vector3d other) { diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/OrthogonalRegressionPlane.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/OrthogonalRegressionPlane.java index 724d731697f1d6ac501727dcae51d77b13785d3b..237501906236333c00e8bfa400c8321aa05f4324 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/OrthogonalRegressionPlane.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/OrthogonalRegressionPlane.java @@ -55,10 +55,10 @@ public class OrthogonalRegressionPlane { double eig2 = eigenvalues.getZ(); Matrix v = ed.getV(); Matrix eigenVector; - if (eig0 < eig1 && eig0 < eig2) { + if (eig0 <= eig1 && eig0 <= eig2) { // the first eigenvalue is the lowest eigenVector = v.getMatrix(0, 2, 0, 0); - } else if (eig1 < eig0 && eig1 < eig2) { + } else if (eig1 <= eig0 && eig1 <= eig2) { // the second eigenvalue is the lowest eigenVector = v.getMatrix(0, 2, 1, 1); } else { diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/BoundingBoxCalculator.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/BoundingBoxCalculator.java index 5ff2bf86d2ce9000aef0974a1557daae6b20b349..2d50bf660c9d767dbe27e61096eb32891360793e 100644 --- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/BoundingBoxCalculator.java +++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/BoundingBoxCalculator.java @@ -63,17 +63,20 @@ public class BoundingBoxCalculator { for (Vertex v : p.getExteriorRing().getVertices()) { if (v.getX() < lowX) { lowX = v.getX(); - } else if (v.getX() > highX) { + } + if (v.getX() > highX) { highX = v.getX(); } if (v.getY() < lowY) { lowY = v.getY(); - } else if (v.getY() > highY) { + } + if (v.getY() > highY) { highY = v.getY(); } if (v.getZ() < lowZ) { lowZ = v.getZ(); - } else if (v.getZ() > highZ) { + } + if (v.getZ() > highZ) { highZ = v.getZ(); } } @@ -92,7 +95,7 @@ public class BoundingBoxCalculator { */ public static BoundingBox calculateBoundingBox(CityDoctorModel model) { Vector3d low = new Vector3d(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE); - Vector3d high = new Vector3d(Double.MIN_VALUE, Double.MIN_VALUE, Double.MIN_VALUE); + Vector3d high = new Vector3d(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY); findMinMax(low, high, model.getBuildings()); findMinMax(low, high, model.getBridges()); @@ -107,6 +110,40 @@ public class BoundingBoxCalculator { return BoundingBox.of(result); } + public static BoundingBox calculateBoundingBoxFromPoints(List points) { + double lowX = Double.MAX_VALUE; + double highX = Double.NEGATIVE_INFINITY; + double lowY = Double.MAX_VALUE; + double highY = Double.NEGATIVE_INFINITY; + double lowZ = Double.MAX_VALUE; + double highZ = Double.NEGATIVE_INFINITY; + // only need to check exterior rings + for (Vector3d v : points) { + if (v.getX() < lowX) { + lowX = v.getX(); + } + if (v.getX() > highX) { + highX = v.getX(); + } + if (v.getY() < lowY) { + lowY = v.getY(); + } + if (v.getY() > highY) { + highY = v.getY(); + } + if (v.getZ() < lowZ) { + lowZ = v.getZ(); + } + if (v.getZ() > highZ) { + highZ = v.getZ(); + } + } + Vector3d[] result = new Vector3d[2]; + result[0] = new Vector3d(lowX, lowY, lowZ); + result[1] = new Vector3d(highX, highY, highZ); + return BoundingBox.of(result); + } + private static void findMinMax(Vector3d low, Vector3d high, List features) { for (CityObject co : features) { findMinMax(low, high, co); @@ -121,17 +158,20 @@ public class BoundingBoxCalculator { for (Vertex v : geom.getVertices()) { if (v.getX() < low.getX()) { low.setX(v.getX()); - } else if (v.getX() > high.getX()) { + } + if (v.getX() > high.getX()) { high.setX(v.getX()); } if (v.getY() < low.getY()) { low.setY(v.getY()); - } else if (v.getY() > high.getY()) { + } + if (v.getY() > high.getY()) { high.setY(v.getY()); } if (v.getZ() < low.getZ()) { low.setZ(v.getZ()); - } else if (v.getZ() > high.getZ()) { + } + if (v.getZ() > high.getZ()) { high.setZ(v.getZ()); } } diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java index 6ca48f1d1affa1444ba7ee4a0f803252d85bf941..c24700dfdf9778d280bc5100698a6b99defbc132 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java @@ -23,7 +23,6 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; -import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -33,7 +32,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; import javax.xml.XMLConstants; @@ -47,8 +45,6 @@ import javax.xml.transform.stream.StreamSource; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.citygml4j.factory.GMLGeometryFactory; -import org.citygml4j.model.citygml.core.CityModel; import org.w3c.dom.Document; import de.hft.stuttgart.citydoctor2.check.error.AttributeMissingError; @@ -60,15 +56,9 @@ import de.hft.stuttgart.citydoctor2.checks.CheckPrototype; import de.hft.stuttgart.citydoctor2.checks.Checks; import de.hft.stuttgart.citydoctor2.checks.SvrlContentHandler; import de.hft.stuttgart.citydoctor2.checks.util.FeatureCheckedListener; -import de.hft.stuttgart.citydoctor2.datastructure.BridgeObject; -import de.hft.stuttgart.citydoctor2.datastructure.Building; import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel; import de.hft.stuttgart.citydoctor2.datastructure.CityObject; import de.hft.stuttgart.citydoctor2.datastructure.FeatureType; -import de.hft.stuttgart.citydoctor2.datastructure.LandObject; -import de.hft.stuttgart.citydoctor2.datastructure.TransportationObject; -import de.hft.stuttgart.citydoctor2.datastructure.Vegetation; -import de.hft.stuttgart.citydoctor2.datastructure.WaterObject; import de.hft.stuttgart.citydoctor2.parser.CityGmlConsumer; import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException; import de.hft.stuttgart.citydoctor2.parser.CityGmlParser; @@ -81,15 +71,10 @@ import de.hft.stuttgart.citydoctor2.reporting.XmlValidationReporter; import de.hft.stuttgart.citydoctor2.reporting.pdf.PdfReporter; import de.hft.stuttgart.citydoctor2.reporting.pdf.PdfStreamReporter; import de.hft.stuttgart.citydoctor2.utils.Localization; -import de.hft.stuttgart.citydoctor2.utils.QualityADEUtils; -import de.hft.stuttgart.quality.model.Validation; import de.hft.stuttgart.quality.model.jaxb.Checking; -import de.hft.stuttgart.quality.model.jaxb.ErrorStatistics; -import de.hft.stuttgart.quality.model.jaxb.FeatureStatistics; import de.hft.stuttgart.quality.model.jaxb.Parameter; import de.hft.stuttgart.quality.model.jaxb.Requirement; import de.hft.stuttgart.quality.model.jaxb.RequirementId; -import de.hft.stuttgart.quality.model.jaxb.Statistics; import de.hft.stuttgart.quality.model.jaxb.TopLevelFeatureType; import de.hft.stuttgart.quality.model.jaxb.ValidationPlan; import net.sf.saxon.s9api.DOMDestination; @@ -235,7 +220,7 @@ public class Checker { }); } - private static void handleSchematronErrorsForCityObject(List v, CityObject co) { + static void handleSchematronErrorsForCityObject(List v, CityObject co) { int count = 0; for (SchematronError se : v) { CheckError err; @@ -252,11 +237,11 @@ public class Checker { } } - private ValidationPlan createValidationPlan() { + ValidationPlan createValidationPlan() { ValidationPlan plan = new ValidationPlan(); List filter = createFilter(); - for (Entry e : config.getChecks().entrySet()) { + for (Entry e : config.getRequirements().entrySet()) { RequirementId reqId = mapToRequirement(e.getKey()); if (reqId == null) { continue; @@ -265,12 +250,12 @@ public class Checker { req.setName(reqId); req.setEnabled(e.getValue().isEnabled()); plan.getRequirements().add(req); - CheckPrototype proto = Checks.getCheckPrototypeForId(e.getKey()); Map parameters = e.getValue().getParameters(); + Map reqs = Checks.getAvailableRequirements(); if (parameters != null) { for (Entry param : parameters.entrySet()) { Parameter p = new Parameter(); - DefaultParameter defaultP = getDefaultParameter(param.getKey(), proto); + DefaultParameter defaultP = getDefaultParameter(param.getKey(), reqs); if (defaultP != null) { p.setUom(defaultP.getUnitType().getGmlRepresentation()); } @@ -307,10 +292,14 @@ public class Checker { return plan; } - private DefaultParameter getDefaultParameter(String key, CheckPrototype proto) { - for (DefaultParameter param : proto.getDefaultParameter()) { - if (param.getName().equals(key)) { - return param; + private DefaultParameter getDefaultParameter(String key, + Map reqs) { + de.hft.stuttgart.citydoctor2.check.Requirement requirement = reqs.get(key); + if (requirement != null) { + for (DefaultParameter param : requirement.getDefaultParameter()) { + if (param.getName().equals(key)) { + return param; + } } } return null; @@ -397,43 +386,10 @@ public class Checker { } } - private RequirementId mapToRequirement(CheckId key) { - switch (key.getName()) { - case "C_GE_R_TOO_FEW_POINTS": - return RequirementId.R_GE_R_TOO_FEW_POINTS; - case "C_GE_R_NOT_CLOSED": - return RequirementId.R_GE_R_NOT_CLOSED; - case "C_GE_R_DUPLICATE_POINT": - return RequirementId.R_GE_R_CONSECUTIVE_POINTS_SAME; - case "C_GE_R_SELF_INTERSECTION": - return RequirementId.R_GE_R_SELF_INTERSECTION; - case "C_GE_P_INTERIOR_DISCONNECTED": - return RequirementId.R_GE_P_INTERIOR_DISCONNECTED; - case "C_GE_P_INTERSECTING_RINGS": - return RequirementId.R_GE_P_INTERSECTING_RINGS; - case "C_GE_P_NON_PLANAR": - return RequirementId.R_GE_P_NON_PLANAR; - case "C_GE_S_TOO_FEW_POLYGONS": - return RequirementId.R_GE_S_TOO_FEW_POLYGONS; - case "C_GE_S_NON_MANIFOLD_EDGE": - return RequirementId.R_GE_S_NON_MANIFOLD_EDGE; - case "C_GE_S_POLYGON_WRONG_ORIENTATION": - return RequirementId.R_GE_S_POLYGON_WRONG_ORIENTATION; - case "C_GE_S_ALL_POLYGONS_WRONG_ORIENTATION": - return RequirementId.R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION; - case "C_GE_S_NON_MANIFOLD_VERTEX": - return RequirementId.R_GE_S_NON_MANIFOLD_VERTEX; - case "C_GE_S_SELF_INTERSECTION": - return RequirementId.R_GE_S_SELF_INTERSECTION; - case "C_GE_P_HOLE_OUTSIDE": - return RequirementId.R_GE_P_HOLE_OUTSIDE; - case "C_GE_P_INNER_RINGS_NESTED": - return RequirementId.R_GE_P_INNER_RINGS_NESTED; - case "C_GE_S_NOT_CLOSED": - return RequirementId.R_GE_S_NOT_CLOSED; - case "C_GE_S_MULTIPLE_CONNECTED_COMPONENTS": - return RequirementId.R_GE_S_MULTIPLE_CONNECTED_COMPONENTS; - default: + private RequirementId mapToRequirement(String requirementName) { + try { + return RequirementId.valueOf(requirementName); + } catch (IllegalArgumentException e) { return null; } } @@ -475,6 +431,8 @@ public class Checker { expandTransformer.setDestination(xslt2Transformer); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); Document doc = factory.newDocumentBuilder().newDocument(); DOMDestination domDestination = new DOMDestination(doc); @@ -570,20 +528,71 @@ public class Checker { } private List collectEnabledChecksAndInit(ParserConfiguration parserConfig, ValidationConfiguration config) { - List checks = new ArrayList<>(); - for (Entry e : config.getChecks().entrySet()) { - if (e.getValue().isEnabled()) { - Check c = checkConfig.getCheckForId(e.getKey()); - Map parameters = new HashMap<>(); - parameters.putAll(e.getValue().getParameters()); - parameters.put("numberOfRoundingPlaces", "" + config.getNumberOfRoundingPlaces()); - parameters.put("minVertexDistance", "" + config.getMinVertexDistance()); - // initialize checks with parameters - c.init(parameters, parserConfig); - checks.add(c); + Set enabledCheck = new HashSet<>(); + Map> parameterMap = new HashMap<>(); + for (Entry e : config.getRequirements().entrySet()) { + de.hft.stuttgart.citydoctor2.check.Requirement req = Checks.getAvailableRequirements().get(e.getKey()); + if (req == null) { + logger.warn("Could not find any check that satisfies requirement {}, it will not be checked", + e.getKey()); + } else { + if (e.getValue().isEnabled()) { + // this requirement is enabled + for (CheckPrototype proto : Checks.getCheckPrototypes()) { + if (proto.checksRequirements().contains(req)) { + // this requirement is checked by this check + // put all requirement parameter in the map + parameterMap.compute(proto.getCheckId(), (k, v) -> { + if (v == null) { + v = new HashMap<>(); + v.put(GlobalParameters.NUMBER_OF_ROUNDING_PLACES, + config.getNumberOfRoundingPlacesAsString()); + v.put(GlobalParameters.MIN_VERTEX_DISTANCE, config.getMinVertexDistanceAsString()); + } + v.putAll(e.getValue().getParameters()); + return v; + }); + enabledCheck.add(proto.getCheckId()); + collectDependencyChecks(proto, enabledCheck); + } + } + } } } - return checks; + fillParameterMapsWithDefaultParameter(enabledCheck, parameterMap); + ArrayList checkList = new ArrayList<>(); + for (CheckId id : enabledCheck) { + Check c = checkConfig.getCheckForId(id); + c.init(parameterMap.get(id), parserConfig); + checkList.add(c); + } + return checkList; + } + + private void fillParameterMapsWithDefaultParameter(Set enabledCheck, + Map> parameterMap) { + for (CheckId id : enabledCheck) { + CheckPrototype proto = Checks.getCheckPrototypeForId(id); + Map map = parameterMap.computeIfAbsent(id, k -> new HashMap<>()); + for (de.hft.stuttgart.citydoctor2.check.Requirement req : proto.checksRequirements()) { + if (proto.checksRequirements().contains(req)) { + for (DefaultParameter param : req.getDefaultParameter()) { + map.computeIfAbsent(param.getName(), k -> param.getValue()); + } + } + } + } + } + + private void collectDependencyChecks(CheckPrototype proto, Set enabledChecks) { + enabledChecks.addAll(proto.getDependencies()); + for (CheckId id : proto.getDependencies()) { + if (enabledChecks.contains(id)) { + continue; + } + CheckPrototype depProto = Checks.getCheckPrototypeForId(id); + collectDependencyChecks(depProto, enabledChecks); + } } private void checkCityModel(CityDoctorModel model, ProgressListener l) { @@ -724,97 +733,18 @@ public class Checker { BufferedOutputStream pdfBos = getPdfOutputMaybe(pdfOutput)) { Checker c = new Checker(config, null); String fileName = inputFile.getName(); - + // create reporter if available XmlStreamReporter xmlReporter = getXmlReporter(config, xmlBos, fileName); PdfStreamReporter pdfReporter = getPdfReporter(config, logoLocation, pdfBos, fileName); - - // create quality ade structures - Validation val = new Validation(); - val.setValidationDate(ZonedDateTime.now()); - val.setValidationSoftware("CityDoctor " + Localization.getText(Localization.VERSION)); - Statistics statistics = new Statistics(); - FeatureStatistics buildingStatistics = new FeatureStatistics(); - statistics.setNumErrorBuildings(buildingStatistics); - FeatureStatistics bridgeStatistics = new FeatureStatistics(); - statistics.setNumErrorBridgeObjects(bridgeStatistics); - FeatureStatistics transportationStatistics = new FeatureStatistics(); - statistics.setNumErrorTransportation(transportationStatistics); - FeatureStatistics vegetationStatistics = new FeatureStatistics(); - statistics.setNumErrorVegetation(vegetationStatistics); - FeatureStatistics landStatistics = new FeatureStatistics(); - statistics.setNumErrorLandObjects(landStatistics); - FeatureStatistics waterStatistics = new FeatureStatistics(); - statistics.setNumErrorWaterObjects(waterStatistics); - - // map for counting individual error counts - Map errorCount = new HashMap<>(); - GMLGeometryFactory gmlFactory = new GMLGeometryFactory(); - + // execute schematron first SvrlContentHandler handler = executeSchematronValidationIfAvailable(config, inputFile); - - CityGmlConsumer con = new CityGmlConsumer() { - @Override - public void accept(CityObject co) { - c.checkFeature(xmlReporter, pdfReporter, co); - - if (handler != null) { - List errors = handler.getFeatureErrors().get(co.getGmlId().getGmlString()); - if (errors != null) { - handleSchematronErrorsForCityObject(errors, co); - } - } - - // remove existing quality ade datastructure if existing - QualityADEUtils.removeValidationResult(co); - // store quality ade datastructures in cityobject - QualityADEUtils.writeQualityAde(co); - // recreate geometry - co.reCreateGeometries(gmlFactory, config.getParserConfiguration()); - - // store result in statistics - applyToStatistics(buildingStatistics, bridgeStatistics, transportationStatistics, - vegetationStatistics, landStatistics, waterStatistics, co); - - // add errors to statistics - List errorList = new ArrayList<>(); - co.collectContainedErrors(errorList); - Set errors = new HashSet<>(errorList); - for (CheckError e : errors) { - errorCount.compute(e.getErrorId(), (k, v) -> { - if (v == null) { - return new AtomicInteger(1); - } - v.incrementAndGet(); - return v; - }); - } + CityGmlConsumer con = new StreamCityGmlConsumer(c, xmlReporter, pdfReporter, handler, config, l); - if (l != null) { - l.featureChecked(co); - } - } - - @Override - public void accept(CityModel cm) { - QualityADEUtils.removeValidation(cm); - for (Entry e : errorCount.entrySet()) { - ErrorStatistics stats = new ErrorStatistics(); - stats.setAmount(e.getValue().get()); - stats.setName(QualityADEUtils.mapErrorIdToAdeId(e.getKey())); - statistics.getErrorStatistics().add(stats); - } - val.setStatistics(statistics); - val.setValidationPlan(c.createValidationPlan()); - - cm.addGenericApplicationPropertyOfCityModel(val); - } - }; - // parse and validate CityGmlParser.streamCityGml(inputFile, config.getParserConfiguration(), con, outputFile); - + // write reports if available writeReport(xmlReporter, handler); writeReport(pdfReporter, handler); @@ -822,33 +752,6 @@ public class Checker { logger.error(Localization.getText("Checker.failReports"), e); } } - - private static void applyToStatistics(FeatureStatistics buildingStatistics, FeatureStatistics bridgeStatistics, - FeatureStatistics transportationStatistics, FeatureStatistics vegetationStatistics, - FeatureStatistics landStatistics, FeatureStatistics waterStatistics, CityObject co) { - if (co.isValidated()) { - if (co instanceof Building) { - countForFeatureStatistics(buildingStatistics, co); - } else if (co instanceof TransportationObject) { - countForFeatureStatistics(transportationStatistics, co); - } else if (co instanceof BridgeObject) { - countForFeatureStatistics(bridgeStatistics, co); - } else if (co instanceof WaterObject) { - countForFeatureStatistics(waterStatistics, co); - } else if (co instanceof LandObject) { - countForFeatureStatistics(landStatistics, co); - } else if (co instanceof Vegetation) { - countForFeatureStatistics(vegetationStatistics, co); - } - } - } - - private static void countForFeatureStatistics(FeatureStatistics featureStatistics, CityObject co) { - featureStatistics.setNumChecked(featureStatistics.getNumChecked() + 1); - if (co.containsAnyError()) { - featureStatistics.setNumErrors(featureStatistics.getNumErrors() + 1); - } - } private static XmlStreamReporter getXmlReporter(ValidationConfiguration config, BufferedOutputStream xmlBos, String fileName) { diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/GlobalParameters.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/GlobalParameters.java new file mode 100644 index 0000000000000000000000000000000000000000..74e197d67ce3696c08ce2a9ed21528b5a330c25a --- /dev/null +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/GlobalParameters.java @@ -0,0 +1,31 @@ +/*- + * Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart + * + * This file is part of CityDoctor2. + * + * CityDoctor2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CityDoctor2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CityDoctor2. If not, see . + */ +package de.hft.stuttgart.citydoctor2.check; + +public class GlobalParameters { + + private GlobalParameters() { + + } + + public static final String SCHEMATRON_PATH = "schematronPath"; + public static final String MIN_VERTEX_DISTANCE = "minVertexDistance"; + public static final String NUMBER_OF_ROUNDING_PLACES = "numberOfRoundingPlaces"; + +} diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/CheckConfiguration.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/RequirementConfiguration.java similarity index 93% rename from CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/CheckConfiguration.java rename to CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/RequirementConfiguration.java index 142a9b1e121e93cf9ab347d3f20a35356e271304..4ae0c72831a975ff4b654df1be978f17acc92f72 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/CheckConfiguration.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/RequirementConfiguration.java @@ -29,7 +29,7 @@ import java.util.Map; * @author Matthias Betz * */ -public class CheckConfiguration implements Serializable { +public class RequirementConfiguration implements Serializable { private static final long serialVersionUID = -1258195428669813888L; @@ -59,10 +59,7 @@ public class CheckConfiguration implements Serializable { } return parameters; } - - /** - * @param parameters Sets the parameters of this check. - */ + public void setParameters(Map parameters) { this.parameters = parameters; } diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/StreamCityGmlConsumer.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/StreamCityGmlConsumer.java new file mode 100644 index 0000000000000000000000000000000000000000..d960e927b35f9fa8be9ec3f3ed935658902cf2ef --- /dev/null +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/StreamCityGmlConsumer.java @@ -0,0 +1,186 @@ +/*- + * Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart + * + * This file is part of CityDoctor2. + * + * CityDoctor2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CityDoctor2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CityDoctor2. If not, see . + */ +package de.hft.stuttgart.citydoctor2.check; + +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; +import java.util.concurrent.atomic.AtomicInteger; + +import org.citygml4j.factory.GMLGeometryFactory; +import org.citygml4j.model.citygml.core.CityModel; + +import de.hft.stuttgart.citydoctor2.check.error.SchematronError; +import de.hft.stuttgart.citydoctor2.checks.SvrlContentHandler; +import de.hft.stuttgart.citydoctor2.checks.util.FeatureCheckedListener; +import de.hft.stuttgart.citydoctor2.datastructure.BridgeObject; +import de.hft.stuttgart.citydoctor2.datastructure.Building; +import de.hft.stuttgart.citydoctor2.datastructure.CityObject; +import de.hft.stuttgart.citydoctor2.datastructure.LandObject; +import de.hft.stuttgart.citydoctor2.datastructure.TransportationObject; +import de.hft.stuttgart.citydoctor2.datastructure.Vegetation; +import de.hft.stuttgart.citydoctor2.datastructure.WaterObject; +import de.hft.stuttgart.citydoctor2.parser.CityGmlConsumer; +import de.hft.stuttgart.citydoctor2.reporting.XmlStreamReporter; +import de.hft.stuttgart.citydoctor2.reporting.pdf.PdfStreamReporter; +import de.hft.stuttgart.citydoctor2.utils.Localization; +import de.hft.stuttgart.citydoctor2.utils.QualityADEUtils; +import de.hft.stuttgart.quality.model.Validation; +import de.hft.stuttgart.quality.model.jaxb.ErrorStatistics; +import de.hft.stuttgart.quality.model.jaxb.FeatureStatistics; +import de.hft.stuttgart.quality.model.jaxb.Statistics; + +public class StreamCityGmlConsumer implements CityGmlConsumer { + + private Checker c; + private XmlStreamReporter xmlReporter; + private PdfStreamReporter pdfReporter; + private SvrlContentHandler handler; + private Map errorCount; + private GMLGeometryFactory gmlFactory; + private ValidationConfiguration config; + private Statistics statistics; + private FeatureStatistics buildingStatistics; + private FeatureStatistics bridgeStatistics; + private FeatureStatistics transportationStatistics; + private FeatureStatistics vegetationStatistics; + private FeatureStatistics landStatistics; + private FeatureStatistics waterStatistics; + private Validation val; + private FeatureCheckedListener l; + + public StreamCityGmlConsumer(Checker c, XmlStreamReporter xmlReporter, PdfStreamReporter pdfReporter, + SvrlContentHandler handler, ValidationConfiguration config, FeatureCheckedListener l) { + this.c = c; + this.xmlReporter = xmlReporter; + this.pdfReporter = pdfReporter; + this.handler = handler; + this.config = config; + this.l = l; + errorCount = new HashMap<>(); + gmlFactory = new GMLGeometryFactory(); + + val = new Validation(); + val.setValidationDate(ZonedDateTime.now()); + val.setValidationSoftware("CityDoctor " + Localization.getText(Localization.VERSION)); + statistics = new Statistics(); + buildingStatistics = new FeatureStatistics(); + statistics.setNumErrorBuildings(buildingStatistics); + bridgeStatistics = new FeatureStatistics(); + statistics.setNumErrorBridgeObjects(bridgeStatistics); + transportationStatistics = new FeatureStatistics(); + statistics.setNumErrorTransportation(transportationStatistics); + vegetationStatistics = new FeatureStatistics(); + statistics.setNumErrorVegetation(vegetationStatistics); + landStatistics = new FeatureStatistics(); + statistics.setNumErrorLandObjects(landStatistics); + waterStatistics = new FeatureStatistics(); + statistics.setNumErrorWaterObjects(waterStatistics); + + } + + @Override + public void accept(CityObject co) { + c.checkFeature(xmlReporter, pdfReporter, co); + + if (handler != null) { + List errors = handler.getFeatureErrors().get(co.getGmlId().getGmlString()); + if (errors != null) { + Checker.handleSchematronErrorsForCityObject(errors, co); + } + } + + // remove existing quality ade datastructure if existing + QualityADEUtils.removeValidationResult(co); + // store quality ade datastructures in cityobject + QualityADEUtils.writeQualityAde(co); + // recreate geometry + co.reCreateGeometries(gmlFactory, config.getParserConfiguration()); + + // store result in statistics + applyToStatistics(buildingStatistics, bridgeStatistics, transportationStatistics, vegetationStatistics, + landStatistics, waterStatistics, co); + + // add errors to statistics + List errorList = new ArrayList<>(); + co.collectContainedErrors(errorList); + Set errors = new HashSet<>(errorList); + for (CheckError e : errors) { + errorCount.compute(e.getErrorId(), (k, v) -> { + if (v == null) { + return new AtomicInteger(1); + } + v.incrementAndGet(); + return v; + }); + } + + if (l != null) { + l.featureChecked(co); + } + } + + @Override + public void accept(CityModel cm) { + QualityADEUtils.removeValidation(cm); + for (Entry e : errorCount.entrySet()) { + ErrorStatistics stats = new ErrorStatistics(); + stats.setAmount(e.getValue().get()); + stats.setName(QualityADEUtils.mapErrorIdToAdeId(e.getKey())); + statistics.getErrorStatistics().add(stats); + } + val.setStatistics(statistics); + val.setValidationPlan(c.createValidationPlan()); + + cm.addGenericApplicationPropertyOfCityModel(val); + } + + private static void applyToStatistics(FeatureStatistics buildingStatistics, FeatureStatistics bridgeStatistics, + FeatureStatistics transportationStatistics, FeatureStatistics vegetationStatistics, + FeatureStatistics landStatistics, FeatureStatistics waterStatistics, CityObject co) { + if (co.isValidated()) { + if (co instanceof Building) { + countForFeatureStatistics(buildingStatistics, co); + } else if (co instanceof TransportationObject) { + countForFeatureStatistics(transportationStatistics, co); + } else if (co instanceof BridgeObject) { + countForFeatureStatistics(bridgeStatistics, co); + } else if (co instanceof WaterObject) { + countForFeatureStatistics(waterStatistics, co); + } else if (co instanceof LandObject) { + countForFeatureStatistics(landStatistics, co); + } else if (co instanceof Vegetation) { + countForFeatureStatistics(vegetationStatistics, co); + } + } + } + + private static void countForFeatureStatistics(FeatureStatistics featureStatistics, CityObject co) { + featureStatistics.setNumChecked(featureStatistics.getNumChecked() + 1); + if (co.containsAnyError()) { + featureStatistics.setNumErrors(featureStatistics.getNumErrors() + 1); + } + } + +} diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/ValidationConfiguration.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/ValidationConfiguration.java index 35fbe42c794824fa680a2123e4eb673efe617f68..75b0da902bcb5bdf7956be64480c5b6fee09ec61 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/ValidationConfiguration.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/ValidationConfiguration.java @@ -28,6 +28,7 @@ import java.io.InputStream; import java.io.Serializable; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -40,7 +41,6 @@ import org.yaml.snakeyaml.representer.Representer; import de.hft.stuttgart.citydoctor2.checks.CheckPrototype; import de.hft.stuttgart.citydoctor2.checks.Checks; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; -import de.hft.stuttgart.citydoctor2.utils.Localization; /** * The validation configuration class represented in the yaml configuration @@ -52,19 +52,17 @@ import de.hft.stuttgart.citydoctor2.utils.Localization; */ public class ValidationConfiguration implements Serializable { + private static final String NUMBER_OF_ROUNDING_PLACES_DEFAULT = "8"; + private static final String MIN_VERTEX_DISTANCE_DEFAULT = "0.0001"; private static final long serialVersionUID = -8020055032177740646L; - private static final Logger logger = LogManager.getLogger(ValidationConfiguration.class); - private int numberOfRoundingPlaces = 8; - private double minVertexDistance = 0.0001; - - private String schematronFilePath = null; - + + private Map globalParameters; private boolean xmlValidation = false; private boolean useStreaming = false; private FilterConfiguration filter; - private Map checks; + private Map requirements; private ParserConfiguration parserConfig; @@ -81,19 +79,20 @@ public class ValidationConfiguration implements Serializable { public static ValidationConfiguration loadStandardValidationConfig() { ValidationConfiguration config = new ValidationConfiguration(); - config.checks = new HashMap<>(); + config.requirements = new HashMap<>(); for (CheckPrototype c : Checks.getCheckPrototypes()) { - CheckConfiguration cConfig = new CheckConfiguration(); - cConfig.setEnabled(true); - if (!c.getDefaultParameter().isEmpty()) { - Map paramMap = new HashMap<>(); - for (DefaultParameter param : c.getDefaultParameter()) { - paramMap.put(param.getName(), param.getDefaultValue()); + for (Requirement req : c.checksRequirements()) { + RequirementConfiguration reqConfig = new RequirementConfiguration(); + reqConfig.setEnabled(true); + for (DefaultParameter param : req.getDefaultParameter()) { + reqConfig.getParameters().put(param.getName(), param.getValue()); } - cConfig.setParameters(paramMap); + config.requirements.put(req.getId(), reqConfig); } - config.checks.put(c.getCheckId(), cConfig); } + config.globalParameters = new HashMap<>(); + config.globalParameters.put(GlobalParameters.NUMBER_OF_ROUNDING_PLACES, NUMBER_OF_ROUNDING_PLACES_DEFAULT); + config.globalParameters.put(GlobalParameters.MIN_VERTEX_DISTANCE, MIN_VERTEX_DISTANCE_DEFAULT); return config; } @@ -117,14 +116,6 @@ public class ValidationConfiguration implements Serializable { this.xmlValidation = xmlValidation; } - public String getSchematronFilePath() { - return schematronFilePath; - } - - public void setSchematronFilePath(String schematronFilePath) { - this.schematronFilePath = schematronFilePath; - } - public boolean isUseStreaming() { return useStreaming; } @@ -141,88 +132,67 @@ public class ValidationConfiguration implements Serializable { this.filter = filter; } - public Map getChecks() { - if (checks == null) { - checks = new HashMap<>(); + public Map getRequirements() { + if (requirements == null) { + requirements = new HashMap<>(); } - return checks; + return requirements; } - public void setChecks(Map checks) { - this.checks = checks; + public Map getGlobalParameters() { + if (globalParameters == null) { + globalParameters = new HashMap<>(); + } + return globalParameters; + } + + public void setGlobalParameters(Map globalParameters) { + this.globalParameters = globalParameters; } /** - * Validates the configuration, adds all missing checks as enabled, reenables - * checks that are necessary to perform other checks + * Validates the configuration, adds all missing requirements as enabled. * - * @return true if it reenabled disabled checks, false otherwise */ - public boolean validateConfiguration() { - for (CheckPrototype c : Checks.getCheckPrototypes()) { - // enable all checks that are missing in the validation config - checks.computeIfAbsent(c.getCheckId(), id -> { - CheckConfiguration cConfig = new CheckConfiguration(); - cConfig.setEnabled(true); - return cConfig; - }); - } - boolean reenabledChecks = reenableNecessaryChecks(); - if (schematronFilePath != null && !schematronFilePath.isEmpty()) { - File f = new File(schematronFilePath); - if (!f.exists() || !f.isFile()) { - schematronFilePath = null; - if (logger.isWarnEnabled()) { - logger.warn(Localization.getText("ValidationConfiguration.missingSchematron"), f.getAbsolutePath()); + public void validateConfiguration() { + logger.trace("Validating configuration"); + Map availableRequirements = Checks.getAvailableRequirements(); + + for (Entry entry : requirements.entrySet()) { + Requirement req = availableRequirements.get(entry.getKey()); + if (req != null) { + for (DefaultParameter param : req.getDefaultParameter()) { + RequirementConfiguration config = entry.getValue(); + config.getParameters().computeIfAbsent(param.getName(), k -> param.getValue()); } } } - return reenabledChecks; - } - - private boolean reenableNecessaryChecks() { - boolean reenabledChecks = false; - for (java.util.Map.Entry e : checks.entrySet()) { - if (!e.getValue().isEnabled()) { - continue; - } - CheckPrototype c = Checks.getCheckPrototypeForId(e.getKey()); - for (CheckId dep : c.getDependencies()) { - CheckConfiguration checkConfig = checks.get(dep); - if (!checkConfig.isEnabled()) { - checkConfig.setEnabled(true); - reenabledChecks = true; - if (logger.isWarnEnabled()) { - logger.warn(Localization.getText("ValidationConfiguration.reenable"), dep, c.getCheckId()); - } + for (Requirement req : availableRequirements.values()) { + requirements.computeIfAbsent(req.getId(), id -> { + RequirementConfiguration cConfig = new RequirementConfiguration(); + cConfig.setEnabled(true); + for (DefaultParameter param : req.getDefaultParameter()) { + cConfig.getParameters().put(param.getName(), param.getValue()); } - } - insertMissingParametersWithDefaultParameters(e, c); - } - return reenabledChecks; - } - - private void insertMissingParametersWithDefaultParameters(java.util.Map.Entry e, - CheckPrototype c) { - for (DefaultParameter param : c.getDefaultParameter()) { - String configuredValue = e.getValue().getParameters().get(param.getName()); - if (configuredValue == null) { - e.getValue().getParameters().put(param.getName(), param.getDefaultValue()); - } + return cConfig; + }); } + globalParameters.computeIfAbsent(GlobalParameters.MIN_VERTEX_DISTANCE, k -> MIN_VERTEX_DISTANCE_DEFAULT); + globalParameters.computeIfAbsent(GlobalParameters.NUMBER_OF_ROUNDING_PLACES, + k -> NUMBER_OF_ROUNDING_PLACES_DEFAULT); } public int getNumberOfRoundingPlaces() { - return numberOfRoundingPlaces; + return Integer.parseInt(globalParameters.get(GlobalParameters.NUMBER_OF_ROUNDING_PLACES)); } - public void setNumberOfRoundingPlaces(int numberOfRoundingPlaces) { - this.numberOfRoundingPlaces = numberOfRoundingPlaces; + public void setNumberOfRoundingPlacesInGlobalParameters(int numberOfRoundingPlaces) { + globalParameters.put(GlobalParameters.NUMBER_OF_ROUNDING_PLACES, Integer.toString(numberOfRoundingPlaces)); } public ParserConfiguration getParserConfiguration() { if (parserConfig == null) { - parserConfig = new ParserConfiguration(numberOfRoundingPlaces, xmlValidation); + parserConfig = new ParserConfiguration(getNumberOfRoundingPlaces(), xmlValidation); } return parserConfig; } @@ -231,11 +201,31 @@ public class ValidationConfiguration implements Serializable { this.parserConfig = parserConfig; } - public void setMinVertexDistance(double minVertexDistance) { - this.minVertexDistance = minVertexDistance; + public void setMinVertexDistanceInGlobalParameters(double minVertexDistance) { + globalParameters.put(GlobalParameters.MIN_VERTEX_DISTANCE, Double.toString(minVertexDistance)); } public double getMinVertexDistance() { - return minVertexDistance; + return Double.parseDouble(globalParameters.get(GlobalParameters.MIN_VERTEX_DISTANCE)); + } + + public String getSchematronFilePath() { + return globalParameters.get(GlobalParameters.SCHEMATRON_PATH); + } + + public String getNumberOfRoundingPlacesAsString() { + return globalParameters.get(GlobalParameters.NUMBER_OF_ROUNDING_PLACES); + } + + public String getMinVertexDistanceAsString() { + return globalParameters.get(GlobalParameters.MIN_VERTEX_DISTANCE); + } + + public void setSchematronFilePathInGlobalParameters(String string) { + globalParameters.put(GlobalParameters.SCHEMATRON_PATH, string); + } + + public void setRequirements(Map requirements) { + this.requirements = requirements; } } diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/CheckContainer.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/CheckContainer.java index e60d8ec13dea80c9cfc96d8bbeaf62098086d736..8040f6b08be6c63513d5deceee60b2c1344fbf5e 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/CheckContainer.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/CheckContainer.java @@ -20,6 +20,7 @@ package de.hft.stuttgart.citydoctor2.checks; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -28,9 +29,9 @@ import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; import de.hft.stuttgart.citydoctor2.check.Checkable; -import de.hft.stuttgart.citydoctor2.check.DefaultParameter; +import de.hft.stuttgart.citydoctor2.check.Requirement; +import de.hft.stuttgart.citydoctor2.check.RequirementType; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.UnknownCheckError; import de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding; @@ -68,6 +69,11 @@ public class CheckContainer extends Check { public CheckContainer(Check check) { this.check = check; } + + @Override + public Set appliesToRequirements() { + return check.appliesToRequirements(); + } @Override public void init(Map parameters, ParserConfiguration config) { @@ -98,11 +104,6 @@ public class CheckContainer extends Check { c.addCheckResult(cr); } - @Override - public List getDefaultParameter() { - return check.getDefaultParameter(); - } - @Override public List getDependencies() { return check.getDependencies(); @@ -244,7 +245,7 @@ public class CheckContainer extends Check { } @Override - public CheckType getType() { + public RequirementType getType() { return check.getType(); } diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/CheckPrototype.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/CheckPrototype.java index 9676b59baaa5559ac22a2bbc3f3a8bd56a09a35c..452990549743529330ed19ed1fffb8a4338ea4b3 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/CheckPrototype.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/CheckPrototype.java @@ -19,11 +19,12 @@ package de.hft.stuttgart.citydoctor2.checks; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckId; -import de.hft.stuttgart.citydoctor2.check.CheckType; -import de.hft.stuttgart.citydoctor2.check.DefaultParameter; +import de.hft.stuttgart.citydoctor2.check.Requirement; +import de.hft.stuttgart.citydoctor2.check.RequirementType; /** * This class is for having a read only access to a check for accessing meta @@ -58,12 +59,12 @@ public class CheckPrototype { return c.getDependencies(); } - public List getDefaultParameter() { - return c.getDefaultParameter(); + public RequirementType getType() { + return c.getType(); } - public CheckType getType() { - return c.getType(); + public Set checksRequirements() { + return c.appliesToRequirements(); } } diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/Checks.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/Checks.java index cbae54fd03436c3afc344c491fe7a0880a9224a1..813170a93ed7ed69af5de5597c94fb4309225927 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/Checks.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/Checks.java @@ -29,15 +29,15 @@ import org.apache.logging.log4j.Logger; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckId; +import de.hft.stuttgart.citydoctor2.check.Requirement; +import de.hft.stuttgart.citydoctor2.checks.geometry.AllPolygonsWrongOrientationCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.DuplicatePointsCheck; -import de.hft.stuttgart.citydoctor2.checks.geometry.FaceOutCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.HoleOutsideCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.InteriorDisconnectedCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.ManifoldVertexCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.MultipleConnectedComponentCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.NestedRingsCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.NonManifoldEdgeCheck; -import de.hft.stuttgart.citydoctor2.checks.geometry.NumPointsCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.PlanarCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.PolygonIntersectingRingsCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.PolygonSameOrientationCheck; @@ -46,6 +46,7 @@ import de.hft.stuttgart.citydoctor2.checks.geometry.RingNotClosedCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.RingSelfIntCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.SolidNotClosedCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.SolidSelfIntCheck; +import de.hft.stuttgart.citydoctor2.checks.geometry.TooFewPointsCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.TooFewPolygonsCheck; import de.hft.stuttgart.citydoctor2.checks.semantics.IsCeilingCheck; import de.hft.stuttgart.citydoctor2.checks.semantics.IsFloorCheck; @@ -62,11 +63,15 @@ import de.hft.stuttgart.citydoctor2.utils.Localization; * */ public class Checks { + + public static final double MIN_VERTEX_DISTANCE_DEFAULT = 0.0001; private static final Logger logger = LogManager.getLogger(Checks.class); private static List checkPrototypes; private static Map prototypeMap; + private static Map availableRequirements; + private Map checkMap; @@ -75,21 +80,26 @@ public class Checks { prototypeMap = new HashMap<>(); // add new checks here - publish(new NumPointsCheck()); + // ring checks + publish(new TooFewPointsCheck()); publish(new RingNotClosedCheck()); publish(new DuplicatePointsCheck()); publish(new RingSelfIntCheck()); + + // polygon checks publish(new PlanarCheck()); publish(new PolygonSameOrientationCheck()); publish(new HoleOutsideCheck()); publish(new NestedRingsCheck()); publish(new PolygonIntersectingRingsCheck()); publish(new InteriorDisconnectedCheck()); + + // solid checks publish(new MultipleConnectedComponentCheck()); publish(new SolidNotClosedCheck()); publish(new NonManifoldEdgeCheck()); publish(new PolygonWrongOrientationCheck()); - publish(new FaceOutCheck()); + publish(new AllPolygonsWrongOrientationCheck()); publish(new TooFewPolygonsCheck()); publish(new ManifoldVertexCheck()); publish(new SolidSelfIntCheck()); @@ -121,6 +131,30 @@ public class Checks { } } + private static Map collectRequirements() { + Map requirements = new HashMap<>(); + for (CheckPrototype proto : checkPrototypes) { + for (Requirement req : proto.checksRequirements()) { + requirements.put(req.getId(), req); + } + } + return requirements; + } + + /** + * Gets all requirements for which there are checks that can verify the + * requirements. This is dependent on the available checks as only the checks + * know which requirements they check. + * + * @return a set of available requirements + */ + public static Map getAvailableRequirements() { + if (availableRequirements == null) { + availableRequirements = collectRequirements(); + } + return availableRequirements; + } + private static void publish(Check check) { CheckPrototype prototype = new CheckPrototype(check); checkPrototypes.add(prototype); diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/FaceOutCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/AllPolygonsWrongOrientationCheck.java similarity index 91% rename from CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/FaceOutCheck.java rename to CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/AllPolygonsWrongOrientationCheck.java index 00799cd3200d6f2d96c3355678954fc388aaf43c..17d3b1a28d0313ee8cd7a9edf55726928bfdd43c 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/FaceOutCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/AllPolygonsWrongOrientationCheck.java @@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.AllPolygonsWrongOrientationError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; import de.hft.stuttgart.citydoctor2.datastructure.Polygon; @@ -38,11 +41,12 @@ import de.hft.stuttgart.citydoctor2.math.Vector3d; import de.hft.stuttgart.citydoctor2.tesselation.TesselatedPolygon; /** + * Checks whether all polygons have the wrong orientation. * - * @author Matthias Betz - 71bema1mst@hft-stuttgart.de + * @author Matthias Betz * */ -public class FaceOutCheck extends Check { +public class AllPolygonsWrongOrientationCheck extends Check { private static final List dependencies; @@ -171,15 +175,20 @@ public class FaceOutCheck extends Check { public List getDependencies() { return dependencies; } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION); + } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override public Check createNewInstance() { - return new FaceOutCheck(); + return new AllPolygonsWrongOrientationCheck(); } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/DuplicatePointsCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/DuplicatePointsCheck.java index d564b8365d7611e56aa2127d526100f61bac4f9b..991e7f259e5661ab98f27d08f4410edbfd687572 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/DuplicatePointsCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/DuplicatePointsCheck.java @@ -22,16 +22,19 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; import de.hft.stuttgart.citydoctor2.check.Checkable; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.ConsecutivePointSameError; import de.hft.stuttgart.citydoctor2.check.error.RingDuplicatePointError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing; import de.hft.stuttgart.citydoctor2.datastructure.Vertex; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; @@ -44,7 +47,7 @@ import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; *
*
CP_CLOSE
* - * @author Matthias Betz - 12bema1bif@hft-stuttgart.de + * @author Matthias Betz * */ public class DuplicatePointsCheck extends Check { @@ -68,9 +71,7 @@ public class DuplicatePointsCheck extends Check { @Override public void init(Map params, ParserConfiguration config) { String epsilonString = params.get(EPSILON_NAME); - if (epsilonString == null) { - epsilon = 0.0001; - } else { + if (epsilonString != null) { epsilon = Double.parseDouble(epsilonString); } } @@ -79,6 +80,11 @@ public class DuplicatePointsCheck extends Check { public List getDependencies() { return dependencies; } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.asSet(Requirement.R_GE_R_CONSECUTIVE_POINTS_SAME, Requirement.R_GE_R_SELF_INTERSECTION); + } @Override public void check(LinearRing lr) { @@ -99,8 +105,8 @@ public class DuplicatePointsCheck extends Check { // ignore last point, because last point = first, but this is allowed for (int i = 0; i < pointList.size() - 2; i++) { + Vertex point1 = pointList.get(i); for (int j = i + 2; j < pointList.size() - 1; j++) { - Vertex point1 = pointList.get(i); Vertex point2 = pointList.get(j); if (point1.equalsWithEpsilon(point2, epsilon)) { // non consecutive points same @@ -116,8 +122,8 @@ public class DuplicatePointsCheck extends Check { } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/HoleOutsideCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/HoleOutsideCheck.java index 68f60a14186571f533a6cdb89a503e8eb108bb24..8bb90e5a2df5ad5fec0ed29c7bed85e906c9a627 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/HoleOutsideCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/HoleOutsideCheck.java @@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.PolygonHoleOutsideError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing; import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.datastructure.Vertex; @@ -79,10 +82,15 @@ public class HoleOutsideCheck extends Check { public List getDependencies() { return dependencies; } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_P_HOLE_OUTSIDE); + } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/InteriorDisconnectedCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/InteriorDisconnectedCheck.java index 95c3e4d24ecd300df18bde011a5f80a9208d8068..99fa9f41016c0ebf955c3d084705addcb01e73a4 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/InteriorDisconnectedCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/InteriorDisconnectedCheck.java @@ -23,14 +23,17 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.PolygonInteriorDisconnectedError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing; import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.datastructure.Vertex; @@ -38,12 +41,18 @@ import de.hft.stuttgart.citydoctor2.math.Segment3d; import de.hft.stuttgart.citydoctor2.math.graph.CycleNode; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; +/** + * Checks if a polygon is split up into multiple polygons by interior rings + * + * @author Matthias Betz + * + */ public class InteriorDisconnectedCheck extends Check { - + private static final String EPSILON_NAME = "minVertexDistance"; - + private static final List dependencies; - + static { ArrayList deps = new ArrayList<>(); deps.add(CheckId.C_GE_R_TOO_FEW_POINTS); @@ -53,19 +62,17 @@ public class InteriorDisconnectedCheck extends Check { deps.add(CheckId.C_GE_P_NON_PLANAR); dependencies = Collections.unmodifiableList(deps); } - + private double epsilon = 0.0001; - + @Override public void init(Map params, ParserConfiguration config) { String epsilonString = params.get(EPSILON_NAME); - if (epsilonString == null) { - epsilon = 0.0001; - } else { + if (epsilonString != null) { epsilon = Double.parseDouble(epsilonString); } } - + @Override public void check(Polygon p) { if (p.getInnerRings().isEmpty()) { @@ -88,7 +95,7 @@ public class InteriorDisconnectedCheck extends Check { } } } - + for (CycleNode node : nodeMap.values()) { if (node.hasMoreThan2CycleDepth(null)) { // found ring in graph with more than 1 node @@ -127,7 +134,7 @@ public class InteriorDisconnectedCheck extends Check { p.addCheckResult(cr); return true; } - + } } } @@ -152,15 +159,20 @@ public class InteriorDisconnectedCheck extends Check { nodeMap.put(lr, node); } } - + @Override public List getDependencies() { return dependencies; } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_P_INTERIOR_DISCONNECTED); + } + + @Override + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/ManifoldVertexCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/ManifoldVertexCheck.java index 5a2c1c928e266b5b6c1d420ed6686ff069a78ed4..5e97cd55d6efd180910d6ec02a5d4092d034b1f7 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/ManifoldVertexCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/ManifoldVertexCheck.java @@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.NonManifoldVertexError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.Edge; import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; @@ -40,7 +43,7 @@ import de.hft.stuttgart.citydoctor2.math.graph.PolygonGraph; * Checks if the polygons adjacent to a vertex are attached via edges or are * they discontinuous. * - * @author Matthias Betz - 12bema1bif@hft-stuttgart.de + * @author Matthias Betz * */ public class ManifoldVertexCheck extends Check { @@ -92,10 +95,15 @@ public class ManifoldVertexCheck extends Check { public List getDependencies() { return dependencies; } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_S_NON_MANIFOLD_VERTEX); + } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/MultipleConnectedComponentCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/MultipleConnectedComponentCheck.java index 0caf422718a704e99ffbd5eaa1c16eca38b8406f..3d879923cf386fb32ce17ae1ae77b06091fd9ca5 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/MultipleConnectedComponentCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/MultipleConnectedComponentCheck.java @@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.MultipleConnectedComponentsError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; import de.hft.stuttgart.citydoctor2.datastructure.Polygon; @@ -38,7 +41,7 @@ import de.hft.stuttgart.citydoctor2.math.graph.PolygonGraph; /** * Checks if all parts of a solid are connected or not. * - * @author Matthias Betz - 12bema1bif@hft-stuttgart.de + * @author Matthias Betz * */ public class MultipleConnectedComponentCheck extends Check { @@ -86,10 +89,15 @@ public class MultipleConnectedComponentCheck extends Check { public List getDependencies() { return dependencies; } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_S_MULTIPLE_CONNECTED_COMPONENTS); + } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/NestedRingsCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/NestedRingsCheck.java index 7d5f9cc388ae96c6eb091513776b21a733c413a2..fed3f15e04d7c3aaf9d9cfe6b2e57fcac145749c 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/NestedRingsCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/NestedRingsCheck.java @@ -21,20 +21,30 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.NestedRingError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing; import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.datastructure.Vertex; +/** + * Checks whether a inner ring is completely contained in another inner ring + * within the same polygon + * + * @author Matthias Betz + * + */ public class NestedRingsCheck extends Check { - + private static final List dependencies; static { @@ -47,7 +57,7 @@ public class NestedRingsCheck extends Check { deps.add(CheckId.C_GE_P_ORIENTATION_RINGS_SAME); dependencies = Collections.unmodifiableList(deps); } - + @Override public void check(Polygon p) { for (LinearRing interiorRing : p.getInnerRings()) { @@ -85,10 +95,15 @@ public class NestedRingsCheck extends Check { public List getDependencies() { return dependencies; } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_P_INNER_RINGS_NESTED); + } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/NonManifoldEdgeCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/NonManifoldEdgeCheck.java index 2f634d42d8d93ab0bd94b30f16997fb184136e36..9d4261cd61888fdcbc3b74e18ab4be89aaa25f74 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/NonManifoldEdgeCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/NonManifoldEdgeCheck.java @@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.NonManifoldEdgeError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.Edge; import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; @@ -37,7 +40,9 @@ import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; * This class detects half edges with more than two neighbors, i.e. * non-2-manifold geometries * - * @author dwagner, alam + * @author dwagner + * @author alam + * @author Matthias Betz */ public class NonManifoldEdgeCheck extends Check { @@ -80,6 +85,11 @@ public class NonManifoldEdgeCheck extends Check { } g.addCheckResult(cr); } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_S_NON_MANIFOLD_EDGE); + } @Override public List getDependencies() { @@ -87,8 +97,8 @@ public class NonManifoldEdgeCheck extends Check { } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/NullAreaCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/NullAreaCheck.java index 8f3a2c40c8878b18315adceaa8d021d758e86957..fdba67d70045cd768780a85dc6a5bb3aa28c6bf4 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/NullAreaCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/NullAreaCheck.java @@ -22,15 +22,16 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; -import de.hft.stuttgart.citydoctor2.check.DefaultParameter; +import de.hft.stuttgart.citydoctor2.check.Requirement; +import de.hft.stuttgart.citydoctor2.check.RequirementType; import de.hft.stuttgart.citydoctor2.check.ResultStatus; -import de.hft.stuttgart.citydoctor2.check.Unit; import de.hft.stuttgart.citydoctor2.check.error.NullAreaError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing; import de.hft.stuttgart.citydoctor2.datastructure.Vertex; import de.hft.stuttgart.citydoctor2.math.Line3d; @@ -45,7 +46,6 @@ public class NullAreaCheck extends Check { private static final String DELTA_NAME = "delta"; private static final List dependencies; - private static final List defaultParameters; static { ArrayList deps = new ArrayList<>(); @@ -53,10 +53,6 @@ public class NullAreaCheck extends Check { deps.add(CheckId.C_GE_R_NOT_CLOSED); deps.add(CheckId.C_GE_R_DUPLICATE_POINT); dependencies = Collections.unmodifiableList(deps); - - ArrayList defParameters = new ArrayList<>(); - defParameters.add(new DefaultParameter(DELTA_NAME, "0.0001", Unit.SQUARE_METER)); - defaultParameters = Collections.unmodifiableList(defParameters); } private double delta = 0.0001; @@ -68,11 +64,6 @@ public class NullAreaCheck extends Check { } } - @Override - public List getDefaultParameter() { - return defaultParameters; - } - @Override public void check(LinearRing lr) { boolean areaIsNull = checkWithDistanceToRegressionLine(lr, delta); @@ -106,6 +97,11 @@ public class NullAreaCheck extends Check { } return area < 0.0001; } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_R_NULL_AREA); + } @Override public List getDependencies() { @@ -113,8 +109,8 @@ public class NullAreaCheck extends Check { } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public RequirementType getType() { + return RequirementType.GEOMETRY; } diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PlanarCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PlanarCheck.java index 8135788c0ee199a28751bd8b985ef4df2e2f89c4..f0b1d3ea453738dd60be93e31e678d58b1ad4706 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PlanarCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PlanarCheck.java @@ -22,23 +22,26 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; import Jama.EigenvalueDecomposition; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; -import de.hft.stuttgart.citydoctor2.check.DefaultParameter; +import de.hft.stuttgart.citydoctor2.check.Requirement; +import de.hft.stuttgart.citydoctor2.check.RequirementType; import de.hft.stuttgart.citydoctor2.check.ResultStatus; -import de.hft.stuttgart.citydoctor2.check.Unit; +import de.hft.stuttgart.citydoctor2.check.error.DegeneratedPolygonError; import de.hft.stuttgart.citydoctor2.check.error.NonPlanarPolygonDistancePlaneError; import de.hft.stuttgart.citydoctor2.check.error.NonPlanarPolygonNormalsDeviation; -import de.hft.stuttgart.citydoctor2.check.error.DegeneratedPolygonError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; +import de.hft.stuttgart.citydoctor2.datastructure.BoundingBox; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing; import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.datastructure.Vertex; import de.hft.stuttgart.citydoctor2.math.CovarianceMatrix; +import de.hft.stuttgart.citydoctor2.math.Matrix3x3d; import de.hft.stuttgart.citydoctor2.math.OrthogonalRegressionPlane; import de.hft.stuttgart.citydoctor2.math.Plane; import de.hft.stuttgart.citydoctor2.math.Triangle3d; @@ -48,7 +51,8 @@ import de.hft.stuttgart.citydoctor2.tesselation.JoglTesselator; import de.hft.stuttgart.citydoctor2.tesselation.TesselatedPolygon; /** - * Check class to check for planarity issues + * Check class to check for planarity issues as well as degenerated polygons. + * Checks for regression plane and normal issues. * * @author Matthias Betz * @@ -62,7 +66,6 @@ public class PlanarCheck extends Check { private static final String DEGENERATED_POLYGON_TOLERANCE = "degeneratedPolygonTolerance"; private static final List dependencies; - private static final List defaultParameters; static { ArrayList deps = new ArrayList<>(4); @@ -71,14 +74,6 @@ public class PlanarCheck extends Check { deps.add(CheckId.C_GE_R_DUPLICATE_POINT); deps.add(CheckId.C_GE_R_SELF_INTERSECTION); dependencies = Collections.unmodifiableList(deps); - - ArrayList defParameters = new ArrayList<>(3); - defParameters.add(new DefaultParameter(TYPE, DISTANCE, Unit.NONE)); - defParameters.add(new DefaultParameter(DISTANCE_TOLERANCE, "0.01", Unit.METER)); - defParameters.add(new DefaultParameter(ANGLE_TOLERANCE, "1", Unit.DEGREE)); - defParameters.add(new DefaultParameter(DEGENERATED_POLYGON_TOLERANCE, "0.00000", Unit.METER)); - defaultParameters = Collections.unmodifiableList(defParameters); - } private String planarCheckType = DISTANCE; @@ -91,6 +86,8 @@ public class PlanarCheck extends Check { public void init(Map parameters, ParserConfiguration config) { if (parameters.containsKey(TYPE)) { planarCheckType = parameters.get(TYPE).toLowerCase(); + } else { + throw new IllegalStateException("Parameter " + TYPE + " is missing from parameters"); } if (parameters.containsKey(ANGLE_TOLERANCE)) { rad = Math.toRadians(Double.parseDouble(parameters.get(ANGLE_TOLERANCE))); @@ -103,11 +100,6 @@ public class PlanarCheck extends Check { } } - @Override - public List getDefaultParameter() { - return defaultParameters; - } - @Override public void check(Polygon p) { if (DISTANCE.equals(planarCheckType)) { @@ -118,8 +110,7 @@ public class PlanarCheck extends Check { ArrayList vertices = collectVertices(p); Vector3d centroid = CovarianceMatrix.getCentroid(vertices); EigenvalueDecomposition ed = OrthogonalRegressionPlane.decompose(vertices, centroid); - Vector3d eigenvalues = OrthogonalRegressionPlane.getEigenvalues(ed); - if (checkEigenvalues(p, eigenvalues)) { + if (checkEigenvalues(p, vertices, ed)) { // found tiny edge error, abort further checking return; } @@ -181,13 +172,13 @@ public class PlanarCheck extends Check { ArrayList vertices = collectVertices(p); Vector3d centroid = CovarianceMatrix.getCentroid(vertices); EigenvalueDecomposition ed = OrthogonalRegressionPlane.decompose(vertices, centroid); - Vector3d eigenvalues = OrthogonalRegressionPlane.getEigenvalues(ed); - if (checkEigenvalues(p, eigenvalues)) { + if (checkEigenvalues(p, vertices, ed)) { // found tiny edge error, abort further checking return; } + Vector3d eigenvalues = OrthogonalRegressionPlane.getEigenvalues(ed); Plane plane = OrthogonalRegressionPlane.calculatePlane(centroid, ed, eigenvalues); for (Vertex v : vertices) { double distance = plane.getDistance(v); @@ -220,13 +211,25 @@ public class PlanarCheck extends Check { return vertices; } - private boolean checkEigenvalues(Polygon p, Vector3d eigenvalues) { + private boolean checkEigenvalues(Polygon p, List points, EigenvalueDecomposition ed) { + Matrix3x3d mat = new Matrix3x3d(ed.getV().getArray()); + List rotatedVertices = new ArrayList<>(); + for (Vertex v : points) { + rotatedVertices.add(mat.mult(v)); + } + BoundingBox bbox = BoundingBox.ofPoints(rotatedVertices); + int nrOfEigenvaluesBelowTolerance = 0; - for (double d : eigenvalues.getCoordinates()) { - if (d <= degeneratedPolygonTolerance) { - nrOfEigenvaluesBelowTolerance++; - } + if (bbox.getWidth() < degeneratedPolygonTolerance) { + nrOfEigenvaluesBelowTolerance++; + } + if (bbox.getHeight() < degeneratedPolygonTolerance) { + nrOfEigenvaluesBelowTolerance++; + } + if (bbox.getDepth() < degeneratedPolygonTolerance) { + nrOfEigenvaluesBelowTolerance++; } + if (nrOfEigenvaluesBelowTolerance >= 2) { CheckError err = new DegeneratedPolygonError(p); p.addCheckResult(new CheckResult(this, ResultStatus.ERROR, err)); @@ -241,8 +244,13 @@ public class PlanarCheck extends Check { } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_P_NON_PLANAR); + } + + @Override + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PolygonIntersectingRingsCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PolygonIntersectingRingsCheck.java index 9eb7c24ff7e746ef9a546ee1e834fbc6a2f36b81..0e2e834f710a3273e97410bce98c41029729af1a 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PolygonIntersectingRingsCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PolygonIntersectingRingsCheck.java @@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.PolygonIntersectingRingsError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing; import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.math.Polygon2d; @@ -38,11 +41,16 @@ import de.hft.stuttgart.citydoctor2.math.Vector2d; import de.hft.stuttgart.citydoctor2.utils.Pair; import de.hft.stuttgart.citydoctor2.utils.SerializablePair; +/** + * Checks whether linear rings within a polygon are intersecting with each other + * + * @author Matthias Betz + * + */ public class PolygonIntersectingRingsCheck extends Check { - private static final List dependencies; - + static { ArrayList deps = new ArrayList<>(); deps.add(CheckId.C_GE_R_TOO_FEW_POINTS); @@ -54,7 +62,7 @@ public class PolygonIntersectingRingsCheck extends Check { deps.add(CheckId.C_GE_P_INNER_RINGS_NESTED); dependencies = Collections.unmodifiableList(deps); } - + @Override public void check(Polygon p) { if (p.getInnerRings().isEmpty()) { @@ -73,7 +81,7 @@ public class PolygonIntersectingRingsCheck extends Check { } p.addCheckResult(cr); } - + public SerializablePair interiorRingsIntersectWithExterior(Polygon p) { List>> ringSegments = projectTo2D(p); for (int i = 0; i < ringSegments.size() - 1; i++) { @@ -124,8 +132,13 @@ public class PolygonIntersectingRingsCheck extends Check { } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_P_INTERSECTING_RINGS); + } + + @Override + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PolygonSameOrientationCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PolygonSameOrientationCheck.java index 7257585efbe6f275644c7945af9f49b11495952d..778ec210ff6a9a65c1201f815e0de19a89897d2b 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PolygonSameOrientationCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PolygonSameOrientationCheck.java @@ -21,22 +21,33 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.PolygonSameOrientationError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.checks.util.Orientation; import de.hft.stuttgart.citydoctor2.checks.util.RingOrientationUtil; import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.math.Polygon2d; import de.hft.stuttgart.citydoctor2.math.Ring2d; +/** + * This class checks whether a linear ring and the exterior ring of a polygon + * have the same orientation. A inner ring must be oriented in the opposite + * direction than the exterior ring. + * + * @author Matthias Betz + * + */ public class PolygonSameOrientationCheck extends Check { - + private static final List dependencies; static { @@ -48,7 +59,7 @@ public class PolygonSameOrientationCheck extends Check { deps.add(CheckId.C_GE_P_NON_PLANAR); dependencies = Collections.unmodifiableList(deps); } - + @Override public void check(Polygon p) { if (p.getInnerRings().isEmpty()) { @@ -67,7 +78,7 @@ public class PolygonSameOrientationCheck extends Check { return; } } - + // no error found, or the method would have terminated previously CheckResult cr = new CheckResult(this, ResultStatus.OK, null); p.addCheckResult(cr); @@ -80,8 +91,13 @@ public class PolygonSameOrientationCheck extends Check { } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_P_ORIENTATION_RINGS_SAME); + } + + @Override + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PolygonWrongOrientationCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PolygonWrongOrientationCheck.java index c0e8fd9a2f4a1aa3808513ae84bf575f2fdfc158..38c9629c14efb3ebdd04d890194d4d9dbdcc5fb1 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PolygonWrongOrientationCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PolygonWrongOrientationCheck.java @@ -21,28 +21,32 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.PolygonWrongOrientationError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.Edge; import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; /** - * This class checks the orientation of each face of a solid - * @author Matthias Betz - 12bema1bif@hft-stuttgart.de + * Checks whether polygons share a edge that is walked more than one time in the + * same direction by two or more polygons indicating that a polygon is oriented wrong. + * + * @author Matthias Betz * */ public class PolygonWrongOrientationCheck extends Check { - private static final List dependencies; - + static { ArrayList deps = new ArrayList<>(); deps.add(CheckId.C_GE_R_TOO_FEW_POINTS); @@ -57,19 +61,19 @@ public class PolygonWrongOrientationCheck extends Check { deps.add(CheckId.C_GE_S_NON_MANIFOLD_EDGE); dependencies = Collections.unmodifiableList(deps); } - + @Override public void check(Geometry g) { // only for solids if (g.getType() != GeometryType.SOLID) { return; } - + List faultyEdges = new ArrayList<>(); for (Edge edge : g.getEdges()) { if (edge.getNumberOfHalfEdges() != edge.getNumberOppositeHalfEdges()) { faultyEdges.add(edge); - } + } } CheckResult cr; if (faultyEdges.isEmpty()) { @@ -80,15 +84,20 @@ public class PolygonWrongOrientationCheck extends Check { } g.addCheckResult(cr); } - + @Override public List getDependencies() { return dependencies; } - + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_S_POLYGON_WRONG_ORIENTATION); + } + @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/RingNotClosedCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/RingNotClosedCheck.java index 156af281fc8e7f67002339754fff52d4e42bef5c..b1948f7e5064dd9e734a956ed22e8c923090a3aa 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/RingNotClosedCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/RingNotClosedCheck.java @@ -21,22 +21,25 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.RingNotClosedError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing; import de.hft.stuttgart.citydoctor2.datastructure.Vertex; /** - * CP_CLOSE checks the closeness a linear ring. A linear ring must end where it + * C_GE_R_NOT_CLOSED checks the closeness a linear ring. A linear ring must end where it * started. * - * @author Matthias Betz - 12bema1bif@hft-stuttgart.de + * @author Matthias Betz * */ public class RingNotClosedCheck extends Check { @@ -69,8 +72,13 @@ public class RingNotClosedCheck extends Check { } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public RequirementType getType() { + return RequirementType.GEOMETRY; + } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_R_NOT_CLOSED); } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/RingSelfIntCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/RingSelfIntCheck.java index a3e49ebfdba85d019a323cde98a61845b57e2498..05981213b99353e3d638f70044a38703848fea68 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/RingSelfIntCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/RingSelfIntCheck.java @@ -22,15 +22,19 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.PointTouchesEdgeError; import de.hft.stuttgart.citydoctor2.check.error.RingEdgeIntersectionError; +import de.hft.stuttgart.citydoctor2.checks.Checks; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.Edge; import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing; @@ -39,14 +43,19 @@ import de.hft.stuttgart.citydoctor2.math.DistanceResult; import de.hft.stuttgart.citydoctor2.math.Segment3d; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; +/** + * Checks whether a ring self intersects. Also checks if a point is too close to + * an edge of the ring. + * + * @author Matthias Betz + * + */ public class RingSelfIntCheck extends Check { - + private static final String EPSILON_NAME = "minVertexDistance"; - private static final List dependencies; - static { ArrayList deps = new ArrayList<>(); deps.add(CheckId.C_GE_R_TOO_FEW_POINTS); @@ -55,14 +64,12 @@ public class RingSelfIntCheck extends Check { dependencies = Collections.unmodifiableList(deps); } - private double epsilon = 0.0001; + private double epsilon = Checks.MIN_VERTEX_DISTANCE_DEFAULT; @Override public void init(Map parameters, ParserConfiguration config) { String epsilonString = parameters.get(EPSILON_NAME); - if (epsilonString == null) { - epsilon = 0.0001; - } else { + if (epsilonString != null) { epsilon = Double.parseDouble(epsilonString); } } @@ -74,16 +81,16 @@ public class RingSelfIntCheck extends Check { private void checkRingJava(LinearRing lr) { List edges = getEdgesForRing(lr); - + for (Edge e : edges) { if (checkForPointsTouchingEdge(lr, e)) { return; - } + } } - + for (int i = 0; i < edges.size() - 1; i++) { Edge e1 = edges.get(i); - + for (int j = i + 1; j < edges.size(); j++) { Edge e2 = edges.get(j); if (e1.getConnectionPoint(e2) != null) { @@ -101,7 +108,7 @@ public class RingSelfIntCheck extends Check { } } } - + // no errors detected CheckResult cr = new CheckResult(this, ResultStatus.OK, null); lr.addCheckResult(cr); @@ -141,8 +148,13 @@ public class RingSelfIntCheck extends Check { } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_R_SELF_INTERSECTION); + } + + @Override + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidNotClosedCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidNotClosedCheck.java index 2239d9459280456ffc13f02cd5a21eae320315d2..fb282bbe5e3ff2cd12c8ada297e645b39ccee7f7 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidNotClosedCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidNotClosedCheck.java @@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.SolidNotClosedError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.Edge; import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; @@ -37,8 +40,9 @@ import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; * This class detects half edges without neighbor, i.e. holes in solid * geometries * - * @author dwagner, alam - * @author Matthias Betz - 12bema1bif@hft-stuttgart.de + * @author dwagner + * @author alam + * @author Matthias Betz */ public class SolidNotClosedCheck extends Check { @@ -87,10 +91,15 @@ public class SolidNotClosedCheck extends Check { public List getDependencies() { return dependencies; } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_S_NOT_CLOSED); + } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheck.java index ed5f7d065fef919c7dd54a91455f896e47be60d6..67f16dd4c120e05c325fb65644a9faae3057eb65 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheck.java @@ -21,15 +21,18 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; import de.hft.stuttgart.citydoctor2.check.GeometrySelfIntersection; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.SolidSelfIntError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.checks.util.SelfIntersectionUtil; import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; @@ -98,10 +101,15 @@ public class SolidSelfIntCheck extends Check { public List getDependencies() { return dependencies; } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_S_SELF_INTERSECTION); + } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/NumPointsCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/TooFewPointsCheck.java similarity index 83% rename from CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/NumPointsCheck.java rename to CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/TooFewPointsCheck.java index f2e7cbe8b0754eefcef7e4c53231b6cbfac1a96d..1eb348c325c58f8557335a0db3c9f0c2c325ff95 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/NumPointsCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/TooFewPointsCheck.java @@ -28,23 +28,25 @@ import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.RingTooFewPointsError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing; import de.hft.stuttgart.citydoctor2.datastructure.Vertex; /** - * CP_NUMPOINTS checks the minimum number of point in a linear ring. At least + * C_GE_R_TOO_FEW_POINTS checks the minimum number of point in a linear ring. At least * three vertices are minimum for a linear ring.
*
* Dependency:
*
- *
none
+ *
C_GE_R_NOT_CLOSED
* - * @author Matthias Betz - 12bema1bif@hft-stuttgart.de + * @author Matthias Betz */ -public class NumPointsCheck extends Check { +public class TooFewPointsCheck extends Check { private static final List dependencies; @@ -95,15 +97,20 @@ public class NumPointsCheck extends Check { public List getDependencies() { return dependencies; } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_R_TOO_FEW_POINTS); + } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override public Check createNewInstance() { - return new NumPointsCheck(); + return new TooFewPointsCheck(); } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/TooFewPolygonsCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/TooFewPolygonsCheck.java index 9365e87ebbffc9f09b806e92c9fb6ad3ac7e7893..670e00942330074304ad63f97e968e9bce314d1a 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/TooFewPolygonsCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/TooFewPolygonsCheck.java @@ -21,21 +21,24 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.TooFewPolygonsError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; /** - * This class checks minimum number of planes for a solid + * This class checks minimum number of polygons for a solid * - * @author Matthias Betz 12bema1bif@hft-stuttgart.de + * @author Matthias Betz */ public class TooFewPolygonsCheck extends Check { @@ -59,7 +62,6 @@ public class TooFewPolygonsCheck extends Check { * not. * * @param toBeCheckedGeometry The ViewableGeometry that has to be checked. - * @return Vector of CDErrors */ @Override public void check(Geometry g) { @@ -81,10 +83,15 @@ public class TooFewPolygonsCheck extends Check { public List getDependencies() { return dependencies; } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_GE_S_TOO_FEW_POLYGONS); + } @Override - public CheckType getType() { - return CheckType.GEOMETRY; + public RequirementType getType() { + return RequirementType.GEOMETRY; } @Override diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/GroundSurfaceUnfragmented.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/GroundSurfaceUnfragmented.java index 55bcad728d5ebd9cf4f7a2b8b649b60812af1f5a..6ff7b13b5fbdce70a22118a2a6a0eaf8347e1791 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/GroundSurfaceUnfragmented.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/GroundSurfaceUnfragmented.java @@ -21,12 +21,15 @@ package de.hft.stuttgart.citydoctor2.checks.semantics; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.checks.util.UnfragmentedCheck; import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface; import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurfaceType; @@ -66,10 +69,15 @@ public class GroundSurfaceUnfragmented extends Check { public List getDependencies() { return dependencies; } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_SE_BS_GROUND_UNFRAGMENTED); + } @Override - public CheckType getType() { - return CheckType.SEMANTIC; + public RequirementType getType() { + return RequirementType.SEMANTIC; } @Override @@ -79,7 +87,7 @@ public class GroundSurfaceUnfragmented extends Check { @Override public CheckId getCheckId() { - return CheckId.C_SEM_BS_GROUND_NOT_FRAGMENTED; + return CheckId.C_SE_BS_GROUND_NOT_FRAGMENTED; } } diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsCeilingCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsCeilingCheck.java index c825c04b401dfaa6e73f340fdaf594c0fe7eaa83..67df459f4f584ffce836f2a56ebd1d5a076f7255 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsCeilingCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsCeilingCheck.java @@ -21,13 +21,16 @@ package de.hft.stuttgart.citydoctor2.checks.semantics; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.NotCeilingError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface; import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurfaceType; import de.hft.stuttgart.citydoctor2.datastructure.Geometry; @@ -80,10 +83,15 @@ public class IsCeilingCheck extends Check { public List getDependencies() { return dependencies; } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_SE_BS_IS_CEILING); + } @Override - public CheckType getType() { - return CheckType.SEMANTIC; + public RequirementType getType() { + return RequirementType.SEMANTIC; } @Override @@ -93,7 +101,7 @@ public class IsCeilingCheck extends Check { @Override public CheckId getCheckId() { - return CheckId.C_SEM_BS_NOT_CEILING; + return CheckId.C_SE_BS_IS_CEILING; } } diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsFloorCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsFloorCheck.java index e2e0017fd6e235adeb5f257c8ce911e0d41ed1c7..5e550825f79e0d3f84f32f495750491f3446b50a 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsFloorCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsFloorCheck.java @@ -21,13 +21,16 @@ package de.hft.stuttgart.citydoctor2.checks.semantics; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.NotFloorError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface; import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurfaceType; import de.hft.stuttgart.citydoctor2.datastructure.Geometry; @@ -83,8 +86,13 @@ public class IsFloorCheck extends Check { } @Override - public CheckType getType() { - return CheckType.SEMANTIC; + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_SE_BS_IS_FLOOR); + } + + @Override + public RequirementType getType() { + return RequirementType.SEMANTIC; } @Override @@ -94,7 +102,7 @@ public class IsFloorCheck extends Check { @Override public CheckId getCheckId() { - return CheckId.C_SEM_BS_NOT_FLOOR; + return CheckId.C_SE_BS_IS_FLOOR; } } diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsGroundCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsGroundCheck.java index 0d4e46fe261551e203a13ff356c58427cd1939e3..89a1b193a3adb66d932560ab02177c58ba14d882 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsGroundCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsGroundCheck.java @@ -21,13 +21,16 @@ package de.hft.stuttgart.citydoctor2.checks.semantics; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.error.NotGroundError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface; import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurfaceType; import de.hft.stuttgart.citydoctor2.datastructure.Geometry; @@ -80,10 +83,15 @@ public class IsGroundCheck extends Check { public List getDependencies() { return dependencies; } + + @Override + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_SE_BS_IS_GROUND); + } @Override - public CheckType getType() { - return CheckType.SEMANTIC; + public RequirementType getType() { + return RequirementType.SEMANTIC; } @Override @@ -93,6 +101,6 @@ public class IsGroundCheck extends Check { @Override public CheckId getCheckId() { - return CheckId.C_SEM_BS_NOT_GROUND; + return CheckId.C_SE_BS_IS_GROUND; } } diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsWallCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsWallCheck.java index 85437c59efb7778b1306475203d870440c05c690..dfcfedd3d82d9ed3dbc0fe5cc7d13485d7d3910c 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsWallCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/IsWallCheck.java @@ -22,15 +22,16 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; -import de.hft.stuttgart.citydoctor2.check.DefaultParameter; +import de.hft.stuttgart.citydoctor2.check.Requirement; +import de.hft.stuttgart.citydoctor2.check.RequirementType; import de.hft.stuttgart.citydoctor2.check.ResultStatus; -import de.hft.stuttgart.citydoctor2.check.Unit; import de.hft.stuttgart.citydoctor2.check.error.NotWallError; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface; import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurfaceType; import de.hft.stuttgart.citydoctor2.datastructure.Geometry; @@ -52,7 +53,6 @@ public class IsWallCheck extends Check { private static final String UPPER_ANGLE_NAME = "upperAngle"; private static final List dependencies; - private static final List defaultParameters; static { ArrayList deps = new ArrayList<>(); @@ -63,10 +63,6 @@ public class IsWallCheck extends Check { deps.add(CheckId.C_GE_P_NON_PLANAR); dependencies = Collections.unmodifiableList(deps); - ArrayList defParameters = new ArrayList<>(3); - defParameters.add(new DefaultParameter(LOWER_ANGLE_NAME, "45", Unit.DEGREE)); - defParameters.add(new DefaultParameter(UPPER_ANGLE_NAME, "135", Unit.DEGREE)); - defaultParameters = Collections.unmodifiableList(defParameters); } private static final Vector3d Z_AXIS = new Vector3d(0, 0, 1); @@ -133,13 +129,13 @@ public class IsWallCheck extends Check { } @Override - public List getDefaultParameter() { - return defaultParameters; + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_SE_BS_IS_WALL); } - + @Override - public CheckType getType() { - return CheckType.SEMANTIC; + public RequirementType getType() { + return RequirementType.SEMANTIC; } @Override @@ -149,7 +145,7 @@ public class IsWallCheck extends Check { @Override public CheckId getCheckId() { - return CheckId.C_SEM_BS_IS_WALL; + return CheckId.C_SE_BS_IS_WALL; } } diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/RoofSurfaceUnfragmentedCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/RoofSurfaceUnfragmentedCheck.java index 692ed2ee4f0839641c9b67d5b157d5452327c57c..4996b70f09ac2be386ac7a1ab4c2fd6856cf1b00 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/RoofSurfaceUnfragmentedCheck.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/semantics/RoofSurfaceUnfragmentedCheck.java @@ -22,13 +22,14 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; -import de.hft.stuttgart.citydoctor2.check.DefaultParameter; -import de.hft.stuttgart.citydoctor2.check.Unit; +import de.hft.stuttgart.citydoctor2.check.Requirement; +import de.hft.stuttgart.citydoctor2.check.RequirementType; +import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils; import de.hft.stuttgart.citydoctor2.checks.util.UnfragmentedCheck; import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface; import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurfaceType; @@ -43,17 +44,12 @@ import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; public class RoofSurfaceUnfragmentedCheck extends Check { private static final List dependencies; - private static final List defaultParameters; private static final String MAX_ANGLE_DEVIATION = "maxAngleDeviation"; private double maxAngleDeviation = Math.toRadians(1); static { - ArrayList defParameters = new ArrayList<>(3); - defParameters.add(new DefaultParameter(MAX_ANGLE_DEVIATION, "1", Unit.DEGREE)); - defaultParameters = Collections.unmodifiableList(defParameters); - ArrayList deps = new ArrayList<>(); deps.add(CheckId.C_GE_R_TOO_FEW_POINTS); deps.add(CheckId.C_GE_R_NOT_CLOSED); @@ -88,13 +84,13 @@ public class RoofSurfaceUnfragmentedCheck extends Check { } @Override - public List getDefaultParameter() { - return defaultParameters; + public Set appliesToRequirements() { + return CollectionUtils.singletonSet(Requirement.R_SE_BS_ROOF_UNFRAGMENTED); } @Override - public CheckType getType() { - return CheckType.SEMANTIC; + public RequirementType getType() { + return RequirementType.SEMANTIC; } @Override @@ -104,7 +100,7 @@ public class RoofSurfaceUnfragmentedCheck extends Check { @Override public CheckId getCheckId() { - return CheckId.C_SEM_BS_ROOF_NOT_FRAGMENTED; + return CheckId.C_SE_BS_ROOF_UNFRAGMENTED; } } diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/util/CollectionUtils.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/util/CollectionUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..cdbe4667f80817a29e9b36460c8bbbfd94ba4c67 --- /dev/null +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/util/CollectionUtils.java @@ -0,0 +1,43 @@ +/*- + * Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart + * + * This file is part of CityDoctor2. + * + * CityDoctor2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CityDoctor2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CityDoctor2. If not, see . + */ +package de.hft.stuttgart.citydoctor2.checks.util; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class CollectionUtils { + + private CollectionUtils() { + } + + public static Set singletonSet(T v) { + HashSet set = new HashSet<>(2); + set.add(v); + return set; + } + + @SafeVarargs + public static Set asSet(T... values) { + HashSet set = new HashSet<>((int) (values.length * 1.25)); + set.addAll(Arrays.asList(values)); + return set; + } + +} diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/XmlStreamReporter.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/XmlStreamReporter.java index 1deaad7100546182d398adfe0ac6fedea60eeea3..82fd142d918a562eaff3411d8515fcae3b1be014 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/XmlStreamReporter.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/XmlStreamReporter.java @@ -32,10 +32,9 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import de.hft.stuttgart.citydoctor2.check.CheckConfiguration; import de.hft.stuttgart.citydoctor2.check.CheckError; -import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.ErrorType; +import de.hft.stuttgart.citydoctor2.check.RequirementConfiguration; import de.hft.stuttgart.citydoctor2.check.ValidationConfiguration; import de.hft.stuttgart.citydoctor2.checkresult.CheckReport; import de.hft.stuttgart.citydoctor2.checkresult.Environment; @@ -115,10 +114,10 @@ public class XmlStreamReporter implements StreamReporter { plan.setNumberOfRoundingPlaces(config.getNumberOfRoundingPlaces()); List checkConfigs = new ArrayList<>(); plan.setChecks(checkConfigs); - for (Entry e : config.getChecks().entrySet()) { + for (Entry e : config.getRequirements().entrySet()) { PlanCheck checkConfig = new PlanCheck(); checkConfigs.add(checkConfig); - checkConfig.setName(e.getKey().toString()); + checkConfig.setName(e.getKey()); if (e.getValue().isEnabled()) { checkConfig.setActivated(true); Map checkParams = e.getValue().getParameters(); diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfReport.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfReport.java index b80ffa63d6e83f59a09c841b4f91048aa7d22570..3ddd133aa33f88b08ddd810e2b75acaac5462b9d 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfReport.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfReport.java @@ -41,6 +41,10 @@ import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; import org.apache.fop.apps.FopFactory; +import org.apache.fop.events.EventFormatter; +import org.apache.fop.events.model.EventSeverity; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.xmlgraphics.util.MimeConstants; import org.jdom2.Document; import org.jdom2.Element; @@ -57,6 +61,8 @@ import de.hft.stuttgart.citydoctor2.checkresult.utility.CheckReportWriteExceptio */ public class PdfReport { + private static final Logger logger = LogManager.getLogger(PdfReport.class); + private static final String FRONT_PAGE = "front-page"; private static final String REGION_BODY = "region-body"; private static final String MASTER_NAME = "master-name"; @@ -160,16 +166,28 @@ public class PdfReport { try { FOUserAgent userAgent = FOP_FACTORY.newFOUserAgent(); + userAgent.getEventBroadcaster().addEventListener(event -> { + EventSeverity severity = event.getSeverity(); + String msg = EventFormatter.format(event); + if (severity == EventSeverity.ERROR) { + logger.error(msg); + } else if (severity == EventSeverity.FATAL) { + logger.fatal(msg); + } else if (severity == EventSeverity.INFO) { + logger.info(msg); + } else if (severity == EventSeverity.WARN) { + logger.warn(msg); + } + }); Fop fop = FOP_FACTORY.newFop(MimeConstants.MIME_PDF, userAgent, outFile); - TransformerFactory factory = TransformerFactory.newInstance(); // deactivate external dtds because of security issues factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + // identity transformer Transformer transformer = factory.newTransformer(); DOMOutputter domOutputter = new DOMOutputter(); - Source src = new DOMSource(domOutputter.output(doc)); Result res = new SAXResult(fop.getDefaultHandler()); transformer.transform(src, res); diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfStreamReporter.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfStreamReporter.java index bfd739e009101bfb21c380e8055b33750a8dcd25..ebde6ffc0763231b72b4cabeacb70ca66ab7bde4 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfStreamReporter.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfStreamReporter.java @@ -32,7 +32,7 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import de.hft.stuttgart.citydoctor2.check.CheckConfiguration; +import de.hft.stuttgart.citydoctor2.check.RequirementConfiguration; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; @@ -133,8 +133,8 @@ public class PdfStreamReporter implements StreamReporter { if (config.getSchematronFilePath() != null && !config.getSchematronFilePath().isEmpty()) { vp.addTextElement("Schematron file: " + config.getSchematronFilePath()); } - for (Entry e : config.getChecks().entrySet()) { - String text = e.getKey().toString(); + for (Entry e : config.getRequirements().entrySet()) { + String text = e.getKey(); String color; if (e.getValue().isEnabled()) { text = text + " = enabled"; diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfUtils.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfUtils.java index c78f67f467f1162bca1ec8d986664207421a030f..af2ffe95e884b6c8d0822a440049a904083a799b 100644 --- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfUtils.java +++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/pdf/PdfUtils.java @@ -29,6 +29,10 @@ import org.jdom2.Namespace; */ public class PdfUtils { + private static final String HEIGHT_STRING = "height"; + + private static final String WIDTH_STRING = "width"; + private static final Namespace svgNs = Namespace.getNamespace("svg", "http://www.w3.org/2000/svg"); private static final int WIDTH = 450; @@ -46,8 +50,8 @@ public class PdfUtils { String val2LengthString = "" + val2Length; Element svgElement = new Element("svg", svgNs); - svgElement.setAttribute("width", "450px"); - svgElement.setAttribute("height", "30px"); + svgElement.setAttribute(WIDTH_STRING, "450px"); + svgElement.setAttribute(HEIGHT_STRING, "30px"); if (val1 > 0) { Element gVal1Style = new Element("g", svgNs); @@ -58,8 +62,8 @@ public class PdfUtils { gVal1Style.addContent(val1Rect); val1Rect.setAttribute("x", "0"); val1Rect.setAttribute("y", "0"); - val1Rect.setAttribute("width", val1LengthString); - val1Rect.setAttribute("height", "30"); + val1Rect.setAttribute(WIDTH_STRING, val1LengthString); + val1Rect.setAttribute(HEIGHT_STRING, "30"); Element val1Text = new Element("text", svgNs); svgElement.addContent(val1Text); val1Text.setAttribute("x", "5"); @@ -76,8 +80,8 @@ public class PdfUtils { gVal2Style.addContent(val2Rect); val2Rect.setAttribute("x", val1LengthString); val2Rect.setAttribute("y", "0"); - val2Rect.setAttribute("width", val2LengthString); - val2Rect.setAttribute("height", "30"); + val2Rect.setAttribute(WIDTH_STRING, val2LengthString); + val2Rect.setAttribute(HEIGHT_STRING, "30"); Element val2Text = new Element("text", svgNs); svgElement.addContent(val2Text); String val2String = "" + val2; diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java index 3d2b9d68927984f3c1275a2522c18047e6919699..9191678f777fd4fc3d1d79dd127a924bc185dd5d 100644 --- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java +++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java @@ -51,8 +51,8 @@ public class CheckerTest { @Test public void testSchematron() throws CityGmlParseException, InvalidGmlFileException { ValidationConfiguration config = ValidationConfiguration.loadStandardValidationConfig(); - config.getChecks().get(CheckId.C_SEM_BS_ROOF_NOT_FRAGMENTED).setEnabled(false); - config.setSchematronFilePath("src/test/resources/schematronTest.xml"); + config.getRequirements().get(Requirement.R_SE_BS_ROOF_UNFRAGMENTED.toString()).setEnabled(false); + config.setSchematronFilePathInGlobalParameters("src/test/resources/schematronTest.xml"); CityDoctorModel model = CityGmlParser.parseCityGmlFile( "src/test/resources/SimpleSolid_SrefBS_SchematronTest.gml", config.getParserConfiguration()); Checker checker = new Checker(config, model); diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/ValidationConfigurationTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/ValidationConfigurationTest.java index 45bfce21b2670c79b719a2ac0c5d46d63ed27394..c3f420e9d1f2e48b54258f3e050a1347556531d9 100644 --- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/ValidationConfigurationTest.java +++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/ValidationConfigurationTest.java @@ -25,6 +25,7 @@ import java.io.FileNotFoundException; import org.junit.Test; import de.hft.stuttgart.citydoctor2.datastructure.FeatureType; +import de.hft.stuttgart.quality.model.jaxb.RequirementId; public class ValidationConfigurationTest { @@ -33,33 +34,33 @@ public class ValidationConfigurationTest { String file = "src/test/resources/testConfig.yml"; ValidationConfiguration config = ValidationConfiguration.loadValidationConfig(file); assertEquals(8, config.getNumberOfRoundingPlaces()); - assertTrue(config.getChecks().containsKey(CheckId.C_GE_R_TOO_FEW_POINTS)); - assertTrue(config.getChecks().get(CheckId.C_GE_P_NON_PLANAR).isEnabled()); + assertTrue(config.getRequirements().containsKey(RequirementId.R_GE_R_TOO_FEW_POINTS.toString())); + assertFalse(config.getRequirements().get(RequirementId.R_GE_P_NON_PLANAR.toString()).isEnabled()); assertNull(config.getFilter()); } - + @Test public void testLoadingConfigWithFilter() throws FileNotFoundException { String file = "src/test/resources/testConfigWithFilter.yml"; ValidationConfiguration config = ValidationConfiguration.loadValidationConfig(file); assertEquals(8, config.getNumberOfRoundingPlaces()); - assertTrue(config.getChecks().containsKey(CheckId.C_GE_R_TOO_FEW_POINTS)); - assertTrue(config.getChecks().get(CheckId.C_GE_P_NON_PLANAR).isEnabled()); - + assertTrue(config.getRequirements().containsKey(RequirementId.R_GE_R_TOO_FEW_POINTS.toString())); + assertFalse(config.getRequirements().get(RequirementId.R_GE_P_NON_PLANAR.toString()).isEnabled()); + FilterConfiguration filterConfig = config.getFilter(); assertNotNull(filterConfig); - + ExcludeFilterConfiguration excludeFilter = filterConfig.getExclude(); assertNotNull(excludeFilter); - + assertTrue(excludeFilter.getIds().contains("UUID-8972-kghf-asgv")); assertTrue(excludeFilter.getIds().contains("UUID.*")); assertTrue(excludeFilter.getTypes().contains(FeatureType.BUILDING)); assertTrue(excludeFilter.getTypes().contains(FeatureType.VEGETATION)); - + IncludeFilterConfiguration includeFilter = filterConfig.getInclude(); assertNotNull(includeFilter); - + assertTrue(includeFilter.getIds().contains(".*")); assertTrue(includeFilter.getTypes().contains(FeatureType.BUILDING)); assertTrue(includeFilter.getTypes().contains(FeatureType.VEGETATION)); diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/CheckContainerTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/CheckContainerTest.java index be6ff0a7c5ff3e541d4883f349b9cee68adbf124..6a0899789f393d1122788f759e884540f3cfb846 100644 --- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/CheckContainerTest.java +++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/CheckContainerTest.java @@ -20,13 +20,16 @@ package de.hft.stuttgart.citydoctor2.checks; import static org.junit.Assert.assertEquals; +import java.util.Set; + import org.junit.Test; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckResult; -import de.hft.stuttgart.citydoctor2.check.CheckType; +import de.hft.stuttgart.citydoctor2.check.RequirementType; import de.hft.stuttgart.citydoctor2.check.ErrorId; +import de.hft.stuttgart.citydoctor2.check.Requirement; import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding; import de.hft.stuttgart.citydoctor2.datastructure.Building; @@ -43,7 +46,7 @@ public class CheckContainerTest { } @Override - public CheckType getType() { + public RequirementType getType() { return null; } @@ -56,6 +59,11 @@ public class CheckContainerTest { public CheckId getCheckId() { return CheckId.C_GE_P_HOLE_OUTSIDE; } + + @Override + public Set appliesToRequirements() { + return null; + } }; CheckContainer cc = new CheckContainer(c); diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/DegeneratedPolygonCheckTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/DegeneratedPolygonCheckTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a2fcbe402ca24619cba650fa157661d9f9e7db1b --- /dev/null +++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/DegeneratedPolygonCheckTest.java @@ -0,0 +1,87 @@ +/*- + * Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart + * + * This file is part of CityDoctor2. + * + * CityDoctor2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CityDoctor2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with CityDoctor2. If not, see . + */ +package de.hft.stuttgart.citydoctor2.checks.geometry; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; + +import de.hft.stuttgart.citydoctor2.check.CheckError; +import de.hft.stuttgart.citydoctor2.check.Checker; +import de.hft.stuttgart.citydoctor2.check.ValidationConfiguration; +import de.hft.stuttgart.citydoctor2.datastructure.Building; +import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel; +import de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon; +import de.hft.stuttgart.citydoctor2.datastructure.Geometry; +import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; +import de.hft.stuttgart.citydoctor2.datastructure.LinearRing; +import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType; +import de.hft.stuttgart.citydoctor2.datastructure.Lod; +import de.hft.stuttgart.citydoctor2.datastructure.Vertex; +import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; +import de.hft.stuttgart.quality.model.jaxb.RequirementId; + +public class DegeneratedPolygonCheckTest { + + @Test + public void testDegeneratedPolygon() { + Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, Lod.LOD1); + ConcretePolygon polygon = new ConcretePolygon(); + geom.getPolygons().add(polygon); + polygon.setParent(geom); + LinearRing lr = new LinearRing(LinearRingType.EXTERIOR); + polygon.setExteriorRing(lr); + Vertex v1 = new Vertex(427583.301, 6003502.571, 9.711); + lr.getVertices().add(v1); + Vertex v2 = new Vertex(427583.304, 6003502.574, 9.713); + lr.getVertices().add(v2); + Vertex v3 = new Vertex(427583.304, 6003502.574, 4.097); + lr.getVertices().add(v3); + Vertex v4 = new Vertex(427583.301, 6003502.571, 4.097); + lr.getVertices().add(v4); + lr.getVertices().add(v1); + geom.updateEdgesAndVertices(); + + Building b = new Building(); + b.addGeometry(geom); + + ParserConfiguration config = new ParserConfiguration(8, false); + CityDoctorModel model = new CityDoctorModel(config, new File("")); + model.addBuilding(b); + + ValidationConfiguration valConfig = ValidationConfiguration.loadStandardValidationConfig(); + valConfig.setMinVertexDistanceInGlobalParameters(0.004); + Map parameters = new HashMap<>(); + parameters.put("degeneratedPolygonTolerance", "0.004"); + valConfig.getRequirements().get(RequirementId.R_GE_P_NON_PLANAR.toString()).getParameters().putAll(parameters); + Checker c = new Checker(valConfig, model); + c.runChecks(); + + List errors = new ArrayList<>(); + b.collectContainedErrors(errors); + assertTrue(errors.isEmpty()); + } + +} diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/FaceOutCheckTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/FaceOutCheckTest.java index 96ea54215991053c76867b23695fd0d5b08bad86..68ecbbceecbec40232ff694c2b7e9e8f69f01637 100644 --- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/FaceOutCheckTest.java +++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/FaceOutCheckTest.java @@ -107,7 +107,7 @@ public class FaceOutCheckTest { public void testGoodGeometry() { Geometry geom = createGoodGeometry(); - FaceOutCheck foc = new FaceOutCheck(); + AllPolygonsWrongOrientationCheck foc = new AllPolygonsWrongOrientationCheck(); foc.check(geom); Assert.assertEquals(ResultStatus.OK, geom.getCheckResult(foc).getResultStatus()); @@ -117,7 +117,7 @@ public class FaceOutCheckTest { public void testBadGeometry() { Geometry geom = createBadGeometry(); - FaceOutCheck foc = new FaceOutCheck(); + AllPolygonsWrongOrientationCheck foc = new AllPolygonsWrongOrientationCheck(); foc.check(geom); Assert.assertEquals(ResultStatus.ERROR, geom.getCheckResult(foc).getResultStatus()); diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/NumPointsCheckTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/NumPointsCheckTest.java index b7a0b9b4ed935553cef91a3c425b2206746f7f6e..a9ab3bbce0db40040ffe2a9fea84c8b0851e8ef4 100644 --- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/NumPointsCheckTest.java +++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/NumPointsCheckTest.java @@ -53,7 +53,7 @@ public class NumPointsCheckTest { lr.addVertex(v2); lr.addVertex(v0); - NumPointsCheck check = new NumPointsCheck(); + TooFewPointsCheck check = new TooFewPointsCheck(); ParserConfiguration config = new ParserConfiguration(8, false); check.init(Collections.emptyMap(), config); check.check(lr); @@ -79,7 +79,7 @@ public class NumPointsCheckTest { lr.addVertex(v3); lr.addVertex(v0); - NumPointsCheck check = new NumPointsCheck(); + TooFewPointsCheck check = new TooFewPointsCheck(); ParserConfiguration config = new ParserConfiguration(8, false); check.init(Collections.emptyMap(), config); check.check(lr); diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NonManifoldEdgeSystemTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NonManifoldEdgeSystemTest.java index f5a5885afba3ab1e7395a8b13f981fb76671afa4..a7044537fb7edcb2d9b5fefafd861d983eb1536c 100644 --- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NonManifoldEdgeSystemTest.java +++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NonManifoldEdgeSystemTest.java @@ -34,6 +34,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel; import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException; import de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException; +import de.hft.stuttgart.quality.model.jaxb.RequirementId; /** * @@ -52,10 +53,10 @@ public class NonManifoldEdgeSystemTest { @Test public void testNonManifoldEdge2() throws CityGmlParseException, IOException, InvalidGmlFileException { - Map> paramMap = new HashMap<>(); + Map> paramMap = new HashMap<>(); Map parameter = new HashMap<>(); parameter.put("distanceTolerance", "0.1"); - paramMap.put(CheckId.C_GE_P_NON_PLANAR, parameter); + paramMap.put(RequirementId.R_GE_P_NON_PLANAR.toString(), parameter); CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-SO-0004-T0001.gml", paramMap); Geometry g = c.getBuildings().get(0).getGeometries().get(0); diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/PlanarTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/PlanarTest.java index 24199737d5efc5bd79e0b71b1f15ceeff2defa87..0378718bbc58a4d79cebbfe747ecbd1f7e84fd2d 100644 --- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/PlanarTest.java +++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/PlanarTest.java @@ -37,6 +37,7 @@ import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException; import de.hft.stuttgart.citydoctor2.parser.CityGmlParser; import de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; +import de.hft.stuttgart.quality.model.jaxb.RequirementId; /** * @@ -113,10 +114,10 @@ public class PlanarTest { @Test public void testPlanarPolygon4() throws CityGmlParseException, IOException, InvalidGmlFileException { - Map> paramMap = new HashMap<>(); + Map> paramMap = new HashMap<>(); Map parameter = new HashMap<>(); parameter.put("distanceTolerance", "0.01"); - paramMap.put(CheckId.C_GE_P_NON_PLANAR, parameter); + paramMap.put(RequirementId.R_GE_P_NON_PLANAR.toString(), parameter); CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0002-T0001.gml", paramMap); Polygon p = TestUtil.getPolygonById("_Simple_BD.1_PG.2", c); CheckResult cr = p.getCheckResult(CheckId.C_GE_P_NON_PLANAR); @@ -126,11 +127,11 @@ public class PlanarTest { @Test public void testPlanarPolygon5() throws CityGmlParseException, IOException, InvalidGmlFileException { - Map> paramMap = new HashMap<>(); + Map> paramMap = new HashMap<>(); Map parameter = new HashMap<>(); parameter.put("type", "distance"); parameter.put("distanceTolerance", "0.5"); - paramMap.put(CheckId.C_GE_P_NON_PLANAR, parameter); + paramMap.put(RequirementId.R_GE_P_NON_PLANAR.toString(), parameter); CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0002-T0001.gml", paramMap); Polygon p = TestUtil.getPolygonById("_Simple_BD.1_PG.2", c); CheckResult cr = p.getCheckResult(CheckId.C_GE_P_NON_PLANAR); @@ -139,10 +140,10 @@ public class PlanarTest { @Test public void testPlanarPolygon6() throws CityGmlParseException, IOException, InvalidGmlFileException { - Map> paramMap = new HashMap<>(); + Map> paramMap = new HashMap<>(); Map parameter = new HashMap<>(); parameter.put("type", "both"); - paramMap.put(CheckId.C_GE_P_NON_PLANAR, parameter); + paramMap.put(RequirementId.R_GE_P_NON_PLANAR.toString(), parameter); CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0002-T0002.gml", paramMap); Polygon p = TestUtil.getPolygonById("_Simple_BD.1_PG.1", c); CheckResult cr = p.getCheckResult(CheckId.C_GE_P_NON_PLANAR); diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/TestUtil.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/TestUtil.java index 30d0cc629768651743ef155bd24d0cc30eed5a9a..da96f4f1638425e7eac849ba7019508c6b2d06b8 100644 --- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/TestUtil.java +++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/TestUtil.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.Checker; import de.hft.stuttgart.citydoctor2.check.ValidationConfiguration; import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel; @@ -52,7 +51,7 @@ public class TestUtil { public static CityDoctorModel loadAndCheckCityModel(String path, int numberOfRoundingPlaces) throws CityGmlParseException, IOException, InvalidGmlFileException { ValidationConfiguration config = ValidationConfiguration.loadStandardValidationConfig(); - config.setNumberOfRoundingPlaces(numberOfRoundingPlaces); + config.setNumberOfRoundingPlacesInGlobalParameters(numberOfRoundingPlaces); CityDoctorModel m = CityGmlParser.parseCityGmlFile(path, config.getParserConfiguration()); Checker c = new Checker(config, m); c.runChecks(); @@ -63,8 +62,8 @@ public class TestUtil { public static CityDoctorModel loadAndCheckCityModel(String path, int numberOfRoundingPlaces, double minVertexDistance) throws CityGmlParseException, IOException, InvalidGmlFileException { ValidationConfiguration config = ValidationConfiguration.loadStandardValidationConfig(); - config.setNumberOfRoundingPlaces(numberOfRoundingPlaces); - config.setMinVertexDistance(minVertexDistance); + config.setNumberOfRoundingPlacesInGlobalParameters(numberOfRoundingPlaces); + config.setMinVertexDistanceInGlobalParameters(minVertexDistance); CityDoctorModel m = CityGmlParser.parseCityGmlFile(path, config.getParserConfiguration()); Checker c = new Checker(config, m); c.runChecks(); @@ -72,11 +71,11 @@ public class TestUtil { } - public static CityDoctorModel loadAndCheckCityModel(String path, Map> paramMap) + public static CityDoctorModel loadAndCheckCityModel(String path, Map> paramMap) throws CityGmlParseException, IOException, InvalidGmlFileException { ValidationConfiguration valConfig = ValidationConfiguration.loadStandardValidationConfig(); - for (Entry> e : paramMap.entrySet()) { - valConfig.getChecks().get(e.getKey()).setParameters(e.getValue()); + for (Entry> e : paramMap.entrySet()) { + valConfig.getRequirements().get(e.getKey()).getParameters().putAll(e.getValue()); } CityDoctorModel m = CityGmlParser.parseCityGmlFile(path, valConfig.getParserConfiguration()); Checker c = new Checker(valConfig, m); diff --git a/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfig.yml b/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfig.yml index 0c64010ac895e188c0dce2eb8ddb6ed8db868804..a7611706261c13d6d498703f8ca752bd252e384f 100644 --- a/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfig.yml +++ b/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfig.yml @@ -1,45 +1,53 @@ -numberOfRoundingPlaces: 8 +globalParameters: + numberOfRoundingPlaces: 8 + # in m + minVertexDistance: 0.0001 + schematronFilePath: '' useStreaming: false xmlValidation: false -checks: - C_GE_R_TOO_FEW_POINTS: +requirements: + R_GE_R_TOO_FEW_POINTS: enabled: true - C_GE_R_NOT_CLOSED: + R_GE_R_NOT_CLOSED: enabled: true - C_GE_R_DUPLICATE_POINT: + R_GE_R_CONSECUTIVE_POINTS_SAME: enabled: true - C_GE_R_SELF_INTERSECTION: + R_GE_R_SELF_INTERSECTION: enabled: true - C_GE_S_MULTIPLE_CONNECTED_COMPONENTS: + R_GE_S_MULTIPLE_CONNECTED_COMPONENTS: enabled: true - C_GE_P_INTERIOR_DISCONNECTED: + R_GE_P_INTERIOR_DISCONNECTED: enabled: true - C_GE_P_INTERSECTING_RINGS: + R_GE_P_INTERSECTING_RINGS: enabled: true - C_GE_P_NON_PLANAR: + R_GE_P_NON_PLANAR: enabled: false parameters: # one of ("distance", "angle", "both") type: distance + # in m distanceTolerance: 0.01 - angleTolerance: 0.1 - C_GE_P_HOLE_OUTSIDE: + # in degree + angleTolerance: 1 + # in m + degeneratedPolygonTolerance: 0 + R_GE_P_HOLE_OUTSIDE: enabled: true - C_GE_P_ORIENTATION_RINGS_SAME: + R_GE_P_ORIENTATION_RINGS_SAME: enabled: true - C_GE_P_INNER_RINGS_NESTED: + R_GE_P_INNER_RINGS_NESTED: enabled: true - C_GE_S_TOO_FEW_POLYGONS: + R_GE_S_TOO_FEW_POLYGONS: enabled: true - C_GE_S_NOT_CLOSED: + R_GE_S_NOT_CLOSED: enabled: true - C_GE_S_NON_MANIFOLD_EDGE: + R_GE_S_NON_MANIFOLD_EDGE: enabled: true - C_GE_S_POLYGON_WRONG_ORIENTATION: + R_GE_S_POLYGON_WRONG_ORIENTATION: enabled: true - C_GE_S_ALL_POLYGONS_WRONG_ORIENTATION: + R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION: enabled: true - C_GE_S_NON_MANIFOLD_VERTEX: + R_GE_S_NON_MANIFOLD_VERTEX: enabled: true - C_GE_S_SELF_INTERSECTION: + R_GE_S_SELF_INTERSECTION: enabled: true \ No newline at end of file diff --git a/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithExclude.yml b/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithExclude.yml index c279b3e54aa14b8548350914c2296ed04adca08d..3e052a7c86ff8dccc4f1eaf388efe8314e158848 100644 --- a/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithExclude.yml +++ b/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithExclude.yml @@ -1,4 +1,6 @@ -numberOfRoundingPlaces: 8 +globalParameters: + numberOfRoundingPlaces: 8 + minVertexDistance: 0.0001 filter: exclude: # available types: BUILDING, VEGETATION, TRANSPORTATION, BRIDGE, LAND, WATER @@ -6,45 +8,47 @@ filter: - BUILDING # exlude matching ids (Regex) ids: -checks: - C_GE_R_TOO_FEW_POINTS: +requirements: + R_GE_R_TOO_FEW_POINTS: enabled: true - C_GE_R_NOT_CLOSED: + R_GE_R_NOT_CLOSED: enabled: true - C_GE_R_DUPLICATE_POINT: + R_GE_R_CONSECUTIVE_POINTS_SAME: enabled: true - C_GE_R_SELF_INTERSECTION: + R_GE_R_SELF_INTERSECTION: enabled: true - C_GE_S_MULTIPLE_CONNECTED_COMPONENTS: + R_GE_S_MULTIPLE_CONNECTED_COMPONENTS: enabled: true - C_GE_P_INTERIOR_DISCONNECTED: + R_GE_P_INTERIOR_DISCONNECTED: enabled: true - C_GE_P_INTERSECTING_RINGS: + R_GE_P_INTERSECTING_RINGS: enabled: true - C_GE_P_NON_PLANAR: + R_GE_P_NON_PLANAR: enabled: false parameters: # one of ("distance", "angle", "both") type: distance + # in m distanceTolerance: 0.01 - angleTolerance: 0.1 - C_GE_P_HOLE_OUTSIDE: + # in degree + angleTolerance: 1 + R_GE_P_HOLE_OUTSIDE: enabled: true - C_GE_P_ORIENTATION_RINGS_SAME: + R_GE_P_ORIENTATION_RINGS_SAME: enabled: true - C_GE_P_INNER_RINGS_NESTED: + R_GE_P_INNER_RINGS_NESTED: enabled: true - C_GE_S_TOO_FEW_POLYGONS: + R_GE_S_TOO_FEW_POLYGONS: enabled: true - C_GE_S_NOT_CLOSED: + R_GE_S_NOT_CLOSED: enabled: true - C_GE_S_NON_MANIFOLD_EDGE: + R_GE_S_NON_MANIFOLD_EDGE: enabled: true - C_GE_S_POLYGON_WRONG_ORIENTATION: + R_GE_S_POLYGON_WRONG_ORIENTATION: enabled: true - C_GE_S_ALL_POLYGONS_WRONG_ORIENTATION: + R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION: enabled: true - C_GE_S_NON_MANIFOLD_VERTEX: + R_GE_S_NON_MANIFOLD_VERTEX: enabled: true - C_GE_S_SELF_INTERSECTION: + R_GE_S_SELF_INTERSECTION: enabled: true \ No newline at end of file diff --git a/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithFilter.yml b/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithFilter.yml index afd1032a7f70abac97364a6b6c073954f40f12e3..0b082f40f271838ed3ef0f2180dad50ce41d22b3 100644 --- a/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithFilter.yml +++ b/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithFilter.yml @@ -1,4 +1,7 @@ -numberOfRoundingPlaces: 8 +globalParameters: + numberOfRoundingPlaces: 8 + # in m + minVertexDistance: 0.0001 filter: include: # available types: BUILDING, VEGETATION, TRANSPORTATION, BRIDGE, LAND, WATER @@ -27,45 +30,47 @@ filter: - UUID-8972-kghf-asgv - UUID-567-asdf-GEGH - UUID.* -checks: - C_GE_R_TOO_FEW_POINTS: +requirements: + R_GE_R_TOO_FEW_POINTS: enabled: true - C_GE_R_NOT_CLOSED: + R_GE_R_NOT_CLOSED: enabled: true - C_GE_R_DUPLICATE_POINT: + R_GE_R_CONSECUTIVE_POINTS_SAME: enabled: true - C_GE_R_SELF_INTERSECTION: + R_GE_R_SELF_INTERSECTION: enabled: true - C_GE_S_MULTIPLE_CONNECTED_COMPONENTS: + R_GE_S_MULTIPLE_CONNECTED_COMPONENTS: enabled: true - C_GE_P_INTERIOR_DISCONNECTED: + R_GE_P_INTERIOR_DISCONNECTED: enabled: true - C_GE_P_INTERSECTING_RINGS: + R_GE_P_INTERSECTING_RINGS: enabled: true - C_GE_P_NON_PLANAR: + R_GE_P_NON_PLANAR: enabled: false parameters: # one of ("distance", "angle", "both") type: distance + # in m distanceTolerance: 0.01 - angleTolerance: 0.1 - C_GE_P_HOLE_OUTSIDE: + # in degree + angleTolerance: 1 + R_GE_P_HOLE_OUTSIDE: enabled: true - C_GE_P_ORIENTATION_RINGS_SAME: + R_GE_P_ORIENTATION_RINGS_SAME: enabled: true - C_GE_P_INNER_RINGS_NESTED: + R_GE_P_INNER_RINGS_NESTED: enabled: true - C_GE_S_TOO_FEW_POLYGONS: + R_GE_S_TOO_FEW_POLYGONS: enabled: true - C_GE_S_NOT_CLOSED: + R_GE_S_NOT_CLOSED: enabled: true - C_GE_S_NON_MANIFOLD_EDGE: + R_GE_S_NON_MANIFOLD_EDGE: enabled: true - C_GE_S_POLYGON_WRONG_ORIENTATION: + R_GE_S_POLYGON_WRONG_ORIENTATION: enabled: true - C_GE_S_ALL_POLYGONS_WRONG_ORIENTATION: + R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION: enabled: true - C_GE_S_NON_MANIFOLD_VERTEX: + R_GE_S_NON_MANIFOLD_VERTEX: enabled: true - C_GE_S_SELF_INTERSECTION: + R_GE_S_SELF_INTERSECTION: enabled: true \ No newline at end of file diff --git a/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithInclude.yml b/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithInclude.yml index 2f8c5af6832e584e3df5d20e3fa14763e9876891..6f49da49aee6021f81bf01d635abad0eee6e5fbb 100644 --- a/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithInclude.yml +++ b/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithInclude.yml @@ -1,48 +1,49 @@ -numberOfRoundingPlaces: 8 +globalParameters: + numberOfRoundingPlaces: 8 filter: include: # available types: BUILDING, VEGETATION, TRANSPORTATION, BRIDGE, LAND, WATER types: - TRANSPORTATION -checks: - C_GE_R_TOO_FEW_POINTS: +requirements: + R_GE_R_TOO_FEW_POINTS: enabled: true - C_GE_R_NOT_CLOSED: + R_GE_R_NOT_CLOSED: enabled: true - C_GE_R_DUPLICATE_POINT: + R_GE_R_CONSECUTIVE_POINTS_SAME: enabled: true - C_GE_R_SELF_INTERSECTION: + R_GE_R_SELF_INTERSECTION: enabled: true - C_GE_S_MULTIPLE_CONNECTED_COMPONENTS: + R_GE_S_MULTIPLE_CONNECTED_COMPONENTS: enabled: true - C_GE_P_INTERIOR_DISCONNECTED: + R_GE_P_INTERIOR_DISCONNECTED: enabled: true - C_GE_P_INTERSECTING_RINGS: + R_GE_P_INTERSECTING_RINGS: enabled: true - C_GE_P_NON_PLANAR: + R_GE_P_NON_PLANAR: enabled: false parameters: # one of ("distance", "angle", "both") type: distance distanceTolerance: 0.01 angleTolerance: 0.1 - C_GE_P_HOLE_OUTSIDE: + R_GE_P_HOLE_OUTSIDE: enabled: true - C_GE_P_ORIENTATION_RINGS_SAME: + R_GE_P_ORIENTATION_RINGS_SAME: enabled: true - C_GE_P_INNER_RINGS_NESTED: + R_GE_P_INNER_RINGS_NESTED: enabled: true - C_GE_S_TOO_FEW_POLYGONS: + R_GE_S_TOO_FEW_POLYGONS: enabled: true - C_GE_S_NOT_CLOSED: + R_GE_S_NOT_CLOSED: enabled: true - C_GE_S_NON_MANIFOLD_EDGE: + R_GE_S_NON_MANIFOLD_EDGE: enabled: true - C_GE_S_POLYGON_WRONG_ORIENTATION: + R_GE_S_POLYGON_WRONG_ORIENTATION: enabled: true - C_GE_S_ALL_POLYGONS_WRONG_ORIENTATION: + R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION: enabled: true - C_GE_S_NON_MANIFOLD_VERTEX: + R_GE_S_NON_MANIFOLD_VERTEX: enabled: true - C_GE_S_SELF_INTERSECTION: + R_GE_S_SELF_INTERSECTION: enabled: true \ No newline at end of file diff --git a/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithStreaming.yml b/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithStreaming.yml index ea1009418f18e1c759bb077b9b9309086aaf3733..311740e36283048724408342783c113ad816e35b 100644 --- a/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithStreaming.yml +++ b/CityDoctorParent/CityDoctorValidation/src/test/resources/testConfigWithStreaming.yml @@ -1,45 +1,46 @@ -numberOfRoundingPlaces: 8 +globalParameters: + numberOfRoundingPlaces: 8 + schematronFilePath: src/test/resources/schematronTest.xml useStreaming: true -schematronFilePath: src/test/resources/schematronTest.xml -checks: - C_GE_R_TOO_FEW_POINTS: +requirements: + R_GE_R_TOO_FEW_POINTS: enabled: true - C_GE_R_NOT_CLOSED: + R_GE_R_NOT_CLOSED: enabled: true - C_GE_R_DUPLICATE_POINT: + R_GE_R_CONSECUTIVE_POINTS_SAME: enabled: true - C_GE_R_SELF_INTERSECTION: + R_GE_R_SELF_INTERSECTION: enabled: true - C_GE_S_MULTIPLE_CONNECTED_COMPONENTS: + R_GE_S_MULTIPLE_CONNECTED_COMPONENTS: enabled: true - C_GE_P_INTERIOR_DISCONNECTED: + R_GE_P_INTERIOR_DISCONNECTED: enabled: true - C_GE_P_INTERSECTING_RINGS: + R_GE_P_INTERSECTING_RINGS: enabled: true - C_GE_P_NON_PLANAR: + R_GE_P_NON_PLANAR: enabled: false parameters: # one of ("distance", "angle", "both") type: distance distanceTolerance: 0.01 angleTolerance: 0.1 - C_GE_P_HOLE_OUTSIDE: + R_GE_P_HOLE_OUTSIDE: enabled: true - C_GE_P_ORIENTATION_RINGS_SAME: + R_GE_P_ORIENTATION_RINGS_SAME: enabled: true - C_GE_P_INNER_RINGS_NESTED: + R_GE_P_INNER_RINGS_NESTED: enabled: true - C_GE_S_TOO_FEW_POLYGONS: + R_GE_S_TOO_FEW_POLYGONS: enabled: true - C_GE_S_NOT_CLOSED: + R_GE_S_NOT_CLOSED: enabled: true - C_GE_S_NON_MANIFOLD_EDGE: + R_GE_S_NON_MANIFOLD_EDGE: enabled: true - C_GE_S_POLYGON_WRONG_ORIENTATION: + R_GE_S_POLYGON_WRONG_ORIENTATION: enabled: true - C_GE_S_ALL_POLYGONS_WRONG_ORIENTATION: + R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION: enabled: true - C_GE_S_NON_MANIFOLD_VERTEX: + R_GE_S_NON_MANIFOLD_VERTEX: enabled: true - C_GE_S_SELF_INTERSECTION: + R_GE_S_SELF_INTERSECTION: enabled: true \ No newline at end of file diff --git a/CityDoctorParent/non-maven-libs/de/hft/stuttgart/citygml4j-quality-ade/0.1.1/citygml4j-quality-ade-0.1.1.jar b/CityDoctorParent/non-maven-libs/de/hft/stuttgart/citygml4j-quality-ade/0.1.1/citygml4j-quality-ade-0.1.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..4e0c6e12eadce2e60a5b3ec19eaa1eca90211a8d Binary files /dev/null and b/CityDoctorParent/non-maven-libs/de/hft/stuttgart/citygml4j-quality-ade/0.1.1/citygml4j-quality-ade-0.1.1.jar differ