Commit 297334ab authored by Matthias Betz's avatar Matthias Betz
Browse files

Add design spec for OpenGL 3D view



Replaces the JavaFX SubScene/MeshView rendering with an OpenGL viewport
(openglfx-jogl, GL 3.3 core), single global VBO, GPU color-picking, and
baked fake shading. Windows/Linux targets; JavaFX 3D path removed.

Co-Authored-By: default avatarClaude Opus 4.8 <noreply@anthropic.com>
parents 5c2847ef bd40b396
......@@ -57,7 +57,6 @@ public record CheckId(String name) implements Serializable {
public static final CheckId C_GE_P_ORIENTATION_RINGS_SAME = new CheckId("C_GE_P_ORIENTATION_RINGS_SAME");
public static final CheckId C_SE_POLYGON_WITHOUT_SURFACE = new CheckId("C_SE_POLYGON_WITHOUT_SURFACE");
@Override
public boolean equals(Object obj) {
if (this == obj)
......
......@@ -24,6 +24,13 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.hft.stuttgart.citydoctor2.utils.CheckErrorFound;
import de.hft.stuttgart.citydoctor2.utils.visitors.CheckableErrorCollector;
import de.hft.stuttgart.citydoctor2.utils.visitors.ClearResultsVisitor;
import de.hft.stuttgart.citydoctor2.utils.visitors.ClearMetaInformationVisitor;
import de.hft.stuttgart.citydoctor2.utils.visitors.ContainsAnyErrorVisitor;
import de.hft.stuttgart.citydoctor2.utils.visitors.ContainsErrorVisitor;
import de.hft.stuttgart.citydoctor2.utils.visitors.PrepareForCheckingVisitor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
......@@ -45,7 +52,7 @@ public abstract class Checkable implements Serializable {
private final Map<CheckId, CheckResult> checkResults = new HashMap<>();
private boolean isValidated = false;
protected void setValidated(boolean validated) {
public void setValidated(boolean validated) {
isValidated = validated;
}
......@@ -67,11 +74,13 @@ public abstract class Checkable implements Serializable {
* @param c the check from which the check method is called with the Checkable
* instance as parameter.
*/
public void accept(Check c) {
public void accept(CheckableVisitor c) {
if (c.canExecute(this)) {
c.check(this);
}
setValidated(true);
if (c.isValidator()) {
setValidated(true);
}
}
/**
......@@ -81,29 +90,47 @@ public abstract class Checkable implements Serializable {
* @return the GML-ID
*/
public abstract GmlId getGmlId();
/**
* This should be called before executing a check if low memory consumption
* method has been enabled. This should create edges and additional meta
* method has been enabled. Creates edges and additional meta
* information necessary to perform checks.
*/
public abstract void prepareForChecking();
public void prepareForChecking() {
this.accept(new PrepareForCheckingVisitor());
}
/**
* This should be called after checking has been done. This should remove any
* created meta information like edges to free up additional memory space
* This should be called after checking has been done. Removes any
* created meta information like edges to free up memory.
*/
public abstract void clearMetaInformation();
public void clearMetaInformation() {
this.accept(new ClearMetaInformationVisitor());
}
/**
* This method checks if the object or any object contained within this
* checkable has an error. It counts as an error if the result status if the
* given check is <code>DEPENDENCIES_NOT_MET<code>.
*
* @param checkIdentifier the name of the check for which an error is searched
* @return true if an error has been found with the given check
* Checks if the object, or any object in its datastructure, has a specific error or is not fulfilling the dependencies
* of it.
*
* @param checkIdentifier the associated CheckID of this error
* @return true if the error was found, false otherwise
*/
public boolean containsError(CheckId checkIdentifier) {
try {
ContainsErrorVisitor.checkObject(this, checkIdentifier);
} catch (CheckErrorFound c) {
return true;
}
return false;
}
/**
* Checks if this checkable has an error or is not meeting the dependencies for it.
*
* @param checkIdentifier the associated CheckID of this error
* @return true if the error was found, false otherwise
*/
public boolean hasError(CheckId checkIdentifier) {
CheckResult cs = getCheckResult(checkIdentifier);
if (cs == null) {
return false;
......@@ -133,8 +160,8 @@ public abstract class Checkable implements Serializable {
}
/**
*
* @return all check results for this checkable.
*
* @return all check results of this checkable.
*/
public Map<CheckId, CheckResult> getAllCheckResults() {
return checkResults;
......@@ -157,13 +184,11 @@ public abstract class Checkable implements Serializable {
}
/**
* Checks whether this checkable has an error. Dependency errors are not
* considered for this function. This will only check this checkable and not
* traverse any checkables contained in this instance.
* Checks whether this checkable has any error, barring dependency errors.
*
* @return true if it has an error, otherwise false
*/
public boolean hasAnyError() {
public boolean hasAnyErrorWithoutDependencies() {
for (CheckResult cr : checkResults.values()) {
if (cr.getResultStatus() == ResultStatus.ERROR) {
return true;
......@@ -196,24 +221,44 @@ public abstract class Checkable implements Serializable {
}
/**
* Clears all errors from this checkable
* Clears the checkResults of this checkable unless the error occured during parsing.
*/
public void clearCheckResults() {
setValidated(false);
checkResults.clear();
checkResults.entrySet().removeIf(e -> {
if (e.getValue().getError() == null) {
return true;
}
return !e.getValue().getError().isParsingError();
});
setValidated(!checkResults.isEmpty());
}
/**
* Removes all errors from this instance and all contained checkables.
* Clears the checkResults list of this checkable and all child objects in its datastructure.
*/
public abstract void clearAllContainedCheckResults();
public final void clearAllContainedCheckResults() {
this.accept(new ClearResultsVisitor());
}
/**
*
* @return false if the checkable or all checkables contained in this one don't
* have any error.
* Checks if this checkable contains any error within its datastructure.
*
* @return true if any checkable of this datastructure contains an error, false otherwise
*/
public final boolean containsAnyError() {
try {
ContainsAnyErrorVisitor.checkObject(this);
} catch (CheckErrorFound c) {
return true;
}
return false;
}
/**
* Checks if this checkable has any error
* @return true if this checkable has any error, false otherwise
*/
public boolean containsAnyError() {
public boolean hasAnyError() {
for (CheckResult cr : checkResults.values()) {
if (cr.getResultStatus() == ResultStatus.ERROR
|| cr.getResultStatus() == ResultStatus.DEPENDENCIES_NOT_MET) {
......@@ -230,6 +275,16 @@ public abstract class Checkable implements Serializable {
* @param errors the collection in which the errors are added.
*/
public void collectContainedErrors(List<CheckError> errors) {
this.accept(new CheckableErrorCollector(errors));
}
/**
* Collects all errors from this checkable and adds
* them to the given list. DEPENDENCY_NOT_MET errors are excluded from this.
*
* @param errors the collection in which the errors are added.
*/
public void collectErrors(List<CheckError> errors) {
for (CheckResult cr : checkResults.values()) {
if (cr.getResultStatus() == ResultStatus.ERROR) {
errors.add(cr.getError());
......
/*-
* 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 de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding;
import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface;
import de.hft.stuttgart.citydoctor2.datastructure.BridgeObject;
import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.BuildingPart;
import de.hft.stuttgart.citydoctor2.datastructure.CityFurniture;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.GenericCityObject;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.Installation;
import de.hft.stuttgart.citydoctor2.datastructure.LandObject;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Opening;
import de.hft.stuttgart.citydoctor2.datastructure.OtherConstructionObject;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.ReliefObject;
import de.hft.stuttgart.citydoctor2.datastructure.TinObject;
import de.hft.stuttgart.citydoctor2.datastructure.TransportationObject;
import de.hft.stuttgart.citydoctor2.datastructure.Vegetation;
import de.hft.stuttgart.citydoctor2.datastructure.WaterObject;
/**
*
* This class serves as the base for CheckableVisitors which fulfill utility functions, like e.g. collecting all
* sub-CityObjects in the datastructure of a CityObject.
* </p>
* Visitors extending from this class will not change the validated-flag of the visited Checkables.
*
*/
public abstract non-sealed class CheckableUtilsVisitor implements CheckableVisitor {
/**
* This function is used for checking of dependencies in {@link Check}. Since UtilsVisitors do not have
* dependencies this function will always return true.
*
* @param c a Checkable
* @return true
*/
@Override
public boolean canExecute(Checkable c) {
return true;
}
@Override
public final boolean isValidator() {
return false;
}
@Override
public void check(Checkable checkable) {
}
@Override
public void check(AbstractBuilding ab) {
}
@Override
public void check(BoundarySurface bs) {
}
@Override
public void check(BridgeObject bo) {
}
@Override
public void check(Building b) {
}
@Override
public void check(Installation bi) {
}
@Override
public void check(BuildingPart bp) {
}
@Override
public void check(CityObject co) {
}
@Override
public void check(LandObject lo) {
}
@Override
public void check(Opening o) {
}
@Override
public void check(TransportationObject to) {
}
@Override
public void check(Vegetation veg) {
}
@Override
public void check(WaterObject wo) {
}
@Override
public void check(Geometry geom) {
}
@Override
public void check(Polygon poly) {
}
@Override
public void check(LinearRing ring) {
}
@Override
public void check(TinObject tin) {
}
@Override
public void check(ReliefObject relief) {
}
@Override
public void check(CityFurniture cf) {
}
@Override
public void check(GenericCityObject gco) {
}
@Override
public void check(OtherConstructionObject oco){
}
}
package de.hft.stuttgart.citydoctor2.check;
import de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding;
import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface;
import de.hft.stuttgart.citydoctor2.datastructure.BridgeObject;
import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.BuildingPart;
import de.hft.stuttgart.citydoctor2.datastructure.CityFurniture;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.GenericCityObject;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.Installation;
import de.hft.stuttgart.citydoctor2.datastructure.LandObject;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Opening;
import de.hft.stuttgart.citydoctor2.datastructure.OtherConstructionObject;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.ReliefObject;
import de.hft.stuttgart.citydoctor2.datastructure.TinObject;
import de.hft.stuttgart.citydoctor2.datastructure.TransportationObject;
import de.hft.stuttgart.citydoctor2.datastructure.Vegetation;
import de.hft.stuttgart.citydoctor2.datastructure.WaterObject;
public sealed interface CheckableVisitor permits Check, CheckableUtilsVisitor {
/**
* Returns whether a Checkable should be flagged as validated after accepting this Visitor.
*/
boolean isValidator();
boolean canExecute(Checkable c);
void check(Checkable checkable);
void check(AbstractBuilding ab);
void check(BoundarySurface bs);
void check(BridgeObject bo);
void check(Building b);
void check(Installation bi);
void check(BuildingPart bp);
void check(CityObject co);
void check(LandObject lo);
void check(Opening o);
void check(TransportationObject to);
void check(Vegetation veg);
void check(WaterObject wo);
void check(Geometry geom);
void check(Polygon poly);
void check(LinearRing ring);
void check(TinObject tin);
void check(ReliefObject relief);
void check(CityFurniture cf);
void check(GenericCityObject gco);
void check(OtherConstructionObject oco);
}
......@@ -66,6 +66,7 @@ public record ErrorId(String name) implements Serializable {
public static final ErrorId SE_BS_UNFRAGMENTED = new ErrorId("SE_BS_UNFRAGMENTED");
public static final ErrorId GE_P_DEGENERATED_RING = new ErrorId("GE_P_DEGENERATED_POLYGON");
public static final ErrorId SE_POLYGON_WITHOUT_SURFACE = new ErrorId("SE_POLYGON_WITHOUT_SURFACE");
public static final ErrorId SC_SCHEMA_VALIDATION = new ErrorId("SC_SCHEMA_VALIDATION");
......
......@@ -23,6 +23,7 @@ import de.hft.stuttgart.citydoctor2.check.error.AttributeInvalidError;
import de.hft.stuttgart.citydoctor2.check.error.AttributeMissingError;
import de.hft.stuttgart.citydoctor2.check.error.AttributeValueWrongError;
import de.hft.stuttgart.citydoctor2.check.error.ConsecutivePointSameError;
import de.hft.stuttgart.citydoctor2.check.error.DegeneratedRingError;
import de.hft.stuttgart.citydoctor2.check.error.DependenciesNotMetError;
import de.hft.stuttgart.citydoctor2.check.error.MultipleConnectedComponentsError;
import de.hft.stuttgart.citydoctor2.check.error.NestedRingError;
......@@ -35,7 +36,9 @@ import de.hft.stuttgart.citydoctor2.check.error.NotFloorError;
import de.hft.stuttgart.citydoctor2.check.error.NotGroundError;
import de.hft.stuttgart.citydoctor2.check.error.NotWallError;
import de.hft.stuttgart.citydoctor2.check.error.NullAreaError;
import de.hft.stuttgart.citydoctor2.check.error.PlanarityError;
import de.hft.stuttgart.citydoctor2.check.error.PointTouchesEdgeError;
import de.hft.stuttgart.citydoctor2.check.error.PolygonError;
import de.hft.stuttgart.citydoctor2.check.error.PolygonHoleOutsideError;
import de.hft.stuttgart.citydoctor2.check.error.PolygonInteriorDisconnectedError;
import de.hft.stuttgart.citydoctor2.check.error.PolygonIntersectingRingsError;
......@@ -44,15 +47,18 @@ import de.hft.stuttgart.citydoctor2.check.error.PolygonWithoutSurfaceError;
import de.hft.stuttgart.citydoctor2.check.error.PolygonWrongOrientationError;
import de.hft.stuttgart.citydoctor2.check.error.RingDuplicatePointError;
import de.hft.stuttgart.citydoctor2.check.error.RingEdgeIntersectionError;
import de.hft.stuttgart.citydoctor2.check.error.RingError;
import de.hft.stuttgart.citydoctor2.check.error.RingNotClosedError;
import de.hft.stuttgart.citydoctor2.check.error.RingSelfIntersectionError;
import de.hft.stuttgart.citydoctor2.check.error.RingTooFewPointsError;
import de.hft.stuttgart.citydoctor2.check.error.SchematronError;
import de.hft.stuttgart.citydoctor2.check.error.SolidError;
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.DegeneratedRingError;
import de.hft.stuttgart.citydoctor2.check.error.SurfaceFragmentedError;
import de.hft.stuttgart.citydoctor2.check.error.TooFewPolygonsError;
import de.hft.stuttgart.citydoctor2.check.error.UnknownCheckError;
import de.hft.stuttgart.citydoctor2.check.error.XMLValidationError;
/**
* Visitor pattern interface to access errors. This is to determine the type of
......@@ -62,7 +68,15 @@ import de.hft.stuttgart.citydoctor2.check.error.UnknownCheckError;
*
*/
public interface ErrorVisitor {
public void visit(RingError err);
public void visit(PolygonError err);
public void visit(RingSelfIntersectionError err);
public void visit(PlanarityError err);
public void visit(PolygonHoleOutsideError err);
public void visit(NonManifoldEdgeError err);
......@@ -119,11 +133,9 @@ public interface ErrorVisitor {
public void visit(NotGroundError err);
public void visit(CheckError err);
public void visit(SchematronError err);
public void visit(SurfaceUnfragmentedError err);
public void visit(SurfaceFragmentedError err);
public void visit(DegeneratedRingError err);
......@@ -134,5 +146,11 @@ public interface ErrorVisitor {
public void visit(AttributeInvalidError err);
public void visit(PolygonWithoutSurfaceError err);
public void visit(CheckError err);
public void visit(SolidError err);
public void visit(XMLValidationError err);
}
......@@ -48,9 +48,10 @@ import de.hft.stuttgart.citydoctor2.check.error.RingTooFewPointsError;
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.SurfaceFragmentedError;
import de.hft.stuttgart.citydoctor2.check.error.TooFewPolygonsError;
import de.hft.stuttgart.citydoctor2.check.error.UnknownCheckError;
import de.hft.stuttgart.citydoctor2.check.error.XMLValidationError;
/**
* Visitor pattern interface used in the healing procedures. The modification
......@@ -188,7 +189,7 @@ public interface HealingMethod {
return false;
}
default boolean visit(SurfaceUnfragmentedError err, ModificationListener l) {
default boolean visit(SurfaceFragmentedError err, ModificationListener l) {
return false;
}
......@@ -199,6 +200,10 @@ public interface HealingMethod {
default boolean visit(PolygonWithoutSurfaceError err, ModificationListener l) {
return false;
}
default boolean visit(XMLValidationError err, ModificationListener l) {
return false;
}
public HealingMethod createNew();
......
......@@ -55,9 +55,10 @@ import de.hft.stuttgart.citydoctor2.check.error.RingTooFewPointsError;
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.SurfaceFragmentedError;
import de.hft.stuttgart.citydoctor2.check.error.TooFewPolygonsError;
import de.hft.stuttgart.citydoctor2.check.error.UnknownCheckError;
import de.hft.stuttgart.citydoctor2.check.error.XMLValidationError;
import de.hft.stuttgart.citydoctor2.datastructure.Edge;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
......@@ -89,7 +90,7 @@ import de.hft.stuttgart.quality.model.types.SolidSelfIntersectionError;
import de.hft.stuttgart.quality.model.types.SolidTooFewPolygonsError;
import de.hft.stuttgart.quality.model.types.ValidationResult;
public class QualityAdeErrorVisitor implements ErrorVisitor {
public class QualityAdeErrorVisitor extends AbstractErrorVisitor {
private final ValidationResult res;
......@@ -366,7 +367,7 @@ public class QualityAdeErrorVisitor implements ErrorVisitor {
}
@Override
public void visit(SurfaceUnfragmentedError err) {
public void visit(SurfaceFragmentedError err) {
// not translated
}
......@@ -403,5 +404,10 @@ public class QualityAdeErrorVisitor implements ErrorVisitor {
public void visit(PolygonWithoutSurfaceError err) {
// not translated
}
@Override
public void visit(XMLValidationError err) {
// not translated
}
}
......@@ -63,7 +63,7 @@ public class Requirement implements Serializable {
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_ROOF_UNFRAGMENTED = new Requirement("R_SE_BS_ROOF_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);
......@@ -83,6 +83,7 @@ public class Requirement implements Serializable {
defaultParameters.add(new DefaultParameter(UPPER_ANGLE_NAME, "135", Unit.DEGREE));
R_SE_BS_IS_WALL.parameters = Collections.unmodifiableList(defaultParameters);
defaultParameters = new ArrayList<>();
defaultParameters.add(new DefaultParameter(MAX_ANGLE_DEVIATION, "1", Unit.DEGREE));
R_SE_BS_ROOF_UNFRAGMENTED.parameters = Collections.unmodifiableList(defaultParameters);
......
......@@ -29,7 +29,7 @@ import de.hft.stuttgart.citydoctor2.utils.Localization;
*/
public enum Unit {
KWH("kWh", "kWh"), METER("m", "m"), SQUARE_METER("m²", "m2"), CUBIC_METER("m³", "m3"), RADIAN(Localization.getText("Unit.Radian"), "rad"), NONE("", null), DEGREE(Localization.getText("Unit.Degree"), "deg");
KWH("kWh", "kWh"), METER("m", "m"), SQUARE_METER("m²", "m2"), CUBIC_METER("m³", "m3"), RADIAN(Localization.getText("Unit.Radian"), "rad"), NONE("", ""), DEGREE(Localization.getText("Unit.Degree"), "deg");
private final String representation;
private final String gmlRep;
......
......@@ -18,9 +18,9 @@
*/
package de.hft.stuttgart.citydoctor2.check.error;
import de.hft.stuttgart.citydoctor2.check.CheckError;
import java.io.Serial;
import de.hft.stuttgart.citydoctor2.check.ErrorId;
import de.hft.stuttgart.citydoctor2.check.ErrorReport;
import de.hft.stuttgart.citydoctor2.check.ErrorType;
import de.hft.stuttgart.citydoctor2.check.ErrorVisitor;
import de.hft.stuttgart.citydoctor2.check.HealingMethod;
......@@ -28,47 +28,35 @@ import de.hft.stuttgart.citydoctor2.check.ModificationListener;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.GmlElement;
import java.io.Serial;
/**
* Error when all polygons are oriented wrong.
*
* @author Matthias Betz
*
*/
public class AllPolygonsWrongOrientationError implements CheckError {
public class AllPolygonsWrongOrientationError extends SolidError {
@Serial
private static final long serialVersionUID = 2263993313732858840L;
private final Geometry geom;
public AllPolygonsWrongOrientationError(Geometry geom) {
this.geom = geom;
}
public Geometry getGeometry() {
return geom;
super(geom);
}
@Override
public void accept(ErrorVisitor errorVisitor) {
super.accept(errorVisitor);
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
return super.accept(method, l) || method.visit(this, l);
}
@Override
public String toString() {
return "AllPolygonsWrongOrientationError [geom=" + geom + "]";
}
@Override
public void report(ErrorReport report) {
report.add(geom);
return "AllPolygonsWrongOrientationError [geom=" + getGeometry() + "]";
}
@Override
......
......@@ -18,7 +18,8 @@
*/
package de.hft.stuttgart.citydoctor2.check.error;
import de.hft.stuttgart.citydoctor2.check.CheckError;
import java.io.Serial;
import de.hft.stuttgart.citydoctor2.check.ErrorId;
import de.hft.stuttgart.citydoctor2.check.ErrorReport;
import de.hft.stuttgart.citydoctor2.check.ErrorType;
......@@ -29,8 +30,6 @@ import de.hft.stuttgart.citydoctor2.datastructure.GmlElement;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import java.io.Serial;
/**
* When two points are too close to each other and are consecutive in a linear
* ring, this error is created.
......@@ -38,25 +37,20 @@ import java.io.Serial;
* @author Matthias Betz
*
*/
public class ConsecutivePointSameError implements CheckError {
public class ConsecutivePointSameError extends RingError {
@Serial
private static final long serialVersionUID = -6355935751554777494L;
private final LinearRing lr;
private final Vertex p1;
private final Vertex p2;
public ConsecutivePointSameError(LinearRing lr, Vertex p1, Vertex p2) {
this.lr = lr;
super(lr);
this.p1 = p1;
this.p2 = p2;
}
public LinearRing getRing() {
return lr;
}
public Vertex getVertex1() {
return p1;
}
......@@ -67,22 +61,23 @@ public class ConsecutivePointSameError implements CheckError {
@Override
public void accept(ErrorVisitor errorVisitor) {
super.accept(errorVisitor);
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
return super.accept(method, l) || method.visit(this, l);
}
@Override
public String toString() {
return "ConsecutivePointSameError [lr=" + lr + ", p1=" + p1 + ", p2=" + p2 + "]";
return "ConsecutivePointSameError [lr=" + getRing() + ", p1=" + p1 + ", p2=" + p2 + "]";
}
@Override
public void report(ErrorReport report) {
report.add(lr);
super.report(report);
report.add("duplicate point 1", p1);
report.add("duplicate point 2", p2);
}
......
......@@ -18,7 +18,8 @@
*/
package de.hft.stuttgart.citydoctor2.check.error;
import de.hft.stuttgart.citydoctor2.check.CheckError;
import java.io.Serial;
import de.hft.stuttgart.citydoctor2.check.ErrorId;
import de.hft.stuttgart.citydoctor2.check.ErrorReport;
import de.hft.stuttgart.citydoctor2.check.ErrorType;
......@@ -28,37 +29,30 @@ import de.hft.stuttgart.citydoctor2.check.ModificationListener;
import de.hft.stuttgart.citydoctor2.datastructure.GmlElement;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import java.io.Serial;
public class DegeneratedRingError implements CheckError {
public class DegeneratedRingError extends RingSelfIntersectionError {
@Serial
private static final long serialVersionUID = 865493182529055651L;
private final LinearRing lr;
public DegeneratedRingError(LinearRing lr) {
this.lr = lr;
super(lr);
}
public LinearRing getRing() {
return lr;
}
@Override
public void accept(ErrorVisitor errorVisitor) {
super.accept(errorVisitor);
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
return super.accept(method, l) || method.visit(this, l);
}
@Override
public void report(ErrorReport report) {
report.add("type", "degenerated ring");
report.add(getRing());
super.report(report);
}
@Override
......
......@@ -21,7 +21,6 @@ package de.hft.stuttgart.citydoctor2.check.error;
import java.io.Serial;
import java.util.List;
import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.ErrorId;
import de.hft.stuttgart.citydoctor2.check.ErrorReport;
import de.hft.stuttgart.citydoctor2.check.ErrorType;
......@@ -39,30 +38,25 @@ import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
* @author Matthias Betz
*
*/
public class MultipleConnectedComponentsError implements CheckError {
public class MultipleConnectedComponentsError extends SolidError {
@Serial
private static final long serialVersionUID = 2152069835068857036L;
private final Geometry geom;
private final List<List<Polygon>> components;
public MultipleConnectedComponentsError(Geometry geom, List<List<Polygon>> components) {
this.geom = geom;
super(geom);
this.components = components;
}
public Geometry getGeometry() {
return geom;
}
public List<List<Polygon>> getComponents() {
return components;
}
@Override
public void report(ErrorReport report) {
report.add(geom);
super.report(report);
for (int i = 0; i < components.size(); i++) {
List<Polygon> polygons = components.get(i);
report.addPolygons("component nr: " + (i + 1), polygons);
......@@ -71,17 +65,18 @@ public class MultipleConnectedComponentsError implements CheckError {
@Override
public void accept(ErrorVisitor errorVisitor) {
super.accept(errorVisitor);
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
return super.accept(method, l) || method.visit(this, l);
}
@Override
public String toString() {
return "MultipleConnectedComponentsError [geom=" + geom + ", components=" + components + "]";
return "MultipleConnectedComponentsError [geom=" + getGeometry() + ", components=" + components + "]";
}
@Override
......
......@@ -18,7 +18,8 @@
*/
package de.hft.stuttgart.citydoctor2.check.error;
import de.hft.stuttgart.citydoctor2.check.CheckError;
import java.io.Serial;
import de.hft.stuttgart.citydoctor2.check.ErrorId;
import de.hft.stuttgart.citydoctor2.check.ErrorReport;
import de.hft.stuttgart.citydoctor2.check.ErrorType;
......@@ -29,32 +30,26 @@ import de.hft.stuttgart.citydoctor2.datastructure.GmlElement;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import java.io.Serial;
/**
* If an inner ring is with in the boundaries of another, this error is created.
*
* @author Matthias Betz
*
*/
public class NestedRingError implements CheckError {
public class NestedRingError extends PolygonError {
@Serial
private static final long serialVersionUID = -3396113374745830193L;
private final Polygon p;
private final LinearRing innerRing;
private final LinearRing withinRing;
public NestedRingError(Polygon p, LinearRing innerRing, LinearRing withinRing) {
this.p = p;
super(p);
this.innerRing = innerRing;
this.withinRing = withinRing;
}
public Polygon getPolygon() {
return p;
}
public LinearRing getInnerRing() {
return innerRing;
......@@ -66,23 +61,24 @@ public class NestedRingError implements CheckError {
@Override
public void report(ErrorReport report) {
report.add(p);
super.report(report);
report.add(innerRing);
}
@Override
public void accept(ErrorVisitor errorVisitor) {
super.accept(errorVisitor);
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
return super.accept(method, l) || method.visit(this, l);
}
@Override
public String toString() {
return "NestedRingError [p=" + p + ", innerRing=" + innerRing + "]";
return "NestedRingError [p=" + getPolygon() + ", innerRing=" + innerRing + "]";
}
@Override
......
......@@ -21,7 +21,6 @@ package de.hft.stuttgart.citydoctor2.check.error;
import java.io.Serial;
import java.util.List;
import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.ErrorId;
import de.hft.stuttgart.citydoctor2.check.ErrorReport;
import de.hft.stuttgart.citydoctor2.check.ErrorType;
......@@ -38,48 +37,44 @@ import de.hft.stuttgart.citydoctor2.datastructure.GmlElement;
* @author Matthias Betz
*
*/
public class NonManifoldEdgeError implements CheckError {
public class NonManifoldEdgeError extends SolidError {
@Serial
private static final long serialVersionUID = -6742948557014332402L;
private final List<Edge> edges;
private final Geometry geom;
public NonManifoldEdgeError(Geometry geom, List<Edge> edges) {
super(geom);
this.edges = edges;
this.geom = geom;
}
public List<Edge> getEdges() {
return edges;
}
public Geometry getGeometry() {
return geom;
}
@Override
public void report(ErrorReport report) {
report.add(geom);
super.report(report);
for (Edge e : edges) {
report.add(e);
}
}
@Override
public void accept(ErrorVisitor errorVisitor) {
super.accept(errorVisitor);
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
return super.accept(method, l) || method.visit(this, l);
}
@Override
public String toString() {
return "ManifoldEdgeError [edges=" + edges + ", geom=" + geom + "]";
return "ManifoldEdgeError [edges=" + edges + ", geom=" + getGeometry() + "]";
}
@Override
......
......@@ -21,7 +21,6 @@ package de.hft.stuttgart.citydoctor2.check.error;
import java.io.Serial;
import java.util.List;
import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.ErrorId;
import de.hft.stuttgart.citydoctor2.check.ErrorReport;
import de.hft.stuttgart.citydoctor2.check.ErrorType;
......@@ -40,17 +39,16 @@ import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
* @author Matthias Betz
*
*/
public class NonManifoldVertexError implements CheckError {
public class NonManifoldVertexError extends SolidError {
@Serial
private static final long serialVersionUID = -3915669943428175777L;
private final List<List<Polygon>> components;
private final Geometry geom;
private final Vertex v;
public NonManifoldVertexError(Geometry geom, List<List<Polygon>> components, Vertex v) {
this.geom = geom;
super(geom);
this.components = components;
this.v = v;
}
......@@ -59,17 +57,13 @@ public class NonManifoldVertexError implements CheckError {
return components;
}
public Geometry getGeometry() {
return geom;
}
public Vertex getVertex() {
return v;
}
@Override
public void report(ErrorReport report) {
report.add(geom);
super.report(report);
report.add(v);
for (int i = 0; i < components.size(); i++) {
List<Polygon> polygons = components.get(i);
......@@ -83,17 +77,18 @@ public class NonManifoldVertexError implements CheckError {
@Override
public void accept(ErrorVisitor errorVisitor) {
super.accept(errorVisitor);
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
return super.accept(method, l) || method.visit(this, l);
}
@Override
public String toString() {
return "NonManifoldVertexError [components=" + components + ", geom=" + geom + ", v=" + v + "]";
return "NonManifoldVertexError [components=" + components + ", geom=" + getGeometry() + ", v=" + v + "]";
}
@Override
......
......@@ -18,7 +18,8 @@
*/
package de.hft.stuttgart.citydoctor2.check.error;
import de.hft.stuttgart.citydoctor2.check.CheckError;
import java.io.Serial;
import de.hft.stuttgart.citydoctor2.check.ErrorId;
import de.hft.stuttgart.citydoctor2.check.ErrorReport;
import de.hft.stuttgart.citydoctor2.check.ErrorType;
......@@ -31,8 +32,6 @@ import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.math.Plane;
import de.hft.stuttgart.citydoctor2.utils.Localization;
import java.io.Serial;
/**
* Error object for planarity errors containing the polygon, the regression
* plane and the distance to the plane.
......@@ -40,18 +39,17 @@ import java.io.Serial;
* @author Matthias Betz
*
*/
public class NonPlanarPolygonDistancePlaneError implements CheckError {
public class NonPlanarPolygonDistancePlaneError extends PlanarityError {
@Serial
private static final long serialVersionUID = -3504364055236383519L;
private final Polygon p;
private final double distance;
private final Vertex v;
private final Plane plane;
public NonPlanarPolygonDistancePlaneError(Polygon p, double distance, Vertex v, Plane plane) {
this.p = p;
super(p);
this.distance = distance;
this.v = v;
this.plane = plane;
......@@ -61,10 +59,6 @@ public class NonPlanarPolygonDistancePlaneError implements CheckError {
return plane;
}
public Polygon getPolygon() {
return p;
}
public double getDistance() {
return distance;
}
......@@ -75,24 +69,25 @@ public class NonPlanarPolygonDistancePlaneError implements CheckError {
@Override
public void accept(ErrorVisitor errorVisitor) {
super.accept(errorVisitor);
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
return super.accept(method, l) || method.visit(this, l);
}
@Override
public void report(ErrorReport report) {
report.add(p);
super.report(report);
report.add(v);
report.add(Localization.getText("DistanceError.distanceFromPlane"), distance);
}
@Override
public String toString() {
return "NonPlanarPolygonDistancePlaneError [p=" + p + ", distance=" + distance + ", v=" + v + ", plane=" + plane + "]";
return "NonPlanarPolygonDistancePlaneError [p=" + getPolygon() + ", distance=" + distance + ", v=" + v + ", plane=" + plane + "]";
}
@Override
......
......@@ -18,7 +18,8 @@
*/
package de.hft.stuttgart.citydoctor2.check.error;
import de.hft.stuttgart.citydoctor2.check.CheckError;
import java.io.Serial;
import de.hft.stuttgart.citydoctor2.check.ErrorId;
import de.hft.stuttgart.citydoctor2.check.ErrorReport;
import de.hft.stuttgart.citydoctor2.check.ErrorType;
......@@ -28,8 +29,6 @@ import de.hft.stuttgart.citydoctor2.check.ModificationListener;
import de.hft.stuttgart.citydoctor2.datastructure.GmlElement;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import java.io.Serial;
/**
* When the normal of the triangles created from the triangulation of the
* polygon have a too large angle between them, this error is created.
......@@ -37,46 +36,42 @@ import java.io.Serial;
* @author Matthias Betz
*
*/
public class NonPlanarPolygonNormalsDeviation implements CheckError {
public class NonPlanarPolygonNormalsDeviation extends PlanarityError {
@Serial
private static final long serialVersionUID = 69073161885265794L;
private final Polygon p;
private final double deviation;
public NonPlanarPolygonNormalsDeviation(Polygon p, double deviation) {
this.p = p;
super(p);
this.deviation = deviation;
}
public Polygon getPolygon() {
return p;
}
public double getDeviation() {
return deviation;
}
@Override
public void report(ErrorReport report) {
report.add(p);
super.report(report);
report.add("normal deviation (in rad)", deviation);
}
@Override
public void accept(ErrorVisitor errorVisitor) {
super.accept(errorVisitor);
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
return super.accept(method, l) || method.visit(this, l);
}
@Override
public String toString() {
return "NormalDeviationError [p=" + p + ", deviation=" + deviation + "]";
return "NormalDeviationError [p=" + getPolygon() + ", deviation=" + deviation + "]";
}
@Override
......
......@@ -18,9 +18,9 @@
*/
package de.hft.stuttgart.citydoctor2.check.error;
import de.hft.stuttgart.citydoctor2.check.CheckError;
import java.io.Serial;
import de.hft.stuttgart.citydoctor2.check.ErrorId;
import de.hft.stuttgart.citydoctor2.check.ErrorReport;
import de.hft.stuttgart.citydoctor2.check.ErrorType;
import de.hft.stuttgart.citydoctor2.check.ErrorVisitor;
import de.hft.stuttgart.citydoctor2.check.HealingMethod;
......@@ -28,47 +28,35 @@ import de.hft.stuttgart.citydoctor2.check.ModificationListener;
import de.hft.stuttgart.citydoctor2.datastructure.GmlElement;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import java.io.Serial;
/**
* When a linear ring has a near zero area this error is created.
*
* @author Matthias Betz
*
*/
public class NullAreaError implements CheckError {
public class NullAreaError extends RingError {
@Serial
private static final long serialVersionUID = 1358910429039553687L;
private final LinearRing lr;
public NullAreaError(LinearRing lr) {
this.lr = lr;
}
public LinearRing getRing() {
return lr;
}
@Override
public void report(ErrorReport report) {
report.add(lr);
super(lr);
}
@Override
public void accept(ErrorVisitor errorVisitor) {
super.accept(errorVisitor);
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
return super.accept(method, l) || method.visit(this, l);
}
@Override
public String toString() {
return "NullAreaError [lr=" + lr + "]";
return "NullAreaError [lr=" + getRing() + "]";
}
@Override
......
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