Commit 85cf93b6 authored by Matthias Betz's avatar Matthias Betz
Browse files

reworked check engine now working on requirements

parent 35577785
Pipeline #2108 passed with stage
in 3 minutes and 6 seconds
...@@ -28,6 +28,7 @@ import java.io.InputStream; ...@@ -28,6 +28,7 @@ import java.io.InputStream;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
...@@ -40,7 +41,6 @@ import org.yaml.snakeyaml.representer.Representer; ...@@ -40,7 +41,6 @@ import org.yaml.snakeyaml.representer.Representer;
import de.hft.stuttgart.citydoctor2.checks.CheckPrototype; import de.hft.stuttgart.citydoctor2.checks.CheckPrototype;
import de.hft.stuttgart.citydoctor2.checks.Checks; import de.hft.stuttgart.citydoctor2.checks.Checks;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.utils.Localization;
/** /**
* The validation configuration class represented in the yaml configuration * The validation configuration class represented in the yaml configuration
...@@ -52,19 +52,17 @@ import de.hft.stuttgart.citydoctor2.utils.Localization; ...@@ -52,19 +52,17 @@ import de.hft.stuttgart.citydoctor2.utils.Localization;
*/ */
public class ValidationConfiguration implements Serializable { 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 long serialVersionUID = -8020055032177740646L;
private static final Logger logger = LogManager.getLogger(ValidationConfiguration.class); private static final Logger logger = LogManager.getLogger(ValidationConfiguration.class);
private int numberOfRoundingPlaces = 8;
private double minVertexDistance = 0.0001; private Map<String, String> globalParameters;
private String schematronFilePath = null;
private boolean xmlValidation = false; private boolean xmlValidation = false;
private boolean useStreaming = false; private boolean useStreaming = false;
private FilterConfiguration filter; private FilterConfiguration filter;
private Map<CheckId, CheckConfiguration> checks; private Map<String, RequirementConfiguration> requirements;
private ParserConfiguration parserConfig; private ParserConfiguration parserConfig;
...@@ -81,19 +79,20 @@ public class ValidationConfiguration implements Serializable { ...@@ -81,19 +79,20 @@ public class ValidationConfiguration implements Serializable {
public static ValidationConfiguration loadStandardValidationConfig() { public static ValidationConfiguration loadStandardValidationConfig() {
ValidationConfiguration config = new ValidationConfiguration(); ValidationConfiguration config = new ValidationConfiguration();
config.checks = new HashMap<>(); config.requirements = new HashMap<>();
for (CheckPrototype c : Checks.getCheckPrototypes()) { for (CheckPrototype c : Checks.getCheckPrototypes()) {
CheckConfiguration cConfig = new CheckConfiguration(); for (Requirement req : c.checksRequirements()) {
cConfig.setEnabled(true); RequirementConfiguration reqConfig = new RequirementConfiguration();
if (!c.getDefaultParameter().isEmpty()) { reqConfig.setEnabled(true);
Map<String, String> paramMap = new HashMap<>(); for (DefaultParameter param : req.getDefaultParameter()) {
for (DefaultParameter param : c.getDefaultParameter()) { reqConfig.getParameters().put(param.getName(), param.getValue());
paramMap.put(param.getName(), param.getDefaultValue());
} }
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; return config;
} }
...@@ -117,14 +116,6 @@ public class ValidationConfiguration implements Serializable { ...@@ -117,14 +116,6 @@ public class ValidationConfiguration implements Serializable {
this.xmlValidation = xmlValidation; this.xmlValidation = xmlValidation;
} }
public String getSchematronFilePath() {
return schematronFilePath;
}
public void setSchematronFilePath(String schematronFilePath) {
this.schematronFilePath = schematronFilePath;
}
public boolean isUseStreaming() { public boolean isUseStreaming() {
return useStreaming; return useStreaming;
} }
...@@ -141,88 +132,67 @@ public class ValidationConfiguration implements Serializable { ...@@ -141,88 +132,67 @@ public class ValidationConfiguration implements Serializable {
this.filter = filter; this.filter = filter;
} }
public Map<CheckId, CheckConfiguration> getChecks() { public Map<String, RequirementConfiguration> getRequirements() {
if (checks == null) { if (requirements == null) {
checks = new HashMap<>(); requirements = new HashMap<>();
} }
return checks; return requirements;
} }
public void setChecks(Map<CheckId, CheckConfiguration> checks) { public Map<String, String> getGlobalParameters() {
this.checks = checks; if (globalParameters == null) {
globalParameters = new HashMap<>();
}
return globalParameters;
}
public void setGlobalParameters(Map<String, String> globalParameters) {
this.globalParameters = globalParameters;
} }
/** /**
* Validates the configuration, adds all missing checks as enabled, reenables * Validates the configuration, adds all missing requirements as enabled.
* checks that are necessary to perform other checks
* *
* @return true if it reenabled disabled checks, false otherwise
*/ */
public boolean validateConfiguration() { public void validateConfiguration() {
for (CheckPrototype c : Checks.getCheckPrototypes()) { logger.trace("Validating configuration");
// enable all checks that are missing in the validation config Map<String, Requirement> availableRequirements = Checks.getAvailableRequirements();
checks.computeIfAbsent(c.getCheckId(), id -> {
CheckConfiguration cConfig = new CheckConfiguration(); for (Entry<String, RequirementConfiguration> entry : requirements.entrySet()) {
cConfig.setEnabled(true); Requirement req = availableRequirements.get(entry.getKey());
return cConfig; if (req != null) {
}); for (DefaultParameter param : req.getDefaultParameter()) {
} RequirementConfiguration config = entry.getValue();
boolean reenabledChecks = reenableNecessaryChecks(); config.getParameters().computeIfAbsent(param.getName(), k -> param.getValue());
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());
} }
} }
} }
return reenabledChecks; for (Requirement req : availableRequirements.values()) {
} requirements.computeIfAbsent(req.getId(), id -> {
RequirementConfiguration cConfig = new RequirementConfiguration();
private boolean reenableNecessaryChecks() { cConfig.setEnabled(true);
boolean reenabledChecks = false; for (DefaultParameter param : req.getDefaultParameter()) {
for (java.util.Map.Entry<CheckId, CheckConfiguration> e : checks.entrySet()) { cConfig.getParameters().put(param.getName(), param.getValue());
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());
}
} }
} return cConfig;
insertMissingParametersWithDefaultParameters(e, c); });
}
return reenabledChecks;
}
private void insertMissingParametersWithDefaultParameters(java.util.Map.Entry<CheckId, CheckConfiguration> 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());
}
} }
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() { public int getNumberOfRoundingPlaces() {
return numberOfRoundingPlaces; return Integer.parseInt(globalParameters.get(GlobalParameters.NUMBER_OF_ROUNDING_PLACES));
} }
public void setNumberOfRoundingPlaces(int numberOfRoundingPlaces) { public void setNumberOfRoundingPlacesInGlobalParameters(int numberOfRoundingPlaces) {
this.numberOfRoundingPlaces = numberOfRoundingPlaces; globalParameters.put(GlobalParameters.NUMBER_OF_ROUNDING_PLACES, Integer.toString(numberOfRoundingPlaces));
} }
public ParserConfiguration getParserConfiguration() { public ParserConfiguration getParserConfiguration() {
if (parserConfig == null) { if (parserConfig == null) {
parserConfig = new ParserConfiguration(numberOfRoundingPlaces, xmlValidation); parserConfig = new ParserConfiguration(getNumberOfRoundingPlaces(), xmlValidation);
} }
return parserConfig; return parserConfig;
} }
...@@ -231,11 +201,31 @@ public class ValidationConfiguration implements Serializable { ...@@ -231,11 +201,31 @@ public class ValidationConfiguration implements Serializable {
this.parserConfig = parserConfig; this.parserConfig = parserConfig;
} }
public void setMinVertexDistance(double minVertexDistance) { public void setMinVertexDistanceInGlobalParameters(double minVertexDistance) {
this.minVertexDistance = minVertexDistance; globalParameters.put(GlobalParameters.MIN_VERTEX_DISTANCE, Double.toString(minVertexDistance));
} }
public double getMinVertexDistance() { 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<String, RequirementConfiguration> requirements) {
this.requirements = requirements;
} }
} }
...@@ -20,6 +20,7 @@ package de.hft.stuttgart.citydoctor2.checks; ...@@ -20,6 +20,7 @@ package de.hft.stuttgart.citydoctor2.checks;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
...@@ -28,9 +29,10 @@ import de.hft.stuttgart.citydoctor2.check.Check; ...@@ -28,9 +29,10 @@ import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.CheckType; import de.hft.stuttgart.citydoctor2.check.RequirementType;
import de.hft.stuttgart.citydoctor2.check.Checkable; import de.hft.stuttgart.citydoctor2.check.Checkable;
import de.hft.stuttgart.citydoctor2.check.DefaultParameter; import de.hft.stuttgart.citydoctor2.check.DefaultParameter;
import de.hft.stuttgart.citydoctor2.check.Requirement;
import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.UnknownCheckError; import de.hft.stuttgart.citydoctor2.check.error.UnknownCheckError;
import de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding; import de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding;
...@@ -68,6 +70,11 @@ public class CheckContainer extends Check { ...@@ -68,6 +70,11 @@ public class CheckContainer extends Check {
public CheckContainer(Check check) { public CheckContainer(Check check) {
this.check = check; this.check = check;
} }
@Override
public Set<Requirement> appliesToRequirements() {
return check.appliesToRequirements();
}
@Override @Override
public void init(Map<String, String> parameters, ParserConfiguration config) { public void init(Map<String, String> parameters, ParserConfiguration config) {
...@@ -244,7 +251,7 @@ public class CheckContainer extends Check { ...@@ -244,7 +251,7 @@ public class CheckContainer extends Check {
} }
@Override @Override
public CheckType getType() { public RequirementType getType() {
return check.getType(); return check.getType();
} }
......
...@@ -19,11 +19,13 @@ ...@@ -19,11 +19,13 @@
package de.hft.stuttgart.citydoctor2.checks; package de.hft.stuttgart.citydoctor2.checks;
import java.util.List; import java.util.List;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckType; import de.hft.stuttgart.citydoctor2.check.RequirementType;
import de.hft.stuttgart.citydoctor2.check.DefaultParameter; import de.hft.stuttgart.citydoctor2.check.DefaultParameter;
import de.hft.stuttgart.citydoctor2.check.Requirement;
/** /**
* This class is for having a read only access to a check for accessing meta * This class is for having a read only access to a check for accessing meta
...@@ -62,8 +64,12 @@ public class CheckPrototype { ...@@ -62,8 +64,12 @@ public class CheckPrototype {
return c.getDefaultParameter(); return c.getDefaultParameter();
} }
public CheckType getType() { public RequirementType getType() {
return c.getType(); return c.getType();
} }
public Set<Requirement> checksRequirements() {
return c.appliesToRequirements();
}
} }
...@@ -29,15 +29,15 @@ import org.apache.logging.log4j.Logger; ...@@ -29,15 +29,15 @@ import org.apache.logging.log4j.Logger;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckId; 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.DuplicatePointsCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.FaceOutCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.HoleOutsideCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.HoleOutsideCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.InteriorDisconnectedCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.InteriorDisconnectedCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.ManifoldVertexCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.ManifoldVertexCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.MultipleConnectedComponentCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.MultipleConnectedComponentCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.NestedRingsCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.NestedRingsCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.NonManifoldEdgeCheck; 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.PlanarCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.PolygonIntersectingRingsCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.PolygonIntersectingRingsCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.PolygonSameOrientationCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.PolygonSameOrientationCheck;
...@@ -46,6 +46,7 @@ import de.hft.stuttgart.citydoctor2.checks.geometry.RingNotClosedCheck; ...@@ -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.RingSelfIntCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.SolidNotClosedCheck; import de.hft.stuttgart.citydoctor2.checks.geometry.SolidNotClosedCheck;
import de.hft.stuttgart.citydoctor2.checks.geometry.SolidSelfIntCheck; 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.geometry.TooFewPolygonsCheck;
import de.hft.stuttgart.citydoctor2.checks.semantics.IsCeilingCheck; import de.hft.stuttgart.citydoctor2.checks.semantics.IsCeilingCheck;
import de.hft.stuttgart.citydoctor2.checks.semantics.IsFloorCheck; import de.hft.stuttgart.citydoctor2.checks.semantics.IsFloorCheck;
...@@ -69,6 +70,8 @@ public class Checks { ...@@ -69,6 +70,8 @@ public class Checks {
private static List<CheckPrototype> checkPrototypes; private static List<CheckPrototype> checkPrototypes;
private static Map<CheckId, CheckPrototype> prototypeMap; private static Map<CheckId, CheckPrototype> prototypeMap;
private static Map<String, Requirement> availableRequirements;
private Map<CheckId, Check> checkMap; private Map<CheckId, Check> checkMap;
...@@ -78,7 +81,7 @@ public class Checks { ...@@ -78,7 +81,7 @@ public class Checks {
// add new checks here // add new checks here
// ring checks // ring checks
publish(new NumPointsCheck()); publish(new TooFewPointsCheck());
publish(new RingNotClosedCheck()); publish(new RingNotClosedCheck());
publish(new DuplicatePointsCheck()); publish(new DuplicatePointsCheck());
publish(new RingSelfIntCheck()); publish(new RingSelfIntCheck());
...@@ -96,7 +99,7 @@ public class Checks { ...@@ -96,7 +99,7 @@ public class Checks {
publish(new SolidNotClosedCheck()); publish(new SolidNotClosedCheck());
publish(new NonManifoldEdgeCheck()); publish(new NonManifoldEdgeCheck());
publish(new PolygonWrongOrientationCheck()); publish(new PolygonWrongOrientationCheck());
publish(new FaceOutCheck()); publish(new AllPolygonsWrongOrientationCheck());
publish(new TooFewPolygonsCheck()); publish(new TooFewPolygonsCheck());
publish(new ManifoldVertexCheck()); publish(new ManifoldVertexCheck());
publish(new SolidSelfIntCheck()); publish(new SolidSelfIntCheck());
...@@ -128,6 +131,30 @@ public class Checks { ...@@ -128,6 +131,30 @@ public class Checks {
} }
} }
private static Map<String, Requirement> collectRequirements() {
Map<String, Requirement> 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<String, Requirement> getAvailableRequirements() {
if (availableRequirements == null) {
availableRequirements = collectRequirements();
}
return availableRequirements;
}
private static void publish(Check check) { private static void publish(Check check) {
CheckPrototype prototype = new CheckPrototype(check); CheckPrototype prototype = new CheckPrototype(check);
checkPrototypes.add(prototype); checkPrototypes.add(prototype);
......
...@@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; ...@@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.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.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.AllPolygonsWrongOrientationError; 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.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
...@@ -38,11 +41,12 @@ import de.hft.stuttgart.citydoctor2.math.Vector3d; ...@@ -38,11 +41,12 @@ import de.hft.stuttgart.citydoctor2.math.Vector3d;
import de.hft.stuttgart.citydoctor2.tesselation.TesselatedPolygon; 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<CheckId> dependencies; private static final List<CheckId> dependencies;
...@@ -171,15 +175,20 @@ public class FaceOutCheck extends Check { ...@@ -171,15 +175,20 @@ public class FaceOutCheck extends Check {
public List<CheckId> getDependencies() { public List<CheckId> getDependencies() {
return dependencies; return dependencies;
} }
@Override
public Set<Requirement> appliesToRequirements() {
return CollectionUtils.singletonSet(Requirement.R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION);
}
@Override @Override
public CheckType getType() { public RequirementType getType() {
return CheckType.GEOMETRY; return RequirementType.GEOMETRY;
} }
@Override @Override
public Check createNewInstance() { public Check createNewInstance() {
return new FaceOutCheck(); return new AllPolygonsWrongOrientationCheck();
} }
@Override @Override
......
...@@ -22,16 +22,19 @@ import java.util.ArrayList; ...@@ -22,16 +22,19 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.CheckType; import de.hft.stuttgart.citydoctor2.check.RequirementType;
import de.hft.stuttgart.citydoctor2.check.Checkable; 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.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.ConsecutivePointSameError; import de.hft.stuttgart.citydoctor2.check.error.ConsecutivePointSameError;
import de.hft.stuttgart.citydoctor2.check.error.RingDuplicatePointError; 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.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex; import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
...@@ -44,7 +47,7 @@ import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; ...@@ -44,7 +47,7 @@ import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
* <dd> * <dd>
* <dd>CP_CLOSE</dd></dd> * <dd>CP_CLOSE</dd></dd>
* *
* @author Matthias Betz - 12bema1bif@hft-stuttgart.de * @author Matthias Betz
* *
*/ */
public class DuplicatePointsCheck extends Check { public class DuplicatePointsCheck extends Check {
...@@ -77,6 +80,11 @@ public class DuplicatePointsCheck extends Check { ...@@ -77,6 +80,11 @@ public class DuplicatePointsCheck extends Check {
public List<CheckId> getDependencies() { public List<CheckId> getDependencies() {
return dependencies; return dependencies;
} }
@Override
public Set<Requirement> appliesToRequirements() {
return CollectionUtils.asSet(Requirement.R_GE_R_CONSECUTIVE_POINTS_SAME, Requirement.R_GE_R_SELF_INTERSECTION);
}
@Override @Override
public void check(LinearRing lr) { public void check(LinearRing lr) {
...@@ -114,8 +122,8 @@ public class DuplicatePointsCheck extends Check { ...@@ -114,8 +122,8 @@ public class DuplicatePointsCheck extends Check {
} }
@Override @Override
public CheckType getType() { public RequirementType getType() {
return CheckType.GEOMETRY; return RequirementType.GEOMETRY;
} }
@Override @Override
......
...@@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; ...@@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.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.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.PolygonHoleOutsideError; 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.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex; import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
...@@ -79,10 +82,15 @@ public class HoleOutsideCheck extends Check { ...@@ -79,10 +82,15 @@ public class HoleOutsideCheck extends Check {
public List<CheckId> getDependencies() { public List<CheckId> getDependencies() {
return dependencies; return dependencies;
} }
@Override
public Set<Requirement> appliesToRequirements() {
return CollectionUtils.singletonSet(Requirement.R_GE_P_HOLE_OUTSIDE);
}
@Override @Override
public CheckType getType() { public RequirementType getType() {
return CheckType.GEOMETRY; return RequirementType.GEOMETRY;
} }
@Override @Override
......
...@@ -23,14 +23,17 @@ import java.util.Collections; ...@@ -23,14 +23,17 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.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.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.PolygonInteriorDisconnectedError; 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.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex; import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
...@@ -38,12 +41,18 @@ import de.hft.stuttgart.citydoctor2.math.Segment3d; ...@@ -38,12 +41,18 @@ import de.hft.stuttgart.citydoctor2.math.Segment3d;
import de.hft.stuttgart.citydoctor2.math.graph.CycleNode; import de.hft.stuttgart.citydoctor2.math.graph.CycleNode;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; 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 { public class InteriorDisconnectedCheck extends Check {
private static final String EPSILON_NAME = "minVertexDistance"; private static final String EPSILON_NAME = "minVertexDistance";
private static final List<CheckId> dependencies; private static final List<CheckId> dependencies;
static { static {
ArrayList<CheckId> deps = new ArrayList<>(); ArrayList<CheckId> deps = new ArrayList<>();
deps.add(CheckId.C_GE_R_TOO_FEW_POINTS); deps.add(CheckId.C_GE_R_TOO_FEW_POINTS);
...@@ -53,19 +62,17 @@ public class InteriorDisconnectedCheck extends Check { ...@@ -53,19 +62,17 @@ public class InteriorDisconnectedCheck extends Check {
deps.add(CheckId.C_GE_P_NON_PLANAR); deps.add(CheckId.C_GE_P_NON_PLANAR);
dependencies = Collections.unmodifiableList(deps); dependencies = Collections.unmodifiableList(deps);
} }
private double epsilon = 0.0001; private double epsilon = 0.0001;
@Override @Override
public void init(Map<String, String> params, ParserConfiguration config) { public void init(Map<String, String> params, ParserConfiguration config) {
String epsilonString = params.get(EPSILON_NAME); String epsilonString = params.get(EPSILON_NAME);
if (epsilonString == null) { if (epsilonString != null) {
epsilon = 0.0001;
} else {
epsilon = Double.parseDouble(epsilonString); epsilon = Double.parseDouble(epsilonString);
} }
} }
@Override @Override
public void check(Polygon p) { public void check(Polygon p) {
if (p.getInnerRings().isEmpty()) { if (p.getInnerRings().isEmpty()) {
...@@ -88,7 +95,7 @@ public class InteriorDisconnectedCheck extends Check { ...@@ -88,7 +95,7 @@ public class InteriorDisconnectedCheck extends Check {
} }
} }
} }
for (CycleNode node : nodeMap.values()) { for (CycleNode node : nodeMap.values()) {
if (node.hasMoreThan2CycleDepth(null)) { if (node.hasMoreThan2CycleDepth(null)) {
// found ring in graph with more than 1 node // found ring in graph with more than 1 node
...@@ -127,7 +134,7 @@ public class InteriorDisconnectedCheck extends Check { ...@@ -127,7 +134,7 @@ public class InteriorDisconnectedCheck extends Check {
p.addCheckResult(cr); p.addCheckResult(cr);
return true; return true;
} }
} }
} }
} }
...@@ -152,15 +159,20 @@ public class InteriorDisconnectedCheck extends Check { ...@@ -152,15 +159,20 @@ public class InteriorDisconnectedCheck extends Check {
nodeMap.put(lr, node); nodeMap.put(lr, node);
} }
} }
@Override @Override
public List<CheckId> getDependencies() { public List<CheckId> getDependencies() {
return dependencies; return dependencies;
} }
@Override @Override
public CheckType getType() { public Set<Requirement> appliesToRequirements() {
return CheckType.GEOMETRY; return CollectionUtils.singletonSet(Requirement.R_GE_P_INTERIOR_DISCONNECTED);
}
@Override
public RequirementType getType() {
return RequirementType.GEOMETRY;
} }
@Override @Override
......
...@@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; ...@@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.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.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.NonManifoldVertexError; 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.Edge;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
...@@ -40,7 +43,7 @@ import de.hft.stuttgart.citydoctor2.math.graph.PolygonGraph; ...@@ -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 * Checks if the polygons adjacent to a vertex are attached via edges or are
* they discontinuous. * they discontinuous.
* *
* @author Matthias Betz - 12bema1bif@hft-stuttgart.de * @author Matthias Betz
* *
*/ */
public class ManifoldVertexCheck extends Check { public class ManifoldVertexCheck extends Check {
...@@ -92,10 +95,15 @@ public class ManifoldVertexCheck extends Check { ...@@ -92,10 +95,15 @@ public class ManifoldVertexCheck extends Check {
public List<CheckId> getDependencies() { public List<CheckId> getDependencies() {
return dependencies; return dependencies;
} }
@Override
public Set<Requirement> appliesToRequirements() {
return CollectionUtils.singletonSet(Requirement.R_GE_S_NON_MANIFOLD_VERTEX);
}
@Override @Override
public CheckType getType() { public RequirementType getType() {
return CheckType.GEOMETRY; return RequirementType.GEOMETRY;
} }
@Override @Override
......
...@@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; ...@@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.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.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.MultipleConnectedComponentsError; 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.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
...@@ -38,7 +41,7 @@ import de.hft.stuttgart.citydoctor2.math.graph.PolygonGraph; ...@@ -38,7 +41,7 @@ import de.hft.stuttgart.citydoctor2.math.graph.PolygonGraph;
/** /**
* Checks if all parts of a solid are connected or not. * 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 { public class MultipleConnectedComponentCheck extends Check {
...@@ -86,10 +89,15 @@ public class MultipleConnectedComponentCheck extends Check { ...@@ -86,10 +89,15 @@ public class MultipleConnectedComponentCheck extends Check {
public List<CheckId> getDependencies() { public List<CheckId> getDependencies() {
return dependencies; return dependencies;
} }
@Override
public Set<Requirement> appliesToRequirements() {
return CollectionUtils.singletonSet(Requirement.R_GE_S_MULTIPLE_CONNECTED_COMPONENTS);
}
@Override @Override
public CheckType getType() { public RequirementType getType() {
return CheckType.GEOMETRY; return RequirementType.GEOMETRY;
} }
@Override @Override
......
...@@ -21,20 +21,30 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; ...@@ -21,20 +21,30 @@ package de.hft.stuttgart.citydoctor2.checks.geometry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.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.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.NestedRingError; 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.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex; 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 { public class NestedRingsCheck extends Check {
private static final List<CheckId> dependencies; private static final List<CheckId> dependencies;
static { static {
...@@ -47,7 +57,7 @@ public class NestedRingsCheck extends Check { ...@@ -47,7 +57,7 @@ public class NestedRingsCheck extends Check {
deps.add(CheckId.C_GE_P_ORIENTATION_RINGS_SAME); deps.add(CheckId.C_GE_P_ORIENTATION_RINGS_SAME);
dependencies = Collections.unmodifiableList(deps); dependencies = Collections.unmodifiableList(deps);
} }
@Override @Override
public void check(Polygon p) { public void check(Polygon p) {
for (LinearRing interiorRing : p.getInnerRings()) { for (LinearRing interiorRing : p.getInnerRings()) {
...@@ -85,10 +95,15 @@ public class NestedRingsCheck extends Check { ...@@ -85,10 +95,15 @@ public class NestedRingsCheck extends Check {
public List<CheckId> getDependencies() { public List<CheckId> getDependencies() {
return dependencies; return dependencies;
} }
@Override
public Set<Requirement> appliesToRequirements() {
return CollectionUtils.singletonSet(Requirement.R_GE_P_INNER_RINGS_NESTED);
}
@Override @Override
public CheckType getType() { public RequirementType getType() {
return CheckType.GEOMETRY; return RequirementType.GEOMETRY;
} }
@Override @Override
......
...@@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; ...@@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.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.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.NonManifoldEdgeError; 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.Edge;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
...@@ -37,7 +40,9 @@ 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. * This class detects half edges with more than two neighbors, i.e.
* non-2-manifold geometries * non-2-manifold geometries
* *
* @author dwagner, alam * @author dwagner
* @author alam
* @author Matthias Betz
*/ */
public class NonManifoldEdgeCheck extends Check { public class NonManifoldEdgeCheck extends Check {
...@@ -80,6 +85,11 @@ public class NonManifoldEdgeCheck extends Check { ...@@ -80,6 +85,11 @@ public class NonManifoldEdgeCheck extends Check {
} }
g.addCheckResult(cr); g.addCheckResult(cr);
} }
@Override
public Set<Requirement> appliesToRequirements() {
return CollectionUtils.singletonSet(Requirement.R_GE_S_NON_MANIFOLD_EDGE);
}
@Override @Override
public List<CheckId> getDependencies() { public List<CheckId> getDependencies() {
...@@ -87,8 +97,8 @@ public class NonManifoldEdgeCheck extends Check { ...@@ -87,8 +97,8 @@ public class NonManifoldEdgeCheck extends Check {
} }
@Override @Override
public CheckType getType() { public RequirementType getType() {
return CheckType.GEOMETRY; return RequirementType.GEOMETRY;
} }
@Override @Override
......
...@@ -22,15 +22,18 @@ import java.util.ArrayList; ...@@ -22,15 +22,18 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.CheckType; import de.hft.stuttgart.citydoctor2.check.RequirementType;
import de.hft.stuttgart.citydoctor2.check.DefaultParameter; import de.hft.stuttgart.citydoctor2.check.DefaultParameter;
import de.hft.stuttgart.citydoctor2.check.Requirement;
import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.Unit; import de.hft.stuttgart.citydoctor2.check.Unit;
import de.hft.stuttgart.citydoctor2.check.error.NullAreaError; 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.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex; import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.math.Line3d; import de.hft.stuttgart.citydoctor2.math.Line3d;
...@@ -106,6 +109,11 @@ public class NullAreaCheck extends Check { ...@@ -106,6 +109,11 @@ public class NullAreaCheck extends Check {
} }
return area < 0.0001; return area < 0.0001;
} }
@Override
public Set<Requirement> appliesToRequirements() {
return CollectionUtils.singletonSet(Requirement.R_GE_R_NULL_AREA);
}
@Override @Override
public List<CheckId> getDependencies() { public List<CheckId> getDependencies() {
...@@ -113,8 +121,8 @@ public class NullAreaCheck extends Check { ...@@ -113,8 +121,8 @@ public class NullAreaCheck extends Check {
} }
@Override @Override
public CheckType getType() { public RequirementType getType() {
return CheckType.GEOMETRY; return RequirementType.GEOMETRY;
} }
......
...@@ -22,23 +22,28 @@ import java.util.ArrayList; ...@@ -22,23 +22,28 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import Jama.EigenvalueDecomposition; import Jama.EigenvalueDecomposition;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.CheckType; import de.hft.stuttgart.citydoctor2.check.RequirementType;
import de.hft.stuttgart.citydoctor2.check.DefaultParameter; import de.hft.stuttgart.citydoctor2.check.DefaultParameter;
import de.hft.stuttgart.citydoctor2.check.Requirement;
import de.hft.stuttgart.citydoctor2.check.ResultStatus; import de.hft.stuttgart.citydoctor2.check.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.Unit; 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.NonPlanarPolygonDistancePlaneError;
import de.hft.stuttgart.citydoctor2.check.error.NonPlanarPolygonNormalsDeviation; 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.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex; import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.math.CovarianceMatrix; 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.OrthogonalRegressionPlane;
import de.hft.stuttgart.citydoctor2.math.Plane; import de.hft.stuttgart.citydoctor2.math.Plane;
import de.hft.stuttgart.citydoctor2.math.Triangle3d; import de.hft.stuttgart.citydoctor2.math.Triangle3d;
...@@ -48,18 +53,19 @@ import de.hft.stuttgart.citydoctor2.tesselation.JoglTesselator; ...@@ -48,18 +53,19 @@ import de.hft.stuttgart.citydoctor2.tesselation.JoglTesselator;
import de.hft.stuttgart.citydoctor2.tesselation.TesselatedPolygon; 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 * @author Matthias Betz
* *
*/ */
public class PlanarCheck extends Check { public class PlanarCheck extends Check {
private static final String DISTANCE = "distance"; public static final String DISTANCE = "distance";
private static final String DISTANCE_TOLERANCE = "distanceTolerance"; public static final String DISTANCE_TOLERANCE = "distanceTolerance";
private static final String ANGLE_TOLERANCE = "angleTolerance"; public static final String ANGLE_TOLERANCE = "angleTolerance";
private static final String TYPE = "type"; public static final String TYPE = "type";
private static final String DEGENERATED_POLYGON_TOLERANCE = "degeneratedPolygonTolerance"; public static final String DEGENERATED_POLYGON_TOLERANCE = "degeneratedPolygonTolerance";
private static final List<CheckId> dependencies; private static final List<CheckId> dependencies;
private static final List<DefaultParameter> defaultParameters; private static final List<DefaultParameter> defaultParameters;
...@@ -91,6 +97,8 @@ public class PlanarCheck extends Check { ...@@ -91,6 +97,8 @@ public class PlanarCheck extends Check {
public void init(Map<String, String> parameters, ParserConfiguration config) { public void init(Map<String, String> parameters, ParserConfiguration config) {
if (parameters.containsKey(TYPE)) { if (parameters.containsKey(TYPE)) {
planarCheckType = parameters.get(TYPE).toLowerCase(); planarCheckType = parameters.get(TYPE).toLowerCase();
} else {
throw new IllegalStateException("Parameter " + TYPE + " is missing from parameters");
} }
if (parameters.containsKey(ANGLE_TOLERANCE)) { if (parameters.containsKey(ANGLE_TOLERANCE)) {
rad = Math.toRadians(Double.parseDouble(parameters.get(ANGLE_TOLERANCE))); rad = Math.toRadians(Double.parseDouble(parameters.get(ANGLE_TOLERANCE)));
...@@ -115,8 +123,10 @@ public class PlanarCheck extends Check { ...@@ -115,8 +123,10 @@ public class PlanarCheck extends Check {
} else if ("angle".equals(planarCheckType)) { } else if ("angle".equals(planarCheckType)) {
// check for tiny edge as well // check for tiny edge as well
// store all used points in temporary list // store all used points in temporary list
Vector3d eigenvalues = calculatedEigenvalues(p); ArrayList<Vertex> vertices = collectVertices(p);
if (checkEigenvalues(p, eigenvalues)) { Vector3d centroid = CovarianceMatrix.getCentroid(vertices);
EigenvalueDecomposition ed = OrthogonalRegressionPlane.decompose(vertices, centroid);
if (checkEigenvalues(p, vertices, ed)) {
// found tiny edge error, abort further checking // found tiny edge error, abort further checking
return; return;
} }
...@@ -130,13 +140,6 @@ public class PlanarCheck extends Check { ...@@ -130,13 +140,6 @@ public class PlanarCheck extends Check {
} }
} }
private Vector3d calculatedEigenvalues(Polygon p) {
ArrayList<Vertex> vertices = collectVertices(p);
Vector3d centroid = CovarianceMatrix.getCentroid(vertices);
EigenvalueDecomposition ed = OrthogonalRegressionPlane.decompose(vertices, centroid);
return OrthogonalRegressionPlane.getEigenvalues(ed);
}
private void planarNormalDeviation(Polygon p) { private void planarNormalDeviation(Polygon p) {
TesselatedPolygon tp = JoglTesselator.tesselatePolygon(p); TesselatedPolygon tp = JoglTesselator.tesselatePolygon(p);
ArrayList<Vector3d> normals = new ArrayList<>(); ArrayList<Vector3d> normals = new ArrayList<>();
...@@ -185,13 +188,13 @@ public class PlanarCheck extends Check { ...@@ -185,13 +188,13 @@ public class PlanarCheck extends Check {
ArrayList<Vertex> vertices = collectVertices(p); ArrayList<Vertex> vertices = collectVertices(p);
Vector3d centroid = CovarianceMatrix.getCentroid(vertices); Vector3d centroid = CovarianceMatrix.getCentroid(vertices);
EigenvalueDecomposition ed = OrthogonalRegressionPlane.decompose(vertices, centroid); 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 // found tiny edge error, abort further checking
return; return;
} }
Vector3d eigenvalues = OrthogonalRegressionPlane.getEigenvalues(ed);
Plane plane = OrthogonalRegressionPlane.calculatePlane(centroid, ed, eigenvalues); Plane plane = OrthogonalRegressionPlane.calculatePlane(centroid, ed, eigenvalues);
for (Vertex v : vertices) { for (Vertex v : vertices) {
double distance = plane.getDistance(v); double distance = plane.getDistance(v);
...@@ -224,13 +227,25 @@ public class PlanarCheck extends Check { ...@@ -224,13 +227,25 @@ public class PlanarCheck extends Check {
return vertices; return vertices;
} }
private boolean checkEigenvalues(Polygon p, Vector3d eigenvalues) { private boolean checkEigenvalues(Polygon p, List<Vertex> points, EigenvalueDecomposition ed) {
Matrix3x3d mat = new Matrix3x3d(ed.getV().getArray());
List<Vector3d> rotatedVertices = new ArrayList<>();
for (Vertex v : points) {
rotatedVertices.add(mat.mult(v));
}
BoundingBox bbox = BoundingBox.ofPoints(rotatedVertices);
int nrOfEigenvaluesBelowTolerance = 0; int nrOfEigenvaluesBelowTolerance = 0;
for (double d : eigenvalues.getCoordinates()) { if (bbox.getWidth() < degeneratedPolygonTolerance) {
if (d <= degeneratedPolygonTolerance) { nrOfEigenvaluesBelowTolerance++;
nrOfEigenvaluesBelowTolerance++; }
} if (bbox.getHeight() < degeneratedPolygonTolerance) {
nrOfEigenvaluesBelowTolerance++;
}
if (bbox.getDepth() < degeneratedPolygonTolerance) {
nrOfEigenvaluesBelowTolerance++;
} }
if (nrOfEigenvaluesBelowTolerance >= 2) { if (nrOfEigenvaluesBelowTolerance >= 2) {
CheckError err = new DegeneratedPolygonError(p); CheckError err = new DegeneratedPolygonError(p);
p.addCheckResult(new CheckResult(this, ResultStatus.ERROR, err)); p.addCheckResult(new CheckResult(this, ResultStatus.ERROR, err));
...@@ -245,8 +260,13 @@ public class PlanarCheck extends Check { ...@@ -245,8 +260,13 @@ public class PlanarCheck extends Check {
} }
@Override @Override
public CheckType getType() { public Set<Requirement> appliesToRequirements() {
return CheckType.GEOMETRY; return CollectionUtils.singletonSet(Requirement.R_GE_P_NON_PLANAR);
}
@Override
public RequirementType getType() {
return RequirementType.GEOMETRY;
} }
@Override @Override
......
...@@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; ...@@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.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.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.PolygonIntersectingRingsError; 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.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.math.Polygon2d; import de.hft.stuttgart.citydoctor2.math.Polygon2d;
...@@ -38,11 +41,16 @@ import de.hft.stuttgart.citydoctor2.math.Vector2d; ...@@ -38,11 +41,16 @@ import de.hft.stuttgart.citydoctor2.math.Vector2d;
import de.hft.stuttgart.citydoctor2.utils.Pair; import de.hft.stuttgart.citydoctor2.utils.Pair;
import de.hft.stuttgart.citydoctor2.utils.SerializablePair; 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 { public class PolygonIntersectingRingsCheck extends Check {
private static final List<CheckId> dependencies; private static final List<CheckId> dependencies;
static { static {
ArrayList<CheckId> deps = new ArrayList<>(); ArrayList<CheckId> deps = new ArrayList<>();
deps.add(CheckId.C_GE_R_TOO_FEW_POINTS); deps.add(CheckId.C_GE_R_TOO_FEW_POINTS);
...@@ -54,7 +62,7 @@ public class PolygonIntersectingRingsCheck extends Check { ...@@ -54,7 +62,7 @@ public class PolygonIntersectingRingsCheck extends Check {
deps.add(CheckId.C_GE_P_INNER_RINGS_NESTED); deps.add(CheckId.C_GE_P_INNER_RINGS_NESTED);
dependencies = Collections.unmodifiableList(deps); dependencies = Collections.unmodifiableList(deps);
} }
@Override @Override
public void check(Polygon p) { public void check(Polygon p) {
if (p.getInnerRings().isEmpty()) { if (p.getInnerRings().isEmpty()) {
...@@ -73,7 +81,7 @@ public class PolygonIntersectingRingsCheck extends Check { ...@@ -73,7 +81,7 @@ public class PolygonIntersectingRingsCheck extends Check {
} }
p.addCheckResult(cr); p.addCheckResult(cr);
} }
public SerializablePair<LinearRing, LinearRing> interiorRingsIntersectWithExterior(Polygon p) { public SerializablePair<LinearRing, LinearRing> interiorRingsIntersectWithExterior(Polygon p) {
List<Pair<LinearRing, List<Segment2d>>> ringSegments = projectTo2D(p); List<Pair<LinearRing, List<Segment2d>>> ringSegments = projectTo2D(p);
for (int i = 0; i < ringSegments.size() - 1; i++) { for (int i = 0; i < ringSegments.size() - 1; i++) {
...@@ -124,8 +132,13 @@ public class PolygonIntersectingRingsCheck extends Check { ...@@ -124,8 +132,13 @@ public class PolygonIntersectingRingsCheck extends Check {
} }
@Override @Override
public CheckType getType() { public Set<Requirement> appliesToRequirements() {
return CheckType.GEOMETRY; return CollectionUtils.singletonSet(Requirement.R_GE_P_INTERSECTING_RINGS);
}
@Override
public RequirementType getType() {
return RequirementType.GEOMETRY;
} }
@Override @Override
......
...@@ -21,22 +21,33 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; ...@@ -21,22 +21,33 @@ package de.hft.stuttgart.citydoctor2.checks.geometry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.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.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.PolygonSameOrientationError; 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.Orientation;
import de.hft.stuttgart.citydoctor2.checks.util.RingOrientationUtil; import de.hft.stuttgart.citydoctor2.checks.util.RingOrientationUtil;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.math.Polygon2d; import de.hft.stuttgart.citydoctor2.math.Polygon2d;
import de.hft.stuttgart.citydoctor2.math.Ring2d; 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 { public class PolygonSameOrientationCheck extends Check {
private static final List<CheckId> dependencies; private static final List<CheckId> dependencies;
static { static {
...@@ -48,7 +59,7 @@ public class PolygonSameOrientationCheck extends Check { ...@@ -48,7 +59,7 @@ public class PolygonSameOrientationCheck extends Check {
deps.add(CheckId.C_GE_P_NON_PLANAR); deps.add(CheckId.C_GE_P_NON_PLANAR);
dependencies = Collections.unmodifiableList(deps); dependencies = Collections.unmodifiableList(deps);
} }
@Override @Override
public void check(Polygon p) { public void check(Polygon p) {
if (p.getInnerRings().isEmpty()) { if (p.getInnerRings().isEmpty()) {
...@@ -67,7 +78,7 @@ public class PolygonSameOrientationCheck extends Check { ...@@ -67,7 +78,7 @@ public class PolygonSameOrientationCheck extends Check {
return; return;
} }
} }
// no error found, or the method would have terminated previously // no error found, or the method would have terminated previously
CheckResult cr = new CheckResult(this, ResultStatus.OK, null); CheckResult cr = new CheckResult(this, ResultStatus.OK, null);
p.addCheckResult(cr); p.addCheckResult(cr);
...@@ -80,8 +91,13 @@ public class PolygonSameOrientationCheck extends Check { ...@@ -80,8 +91,13 @@ public class PolygonSameOrientationCheck extends Check {
} }
@Override @Override
public CheckType getType() { public Set<Requirement> appliesToRequirements() {
return CheckType.GEOMETRY; return CollectionUtils.singletonSet(Requirement.R_GE_P_ORIENTATION_RINGS_SAME);
}
@Override
public RequirementType getType() {
return RequirementType.GEOMETRY;
} }
@Override @Override
......
...@@ -21,28 +21,32 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; ...@@ -21,28 +21,32 @@ package de.hft.stuttgart.citydoctor2.checks.geometry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.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.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.PolygonWrongOrientationError; 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.Edge;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
/** /**
* This class checks the orientation of each face of a solid * Checks whether polygons share a edge that is walked more than one time in the
* @author Matthias Betz - 12bema1bif@hft-stuttgart.de * same direction by two or more polygons indicating that a polygon is oriented wrong.
*
* @author Matthias Betz
* *
*/ */
public class PolygonWrongOrientationCheck extends Check { public class PolygonWrongOrientationCheck extends Check {
private static final List<CheckId> dependencies; private static final List<CheckId> dependencies;
static { static {
ArrayList<CheckId> deps = new ArrayList<>(); ArrayList<CheckId> deps = new ArrayList<>();
deps.add(CheckId.C_GE_R_TOO_FEW_POINTS); deps.add(CheckId.C_GE_R_TOO_FEW_POINTS);
...@@ -57,19 +61,19 @@ public class PolygonWrongOrientationCheck extends Check { ...@@ -57,19 +61,19 @@ public class PolygonWrongOrientationCheck extends Check {
deps.add(CheckId.C_GE_S_NON_MANIFOLD_EDGE); deps.add(CheckId.C_GE_S_NON_MANIFOLD_EDGE);
dependencies = Collections.unmodifiableList(deps); dependencies = Collections.unmodifiableList(deps);
} }
@Override @Override
public void check(Geometry g) { public void check(Geometry g) {
// only for solids // only for solids
if (g.getType() != GeometryType.SOLID) { if (g.getType() != GeometryType.SOLID) {
return; return;
} }
List<Edge> faultyEdges = new ArrayList<>(); List<Edge> faultyEdges = new ArrayList<>();
for (Edge edge : g.getEdges()) { for (Edge edge : g.getEdges()) {
if (edge.getNumberOfHalfEdges() != edge.getNumberOppositeHalfEdges()) { if (edge.getNumberOfHalfEdges() != edge.getNumberOppositeHalfEdges()) {
faultyEdges.add(edge); faultyEdges.add(edge);
} }
} }
CheckResult cr; CheckResult cr;
if (faultyEdges.isEmpty()) { if (faultyEdges.isEmpty()) {
...@@ -80,15 +84,20 @@ public class PolygonWrongOrientationCheck extends Check { ...@@ -80,15 +84,20 @@ public class PolygonWrongOrientationCheck extends Check {
} }
g.addCheckResult(cr); g.addCheckResult(cr);
} }
@Override @Override
public List<CheckId> getDependencies() { public List<CheckId> getDependencies() {
return dependencies; return dependencies;
} }
@Override
public Set<Requirement> appliesToRequirements() {
return CollectionUtils.singletonSet(Requirement.R_GE_S_POLYGON_WRONG_ORIENTATION);
}
@Override @Override
public CheckType getType() { public RequirementType getType() {
return CheckType.GEOMETRY; return RequirementType.GEOMETRY;
} }
@Override @Override
......
...@@ -21,22 +21,25 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; ...@@ -21,22 +21,25 @@ package de.hft.stuttgart.citydoctor2.checks.geometry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.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.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.RingNotClosedError; 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.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex; 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. * started.
* *
* @author Matthias Betz - 12bema1bif@hft-stuttgart.de * @author Matthias Betz
* *
*/ */
public class RingNotClosedCheck extends Check { public class RingNotClosedCheck extends Check {
...@@ -69,8 +72,13 @@ public class RingNotClosedCheck extends Check { ...@@ -69,8 +72,13 @@ public class RingNotClosedCheck extends Check {
} }
@Override @Override
public CheckType getType() { public RequirementType getType() {
return CheckType.GEOMETRY; return RequirementType.GEOMETRY;
}
@Override
public Set<Requirement> appliesToRequirements() {
return CollectionUtils.singletonSet(Requirement.R_GE_R_NOT_CLOSED);
} }
@Override @Override
......
...@@ -22,16 +22,19 @@ import java.util.ArrayList; ...@@ -22,16 +22,19 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.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.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.PointTouchesEdgeError; import de.hft.stuttgart.citydoctor2.check.error.PointTouchesEdgeError;
import de.hft.stuttgart.citydoctor2.check.error.RingEdgeIntersectionError; import de.hft.stuttgart.citydoctor2.check.error.RingEdgeIntersectionError;
import de.hft.stuttgart.citydoctor2.checks.Checks; 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.Edge;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
...@@ -40,6 +43,13 @@ import de.hft.stuttgart.citydoctor2.math.DistanceResult; ...@@ -40,6 +43,13 @@ import de.hft.stuttgart.citydoctor2.math.DistanceResult;
import de.hft.stuttgart.citydoctor2.math.Segment3d; import de.hft.stuttgart.citydoctor2.math.Segment3d;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; 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 { public class RingSelfIntCheck extends Check {
private static final String EPSILON_NAME = "minVertexDistance"; private static final String EPSILON_NAME = "minVertexDistance";
...@@ -138,8 +148,13 @@ public class RingSelfIntCheck extends Check { ...@@ -138,8 +148,13 @@ public class RingSelfIntCheck extends Check {
} }
@Override @Override
public CheckType getType() { public Set<Requirement> appliesToRequirements() {
return CheckType.GEOMETRY; return CollectionUtils.singletonSet(Requirement.R_GE_R_SELF_INTERSECTION);
}
@Override
public RequirementType getType() {
return RequirementType.GEOMETRY;
} }
@Override @Override
......
...@@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry; ...@@ -21,14 +21,17 @@ package de.hft.stuttgart.citydoctor2.checks.geometry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.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.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.SolidNotClosedError; 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.Edge;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
...@@ -37,8 +40,9 @@ 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 * This class detects half edges without neighbor, i.e. holes in solid
* geometries * geometries
* *
* @author dwagner, alam * @author dwagner
* @author Matthias Betz - 12bema1bif@hft-stuttgart.de * @author alam
* @author Matthias Betz
*/ */
public class SolidNotClosedCheck extends Check { public class SolidNotClosedCheck extends Check {
...@@ -87,10 +91,15 @@ public class SolidNotClosedCheck extends Check { ...@@ -87,10 +91,15 @@ public class SolidNotClosedCheck extends Check {
public List<CheckId> getDependencies() { public List<CheckId> getDependencies() {
return dependencies; return dependencies;
} }
@Override
public Set<Requirement> appliesToRequirements() {
return CollectionUtils.singletonSet(Requirement.R_GE_S_NOT_CLOSED);
}
@Override @Override
public CheckType getType() { public RequirementType getType() {
return CheckType.GEOMETRY; return RequirementType.GEOMETRY;
} }
@Override @Override
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment