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
...@@ -23,6 +23,7 @@ import java.util.ArrayList; ...@@ -23,6 +23,7 @@ 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.error.DependenciesNotMetError; import de.hft.stuttgart.citydoctor2.check.error.DependenciesNotMetError;
import de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding; import de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding;
...@@ -98,6 +99,8 @@ public abstract class Check { ...@@ -98,6 +99,8 @@ public abstract class Check {
public List<CheckId> getDependencies() { public List<CheckId> getDependencies() {
return Collections.emptyList(); return Collections.emptyList();
} }
public abstract Set<Requirement> appliesToRequirements();
/** /**
* Getter for the check id. * Getter for the check id.
...@@ -111,7 +114,7 @@ public abstract class Check { ...@@ -111,7 +114,7 @@ public abstract class Check {
* *
* @return the check type * @return the check type
*/ */
public abstract CheckType getType(); public abstract RequirementType getType();
/** /**
* Checks whether the check can be executed on this checkable, meaning the * Checks whether the check can be executed on this checkable, meaning the
......
...@@ -44,14 +44,13 @@ public class CheckId implements Serializable { ...@@ -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 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 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_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_SE_BS_IS_CEILING = new CheckId("C_SE_BS_IS_CEILING");
public static final CheckId C_SEM_BS_NOT_FLOOR = new CheckId("C_SEM_BS_NOT_FLOOR"); public static final CheckId C_SE_BS_IS_FLOOR = new CheckId("C_SE_BS_IS_FLOOR");
public static final CheckId C_SEM_BS_NOT_GROUND = new CheckId("C_SEM_BS_NOT_GROUND"); public static final CheckId C_SE_BS_IS_GROUND = new CheckId("C_SE_BS_IS_GROUND");
public static final CheckId C_SEM_F_MISSING_ID = new CheckId("C_SEM_F_MISSING_ID"); public static final CheckId C_SE_BS_GROUND_NOT_FRAGMENTED = new CheckId("C_SE_BS_GROUND_NOT_FRAGMENTED");
public static final CheckId C_SEM_BS_GROUND_NOT_FRAGMENTED = new CheckId("C_SEM_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_SEM_BS_IS_WALL = new CheckId("C_SEM_BS_IS_WALL"); public static final CheckId C_SE_SCHEMATRON = new CheckId("C_SE_SCHEMATRON");
public static final CheckId C_SEM_SCHEMATRON = new CheckId("C_SEM_SCHEMATRON"); public static final CheckId C_SE_BS_ROOF_UNFRAGMENTED = new CheckId("C_SE_BS_ROOF_UNFRAGMENTED");
public static final CheckId C_SEM_BS_ROOF_NOT_FRAGMENTED = new CheckId("C_SEM_BS_ROOF_NOT_FRAGMENTED");
public static final CheckId C_GE_S_NOT_CLOSED = new CheckId("C_GE_S_NOT_CLOSED"); 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"); public static final CheckId C_GE_P_ORIENTATION_RINGS_SAME = new CheckId("C_GE_P_ORIENTATION_RINGS_SAME");
......
...@@ -31,7 +31,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.GmlId; ...@@ -31,7 +31,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
/** /**
* Interface to indicate that this object can be checked by Checks. * 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 { public abstract class Checkable implements Serializable {
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
*/ */
package de.hft.stuttgart.citydoctor2.check; package de.hft.stuttgart.citydoctor2.check;
import java.io.Serializable;
/** /**
* Describes a parameter for a check including the default value as a String. * 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<String, * All values are a String as they are passed to the check as a Map<String,
...@@ -26,15 +28,17 @@ package de.hft.stuttgart.citydoctor2.check; ...@@ -26,15 +28,17 @@ package de.hft.stuttgart.citydoctor2.check;
* @author Matthias Betz * @author Matthias Betz
* *
*/ */
public class DefaultParameter { public class DefaultParameter implements Serializable {
private static final long serialVersionUID = -4587211298078974066L;
private String name; private String name;
private String defaultValue; private String value;
private Unit unitType; private Unit unitType;
public DefaultParameter(String name, String defaultValue, Unit unitType) { public DefaultParameter(String name, String defaultValue, Unit unitType) {
this.name = name; this.name = name;
this.defaultValue = defaultValue; this.value = defaultValue;
this.unitType = unitType; this.unitType = unitType;
} }
...@@ -56,8 +60,8 @@ public class DefaultParameter { ...@@ -56,8 +60,8 @@ public class DefaultParameter {
* *
* @return the defaultValue * @return the defaultValue
*/ */
public String getDefaultValue() { public String getValue() {
return defaultValue; return value;
} }
/* /*
...@@ -68,10 +72,10 @@ public class DefaultParameter { ...@@ -68,10 +72,10 @@ public class DefaultParameter {
@Override @Override
public String toString() { public String toString() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("CheckParameter [name="); builder.append("DefaultParameter [name=");
builder.append(name); builder.append(name);
builder.append(", defaultValue="); builder.append(", value=");
builder.append(defaultValue); builder.append(value);
builder.append("]"); builder.append("]");
return builder.toString(); return builder.toString();
} }
......
...@@ -56,13 +56,12 @@ public class ErrorId implements Serializable { ...@@ -56,13 +56,12 @@ public class ErrorId implements Serializable {
public static final ErrorId GE_P_ORIENTATION_RINGS_SAME = new ErrorId("GE_P_ORIENTATION_RINGS_SAME"); public static final ErrorId GE_P_ORIENTATION_RINGS_SAME = new ErrorId("GE_P_ORIENTATION_RINGS_SAME");
public static final ErrorId GE_S_NOT_CLOSED = new ErrorId("GE_S_NOT_CLOSED"); public static final ErrorId GE_S_NOT_CLOSED = new ErrorId("GE_S_NOT_CLOSED");
public static final ErrorId GE_S_TOO_FEW_POLYGONS = new ErrorId("GE_S_TOO_FEW_POLYGONS"); public static final ErrorId GE_S_TOO_FEW_POLYGONS = new ErrorId("GE_S_TOO_FEW_POLYGONS");
public static final ErrorId SEM_F_MISSING_ID = new ErrorId("SEM_F_MISSING_ID"); public static final ErrorId SE_BS_NOT_CEILING = new ErrorId("SE_BS_NOT_CEILING");
public static final ErrorId SEM_BS_NOT_CEILING = new ErrorId("SEM_BS_NOT_CEILING"); public static final ErrorId SE_BS_NOT_WALL = new ErrorId("SE_BS_NOT_WALL");
public static final ErrorId SEM_BS_NOT_WALL = new ErrorId("SEM_BS_NOT_WALL"); public static final ErrorId SE_BS_NOT_FLOOR = new ErrorId("SE_BS_NOT_FLOOR");
public static final ErrorId SEM_BS_NOT_FLOOR = new ErrorId("SEM_BS_NOT_FLOOR"); public static final ErrorId SE_BS_NOT_GROUND = new ErrorId("SE_BS_NOT_GROUND");
public static final ErrorId SEM_BS_NOT_GROUND = new ErrorId("SEM_BS_NOT_GROUND"); public static final ErrorId SE_SCHEMATRON_ERROR = new ErrorId("SE_SCHEMATRON_ERROR");
public static final ErrorId SEM_SCHEMATRON_ERROR = new ErrorId("SEM_SCHEMATRON_ERROR"); public static final ErrorId SE_BS_UNFRAGMENTED = new ErrorId("SE_BS_UNFRAGMENTED");
public static final ErrorId SEM_BS_UNFRAGMENTED = new ErrorId("SEM_BS_UNFRAGMENTED");
public static final ErrorId GE_P_DEGENERATED_POLYGON = new ErrorId("GE_P_DEGENERATED_POLYGON"); public static final ErrorId GE_P_DEGENERATED_POLYGON = new ErrorId("GE_P_DEGENERATED_POLYGON");
private String name; private String name;
......
/*-
* 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 <https://www.gnu.org/licenses/>.
*/
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";
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<DefaultParameter> 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);
}
private String id;
private RequirementType type;
private List<DefaultParameter> parameters;
public Requirement(String id, RequirementType type) {
this.id = id;
this.type = type;
parameters = Collections.emptyList();
}
public String getId() {
return id;
}
public List<DefaultParameter> 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;
}
}
...@@ -26,7 +26,7 @@ package de.hft.stuttgart.citydoctor2.check; ...@@ -26,7 +26,7 @@ package de.hft.stuttgart.citydoctor2.check;
* @author Matthias Betz * @author Matthias Betz
* *
*/ */
public enum CheckType { public enum RequirementType {
GEOMETRY, SEMANTIC GEOMETRY, SEMANTIC
......
...@@ -79,7 +79,7 @@ public class NotCeilingError implements CheckError { ...@@ -79,7 +79,7 @@ public class NotCeilingError implements CheckError {
@Override @Override
public ErrorId getErrorId() { public ErrorId getErrorId() {
return ErrorId.SEM_BS_NOT_CEILING; return ErrorId.SE_BS_NOT_CEILING;
} }
@Override @Override
......
...@@ -77,7 +77,7 @@ public class NotFloorError implements CheckError { ...@@ -77,7 +77,7 @@ public class NotFloorError implements CheckError {
@Override @Override
public ErrorId getErrorId() { public ErrorId getErrorId() {
return ErrorId.SEM_BS_NOT_FLOOR; return ErrorId.SE_BS_NOT_FLOOR;
} }
@Override @Override
......
...@@ -79,7 +79,7 @@ public class NotGroundError implements CheckError { ...@@ -79,7 +79,7 @@ public class NotGroundError implements CheckError {
@Override @Override
public ErrorId getErrorId() { public ErrorId getErrorId() {
return ErrorId.SEM_BS_NOT_GROUND; return ErrorId.SE_BS_NOT_GROUND;
} }
@Override @Override
......
...@@ -82,7 +82,7 @@ public class NotWallError implements CheckError { ...@@ -82,7 +82,7 @@ public class NotWallError implements CheckError {
@Override @Override
public ErrorId getErrorId() { public ErrorId getErrorId() {
return ErrorId.SEM_BS_NOT_WALL; return ErrorId.SE_BS_NOT_WALL;
} }
@Override @Override
......
...@@ -94,7 +94,7 @@ public class SchematronError implements CheckError { ...@@ -94,7 +94,7 @@ public class SchematronError implements CheckError {
@Override @Override
public ErrorId getErrorId() { public ErrorId getErrorId() {
return ErrorId.SEM_SCHEMATRON_ERROR; return ErrorId.SE_SCHEMATRON_ERROR;
} }
@Override @Override
......
...@@ -77,7 +77,7 @@ public class SurfaceUnfragmentedError implements CheckError { ...@@ -77,7 +77,7 @@ public class SurfaceUnfragmentedError implements CheckError {
@Override @Override
public ErrorId getErrorId() { public ErrorId getErrorId() {
return ErrorId.SEM_BS_UNFRAGMENTED; return ErrorId.SE_BS_UNFRAGMENTED;
} }
@Override @Override
......
...@@ -42,6 +42,10 @@ public class BoundingBox { ...@@ -42,6 +42,10 @@ public class BoundingBox {
public static BoundingBox of(List<Polygon> polygons) { public static BoundingBox of(List<Polygon> polygons) {
return BoundingBoxCalculator.calculateBoundingBox(polygons); return BoundingBoxCalculator.calculateBoundingBox(polygons);
} }
public static BoundingBox ofPoints(List<? extends Vector3d> points) {
return BoundingBoxCalculator.calculateBoundingBoxFromPoints(points);
}
/** /**
* Creates an axis aligned bounding box of the whole model. * Creates an axis aligned bounding box of the whole model.
......
...@@ -56,6 +56,12 @@ public class CovarianceMatrix { ...@@ -56,6 +56,12 @@ public class CovarianceMatrix {
covValues[1][2] += ydiff * zdiff; covValues[1][2] += ydiff * zdiff;
covValues[2][2] += zdiff * 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 // the covariance matrix is symmetric, so we can fill in the remaining values
covValues[1][0] = covValues[0][1]; covValues[1][0] = covValues[0][1];
covValues[2][0] = covValues[0][2]; covValues[2][0] = covValues[0][2];
......
...@@ -135,7 +135,7 @@ public class Matrix3x3d { ...@@ -135,7 +135,7 @@ public class Matrix3x3d {
/** /**
* Multiplies this matrix with a 3-dim vector. * Multiplies this matrix with a 3-dim vector.
* *
* @param other the vector * @param the multiplied vector
* @return the result stored in a new vector * @return the result stored in a new vector
*/ */
public Vector3d mult(Vector3d other) { public Vector3d mult(Vector3d other) {
......
...@@ -63,17 +63,20 @@ public class BoundingBoxCalculator { ...@@ -63,17 +63,20 @@ public class BoundingBoxCalculator {
for (Vertex v : p.getExteriorRing().getVertices()) { for (Vertex v : p.getExteriorRing().getVertices()) {
if (v.getX() < lowX) { if (v.getX() < lowX) {
lowX = v.getX(); lowX = v.getX();
} else if (v.getX() > highX) { }
if (v.getX() > highX) {
highX = v.getX(); highX = v.getX();
} }
if (v.getY() < lowY) { if (v.getY() < lowY) {
lowY = v.getY(); lowY = v.getY();
} else if (v.getY() > highY) { }
if (v.getY() > highY) {
highY = v.getY(); highY = v.getY();
} }
if (v.getZ() < lowZ) { if (v.getZ() < lowZ) {
lowZ = v.getZ(); lowZ = v.getZ();
} else if (v.getZ() > highZ) { }
if (v.getZ() > highZ) {
highZ = v.getZ(); highZ = v.getZ();
} }
} }
...@@ -92,7 +95,7 @@ public class BoundingBoxCalculator { ...@@ -92,7 +95,7 @@ public class BoundingBoxCalculator {
*/ */
public static BoundingBox calculateBoundingBox(CityDoctorModel model) { public static BoundingBox calculateBoundingBox(CityDoctorModel model) {
Vector3d low = new Vector3d(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE); 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.getBuildings());
findMinMax(low, high, model.getBridges()); findMinMax(low, high, model.getBridges());
...@@ -107,6 +110,40 @@ public class BoundingBoxCalculator { ...@@ -107,6 +110,40 @@ public class BoundingBoxCalculator {
return BoundingBox.of(result); return BoundingBox.of(result);
} }
public static BoundingBox calculateBoundingBoxFromPoints(List<? extends Vector3d> 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<? extends CityObject> features) { private static void findMinMax(Vector3d low, Vector3d high, List<? extends CityObject> features) {
for (CityObject co : features) { for (CityObject co : features) {
findMinMax(low, high, co); findMinMax(low, high, co);
...@@ -121,17 +158,20 @@ public class BoundingBoxCalculator { ...@@ -121,17 +158,20 @@ public class BoundingBoxCalculator {
for (Vertex v : geom.getVertices()) { for (Vertex v : geom.getVertices()) {
if (v.getX() < low.getX()) { if (v.getX() < low.getX()) {
low.setX(v.getX()); low.setX(v.getX());
} else if (v.getX() > high.getX()) { }
if (v.getX() > high.getX()) {
high.setX(v.getX()); high.setX(v.getX());
} }
if (v.getY() < low.getY()) { if (v.getY() < low.getY()) {
low.setY(v.getY()); low.setY(v.getY());
} else if (v.getY() > high.getY()) { }
if (v.getY() > high.getY()) {
high.setY(v.getY()); high.setY(v.getY());
} }
if (v.getZ() < low.getZ()) { if (v.getZ() < low.getZ()) {
low.setZ(v.getZ()); low.setZ(v.getZ());
} else if (v.getZ() > high.getZ()) { }
if (v.getZ() > high.getZ()) {
high.setZ(v.getZ()); high.setZ(v.getZ());
} }
} }
......
...@@ -241,7 +241,7 @@ public class Checker { ...@@ -241,7 +241,7 @@ public class Checker {
ValidationPlan plan = new ValidationPlan(); ValidationPlan plan = new ValidationPlan();
List<Checking> filter = createFilter(); List<Checking> filter = createFilter();
for (Entry<CheckId, CheckConfiguration> e : config.getChecks().entrySet()) { for (Entry<String, RequirementConfiguration> e : config.getRequirements().entrySet()) {
RequirementId reqId = mapToRequirement(e.getKey()); RequirementId reqId = mapToRequirement(e.getKey());
if (reqId == null) { if (reqId == null) {
continue; continue;
...@@ -250,12 +250,12 @@ public class Checker { ...@@ -250,12 +250,12 @@ public class Checker {
req.setName(reqId); req.setName(reqId);
req.setEnabled(e.getValue().isEnabled()); req.setEnabled(e.getValue().isEnabled());
plan.getRequirements().add(req); plan.getRequirements().add(req);
CheckPrototype proto = Checks.getCheckPrototypeForId(e.getKey());
Map<String, String> parameters = e.getValue().getParameters(); Map<String, String> parameters = e.getValue().getParameters();
Map<String, de.hft.stuttgart.citydoctor2.check.Requirement> reqs = Checks.getAvailableRequirements();
if (parameters != null) { if (parameters != null) {
for (Entry<String, String> param : parameters.entrySet()) { for (Entry<String, String> param : parameters.entrySet()) {
Parameter p = new Parameter(); Parameter p = new Parameter();
DefaultParameter defaultP = getDefaultParameter(param.getKey(), proto); DefaultParameter defaultP = getDefaultParameter(param.getKey(), reqs);
if (defaultP != null) { if (defaultP != null) {
p.setUom(defaultP.getUnitType().getGmlRepresentation()); p.setUom(defaultP.getUnitType().getGmlRepresentation());
} }
...@@ -292,10 +292,14 @@ public class Checker { ...@@ -292,10 +292,14 @@ public class Checker {
return plan; return plan;
} }
private DefaultParameter getDefaultParameter(String key, CheckPrototype proto) { private DefaultParameter getDefaultParameter(String key,
for (DefaultParameter param : proto.getDefaultParameter()) { Map<String, de.hft.stuttgart.citydoctor2.check.Requirement> reqs) {
if (param.getName().equals(key)) { de.hft.stuttgart.citydoctor2.check.Requirement requirement = reqs.get(key);
return param; if (requirement != null) {
for (DefaultParameter param : requirement.getDefaultParameter()) {
if (param.getName().equals(key)) {
return param;
}
} }
} }
return null; return null;
...@@ -382,43 +386,10 @@ public class Checker { ...@@ -382,43 +386,10 @@ public class Checker {
} }
} }
private RequirementId mapToRequirement(CheckId key) { private RequirementId mapToRequirement(String requirementName) {
switch (key.getName()) { try {
case "C_GE_R_TOO_FEW_POINTS": return RequirementId.valueOf(requirementName);
return RequirementId.R_GE_R_TOO_FEW_POINTS; } catch (IllegalArgumentException e) {
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:
return null; return null;
} }
} }
...@@ -557,20 +528,71 @@ public class Checker { ...@@ -557,20 +528,71 @@ public class Checker {
} }
private List<Check> collectEnabledChecksAndInit(ParserConfiguration parserConfig, ValidationConfiguration config) { private List<Check> collectEnabledChecksAndInit(ParserConfiguration parserConfig, ValidationConfiguration config) {
List<Check> checks = new ArrayList<>(); Set<CheckId> enabledCheck = new HashSet<>();
for (Entry<CheckId, CheckConfiguration> e : config.getChecks().entrySet()) { Map<CheckId, Map<String, String>> parameterMap = new HashMap<>();
if (e.getValue().isEnabled()) { for (Entry<String, RequirementConfiguration> e : config.getRequirements().entrySet()) {
Check c = checkConfig.getCheckForId(e.getKey()); de.hft.stuttgart.citydoctor2.check.Requirement req = Checks.getAvailableRequirements().get(e.getKey());
Map<String, String> parameters = new HashMap<>(); if (req == null) {
parameters.putAll(e.getValue().getParameters()); logger.warn("Could not find any check that satisfies requirement {}, it will not be checked",
parameters.put("numberOfRoundingPlaces", "" + config.getNumberOfRoundingPlaces()); e.getKey());
parameters.put("minVertexDistance", "" + config.getMinVertexDistance()); } else {
// initialize checks with parameters if (e.getValue().isEnabled()) {
c.init(parameters, parserConfig); // this requirement is enabled
checks.add(c); 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);
}
}
}
}
}
fillParameterMapsWithDefaultParameter(enabledCheck, parameterMap);
ArrayList<Check> 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<CheckId> enabledCheck,
Map<CheckId, Map<String, String>> parameterMap) {
for (CheckId id : enabledCheck) {
CheckPrototype proto = Checks.getCheckPrototypeForId(id);
Map<String, String> 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<CheckId> enabledChecks) {
enabledChecks.addAll(proto.getDependencies());
for (CheckId id : proto.getDependencies()) {
if (enabledChecks.contains(id)) {
continue;
} }
CheckPrototype depProto = Checks.getCheckPrototypeForId(id);
collectDependencyChecks(depProto, enabledChecks);
} }
return checks;
} }
private void checkCityModel(CityDoctorModel model, ProgressListener l) { private void checkCityModel(CityDoctorModel model, ProgressListener l) {
......
/*-
* 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 <https://www.gnu.org/licenses/>.
*/
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";
}
...@@ -29,7 +29,7 @@ import java.util.Map; ...@@ -29,7 +29,7 @@ import java.util.Map;
* @author Matthias Betz * @author Matthias Betz
* *
*/ */
public class CheckConfiguration implements Serializable { public class RequirementConfiguration implements Serializable {
private static final long serialVersionUID = -1258195428669813888L; private static final long serialVersionUID = -1258195428669813888L;
...@@ -59,10 +59,7 @@ public class CheckConfiguration implements Serializable { ...@@ -59,10 +59,7 @@ public class CheckConfiguration implements Serializable {
} }
return parameters; return parameters;
} }
/**
* @param parameters Sets the parameters of this check.
*/
public void setParameters(Map<String, String> parameters) { public void setParameters(Map<String, String> parameters) {
this.parameters = parameters; this.parameters = parameters;
} }
......
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