Commit a4715310 authored by Matthias Betz's avatar Matthias Betz
Browse files

Moving degeneration test to ring instead of polygon

parent 43660f7f
Pipeline #4349 passed with stage
in 2 minutes and 14 seconds
......@@ -62,7 +62,7 @@ public class ErrorId implements Serializable {
public static final ErrorId SE_BS_NOT_GROUND = new ErrorId("SE_BS_NOT_GROUND");
public static final ErrorId SE_SCHEMATRON_ERROR = new ErrorId("SE_SCHEMATRON_ERROR");
public static final ErrorId SE_BS_UNFRAGMENTED = new ErrorId("SE_BS_UNFRAGMENTED");
public static final ErrorId GE_P_DEGENERATED_POLYGON = new ErrorId("GE_P_DEGENERATED_POLYGON");
public static final ErrorId GE_P_DEGENERATED_RING = new ErrorId("GE_P_DEGENERATED_POLYGON");
private String name;
......
......@@ -48,7 +48,7 @@ import de.hft.stuttgart.citydoctor2.check.error.SchematronError;
import de.hft.stuttgart.citydoctor2.check.error.SolidNotClosedError;
import de.hft.stuttgart.citydoctor2.check.error.SolidSelfIntError;
import de.hft.stuttgart.citydoctor2.check.error.SurfaceUnfragmentedError;
import de.hft.stuttgart.citydoctor2.check.error.DegeneratedPolygonError;
import de.hft.stuttgart.citydoctor2.check.error.DegeneratedRingError;
import de.hft.stuttgart.citydoctor2.check.error.TooFewPolygonsError;
import de.hft.stuttgart.citydoctor2.check.error.UnknownCheckError;
......@@ -123,7 +123,7 @@ public interface ErrorVisitor {
public void visit(SurfaceUnfragmentedError err);
public void visit(DegeneratedPolygonError err);
public void visit(DegeneratedRingError err);
public void visit(AttributeMissingError err);
......
......@@ -47,7 +47,7 @@ import de.hft.stuttgart.citydoctor2.check.error.SchematronError;
import de.hft.stuttgart.citydoctor2.check.error.SolidNotClosedError;
import de.hft.stuttgart.citydoctor2.check.error.SolidSelfIntError;
import de.hft.stuttgart.citydoctor2.check.error.SurfaceUnfragmentedError;
import de.hft.stuttgart.citydoctor2.check.error.DegeneratedPolygonError;
import de.hft.stuttgart.citydoctor2.check.error.DegeneratedRingError;
import de.hft.stuttgart.citydoctor2.check.error.TooFewPolygonsError;
import de.hft.stuttgart.citydoctor2.check.error.UnknownCheckError;
......@@ -65,7 +65,7 @@ public interface HealingMethod {
return false;
}
default boolean visit(DegeneratedPolygonError e, ModificationListener l) {
default boolean visit(DegeneratedRingError e, ModificationListener l) {
return false;
}
......
......@@ -30,7 +30,7 @@ public class Requirement implements Serializable {
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";
public static final String DEGENERATED_RING_TOLERANCE = "degeneratedRingTolerance";
private static final String LOWER_ANGLE_NAME = "lowerAngle";
private static final String UPPER_ANGLE_NAME = "upperAngle";
private static final String MAX_ANGLE_DEVIATION = "maxAngleDeviation";
......@@ -73,7 +73,6 @@ public class Requirement implements Serializable {
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<>();
......@@ -83,6 +82,10 @@ public class Requirement implements Serializable {
defaultParameters.add(new DefaultParameter(MAX_ANGLE_DEVIATION, "1", Unit.DEGREE));
R_SE_BS_ROOF_UNFRAGMENTED.parameters = Collections.unmodifiableList(defaultParameters);
defaultParameters = new ArrayList<>();
defaultParameters.add(new DefaultParameter(DEGENERATED_RING_TOLERANCE, "0.00000", Unit.METER));
R_GE_R_SELF_INTERSECTION.parameters = Collections.unmodifiableList(defaultParameters);
}
......
......@@ -26,20 +26,20 @@ import de.hft.stuttgart.citydoctor2.check.ErrorVisitor;
import de.hft.stuttgart.citydoctor2.check.HealingMethod;
import de.hft.stuttgart.citydoctor2.check.ModificationListener;
import de.hft.stuttgart.citydoctor2.datastructure.GmlElement;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
public class DegeneratedPolygonError implements CheckError {
public class DegeneratedRingError implements CheckError {
private static final long serialVersionUID = 865493182529055651L;
private Polygon p;
private LinearRing lr;
public DegeneratedPolygonError(Polygon p) {
this.p = p;
public DegeneratedRingError(LinearRing lr) {
this.lr = lr;
}
public Polygon getPolygon() {
return p;
public LinearRing getRing() {
return lr;
}
@Override
......@@ -54,7 +54,8 @@ public class DegeneratedPolygonError implements CheckError {
@Override
public void report(ErrorReport report) {
report.add(getPolygon());
report.add("type", "degenerated ring");
report.add(getRing());
}
@Override
......@@ -64,12 +65,12 @@ public class DegeneratedPolygonError implements CheckError {
@Override
public ErrorId getErrorId() {
return ErrorId.GE_P_DEGENERATED_POLYGON;
return ErrorId.GE_R_SELF_INTERSECTION;
}
@Override
public GmlElement getFeature() {
return getPolygon();
return getRing();
}
}
......@@ -32,16 +32,13 @@ import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.Requirement;
import de.hft.stuttgart.citydoctor2.check.RequirementType;
import de.hft.stuttgart.citydoctor2.check.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.DegeneratedPolygonError;
import de.hft.stuttgart.citydoctor2.check.error.NonPlanarPolygonDistancePlaneError;
import de.hft.stuttgart.citydoctor2.check.error.NonPlanarPolygonNormalsDeviation;
import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils;
import de.hft.stuttgart.citydoctor2.datastructure.BoundingBox;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.math.CovarianceMatrix;
import de.hft.stuttgart.citydoctor2.math.Matrix3x3d;
import de.hft.stuttgart.citydoctor2.math.OrthogonalRegressionPlane;
import de.hft.stuttgart.citydoctor2.math.Plane;
import de.hft.stuttgart.citydoctor2.math.Triangle3d;
......@@ -63,7 +60,6 @@ public class PlanarCheck extends Check {
private static final String DISTANCE_TOLERANCE = "distanceTolerance";
private static final String ANGLE_TOLERANCE = "angleTolerance";
private static final String TYPE = "type";
private static final String DEGENERATED_POLYGON_TOLERANCE = "degeneratedPolygonTolerance";
private static final List<CheckId> dependencies;
......@@ -80,7 +76,6 @@ public class PlanarCheck extends Check {
private double rad = Math.toRadians(1);
private double delta = 0.01;
private double degeneratedPolygonTolerance = 0.00000;
@Override
public void init(Map<String, String> parameters, ParserConfiguration config) {
......@@ -95,9 +90,6 @@ public class PlanarCheck extends Check {
if (parameters.containsKey(DISTANCE_TOLERANCE)) {
delta = Double.parseDouble(parameters.get(DISTANCE_TOLERANCE));
}
if (parameters.containsKey(DEGENERATED_POLYGON_TOLERANCE)) {
degeneratedPolygonTolerance = Double.parseDouble(parameters.get(DEGENERATED_POLYGON_TOLERANCE));
}
}
@Override
......@@ -105,15 +97,6 @@ public class PlanarCheck extends Check {
if (DISTANCE.equals(planarCheckType)) {
planarDistance(p);
} else if ("angle".equals(planarCheckType)) {
// check for tiny edge as well
// store all used points in temporary list
ArrayList<Vertex> vertices = collectVertices(p);
Vector3d centroid = CovarianceMatrix.getCentroid(vertices);
EigenvalueDecomposition ed = OrthogonalRegressionPlane.decompose(vertices, centroid);
if (checkEigenvalues(p, vertices, ed)) {
// found tiny edge error, abort further checking
return;
}
planarNormalDeviation(p);
} else if ("both".equals(planarCheckType)) {
planarDistance(p);
......@@ -172,12 +155,6 @@ public class PlanarCheck extends Check {
ArrayList<Vertex> vertices = collectVertices(p);
Vector3d centroid = CovarianceMatrix.getCentroid(vertices);
EigenvalueDecomposition ed = OrthogonalRegressionPlane.decompose(vertices, centroid);
if (checkEigenvalues(p, vertices, ed)) {
// found tiny edge error, abort further checking
return;
}
Vector3d eigenvalues = OrthogonalRegressionPlane.getEigenvalues(ed);
Plane plane = OrthogonalRegressionPlane.calculatePlane(centroid, ed, eigenvalues);
for (Vertex v : vertices) {
......@@ -211,33 +188,6 @@ public class PlanarCheck extends Check {
return vertices;
}
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;
if (bbox.getWidth() < degeneratedPolygonTolerance) {
nrOfEigenvaluesBelowTolerance++;
}
if (bbox.getHeight() < degeneratedPolygonTolerance) {
nrOfEigenvaluesBelowTolerance++;
}
if (bbox.getDepth() < degeneratedPolygonTolerance) {
nrOfEigenvaluesBelowTolerance++;
}
if (nrOfEigenvaluesBelowTolerance >= 2) {
CheckError err = new DegeneratedPolygonError(p);
p.addCheckResult(new CheckResult(this, ResultStatus.ERROR, err));
return true;
}
return false;
}
@Override
public List<CheckId> getDependencies() {
return dependencies;
......
......@@ -24,23 +24,30 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import Jama.EigenvalueDecomposition;
import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.RequirementType;
import de.hft.stuttgart.citydoctor2.check.Requirement;
import de.hft.stuttgart.citydoctor2.check.RequirementType;
import de.hft.stuttgart.citydoctor2.check.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.DegeneratedRingError;
import de.hft.stuttgart.citydoctor2.check.error.PointTouchesEdgeError;
import de.hft.stuttgart.citydoctor2.check.error.RingEdgeIntersectionError;
import de.hft.stuttgart.citydoctor2.checks.Checks;
import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils;
import de.hft.stuttgart.citydoctor2.datastructure.BoundingBox;
import de.hft.stuttgart.citydoctor2.datastructure.Edge;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.math.CovarianceMatrix;
import de.hft.stuttgart.citydoctor2.math.DistanceResult;
import de.hft.stuttgart.citydoctor2.math.Matrix3x3d;
import de.hft.stuttgart.citydoctor2.math.OrthogonalRegressionPlane;
import de.hft.stuttgart.citydoctor2.math.Segment3d;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
/**
......@@ -54,6 +61,9 @@ public class RingSelfIntCheck extends Check {
private static final String EPSILON_NAME = "minVertexDistance";
private double degeneratedRingTolerance = 0.00000;
private static final List<CheckId> dependencies;
static {
......@@ -72,6 +82,9 @@ public class RingSelfIntCheck extends Check {
if (epsilonString != null) {
epsilon = Double.parseDouble(epsilonString);
}
if (parameters.containsKey(Requirement.DEGENERATED_RING_TOLERANCE)) {
degeneratedRingTolerance = Double.parseDouble(parameters.get(Requirement.DEGENERATED_RING_TOLERANCE));
}
}
@Override
......@@ -80,6 +93,17 @@ public class RingSelfIntCheck extends Check {
}
private void checkRingJava(LinearRing lr) {
// check for tiny edge as well
// store all used points in temporary list
List<Vertex> vertices = lr.getVertices();
Vector3d centroid = CovarianceMatrix.getCentroid(vertices);
EigenvalueDecomposition ed = OrthogonalRegressionPlane.decompose(vertices, centroid);
if (checkEigenvalues(lr, vertices, ed)) {
// found tiny edge error, abort further checking
return;
}
List<Edge> edges = getEdgesForRing(lr);
for (Edge e : edges) {
......@@ -113,6 +137,33 @@ public class RingSelfIntCheck extends Check {
CheckResult cr = new CheckResult(this, ResultStatus.OK, null);
lr.addCheckResult(cr);
}
private boolean checkEigenvalues(LinearRing lr, 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;
if (bbox.getWidth() < degeneratedRingTolerance) {
nrOfEigenvaluesBelowTolerance++;
}
if (bbox.getHeight() < degeneratedRingTolerance) {
nrOfEigenvaluesBelowTolerance++;
}
if (bbox.getDepth() < degeneratedRingTolerance) {
nrOfEigenvaluesBelowTolerance++;
}
if (nrOfEigenvaluesBelowTolerance >= 2) {
CheckError err = new DegeneratedRingError(lr);
lr.addCheckResult(new CheckResult(this, ResultStatus.ERROR, err));
return true;
}
return false;
}
private boolean checkForPointsTouchingEdge(LinearRing lr, Edge e1) {
Segment3d seg = new Segment3d(e1.getFrom(), e1.getTo());
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment