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
......@@ -29,6 +29,7 @@ import de.hft.stuttgart.citydoctor2.check.CheckId;
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.checks.util.CollectionUtils;
import de.hft.stuttgart.citydoctor2.checks.util.UnfragmentedCheck;
import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface;
......@@ -60,8 +61,13 @@ public class RoofSurfaceUnfragmentedCheck extends Check {
}
@Override
public void init(Map<String, String> params, ParserConfiguration config) {
String maxAngleString = params.get(MAX_ANGLE_DEVIATION);
public void init(Map<CheckId, Map<String, String>> params, ParserConfiguration config) {
Map<String, String> localParameters = params.get(getCheckId());
if (localParameters == null) {
// no parameters
return;
}
String maxAngleString = localParameters.get(MAX_ANGLE_DEVIATION);
if (maxAngleString != null) {
maxAngleDeviation = Math.toRadians(Double.parseDouble(maxAngleString));
}
......@@ -75,6 +81,10 @@ public class RoofSurfaceUnfragmentedCheck extends Check {
}
// only use lod1 and lod2 polygons
CheckResult cr = UnfragmentedCheck.checkForFragmentedBoundarySurfaces(this, bs, maxAngleDeviation);
if (cr.getResultStatus() == ResultStatus.OK) {
// check if neighboring roof surfaces have the same average normal
// they should be merged
}
bs.addCheckResult(cr);
}
......
......@@ -20,7 +20,9 @@ package de.hft.stuttgart.citydoctor2.checks.util;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.IntStream;
public class CollectionUtils {
......@@ -40,4 +42,11 @@ public class CollectionUtils {
return set;
}
public static <T> List<List<T>> partition(List<T> list, int chunkSize){
return IntStream.iterate(0, i-> i < list.size(), i-> i+ chunkSize)
.mapToObj(i -> list.subList(i, Math.min(i+chunkSize, list.size())))
.toList();
}
}
......@@ -21,6 +21,7 @@ package de.hft.stuttgart.citydoctor2.checks.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
......@@ -83,18 +84,26 @@ public class SelfIntersectionUtil {
private SelfIntersectionUtil() {
}
public static List<PolygonIntersection> calculateSolidSelfIntersection(Geometry g) {
public static List<PolygonIntersection> calculateSolidSelfIntersection(Geometry g, double delta) {
List<TesselatedPolygon> tesselatedPolygons = new ArrayList<>();
for (Polygon p : g.getPolygons()) {
tesselatedPolygons.add(EarcutTesselator.tesselatePolygon(p));
TesselatedPolygon tessPolygon = EarcutTesselator.tesselatePolygon(p);
for (Iterator<Triangle3d> iterator = tessPolygon.getTriangles().iterator(); iterator.hasNext();) {
Triangle3d t = iterator.next();
if (!t.hasMinExtent(delta)) {
iterator.remove();
}
}
tesselatedPolygons.add(tessPolygon);
}
List<PolygonIntersection> intersections = new ArrayList<>();
for (int i = 0; i < tesselatedPolygons.size() - 1; i++) {
TesselatedPolygon p1 = tesselatedPolygons.get(i);
for (int j = i + 1; j < tesselatedPolygons.size(); j++) {
TesselatedPolygon p2 = tesselatedPolygons.get(j);
GeometrySelfIntersection intersection = doPolygonsIntersect(p1, p2);
GeometrySelfIntersection intersection = doPolygonsIntersect(p1, p2, delta);
if (intersection != null) {
intersections.add(PolygonIntersection.triangles(intersection.t1(), intersection.t2()));
}
......@@ -102,9 +111,9 @@ public class SelfIntersectionUtil {
}
return intersections;
}
public static GeometrySelfIntersection doesSolidSelfIntersect(Geometry g) {
return selfIntersectionJava(g);
public static GeometrySelfIntersection doesSolidSelfIntersect(Geometry g, double epsilon) {
return selfIntersectionJava(g, epsilon);
}
public static List<PolygonIntersection> doesSolidSelfIntersect2(Geometry g) {
......@@ -404,7 +413,7 @@ public class SelfIntersectionUtil {
return sign != 0;
}
private static GeometrySelfIntersection selfIntersectionJava(Geometry g) {
private static GeometrySelfIntersection selfIntersectionJava(Geometry g, double epsilon) {
List<TesselatedPolygon> tessPolys = new ArrayList<>();
for (Polygon p : g.getPolygons()) {
tessPolys.add(JoglTesselator.tesselatePolygon(p));
......@@ -413,7 +422,7 @@ public class SelfIntersectionUtil {
TesselatedPolygon p1 = tessPolys.get(i);
for (int j = i + 1; j < tessPolys.size(); j++) {
TesselatedPolygon p2 = tessPolys.get(j);
GeometrySelfIntersection intersection = doPolygonsIntersect(p1, p2);
GeometrySelfIntersection intersection = doPolygonsIntersect(p1, p2, epsilon);
if (intersection != null) {
return intersection;
}
......@@ -422,12 +431,12 @@ public class SelfIntersectionUtil {
return null;
}
private static GeometrySelfIntersection doPolygonsIntersect(TesselatedPolygon p1, TesselatedPolygon p2) {
private static GeometrySelfIntersection doPolygonsIntersect(TesselatedPolygon p1, TesselatedPolygon p2, double epsilon) {
for (int p1Index = 0; p1Index < p1.getTriangles().size(); p1Index++) {
Triangle3d t1 = p1.getTriangles().get(p1Index);
for (int p2Index = 0; p2Index < p2.getTriangles().size(); p2Index++) {
Triangle3d t1 = p1.getTriangles().get(p1Index);
Triangle3d t2 = p2.getTriangles().get(p2Index);
if (t1.doesIntersect(t2)) {
if (t1.doesIntersect(t2, epsilon)) {
logger.trace("{} intersects {}", t1, t2);
logger.trace("GML-ID: {} intersects {}", t1.getPartOf().getOriginal().getGmlId(),
t2.getPartOf().getOriginal().getGmlId());
......
......@@ -24,7 +24,7 @@ import java.util.List;
import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.error.SurfaceUnfragmentedError;
import de.hft.stuttgart.citydoctor2.check.error.SurfaceFragmentedError;
import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
......@@ -75,7 +75,7 @@ public class UnfragmentedCheck {
double dot = averageNormal.dot(n);
double acos = Math.acos(dot);
if (acos > delta) {
SurfaceUnfragmentedError err = new SurfaceUnfragmentedError(bs, acos);
SurfaceFragmentedError err = new SurfaceFragmentedError(bs, acos);
return new CheckResult(c, ResultStatus.ERROR, err);
}
}
......
......@@ -29,6 +29,10 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import de.hft.stuttgart.citydoctor2.datastructure.CityFurniture;
import de.hft.stuttgart.citydoctor2.datastructure.GenericCityObject;
import de.hft.stuttgart.citydoctor2.datastructure.Tunnel;
import de.hft.stuttgart.citydoctor2.datastructure.TunnelPart;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
......@@ -153,6 +157,12 @@ public class XmlStreamReporter implements StreamReporter {
reportWater(wo);
} else if (co instanceof LandObject lo) {
reportLand(lo);
} else if (co instanceof Tunnel to) {
reportTunnel(to);
} else if (co instanceof CityFurniture cf) {
reportCityFurniture(cf);
} else if (co instanceof GenericCityObject gco) {
reportGenericCityObject(gco);
} else {
throw new IllegalStateException("Not reportable CityObject found: " + co.getClass().getSimpleName());
}
......@@ -196,6 +206,24 @@ public class XmlStreamReporter implements StreamReporter {
report.getValidationResults().getBuildingReports().add(fr);
}
private void reportTunnel(Tunnel to) {
FeatureReport fr = createCityObjectReportNode(to);
for (TunnelPart tp : to.getTunnelParts()) {
reportMap.put(tp.getGmlId().getGmlString(), fr);
}
report.getValidationResults().getTunnelReports().add(fr);
}
private void reportCityFurniture(CityFurniture cf) {
FeatureReport fr = createCityObjectReportNode(cf);
report.getValidationResults().getCityFurnitureReports().add(fr);
}
private void reportGenericCityObject(GenericCityObject gco) {
FeatureReport fr = createCityObjectReportNode(gco);
report.getValidationResults().getGenericCityObjectReports().add(fr);
}
private FeatureReport createCityObjectReportNode(CityObject co) {
FeatureReport fr = new FeatureReport();
reportMap.put(co.getGmlId().getGmlString(), fr);
......@@ -257,6 +285,9 @@ public class XmlStreamReporter implements StreamReporter {
createStatistics(globalErrorCount, report.getValidationResults().getTransportationReports());
createStatistics(globalErrorCount, report.getValidationResults().getVegetationReports());
createStatistics(globalErrorCount, report.getValidationResults().getWaterReports());
createStatistics(globalErrorCount, report.getValidationResults().getTunnelReports());
createStatistics(globalErrorCount, report.getValidationResults().getCityFurnitureReports());
createStatistics(globalErrorCount, report.getValidationResults().getGenericCityObjectReports());
addStatisticsObjects(stats.getErrorStats(), globalErrorCount);
report.setGlobalStatistics(stats);
......@@ -271,6 +302,9 @@ public class XmlStreamReporter implements StreamReporter {
modelStats.setNumTransportation(report.getValidationResults().getTransportationReports().size());
modelStats.setNumVegetation(report.getValidationResults().getVegetationReports().size());
modelStats.setNumWaterObjects(report.getValidationResults().getWaterReports().size());
modelStats.setNumTunnelObjects(report.getValidationResults().getTunnelReports().size());
modelStats.setNumCityFurniture(report.getValidationResults().getCityFurnitureReports().size());
modelStats.setNumGenericCityObjects(report.getValidationResults().getGenericCityObjectReports().size());
return modelStats;
}
......@@ -285,6 +319,12 @@ public class XmlStreamReporter implements StreamReporter {
globErrStats
.setNumErrorVegetation(getNumberOfErrorFeatures(report.getValidationResults().getVegetationReports()));
globErrStats.setNumErrorWaterObjects(getNumberOfErrorFeatures(report.getValidationResults().getWaterReports()));
globErrStats.setNumErrorTunnelObjects(
getNumberOfErrorFeatures(report.getValidationResults().getTunnelReports()));
globErrStats.setNumErrorCityFurniture(
getNumberOfErrorFeatures(report.getValidationResults().getCityFurnitureReports()));
globErrStats.setNumErrorGenericCityObjects(
getNumberOfErrorFeatures(report.getValidationResults().getGenericCityObjectReports()));
return globErrStats;
}
......
......@@ -24,13 +24,7 @@ import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.ValidationConfiguration;
import de.hft.stuttgart.citydoctor2.checkresult.utility.CheckReportWriteException;
import de.hft.stuttgart.citydoctor2.checks.Checks;
import de.hft.stuttgart.citydoctor2.datastructure.BridgeObject;
import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.TransportationObject;
import de.hft.stuttgart.citydoctor2.datastructure.Vegetation;
import de.hft.stuttgart.citydoctor2.datastructure.WaterObject;
/**
*
......@@ -42,24 +36,8 @@ public class XmlValidationReporter implements Reporter {
@Override
public void writeReport(Checks checks, OutputStream filePath, CityDoctorModel model, ValidationConfiguration config) throws CheckReportWriteException {
StreamReporter streamReporter = new XmlStreamReporter(filePath, model.getFileName(), config);
for (BridgeObject bo : model.getBridges()) {
streamReporter.report(bo);
}
for (Building b : model.getBuildings()) {
streamReporter.report(b);
}
for (TransportationObject to : model.getTransportation()) {
streamReporter.report(to);
}
for (CityObject lo : model.getLand()) {
streamReporter.report(lo);
}
for (Vegetation v : model.getVegetation()) {
streamReporter.report(v);
}
for (WaterObject wo : model.getWater()) {
streamReporter.report(wo);
}
model.createFeatureStream().forEach(streamReporter::report);
for (CheckError err : model.getGlobalErrors()) {
streamReporter.reportGlobalError(err);
}
......
......@@ -29,6 +29,18 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding;
import de.hft.stuttgart.citydoctor2.datastructure.AbstractFurniture;
import de.hft.stuttgart.citydoctor2.datastructure.AbstractRoom;
import de.hft.stuttgart.citydoctor2.datastructure.AbstractTunnel;
import de.hft.stuttgart.citydoctor2.datastructure.BridgeConstructiveElement;
import de.hft.stuttgart.citydoctor2.datastructure.BuildingUnit;
import de.hft.stuttgart.citydoctor2.datastructure.CityFurniture;
import de.hft.stuttgart.citydoctor2.datastructure.GenericCityObject;
import de.hft.stuttgart.citydoctor2.datastructure.Storey;
import de.hft.stuttgart.citydoctor2.datastructure.Tunnel;
import de.hft.stuttgart.citydoctor2.datastructure.TunnelConstructiveElement;
import de.hft.stuttgart.citydoctor2.datastructure.TunnelPart;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
......@@ -105,6 +117,18 @@ public class PdfStreamReporter implements StreamReporter {
private int numErrorLand;
private int numOkLand;
private Section tunnel;
private int numErrorTunnel;
private int numOkTunnel;
private Section cityFurniture;
private int numErrorCityFurniture;
private int numOkCityFurniture;
private Section genericCityObject;
private int numErrorGenericCityObject;
private int numOkGenericCityObject;
private Section globalErrors;
private final Map<String, Section> sectionMap = new HashMap<>();
......@@ -186,6 +210,12 @@ public class PdfStreamReporter implements StreamReporter {
reportWater(co, hasError);
} else if (co instanceof LandObject) {
reportLand(co, hasError);
} else if (co instanceof Tunnel) {
reportTunnel(co, hasError);
} else if (co instanceof CityFurniture) {
reportCityFurniture(co, hasError);
} else if (co instanceof GenericCityObject) {
reportGenericCityObject(co, hasError);
} else {
throw new IllegalStateException("Unknown City Object found: " + co.getClass());
}
......@@ -237,6 +267,8 @@ public class PdfStreamReporter implements StreamReporter {
bSection.setHeadlineColor(OK_COLOR);
}
writeErrorForCityObject(co, bSection);
BridgeObject bo = (BridgeObject) co;
writeCheckResultForBridgeObject(bo, bSection);
}
private void reportTrans(CityObject co, boolean hasError) {
......@@ -253,10 +285,6 @@ public class PdfStreamReporter implements StreamReporter {
tSection.setHeadlineColor(OK_COLOR);
}
writeErrorForCityObject(co, tSection);
TransportationObject to = (TransportationObject) co;
for (TransportationObject transO : to.getChildren()) {
writeCheckResultForTransportationObject(transO, tSection);
}
}
private void reportVegetation(CityObject co, boolean hasError) {
......@@ -282,22 +310,74 @@ public class PdfStreamReporter implements StreamReporter {
Section bSection = buildings.createSubSection(co.getGmlId().getGmlString());
sectionMap.put(co.getGmlId().getGmlString(), bSection);
if (hasError) {
numErrorBuildings++;
bSection.setHeadlineColor(ERROR_COLOR);
} else {
numOkBuildings++;
bSection.setHeadlineColor(OK_COLOR);
}
writeErrorForCityObject(co, bSection);
Building b = (Building) co;
for (BuildingPart bp : b.getBuildingParts()) {
if (containsError(bp)) {
numErrorBuildings++;
} else {
numOkBuildings++;
}
sectionMap.put(bp.getGmlId().getGmlString(), bSection);
writeCheckResultForBuildingPart(bp, bSection);
writeCheckResultForAbstractBuilding(bp, bSection);
}
for (BoundarySurface bs : b.getBoundarySurfaces()) {
writeCheckResultForBoundarySurface(bs, bSection);
writeCheckResultForAbstractBuilding(b, bSection);
}
private void reportTunnel(CityObject co, boolean hasError) {
if (tunnel == null) {
tunnel = vr.createSubSection("Tunnel");
}
for (Installation bi : b.getBuildingInstallations()) {
writeCheckResultForInstallation(bi, bSection);
Section tSection = tunnel.createSubSection(co.getGmlId().getGmlString());
sectionMap.put(co.getGmlId().getGmlString(), tSection);
if (hasError) {
numErrorTunnel++;
tSection.setHeadlineColor(ERROR_COLOR);
} else {
numOkTunnel++;
tSection.setHeadlineColor(OK_COLOR);
}
writeErrorForCityObject(co, tSection);
Tunnel t = (Tunnel) co;
writeCheckResultForAbstractTunnel(t, tSection);
}
private void reportCityFurniture(CityObject co, boolean hasError) {
if (cityFurniture == null) {
cityFurniture = vr.createSubSection("CityFurniture");
}
Section cfSection = cityFurniture.createSubSection(co.getGmlId().getGmlString());
sectionMap.put(co.getGmlId().getGmlString(), cfSection);
if (hasError) {
numErrorCityFurniture++;
cfSection.setHeadlineColor(ERROR_COLOR);
} else {
numOkCityFurniture++;
cfSection.setHeadlineColor(OK_COLOR);
}
writeErrorForCityObject(co, cfSection);
}
private void reportGenericCityObject(CityObject co, boolean hasError) {
if (genericCityObject == null) {
genericCityObject = vr.createSubSection("GenericCityObject");
}
Section gcSection = genericCityObject.createSubSection(co.getGmlId().getGmlString());
sectionMap.put(co.getGmlId().getGmlString(), gcSection);
if (hasError) {
numErrorGenericCityObject++;
gcSection.setHeadlineColor(ERROR_COLOR);
} else {
numOkGenericCityObject++;
gcSection.setHeadlineColor(OK_COLOR);
}
writeErrorForCityObject(co, gcSection);
}
private void writeCheckResultForInstallation(Installation bi, Section root) {
......@@ -308,21 +388,162 @@ public class PdfStreamReporter implements StreamReporter {
}
}
private void writeCheckResultForTransportationObject(TransportationObject to, Section root) {
Map<CheckId, CheckResult> results = to.getAllCheckResults();
private void writeCheckResultForAbstractBuilding(AbstractBuilding ab, Section root) {
Map<CheckId, CheckResult> results = ab.getAllCheckResults();
writeCheckResults(results.values(), root);
for (Geometry geom : ab.getGeometries()) {
writeCheckResultForGeometry(geom, root);
}
for (AbstractRoom ar : ab.getBuildingRooms()) {
writeCheckResultForRoom(ar, root);
}
for (AbstractFurniture af : ab.getBuildingRoomFurnitureList()) {
writeCheckResultForAbstractFurniture(af, root);
}
for (Storey s : ab.getBuildingStoreys()) {
writeCheckResultForStorey(s, root);
}
for (BuildingUnit bu : ab.getBuildingUnits()) {
writeCheckResultForBuildingUnit(bu, root);
}
for (BoundarySurface bs : ab.getBoundarySurfaces()) {
writeCheckResultForBoundarySurface(bs, root);
}
for (Installation bi : ab.getBuildingInstallations()) {
writeCheckResultForInstallation(bi, root);
}
}
private void writeCheckResultForBridgeObject(BridgeObject bo, Section root) {
Map<CheckId, CheckResult> results = bo.getAllCheckResults();
writeCheckResults(results.values(), root);
for (BridgeObject part : bo.getParts()) {
if (containsError(part)) {
numErrorBridge++;
} else {
numOkBridge++;
}
sectionMap.put(bo.getGmlId().getGmlString(), root);
writeCheckResultForBridgeObject(part, root);
}
for (Geometry geom : bo.getGeometries()) {
writeCheckResultForGeometry(geom, root);
}
for (AbstractRoom ar : bo.getBridgeRooms()) {
writeCheckResultForRoom(ar, root);
}
for (AbstractFurniture af : bo.getBridgeFurniture()) {
writeCheckResultForAbstractFurniture(af, root);
}
for (BridgeConstructiveElement bce : bo.getConstructiveElements()) {
writeCheckResultForBridgeConstructiveElement(bce, root);
}
for (BoundarySurface bs : bo.getBoundarySurfaces()) {
writeCheckResultForBoundarySurface(bs, root);
}
for (Installation bi : bo.getBridgeInstallations()) {
writeCheckResultForInstallation(bi, root);
}
}
private void writeCheckResultForStorey(Storey s, Section root) {
Map<CheckId, CheckResult> results = s.getAllCheckResults();
writeCheckResults(results.values(), root);
for (Geometry geom : s.getGeometries()) {
writeCheckResultForGeometry(geom, root);
}
for (AbstractRoom ar : s.getBuildingRooms()) {
writeCheckResultForRoom(ar, root);
}
for (BuildingUnit bu : s.getBuildingUnits()) {
writeCheckResultForBuildingUnit(bu, root);
}
for (AbstractFurniture af : s.getBuildingRoomFurnitureList()) {
writeCheckResultForAbstractFurniture(af, root);
}
for (BoundarySurface bs : s.getBoundarySurfaces()) {
writeCheckResultForBoundarySurface(bs, root);
}
for (Installation bi : s.getBuildingInstallations()) {
writeCheckResultForInstallation(bi, root);
}
}
private void writeCheckResultForBuildingUnit(BuildingUnit bu, Section root) {
Map<CheckId, CheckResult> results = bu.getAllCheckResults();
writeCheckResults(results.values(), root);
for (Geometry geom : to.getGeometries()) {
for (Geometry geom : bu.getGeometries()) {
writeCheckResultForGeometry(geom, root);
}
for (AbstractRoom ar : bu.getBuildingRooms()) {
writeCheckResultForRoom(ar, root);
}
for (Storey s : bu.getStoreys()) {
writeCheckResultForStorey(s, root);
}
for (AbstractFurniture af : bu.getBuildingRoomFurnitureList()) {
writeCheckResultForAbstractFurniture(af, root);
}
for (BoundarySurface bs : bu.getBoundarySurfaces()) {
writeCheckResultForBoundarySurface(bs, root);
}
for (Installation bi : bu.getBuildingInstallations()) {
writeCheckResultForInstallation(bi, root);
}
}
private void writeCheckResultForAbstractTunnel(AbstractTunnel at, Section root) {
Map<CheckId, CheckResult> results = at.getAllCheckResults();
writeCheckResults(results.values(), root);
for (TunnelPart tp : at.getTunnelParts()) {
if (containsError(tp)) {
numErrorTunnel++;
} else {
numOkTunnel++;
}
sectionMap.put(tp.getGmlId().getGmlString(), root);
writeCheckResultForAbstractTunnel(tp, root);
}
for (Geometry geom : at.getGeometries()) {
writeCheckResultForGeometry(geom, root);
}
for (AbstractRoom ar : at.getTunnelHollows()) {
writeCheckResultForRoom(ar, root);
}
for (TunnelConstructiveElement te : at.getTunnelConstructiveElements()) {
writeCheckResultForTunnelConstructiveElement(te, root);
}
for (AbstractFurniture tf : at.getTunnelFurniture()) {
writeCheckResultForAbstractFurniture(tf, root);
}
for (BoundarySurface bs : at.getBoundarySurfaces()) {
writeCheckResultForBoundarySurface(bs, root);
}
for (Installation bi : at.getTunnelInstallations()) {
writeCheckResultForInstallation(bi, root);
}
}
private void writeCheckResultForTunnelConstructiveElement(TunnelConstructiveElement te, Section root) {
Map<CheckId, CheckResult> results = te.getAllCheckResults();
writeCheckResults(results.values(), root);
for (Geometry geom : te.getGeometries()) {
writeCheckResultForGeometry(geom, root);
}
for (BoundarySurface bs : te.getBoundarySurfaces()) {
writeCheckResultForBoundarySurface(bs, root);
}
}
private void writeCheckResultForBuildingPart(BuildingPart bp, Section root) {
Map<CheckId, CheckResult> results = bp.getAllCheckResults();
private void writeCheckResultForBridgeConstructiveElement(BridgeConstructiveElement bce, Section root) {
Map<CheckId, CheckResult> results = bce.getAllCheckResults();
writeCheckResults(results.values(), root);
for (Geometry geom : bp.getGeometries()) {
for (Geometry geom : bce.getGeometries()) {
writeCheckResultForGeometry(geom, root);
}
for (BoundarySurface bs : bp.getBoundarySurfaces()) {
for (BoundarySurface bs : bce.getBoundarySurfaces()) {
writeCheckResultForBoundarySurface(bs, root);
}
}
......@@ -343,6 +564,31 @@ public class PdfStreamReporter implements StreamReporter {
}
}
private void writeCheckResultForAbstractFurniture(AbstractFurniture af, Section root) {
Map<CheckId, CheckResult> results = af.getAllCheckResults();
writeCheckResults(results.values(), root);
for (Geometry geom : af.getGeometries()) {
writeCheckResultForGeometry(geom, root);
}
for (BoundarySurface bs : af.getBoundarySurfaces()) {
writeCheckResultForBoundarySurface(bs, root);
}
}
private void writeCheckResultForRoom(AbstractRoom ar, Section root) {
Map<CheckId, CheckResult> results = ar.getAllCheckResults();
writeCheckResults(results.values(), root);
for (Geometry geom : ar.getGeometries()) {
writeCheckResultForGeometry(geom, root);
}
for (Installation in : ar.getRoomInstallations()) {
writeCheckResultForInstallation(in, root);
}
for (BoundarySurface bs : ar.getBoundarySurfaces()) {
writeCheckResultForBoundarySurface(bs, root);
}
}
private void writeCheckResultForOpening(Opening o, Section root) {
Map<CheckId, CheckResult> results = o.getAllCheckResults();
writeCheckResults(results.values(), root);
......@@ -392,9 +638,10 @@ public class PdfStreamReporter implements StreamReporter {
@Override
public void finishReport() throws CheckReportWriteException {
if (buildings != null) {
countFinishedReportBuildings();
}
//if (buildings != null) {
// countFinishedReportBuildings();
//}
int numBuildings = numErrorBuildings + numOkBuildings;
if (numBuildings > 0) {
statistics.addDistributionBar("Buildings", numErrorBuildings, numOkBuildings);
......@@ -425,6 +672,21 @@ public class PdfStreamReporter implements StreamReporter {
statistics.addDistributionBar("Land Objects", numErrorLand, numOkLand);
}
int numTunnel = numErrorTunnel + numOkTunnel;
if (numTunnel > 0) {
statistics.addDistributionBar("Tunnel Objects", numErrorTunnel, numOkTunnel);
}
int numCityFurniture = numErrorCityFurniture + numOkCityFurniture;
if (numCityFurniture > 0) {
statistics.addDistributionBar("City Furniture", numErrorCityFurniture, numOkCityFurniture);
}
int numGenericCityObjects = numErrorGenericCityObject + numOkGenericCityObject;
if (numGenericCityObjects > 0) {
statistics.addDistributionBar("Generic City Objects", numErrorGenericCityObject, numOkGenericCityObject);
}
statistics.addTextElement("Error Statistics:");
for (Entry<ErrorId, AtomicInteger> e : errorStatistics.entrySet()) {
statistics.add10PtTextElement(e.getKey().toString() + ": " + e.getValue().intValue(), 10);
......@@ -432,24 +694,6 @@ public class PdfStreamReporter implements StreamReporter {
report.save(outFile);
}
private void countFinishedReportBuildings() {
for (Section s : buildings.getSubSections()) {
if (!s.hasErrors()) {
numOkBuildings++;
// building has no errors, no table
continue;
}
numErrorBuildings++;
Table t = new Table(2);
t.setTableColumnWidth(75, 25);
t.setTitle("Error", "Count");
for (Entry<String, AtomicInteger> e : s.getStats().getErrorCounts().entrySet()) {
t.addRow(e.getKey(), e.getValue().toString());
}
s.addTable(1, t);
}
}
@Override
public void reportGlobalError(CheckError err) {
AtomicInteger errorCount = errorStatistics.computeIfAbsent(err.getErrorId(), k -> new AtomicInteger(0));
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configuration>
<Configuration status="INFO">
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout
pattern="[%-5level] %d{HH:mm:ss.SSS} %c{1} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="debug" additivity="false">
<AppenderRef ref="console" />
</Root>
<Logger name="com.zaxxer.hikari" level="INFO" additivity="false">
<AppenderRef ref="console"/>
</Logger>
</Loggers>
</Configuration>
\ No newline at end of file
/*-
* 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
......@@ -18,28 +18,38 @@
*/
package de.hft.stuttgart.citydoctor2.check;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import org.apache.commons.io.FileUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import de.hft.stuttgart.citydoctor2.CityDoctorValidation;
import de.hft.stuttgart.citydoctor2.checkresult.CheckReport;
import de.hft.stuttgart.citydoctor2.checkresult.GlobalErrorStatistics;
import de.hft.stuttgart.citydoctor2.checkresult.GlobalStatistics;
import de.hft.stuttgart.citydoctor2.checkresult.ModelStatistics;
import de.hft.stuttgart.citydoctor2.checkresult.utility.CheckReportParseException;
import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.exceptions.CityDoctorWriteException;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParser;
import de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
/**
*
* @author Matthias Betz
*
*/
public class CheckerTest {
......@@ -55,7 +65,7 @@ public class CheckerTest {
"src/test/resources/SimpleSolid_SrefBS_SchematronTest.gml", config.getParserConfiguration());
Checker checker = new Checker(config, model);
checker.runChecks();
for (Building b : model.getBuildings()) {
for (Building b : model.getBuildings().toList()) {
if (b.getGmlId().getGmlString().equals("_Simple_BD.1")) {
assertTrue(b.containsAnyError());
} else {
......@@ -66,7 +76,8 @@ public class CheckerTest {
}
@Test
public void testChecker() throws CityGmlParseException, IOException, InvalidGmlFileException, CityDoctorWriteException {
public void testChecker()
throws CityGmlParseException, IOException, InvalidGmlFileException, CityDoctorWriteException {
File f = folder.newFile();
File f2 = folder.newFile();
......@@ -88,7 +99,8 @@ public class CheckerTest {
}
@Test
public void testStreaming() throws CityGmlParseException, IOException, InvalidGmlFileException, CityDoctorWriteException {
public void testStreaming()
throws CityGmlParseException, IOException, InvalidGmlFileException, CityDoctorWriteException {
File f = folder.newFile();
File f2 = folder.newFile();
File f3 = folder.newFile();
......@@ -114,4 +126,86 @@ public class CheckerTest {
f3.delete();
}
}
@Test
public void testStreamingWithXMLValidation() throws CityGmlParseException, IOException, InvalidGmlFileException,
CityDoctorWriteException, CheckReportParseException {
File f2 = folder.newFile();
try {
String[] args = new String[6];
args[0] = "-in";
args[1] = "src/test/resources/SimpleSolid_SrefBS_XMLInvalid.gml";
args[2] = "-config";
args[3] = "src/test/resources/testConfigWithStreamingWithValidation.yml";
args[4] = "-xmlReport";
args[5] = f2.getAbsolutePath();
CityDoctorValidation.main(args);
assertTrue(f2.exists());
CheckReport checkReport = CheckReport.load(f2.toPath());
assertEquals(1, checkReport.getValidationResults().getGlobalErrors().size());
} finally {
f2.delete();
}
}
@Test
public void testReportCreation() throws IOException, CityGmlParseException, InvalidGmlFileException {
Path tmpDir = null;
try {
tmpDir = Files.createTempDirectory("testTmp");
tmpDir.toFile().deleteOnExit();
Path xmlPath = tmpDir.resolve("report.xml");
Path pdfPath = tmpDir.resolve("report.pdf");
File features = new File("src/test/resources/feature_types.gml");
CityDoctorModel model = CityGmlParser.nestedCityGmlFileParse(features.toString(),
new ParserConfiguration(8, false));
assertNotNull(model);
Checker checker = new Checker(model);
checker.runChecks();
checker.writeXmlReport(xmlPath.toString());
checker.writePdfReport(pdfPath.toString());
assertTrue(Files.exists(xmlPath));
assertTrue(Files.exists(pdfPath));
try {
CheckReport report = CheckReport.load(xmlPath.toString());
assertNotNull(report);
GlobalStatistics globalStatistics = report.getGlobalStatistics();
assertNotNull(globalStatistics);
ModelStatistics modelStats = globalStatistics.getModelStats();
assertNotNull(modelStats);
assertEquals(1, modelStats.getNumBuildings());
assertEquals(1, modelStats.getNumVegetation());
assertEquals(1, modelStats.getNumTransportation());
assertEquals(1, modelStats.getNumTunnelObjects());
assertEquals(1, modelStats.getNumBridgeObjects());
assertEquals(1, modelStats.getNumWaterObjects());
assertEquals(1, modelStats.getNumLandObjects());
assertEquals(1, modelStats.getNumCityFurniture());
assertEquals(1, modelStats.getNumGenericCityObjects());
GlobalErrorStatistics globError = globalStatistics.getGlobalErrorStats();
assertNotNull(globError);
assertEquals(0, globError.getNumErrorBuildings());
assertEquals(0, globError.getNumErrorVegetation());
assertEquals(0, globError.getNumErrorTransportation());
assertEquals(0, globError.getNumErrorTunnelObjects());
assertEquals(0, globError.getNumErrorBridgeObjects());
assertEquals(0, globError.getNumErrorWaterObjects());
assertEquals(0, globError.getNumErrorLandObjects());
assertEquals(1, globError.getNumErrorCityFurniture());
assertEquals(1, globError.getNumErrorGenericCityObjects());
} catch (CheckReportParseException e) {
fail("Report should be valid file");
}
} finally {
if (tmpDir != null) {
FileUtils.deleteDirectory(tmpDir.toFile());
}
}
}
}
......@@ -39,18 +39,18 @@ public class FilterTest {
@Test
public void testFilterExclude() throws CityGmlParseException, IOException, InvalidGmlFileException {
ValidationConfiguration config = ValidationConfiguration
.loadValidationConfig("src/test/resources/testConfigWithExclude.yml");
.loadValidationConfigFile("src/test/resources/testConfigWithExclude.yml");
CityDoctorModel model = CityGmlParser.parseCityGmlFile("src/test/resources/testarea.gml",
new ParserConfiguration(8, false));
Checker c = new Checker(config, model);
c.runChecks();
Building b = model.getBuildings().get(0);
Building b = model.getBuildings().toList().get(0);
Geometry geom = b.getGeometries().get(0);
assertFalse(geom.hasCheckResults());
TransportationObject to = model.getTransportation().get(0);
TransportationObject to = model.getTransportation().toList().get(0);
Geometry geom2 = to.getGeometries().get(0);
assertTrue(geom2.getPolygons().get(0).hasCheckResults());
......@@ -59,18 +59,18 @@ public class FilterTest {
@Test
public void testFilterInclude() throws CityGmlParseException, IOException, InvalidGmlFileException {
ValidationConfiguration config = ValidationConfiguration
.loadValidationConfig("src/test/resources/testConfigWithInclude.yml");
.loadValidationConfigFile("src/test/resources/testConfigWithInclude.yml");
CityDoctorModel model = CityGmlParser.parseCityGmlFile("src/test/resources/testarea.gml",
new ParserConfiguration(8, false));
Checker c = new Checker(config, model);
c.runChecks();
Building b = model.getBuildings().get(0);
Building b = model.getBuildings().toList().get(0);
Geometry geom = b.getGeometries().get(0);
assertFalse(geom.hasCheckResults());
TransportationObject to = model.getTransportation().get(0);
TransportationObject to = model.getTransportation().toList().get(0);
Geometry geom2 = to.getGeometries().get(0);
assertTrue(geom2.getPolygons().get(0).hasCheckResults());
......
......@@ -37,7 +37,7 @@ public class ValidationConfigurationTest {
@Test
public void testLoadingConfig() throws FileNotFoundException {
String file = "src/test/resources/testConfig.yml";
ValidationConfiguration config = ValidationConfiguration.loadValidationConfig(file);
ValidationConfiguration config = ValidationConfiguration.loadValidationConfigFile(file);
assertEquals(8, config.getNumberOfRoundingPlaces());
assertTrue(config.getRequirements().containsKey(RequirementId.R_GE_R_TOO_FEW_POINTS.toString()));
assertFalse(config.getRequirements().get(RequirementId.R_GE_P_NON_PLANAR.toString()).isEnabled());
......@@ -47,7 +47,7 @@ public class ValidationConfigurationTest {
@Test
public void testLoadingConfigWithFilter() throws FileNotFoundException {
String file = "src/test/resources/testConfigWithFilter.yml";
ValidationConfiguration config = ValidationConfiguration.loadValidationConfig(file);
ValidationConfiguration config = ValidationConfiguration.loadValidationConfigFile(file);
assertEquals(8, config.getNumberOfRoundingPlaces());
assertTrue(config.getRequirements().containsKey(RequirementId.R_GE_R_TOO_FEW_POINTS.toString()));
assertFalse(config.getRequirements().get(RequirementId.R_GE_P_NON_PLANAR.toString()).isEnabled());
......@@ -76,7 +76,7 @@ public class ValidationConfigurationTest {
String file = "src/test/resources/testConfigVulnerability.yml";
ValidationConfiguration config = null;
try {
config = ValidationConfiguration.loadValidationConfig(file);
config = ValidationConfiguration.loadValidationConfigFile(file);
assertNotNull(config);
fail("Config with Vulnerability should not be successfully loaded");
} catch (FileNotFoundException e){
......
......@@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.hft.stuttgart.citydoctor2.database.UnconnectedCache;
import org.junit.Test;
import de.hft.stuttgart.citydoctor2.check.CheckError;
......@@ -41,14 +42,16 @@ import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.quality.model.enums.RequirementId;
import org.mockito.Mockito;
public class DegeneratedPolygonCheckTest {
@Test
public void testDegeneratedPolygon() {
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, Lod.LOD1, Orientation.OUTWARD);
ConcretePolygon polygon = new ConcretePolygon();
geom.getPolygons().add(polygon);
polygon.setParent(geom);
......@@ -67,9 +70,10 @@ public class DegeneratedPolygonCheckTest {
Building b = new Building();
b.addGeometry(geom);
File file = Mockito.mock(File.class);
Mockito.when(file.getName()).thenReturn("building");
ParserConfiguration config = new ParserConfiguration(8, false);
CityDoctorModel model = new CityDoctorModel(config, new File(""));
CityDoctorModel model = new CityDoctorModel(config, file, new UnconnectedCache());
model.addBuilding(b);
ValidationConfiguration valConfig = ValidationConfiguration.loadStandardValidationConfig();
......
......@@ -34,6 +34,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation;
/**
*
......@@ -44,7 +45,9 @@ public class DuplicatePointsCheckTest {
@Test
public void testCheckOK() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD2, Orientation.OUTWARD);
Polygon p = new ConcretePolygon();
geom.addPolygon(p);
LinearRing lr = new LinearRing(LinearRingType.EXTERIOR);
p.setExteriorRing(lr);
......@@ -66,7 +69,9 @@ public class DuplicatePointsCheckTest {
@Test
public void testCheckConsecutivePointSame() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD2, Orientation.OUTWARD);
Polygon p = new ConcretePolygon();
geom.addPolygon(p);
LinearRing lr = new LinearRing(LinearRingType.EXTERIOR);
p.setExteriorRing(lr);
......@@ -90,7 +95,7 @@ public class DuplicatePointsCheckTest {
@Test
public void testCheckSelfInt() {
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, Lod.LOD1, Orientation.OUTWARD);
Vertex v0 = new Vertex(1, 1, 1);
Vertex v1 = new Vertex(2, 2, 2);
Vertex v2 = new Vertex(3, 3, 3);
......
......@@ -31,6 +31,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation;
/**
*
......@@ -40,7 +41,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
public class FaceOutCheckTest {
private Geometry createBadGeometry() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1, Orientation.OUTWARD);
Vertex v0 = createVertex(0, 0, 0, geom);
Vertex v1 = createVertex(10, 0, 0, geom);
......@@ -62,7 +63,7 @@ public class FaceOutCheckTest {
}
private Geometry createGoodGeometry() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1, Orientation.OUTWARD);
Vertex v0 = createVertex(0, 0, 0, geom);
Vertex v1 = createVertex(10, 0, 0, geom);
......
......@@ -33,6 +33,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation;
/**
*
......@@ -43,7 +44,7 @@ public class HoleOutsideCheckTest {
@Test
public void testHoleOutside() {
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, Lod.LOD1, Orientation.OUTWARD);
Polygon p = new ConcretePolygon();
geom.addPolygon(p);
......@@ -79,7 +80,7 @@ public class HoleOutsideCheckTest {
@Test
public void testPolygonGood() {
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, Lod.LOD1, Orientation.OUTWARD);
Polygon poly = new ConcretePolygon();
geom.addPolygon(poly);
......
......@@ -31,6 +31,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation;
/**
*
......@@ -44,7 +45,7 @@ public class InteriorDisconnectedCheckTest {
*/
@Test
public void testBadPolygon1() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1, Orientation.OUTWARD);
Polygon p = new ConcretePolygon();
geom.addPolygon(p);
......@@ -89,7 +90,7 @@ public class InteriorDisconnectedCheckTest {
*/
@Test
public void testBadPolygon2() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1, Orientation.OUTWARD);
Polygon p = new ConcretePolygon();
geom.addPolygon(p);
......@@ -145,7 +146,7 @@ public class InteriorDisconnectedCheckTest {
*/
@Test
public void testBadPolygon3() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1, Orientation.OUTWARD);
Polygon p = new ConcretePolygon();
geom.addPolygon(p);
......@@ -213,7 +214,7 @@ public class InteriorDisconnectedCheckTest {
*/
@Test
public void testGoodPolygon3() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1, Orientation.OUTWARD);
Polygon p = new ConcretePolygon();
geom.addPolygon(p);
......@@ -274,7 +275,7 @@ public class InteriorDisconnectedCheckTest {
@Test
public void testGoodPolygon2() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1, Orientation.OUTWARD);
Polygon p = new ConcretePolygon();
geom.addPolygon(p);
......
......@@ -31,6 +31,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation;
/**
*
......@@ -41,7 +42,7 @@ public class ManifoldVertexCheckTest {
@Test
public void testNonManifoldVertex() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1, Orientation.OUTWARD);
Vertex v12 = createVertex(10, 10, 3, geom);
Vertex v13 = createVertex(10, 10, 0, geom);
......
......@@ -33,6 +33,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation;
/**
*
......@@ -43,7 +44,7 @@ public class NestedRingsCheckTest {
@Test
public void testNestedRings() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1, Orientation.OUTWARD);
Polygon p = new ConcretePolygon();
geom.addPolygon(p);
......@@ -90,7 +91,7 @@ public class NestedRingsCheckTest {
@Test
public void testPolygonGood() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1, Orientation.OUTWARD);
Polygon poly = new ConcretePolygon();
geom.addPolygon(poly);
......
......@@ -29,6 +29,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation;
/**
*
......@@ -38,7 +39,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
public class NullAreaCheckTest {
private LinearRing setupValidGeometry() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1, Orientation.OUTWARD);
Polygon p = new ConcretePolygon();
geom.addPolygon(p);
......@@ -62,7 +63,7 @@ public class NullAreaCheckTest {
}
private LinearRing setupErrorGeometry() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1, Orientation.OUTWARD);
Polygon p = new ConcretePolygon();
geom.addPolygon(p);
......@@ -90,7 +91,7 @@ public class NullAreaCheckTest {
LinearRing r = setupErrorGeometry();
NullAreaCheck nac = new NullAreaCheck();
nac.check(r);
Assert.assertTrue(r.hasAnyError());
Assert.assertTrue(r.hasAnyErrorWithoutDependencies());
}
......@@ -100,7 +101,7 @@ public class NullAreaCheckTest {
LinearRing r = setupValidGeometry();
NullAreaCheck nac = new NullAreaCheck();
nac.check(r);
Assert.assertFalse(r.hasAnyError());
Assert.assertFalse(r.hasAnyErrorWithoutDependencies());
}
}
......@@ -31,6 +31,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation;
/**
*
......@@ -41,20 +42,20 @@ public class PlanarCheckTest {
@Test
public void testCheckPolygonOK() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1, Orientation.OUTWARD);
Vertex v0 = new Vertex(0, 0, 0);
Vertex v1 = new Vertex(0, 0, 1);
Vertex v2 = new Vertex(1, 0, 1);
Vertex v3 = new Vertex(1, 0, 0);
LinearRing lr = new LinearRing(LinearRingType.EXTERIOR);
Polygon p = new ConcretePolygon();
geom.addPolygon(p);
p.setExteriorRing(lr);
lr.addVertex(v0);
lr.addVertex(v1);
lr.addVertex(v2);
lr.addVertex(v3);
lr.addVertex(v0);
geom.addPolygon(p);
PlanarCheck c = new PlanarCheck();
c.check(p);
assertTrue(p.getCheckResult(c).getResultStatus() == ResultStatus.OK);
......@@ -62,13 +63,14 @@ public class PlanarCheckTest {
@Test
public void testCheckPolygonDistanceERROR() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1);
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD1, Orientation.OUTWARD);
Vertex v0 = new Vertex(0, 0, 0);
Vertex v1 = new Vertex(0, 0.06, 1);
Vertex v2 = new Vertex(1, 1, 1);
Vertex v3 = new Vertex(1, 1, 0);
LinearRing lr = new LinearRing(LinearRingType.EXTERIOR);
Polygon p = new ConcretePolygon();
geom.addPolygon(p);
p.setExteriorRing(lr);
lr.addVertex(v0);
lr.addVertex(v1);
......@@ -76,7 +78,6 @@ public class PlanarCheckTest {
lr.addVertex(v3);
lr.addVertex(v0);
lr.setParent(p);
geom.addPolygon(p);
PlanarCheck c = new PlanarCheck();
c.check(p);
assertTrue(p.getCheckResult(c).getResultStatus() == ResultStatus.ERROR);
......
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