"git@transfer.hft-stuttgart.de:co2ampel2/co-2-ampel.git" did not exist on "032fc6f0d4364d7579f6b762608948e84a887412"
Commit 6d0d664e authored by Matthias Betz's avatar Matthias Betz
Browse files

Merge remote-tracking branch 'remotes/origin/dev' into dev_baris_aabb_auto_mergeable

parents a7ed4b64 cc4fe260
Pipeline #12443 passed with stage
in 2 minutes and 42 seconds
...@@ -22,6 +22,8 @@ import de.hft.stuttgart.citydoctor2.math.Vector3d; ...@@ -22,6 +22,8 @@ import de.hft.stuttgart.citydoctor2.math.Vector3d;
import de.hft.stuttgart.citydoctor2.utils.BoundingBoxCalculator; import de.hft.stuttgart.citydoctor2.utils.BoundingBoxCalculator;
import de.hft.stuttgart.citydoctor2.utils.visitors.MinMaxExtentVisitor; import de.hft.stuttgart.citydoctor2.utils.visitors.MinMaxExtentVisitor;
import java.io.Serial;
import java.io.Serializable;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
...@@ -31,7 +33,10 @@ import java.util.Locale; ...@@ -31,7 +33,10 @@ import java.util.Locale;
* *
* @author Matthias Betz * @author Matthias Betz
*/ */
public class BoundingBox { public class BoundingBox implements Serializable {
@Serial
private static final long serialVersionUID = 1998769586245522486L;
private final Vector3d[] bbox; private final Vector3d[] bbox;
......
...@@ -43,7 +43,7 @@ public abstract class CityObject extends GmlElement { ...@@ -43,7 +43,7 @@ public abstract class CityObject extends GmlElement {
@Serial @Serial
private static final long serialVersionUID = 651712070755024188L; private static final long serialVersionUID = 651712070755024188L;
private BoundingBox bbox;
private final List<Geometry> geometryList = new ArrayList<>(); private final List<Geometry> geometryList = new ArrayList<>();
private final List<GenericAttribute> genericAttributeList = new ArrayList<>(); private final List<GenericAttribute> genericAttributeList = new ArrayList<>();
...@@ -88,6 +88,17 @@ public abstract class CityObject extends GmlElement { ...@@ -88,6 +88,17 @@ public abstract class CityObject extends GmlElement {
this.accept(new UnsetGeometriesVisitor()); this.accept(new UnsetGeometriesVisitor());
} }
public void setBbox(BoundingBox bbox){
this.bbox = bbox;
}
public synchronized BoundingBox getBbox(){
if (bbox == null){
this.setBbox(BoundingBox.of(this));
}
return bbox;
}
/** /**
* Adds a Geometry to this object. * Adds a Geometry to this object.
* @param geom the Geometry to add. * @param geom the Geometry to add.
......
...@@ -9,6 +9,8 @@ import java.io.Serial; ...@@ -9,6 +9,8 @@ import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.StringJoiner;
import java.util.function.Supplier;
public class GenericAttribute implements Serializable { public class GenericAttribute implements Serializable {
...@@ -17,6 +19,7 @@ public class GenericAttribute implements Serializable { ...@@ -17,6 +19,7 @@ public class GenericAttribute implements Serializable {
private static final long serialVersionUID = -4101408947632132328L; private static final long serialVersionUID = -4101408947632132328L;
private static final Logger logger = LogManager.getLogger(GenericAttribute.class); private static final Logger logger = LogManager.getLogger(GenericAttribute.class);
private static final String NULL_VALUE_STRING= "NULL OR INVALID VALUE";
private final AbstractGenericAttributeProperty original; private final AbstractGenericAttributeProperty original;
...@@ -24,6 +27,7 @@ public class GenericAttribute implements Serializable { ...@@ -24,6 +27,7 @@ public class GenericAttribute implements Serializable {
private String name; private String name;
private String value; private String value;
public GenericAttribute(AbstractGenericAttributeProperty attributeProperty) { public GenericAttribute(AbstractGenericAttributeProperty attributeProperty) {
original = attributeProperty; original = attributeProperty;
if (attributeProperty.getObject() == null) { if (attributeProperty.getObject() == null) {
...@@ -34,40 +38,42 @@ public class GenericAttribute implements Serializable { ...@@ -34,40 +38,42 @@ public class GenericAttribute implements Serializable {
if (attributeProperty.getObject() instanceof StringAttribute sa) { if (attributeProperty.getObject() instanceof StringAttribute sa) {
type = "StringAttribute"; type = "StringAttribute";
value = String.format("\"%s\"", sa.getValue()); value = extractValue(() -> String.format("\"%s\"", sa.getValue()));
} else if (attributeProperty.getObject() instanceof IntAttribute ia) { } else if (attributeProperty.getObject() instanceof IntAttribute ia) {
type = "IntAttribute"; type = "IntAttribute";
value = ia.getValue().toString(); value = extractValue(() -> ia.getValue().toString());
} else if (attributeProperty.getObject() instanceof DoubleAttribute da) { } else if (attributeProperty.getObject() instanceof DoubleAttribute da) {
type = "DoubleAttribute"; type = "DoubleAttribute";
value = da.getValue().toString(); value = extractValue(() -> da.getValue().toString());
} else if (attributeProperty.getObject() instanceof DateAttribute date) { } else if (attributeProperty.getObject() instanceof DateAttribute date) {
type = "DateAttribute"; type = "DateAttribute";
value = date.getValue().toString(); value = extractValue(() -> date.getValue().toString());
} else if (attributeProperty.getObject() instanceof UriAttribute ua) { } else if (attributeProperty.getObject() instanceof UriAttribute ua) {
type = "UriAttribute"; type = "UriAttribute";
value = ua.getValue(); value = extractValue(ua::getValue);
} else if (attributeProperty.getObject() instanceof MeasureAttribute ma) { } else if (attributeProperty.getObject() instanceof MeasureAttribute ma) {
type = "MeasureAttribute"; type = "MeasureAttribute";
value = String.format("%s %s", ma.getValue().getValue().toString(), ma.getValue().getUom()); value = extractValue(() ->
String.format("%s %s", ma.getValue().getValue().toString(), ma.getValue().getUom()));
} else if (attributeProperty.getObject() instanceof CodeAttribute ca) { } else if (attributeProperty.getObject() instanceof CodeAttribute ca) {
type = String.format("CodeAttribute (%s)", ca.getValue().getLanguage()); type = String.format("CodeAttribute (%s)", ca.getValue().getLanguage());
value = String.format("'''%s''' %n CodeSpace: %s", ca.getValue().getValue(), ca.getValue().getCodeSpace()); value = extractValue(() ->
String.format("'''%s''' %n CodeSpace: %s", ca.getValue().getValue(), ca.getValue().getCodeSpace()));
} else if (attributeProperty.getObject() instanceof GenericAttributeSet gas) { } else if (attributeProperty.getObject() instanceof GenericAttributeSet gas) {
type = "GenericAttributeSet"; type = "GenericAttributeSet";
List<AbstractGenericAttributeProperty> attributes = gas.getValue(); List<AbstractGenericAttributeProperty> attributes = gas.getValue();
StringBuilder sb = new StringBuilder(); if(attributes == null || attributes.isEmpty()){
sb.append("{"); value = NULL_VALUE_STRING;
return;
}
StringJoiner sj = new StringJoiner("; ","{","}");
sj.setEmptyValue("EMPTY_SET");
for (AbstractGenericAttributeProperty attribute : attributes) { for (AbstractGenericAttributeProperty attribute : attributes) {
if (attribute.getObject() != null) { if (attribute.getObject() != null) {
sb.append(attribute.getObject().getName()); sj.add(String.format("%1$s = %2$s",attribute.getObject().getName(), attribute.getObject().getValue()));
sb.append(" = ");
sb.append(attribute.getObject().getValue());
sb.append("; ");
} }
} }
sb.replace(sb.length() - 1, sb.length(), "}"); value = sj.toString();
value = String.format("'%s'", sb);
} else { } else {
logger.warn("GenericAttribute {} is of unknown type {}", attributeProperty, attributeProperty.getObject()); logger.warn("GenericAttribute {} is of unknown type {}", attributeProperty, attributeProperty.getObject());
...@@ -77,6 +83,14 @@ public class GenericAttribute implements Serializable { ...@@ -77,6 +83,14 @@ public class GenericAttribute implements Serializable {
} }
private String extractValue(Supplier<String> supply){
try{
return supply.get();
}catch (NullPointerException e){
return NULL_VALUE_STRING;
}
}
public AbstractGenericAttributeProperty getOriginal() { public AbstractGenericAttributeProperty getOriginal() {
return original; return original;
} }
......
...@@ -61,6 +61,7 @@ public class ImplicitGeometryHolder extends Geometry { ...@@ -61,6 +61,7 @@ public class ImplicitGeometryHolder extends Geometry {
if(!deferredRelGeomObjects.isEmpty()) { if(!deferredRelGeomObjects.isEmpty()) {
logger.info("Resolving deferred relative geometries"); logger.info("Resolving deferred relative geometries");
} }
Set<GmlId> changedFeatures = new HashSet<>();
for (ImplicitGeometryHolder key : deferredRelGeomObjects.keySet()) { for (ImplicitGeometryHolder key : deferredRelGeomObjects.keySet()) {
ImplicitGeometry ig = deferredRelGeomObjects.get(key); ImplicitGeometry ig = deferredRelGeomObjects.get(key);
String hrefId = ig.getRelativeGeometry().getHref(); String hrefId = ig.getRelativeGeometry().getHref();
...@@ -72,10 +73,15 @@ public class ImplicitGeometryHolder extends Geometry { ...@@ -72,10 +73,15 @@ public class ImplicitGeometryHolder extends Geometry {
CityObject parent = cache.get(key.getParent().getGmlId()); CityObject parent = cache.get(key.getParent().getGmlId());
parent.removeGeometry(igh.getLod(), igh.getType()); parent.removeGeometry(igh.getLod(), igh.getType());
parent.addGeometry(igh); parent.addGeometry(igh);
changedFeatures.add(parent.getTopLevelCityObject().getGmlId());
} else { } else {
missingGeoms.add(gmlId); missingGeoms.add(gmlId);
} }
} }
changedFeatures.forEach(gmlId -> {
CityObject co = cache.get(gmlId);
co.setBbox(BoundingBox.of(co));
});
if (!missingGeoms.isEmpty()) { if (!missingGeoms.isEmpty()) {
logger.warn("RelativeGeometries of the following gmlIDs could not be resolved: {}", missingGeoms); logger.warn("RelativeGeometries of the following gmlIDs could not be resolved: {}", missingGeoms);
} }
...@@ -113,31 +119,6 @@ public class ImplicitGeometryHolder extends Geometry { ...@@ -113,31 +119,6 @@ public class ImplicitGeometryHolder extends Geometry {
LibraryObject.resetObjectMap(); LibraryObject.resetObjectMap();
} }
/**
* Prepares the prototype geometries for checking and sets a lock to prevent clearing of metadata
*/
public static void preparePrototypeGeometriesForChecking(){
RelativeGeometry.preparePrototypeGeometriesForChecking();
LibraryObject.preparePrototypeGeometriesForChecking();
}
/**
* Clears metadata creating for checking of prototype geometries and releases the metadata lock
*/
public static void clearMetaDataOfPrototypeGeometries(){
RelativeGeometry.clearMetaDataOfPrototypeGeometries();
LibraryObject.clearMetaDataOfPrototypeGeometries();
}
@Override
public void accept(CheckableVisitor c) {
prototypeGeometry.accept(c);
}
@Override
public boolean isValidated() {
return prototypeGeometry.isValidated();
}
} }
...@@ -26,7 +26,6 @@ public class LibraryObject extends Geometry { ...@@ -26,7 +26,6 @@ public class LibraryObject extends Geometry {
private static final Logger logger = LogManager.getLogger(LibraryObject.class); private static final Logger logger = LogManager.getLogger(LibraryObject.class);
@Serial @Serial
private static final long serialVersionUID = -50293435187454911L; private static final long serialVersionUID = -50293435187454911L;
private static boolean metadataLocked = false;
private static final Map<String, LibraryObject> libraryObjects = new ConcurrentHashMap<>(); private static final Map<String, LibraryObject> libraryObjects = new ConcurrentHashMap<>();
public static LibraryObject of(Path path, ParserConfiguration config) { public static LibraryObject of(Path path, ParserConfiguration config) {
...@@ -79,33 +78,8 @@ public class LibraryObject extends Geometry { ...@@ -79,33 +78,8 @@ public class LibraryObject extends Geometry {
return objects.get(0).getHighestLodGeometry(); return objects.get(0).getHighestLodGeometry();
} }
public static void resetObjectMap() { public static void resetObjectMap() {
libraryObjects.clear(); libraryObjects.clear();
} }
public static void preparePrototypeGeometriesForChecking() {
libraryObjects.values().forEach(LibraryObject::updateEdgesAndVertices);
metadataLocked = true;
}
public static void clearMetaDataOfPrototypeGeometries() {
metadataLocked = false;
libraryObjects.values().forEach(LibraryObject::clearMetaData);
}
@Override
public void updateEdgesAndVertices(){
if (!metadataLocked) {
super.updateEdgesAndVertices();
}
}
@Override
public void clearMetaData(){
if (!metadataLocked) {
super.clearMetaData();
}
}
} }
...@@ -19,8 +19,11 @@ ...@@ -19,8 +19,11 @@
package de.hft.stuttgart.citydoctor2.datastructure; package de.hft.stuttgart.citydoctor2.datastructure;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult; import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.Checkable;
import de.hft.stuttgart.citydoctor2.check.CheckableUtilsVisitor;
import de.hft.stuttgart.citydoctor2.check.CheckableVisitor; import de.hft.stuttgart.citydoctor2.check.CheckableVisitor;
import de.hft.stuttgart.citydoctor2.math.Vector3d; import de.hft.stuttgart.citydoctor2.math.Vector3d;
import de.hft.stuttgart.citydoctor2.tesselation.TesselatedPolygon; import de.hft.stuttgart.citydoctor2.tesselation.TesselatedPolygon;
...@@ -62,6 +65,52 @@ public class LinkedPolygon extends Polygon { ...@@ -62,6 +65,52 @@ public class LinkedPolygon extends Polygon {
} }
} }
@Override
public boolean hasExistingGmlId() {
return poly.hasExistingGmlId();
}
@Override
public void setValidated(boolean validated) {
// Linked polys themselves are not checked
}
@Override
public boolean isValidated() {
return poly.isValidated();
}
//TODO: Think how to handle this, as it violates class contract if ignored
@Override
public void prepareForChecking() {
// Linked polys themselves are not checked
}
@Override
public void clearMetaInformation() {
// Linked polys themselves are not checked
}
@Override
public boolean hasError(CheckId checkIdentifier) {
return poly.hasError(checkIdentifier);
}
@Override
public boolean hasAnyError() {
return poly.hasAnyError();
}
@Override
public void collectContainedErrors(List<CheckError> errors) {
poly.collectContainedErrors(errors);
}
@Override
public void collectErrors(List<CheckError> errors) {
poly.collectErrors(errors);
}
@Override @Override
public CheckResult getCheckResult(Check c) { public CheckResult getCheckResult(Check c) {
return poly.getCheckResult(c); return poly.getCheckResult(c);
...@@ -104,8 +153,12 @@ public class LinkedPolygon extends Polygon { ...@@ -104,8 +153,12 @@ public class LinkedPolygon extends Polygon {
@Override @Override
public void accept(CheckableVisitor c) { public void accept(CheckableVisitor c) {
// linked polygons are not checked // LinkedPolygon should ignore Checks, as their referenced ConcretePolygon must be within the same TopLevelFeature.
setValidated(true); // Checks always start iterating from a TopLevelFeature and thus will visit the referenced ConcretePolygon.
if (!c.isValidator()){
// Utility Visitors get passed to the ConcretePolygon, as they can start iterating from a sub-CityObject.
poly.accept(c);
}
} }
@Override @Override
......
...@@ -15,7 +15,6 @@ public class RelativeGeometry extends Geometry { ...@@ -15,7 +15,6 @@ public class RelativeGeometry extends Geometry {
private static final long serialVersionUID = -686112245455298977L; private static final long serialVersionUID = -686112245455298977L;
private static final Map<GmlId, RelativeGeometry> relativeGeometries = new ConcurrentHashMap<>(); private static final Map<GmlId, RelativeGeometry> relativeGeometries = new ConcurrentHashMap<>();
private static boolean metadataLocked = false;
public static RelativeGeometry of(GmlId gmlId, Geometry geom) { public static RelativeGeometry of(GmlId gmlId, Geometry geom) {
if (relativeGeometries.containsKey(gmlId)) { if (relativeGeometries.containsKey(gmlId)) {
...@@ -40,27 +39,5 @@ public class RelativeGeometry extends Geometry { ...@@ -40,27 +39,5 @@ public class RelativeGeometry extends Geometry {
relativeGeometries.clear(); relativeGeometries.clear();
} }
public static void preparePrototypeGeometriesForChecking() {
relativeGeometries.values().forEach(RelativeGeometry::updateEdgesAndVertices);
metadataLocked = true;
}
public static void clearMetaDataOfPrototypeGeometries() {
metadataLocked = false;
relativeGeometries.values().forEach(RelativeGeometry::clearMetaData);
}
@Override
public void updateEdgesAndVertices(){
if (!metadataLocked) {
super.updateEdgesAndVertices();
}
}
@Override
public void clearMetaData(){
if (!metadataLocked) {
super.clearMetaData();
}
}
} }
package de.hft.stuttgart.citydoctor2.exceptions;
import java.io.Serial;
public class CityObjectCacheException extends RuntimeException{
@Serial
private static final long serialVersionUID = -460467145629964615L;
public CityObjectCacheException(String message) {
super(message);
}
public CityObjectCacheException(String message, Throwable cause) {
super(message, cause);
}
}
package de.hft.stuttgart.citydoctor2.exceptions;
import java.io.Serial;
public class EmbeddedDatabaseHandlerException extends RuntimeException{
@Serial
private static final long serialVersionUID = -7848325704234347425L;
public EmbeddedDatabaseHandlerException(String message) {
super(message);
}
public EmbeddedDatabaseHandlerException(String message, Throwable cause) {
super(message, cause);
}
public EmbeddedDatabaseHandlerException(Throwable cause){
super(cause);
}
}
...@@ -28,6 +28,7 @@ import java.util.function.Function; ...@@ -28,6 +28,7 @@ import java.util.function.Function;
import de.hft.stuttgart.citydoctor2.database.FeatureCache; import de.hft.stuttgart.citydoctor2.database.FeatureCache;
import de.hft.stuttgart.citydoctor2.database.UnconnectedCache; import de.hft.stuttgart.citydoctor2.database.UnconnectedCache;
import de.hft.stuttgart.citydoctor2.datastructure.BoundingBox;
import de.hft.stuttgart.citydoctor2.datastructure.OtherConstructionObject; import de.hft.stuttgart.citydoctor2.datastructure.OtherConstructionObject;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
...@@ -168,7 +169,7 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -168,7 +169,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
private static final Logger logger = LogManager.getLogger(Citygml3FeatureMapper.class); private static final Logger logger = LogManager.getLogger(Citygml3FeatureMapper.class);
private static FeatureCache featureCache = new FeatureCache(); private static final FeatureCache featureCache = new FeatureCache();
private final CityDoctorModel model; private final CityDoctorModel model;
private final ParserConfiguration config; private final ParserConfiguration config;
private final Path directory; private final Path directory;
...@@ -207,6 +208,7 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -207,6 +208,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
return; return;
} }
boolean xLinkGlobalError = false; boolean xLinkGlobalError = false;
String emptyXLinkLog = Localization.getText("CityGmlFeatureMapper.emptyCrossFeatureReference");
List<String> crossRefs = new ArrayList<>(); List<String> crossRefs = new ArrayList<>();
for (Map.Entry<String, List<GmlId>> entry : unresolvedPolyRefIDMap.entrySet()) { for (Map.Entry<String, List<GmlId>> entry : unresolvedPolyRefIDMap.entrySet()) {
String id = entry.getKey(); String id = entry.getKey();
...@@ -217,18 +219,16 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -217,18 +219,16 @@ public class Citygml3FeatureMapper extends ObjectWalker {
StringJoiner joiner = new StringJoiner(", "); StringJoiner joiner = new StringJoiner(", ");
gmlIds.forEach(gmlId -> joiner.add(gmlId.toString())); gmlIds.forEach(gmlId -> joiner.add(gmlId.toString()));
GmlId crossFeatureId = parsedPolygonsIdMap.get(id); GmlId crossFeatureId = parsedPolygonsIdMap.get(id);
//TODO: Localize String logger.warn(emptyXLinkLog, id, crossFeatureId, joiner);
logger.warn("Polygon {} of Feature {} is being referenced in other Features: {}", id, crossFeatureId, joiner);
crossRefs.add(id); crossRefs.add(id);
} }
} }
if (xLinkGlobalError) { if (xLinkGlobalError) {
//TODO: Localize String logger.warn(Localization.getText("CityGmlFeatureMapper.crossFeatureReferencesDetected"));
logger.warn("Model has Features containing cross-feature references without their own copies of the referenced polygons");
} }
crossRefs.forEach(unresolvedPolyRefIDMap::remove); crossRefs.forEach(unresolvedPolyRefIDMap::remove);
if(!unresolvedPolyRefIDMap.isEmpty()) { if(!unresolvedPolyRefIDMap.isEmpty()) {
logger.warn("Model contains polygon references that could not be found"); logger.warn(Localization.getText("CityGmlFeatureMapper.unresolvedReferencesDetected"));
} }
} }
...@@ -941,6 +941,7 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -941,6 +941,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
co.clearGmlGeometries(); co.clearGmlGeometries();
resolveAndClearReferences(co); resolveAndClearReferences(co);
updateEdgesAndVertices(co); updateEdgesAndVertices(co);
co.setBbox(BoundingBox.of(co));
} }
private void mapAbstractTransportationSpace(AbstractTransportationSpace ats, TransportationSpace trsp) { private void mapAbstractTransportationSpace(AbstractTransportationSpace ats, TransportationSpace trsp) {
......
...@@ -34,8 +34,6 @@ public class Segment3d implements Serializable { ...@@ -34,8 +34,6 @@ public class Segment3d implements Serializable {
private static final double PRECISION = 0.00000001; private static final double PRECISION = 0.00000001;
private static final double EPSILON = 0.01;
private final Vector3d pointA; private final Vector3d pointA;
private final Vector3d pointB; private final Vector3d pointB;
...@@ -178,7 +176,7 @@ public class Segment3d implements Serializable { ...@@ -178,7 +176,7 @@ public class Segment3d implements Serializable {
return "Segment3d [pointA=" + pointA + ", pointB=" + pointB + "]"; return "Segment3d [pointA=" + pointA + ", pointB=" + pointB + "]";
} }
public Vector3d intersection(Triangle3d triangle) { public Vector3d intersection(Triangle3d triangle, double eps) {
Vector3d v0 = triangle.getP1(); Vector3d v0 = triangle.getP1();
Vector3d v1 = triangle.getP2(); Vector3d v1 = triangle.getP2();
Vector3d v2 = triangle.getP3(); Vector3d v2 = triangle.getP3();
...@@ -188,7 +186,7 @@ public class Segment3d implements Serializable { ...@@ -188,7 +186,7 @@ public class Segment3d implements Serializable {
Vector3d p = direction.cross(edge2); Vector3d p = direction.cross(edge2);
double det = edge1.dot(p); double det = edge1.dot(p);
if (det > -EPSILON && det < EPSILON) { if (det > -eps && det < eps) {
return null; return null;
} }
...@@ -197,7 +195,7 @@ public class Segment3d implements Serializable { ...@@ -197,7 +195,7 @@ public class Segment3d implements Serializable {
Vector3d s = pointA.minus(v0); Vector3d s = pointA.minus(v0);
double u = invDet * s.dot(p); double u = invDet * s.dot(p);
if (u < EPSILON || u > (1.0 - EPSILON)) { if (u < eps || u > (1.0 - eps)) {
return null; return null;
} }
...@@ -210,7 +208,7 @@ public class Segment3d implements Serializable { ...@@ -210,7 +208,7 @@ public class Segment3d implements Serializable {
} }
double t = edge2.dot(q) * invDet; double t = edge2.dot(q) * invDet;
if (t > EPSILON && t < 1 - EPSILON) { if (t > eps && t < 1 - eps) {
// t is in segment // t is in segment
return pointA.plus(direction.mult(t)); return pointA.plus(direction.mult(t));
} }
......
...@@ -35,6 +35,8 @@ public class Triangle3d implements Serializable { ...@@ -35,6 +35,8 @@ public class Triangle3d implements Serializable {
private static final long serialVersionUID = -6907333357794272435L; private static final long serialVersionUID = -6907333357794272435L;
private static final double EPSILON = 0.0001; private static final double EPSILON = 0.0001;
private static final double PLANAR_EPSILON = 0.0000001;
private final Vector3d p1; private final Vector3d p1;
private final Vector3d p2; private final Vector3d p2;
private final Vector3d p3; private final Vector3d p3;
...@@ -51,7 +53,54 @@ public class Triangle3d implements Serializable { ...@@ -51,7 +53,54 @@ public class Triangle3d implements Serializable {
this.p3 = p3; this.p3 = p3;
this.partOf = partOf; this.partOf = partOf;
} }
public boolean hasMinExtent(double minExtent) {
Vector3d ab = p2.minus(p1);
Vector3d ac = p3.minus(p1);
Vector3d bc = p3.minus(p2);
// Find the longest edge to use as primary axis
double lenAB2 = ab.getSquaredLength();
double lenAC2 = ac.getSquaredLength();
double lenBC2 = bc.getSquaredLength();
Vector3d axisX;
if (lenAB2 >= lenAC2 && lenAB2 >= lenBC2) {
axisX = ab;
} else if (lenAC2 >= lenBC2) {
axisX = ac;
} else {
axisX = bc;
}
axisX = axisX.normalize();
// Pick any vector not parallel to axisX for in-plane Y axis
Vector3d axisY = pickPerpendicular(axisX);
// Project vertices onto axes
double minX = Math.min(p1.dot(axisX), Math.min(p2.dot(axisX), p3.dot(axisX)));
double maxX = Math.max(p1.dot(axisX), Math.max(p2.dot(axisX), p3.dot(axisX)));
double minY = Math.min(p1.dot(axisY), Math.min(p2.dot(axisY), p3.dot(axisY)));
double maxY = Math.max(p1.dot(axisY), Math.max(p2.dot(axisY), p3.dot(axisY)));
double extentX = maxX - minX;
double extentY = maxY - minY;
return extentX > minExtent && extentY > minExtent;
}
private Vector3d pickPerpendicular(Vector3d v) {
// choose smallest component to avoid near-zero cross
if (Math.abs(v.getX()) < Math.abs(v.getY()) && Math.abs(v.getX()) < Math.abs(v.getZ())) {
return new Vector3d(0, -v.getZ(), v.getY()).normalize();
}
if (Math.abs(v.getY()) < Math.abs(v.getZ())) {
return new Vector3d(-v.getZ(), 0, v.getX()).normalize();
}
return new Vector3d(-v.getY(), v.getX(), 0).normalize();
}
public TesselatedPolygon getPartOf() { public TesselatedPolygon getPartOf() {
return partOf; return partOf;
} }
...@@ -101,13 +150,13 @@ public class Triangle3d implements Serializable { ...@@ -101,13 +150,13 @@ public class Triangle3d implements Serializable {
double distanceP2T2 = planeT2.getSignedDistance(p2); double distanceP2T2 = planeT2.getSignedDistance(p2);
double distanceP3T2 = planeT2.getSignedDistance(p3); double distanceP3T2 = planeT2.getSignedDistance(p3);
if (Math.abs(distanceP1T2) < epsilon) { if (Math.abs(distanceP1T2) < PLANAR_EPSILON) {
distanceP1T2 = 0.0; distanceP1T2 = 0.0;
} }
if (Math.abs(distanceP2T2) < epsilon) { if (Math.abs(distanceP2T2) < PLANAR_EPSILON) {
distanceP2T2 = 0.0; distanceP2T2 = 0.0;
} }
if (Math.abs(distanceP3T2) < epsilon) { if (Math.abs(distanceP3T2) < PLANAR_EPSILON) {
distanceP3T2 = 0.0; distanceP3T2 = 0.0;
} }
...@@ -144,20 +193,18 @@ public class Triangle3d implements Serializable { ...@@ -144,20 +193,18 @@ public class Triangle3d implements Serializable {
return false; return false;
} }
boolean intersects = checkTriangleLineIntersection(other, p1, p2) || checkTriangleLineIntersection(other, p1, p3) boolean intersects = checkTriangleLineIntersection(other, p1, p2, epsilon)
|| checkTriangleLineIntersection(other, p2, p3) || checkTriangleLineIntersection(other, p1, p3, epsilon)
|| checkTriangleLineIntersection(this, other.p1, other.p2) || checkTriangleLineIntersection(other, p2, p3, epsilon)
|| checkTriangleLineIntersection(this, other.p1, other.p3) || checkTriangleLineIntersection(this, other.p1, other.p2, epsilon)
|| checkTriangleLineIntersection(this, other.p2, other.p3); || checkTriangleLineIntersection(this, other.p1, other.p3, epsilon)
if (intersects) { || checkTriangleLineIntersection(this, other.p2, other.p3, epsilon);
System.out.println();
}
return intersects; return intersects;
} }
private boolean checkTriangleLineIntersection(Triangle3d other, Vector3d a, Vector3d b) { private boolean checkTriangleLineIntersection(Triangle3d other, Vector3d a, Vector3d b, double eps) {
Segment3d seg = new Segment3d(a, b); Segment3d seg = new Segment3d(a, b);
Vector3d intersection1 = seg.intersection(other); Vector3d intersection1 = seg.intersection(other, eps);
return intersection1 != null; return intersection1 != null;
} }
...@@ -274,5 +321,4 @@ public class Triangle3d implements Serializable { ...@@ -274,5 +321,4 @@ public class Triangle3d implements Serializable {
public void setPartOf(TesselatedPolygon p) { public void setPartOf(TesselatedPolygon p) {
partOf = p; partOf = p;
} }
} }
...@@ -46,9 +46,10 @@ public class Vector3d implements Serializable { ...@@ -46,9 +46,10 @@ public class Vector3d implements Serializable {
public Vector3d() { public Vector3d() {
this(0d, 0d, 0d); this(0d, 0d, 0d);
} }
/** /**
* Convert JTS Coordinate class to Vector3d. * Convert JTS Coordinate class to Vector3d.
*
* @param coord JTS Coordinate * @param coord JTS Coordinate
*/ */
public Vector3d(Coordinate coord) { public Vector3d(Coordinate coord) {
...@@ -210,7 +211,8 @@ public class Vector3d implements Serializable { ...@@ -210,7 +211,8 @@ public class Vector3d implements Serializable {
} }
/** /**
* normalizes this vector. This method changes the coordinates of this instance. * returns a normalized vector in the same direction as this one. This method
* does not change the coordinates of this instance.
*/ */
public UnitVector3d normalize() { public UnitVector3d normalize() {
return UnitVector3d.of(this); return UnitVector3d.of(this);
...@@ -253,9 +255,9 @@ public class Vector3d implements Serializable { ...@@ -253,9 +255,9 @@ public class Vector3d implements Serializable {
@Override @Override
public String toString() { public String toString() {
final int maxLen = 5; final int maxLen = 5;
return "Vector3d [coords=" + return "Vector3d [coords="
(coords != null ? Arrays.toString(Arrays.copyOf(coords, Math.min(coords.length, maxLen))) : null) + + (coords != null ? Arrays.toString(Arrays.copyOf(coords, Math.min(coords.length, maxLen))) : null)
"]"; + "]";
} }
@Override @Override
......
...@@ -300,12 +300,6 @@ public class CityGmlParser { ...@@ -300,12 +300,6 @@ public class CityGmlParser {
} }
} }
public static void streamCityGml(String file, ParserConfiguration config, CityGmlConsumer cityObjectConsumer,
String outputFile) throws CityGmlParseException {
Path f = Paths.get(file);
streamCityGml(f, config, null, cityObjectConsumer, outputFile);
}
public static void streamCityGml(File file, ParserConfiguration parserConfig, CityGmlConsumer cityObjectConsumer, public static void streamCityGml(File file, ParserConfiguration parserConfig, CityGmlConsumer cityObjectConsumer,
String outputFile) throws CityGmlParseException { String outputFile) throws CityGmlParseException {
streamCityGml(file.toPath(), parserConfig, null, cityObjectConsumer, outputFile); streamCityGml(file.toPath(), parserConfig, null, cityObjectConsumer, outputFile);
......
...@@ -6,15 +6,18 @@ CheckContainer.error=Unexpected exception while executing check: {} ...@@ -6,15 +6,18 @@ CheckContainer.error=Unexpected exception while executing check: {}
CheckDialog.availableChecksLabel=Available Checks CheckDialog.availableChecksLabel=Available Checks
CheckDialog.cancelBtn=Cancel CheckDialog.cancelBtn=Cancel
CheckDialog.checkBtn=Check CheckDialog.checkBtn=Check
CheckDialog.checkDescriptionsLabel=Explanations for the requirements are available on CityDoctor's homepage
CheckDialog.checkEnabled=Enabled CheckDialog.checkEnabled=Enabled
CheckDialog.checkName=Name CheckDialog.checkName=Name
CheckDialog.checksDone=Checks done CheckDialog.checksDone=Checks done
CheckDialog.checksReenabledAlert=Some checks have been reenabled so that other wanted checks can be executed\nSee the log for more information. CheckDialog.checksReenabledAlert=Some checks have been reenabled so that other wanted checks can be executed\nSee the log for more information.
CheckDialog.checksTab=Checks CheckDialog.checksTab=Checks
CheckDialog.clickHereToOpen=[Click here to open]
CheckDialog.failedChecks=Failed to execute checks CheckDialog.failedChecks=Failed to execute checks
CheckDialog.filterTab=Filter CheckDialog.filterTab=Filter
CheckDialog.geometricChecksLabel=Geometric Checks CheckDialog.geometricChecksLabel=Geometric Checks
CheckDialog.globalParametersLabel=Global Parameters CheckDialog.globalParametersLabel=Global Parameters
CheckDialog.homepageHyperlink=https://transfer.hft-stuttgart.de/pages/citydoctor/citydoctorhomepage/en/requirements/
CheckDialog.noPathError=Output path is missing! CheckDialog.noPathError=Output path is missing!
CheckDialog.outputPathBtn=Select CheckDialog.outputPathBtn=Select
CheckDialog.outputPathLabel=Output directory (Required): CheckDialog.outputPathLabel=Output directory (Required):
...@@ -25,12 +28,14 @@ CheckDialog.schematronChooserTitle=Choose schematron file ... ...@@ -25,12 +28,14 @@ CheckDialog.schematronChooserTitle=Choose schematron file ...
CheckDialog.schematronFileLabel=Schematron File: CheckDialog.schematronFileLabel=Schematron File:
CheckDialog.schematronFileNotExisting=Schematron file does not exist, Schematron will be skipped CheckDialog.schematronFileNotExisting=Schematron file does not exist, Schematron will be skipped
CheckDialog.schematronFiles=Schematron Files CheckDialog.schematronFiles=Schematron Files
CheckDialog.selectAllChecksBtn=Select All
CheckDialog.selectBtn=Select CheckDialog.selectBtn=Select
CheckDialog.semanticChecksLabel=Semantic Checks CheckDialog.semanticChecksLabel=Semantic Checks
CheckDialog.startingChecks=Starting checks CheckDialog.startingChecks=Starting checks
CheckDialog.streamCheckLabel=Citymodels are not loaded and kept in memory. Check results are saved to the QualityADE in copies of the input files. CheckDialog.streamCheckLabel=Citymodels are not loaded and kept in memory. Check results are saved to the QualityADE in copies of the input files.
CheckDialog.streamCheckOption=Use low memory mode CheckDialog.streamCheckOption=Use low memory mode
CheckDialog.title=Check Configuration CheckDialog.title=Check Configuration
CheckDialog.unselectAllChecksBtn=Unselect All
CheckDialog.validationConfiguration=Validation Configuration CheckDialog.validationConfiguration=Validation Configuration
CheckDialog.xmlReportsOption=Create XML reports CheckDialog.xmlReportsOption=Create XML reports
Checker.checkFeature=Checking feature: {} Checker.checkFeature=Checking feature: {}
...@@ -70,6 +75,9 @@ CityDoctorValidation.notExactlyOneOutputFile=Specify exactly one file as output. ...@@ -70,6 +75,9 @@ CityDoctorValidation.notExactlyOneOutputFile=Specify exactly one file as output.
CityDoctorValidation.notExactlyOnePDFOutput=Specify exactly one file as pdfReport CityDoctorValidation.notExactlyOnePDFOutput=Specify exactly one file as pdfReport
CityDoctorValidation.notExactlyOneXMLOutput=Specify exactly one file as xmlReport CityDoctorValidation.notExactlyOneXMLOutput=Specify exactly one file as xmlReport
CityDoctorValidation.wrongInputFileFormat=Input file '{}' does not end with .gml or .xml CityDoctorValidation.wrongInputFileFormat=Input file '{}' does not end with .gml or .xml
CityGmlFeatureMapper.crossFeatureReferencesDetected=Model has Features containing cross-feature references without their own copies of the referenced polygons
CityGmlFeatureMapper.emptyCrossFeatureReference=Polygon {} of Feature {} is being referenced in other Features: {}
CityGmlFeatureMapper.unresolvedReferencesDetected=Model contains polygon references that could not be found
CityGmlParser.chunkReadFailed=Failed to read GML file in chunks, falling back to reading the complete file CityGmlParser.chunkReadFailed=Failed to read GML file in chunks, falling back to reading the complete file
CityGmlParser.convertCrsToUtmZoneN=Converting coordinate system to UTM zone {}N CityGmlParser.convertCrsToUtmZoneN=Converting coordinate system to UTM zone {}N
CityGmlParser.convertCrsToUtmZoneS=Converting coordinate system to UTM zone {}S CityGmlParser.convertCrsToUtmZoneS=Converting coordinate system to UTM zone {}S
...@@ -99,6 +107,9 @@ DatabaseHandler.serializationFailure=Serialization of CityObject {} failed! ...@@ -99,6 +107,9 @@ DatabaseHandler.serializationFailure=Serialization of CityObject {} failed!
DatabaseHandler.setupFailure=FATAL ERROR: Creation of embedded database failed! DatabaseHandler.setupFailure=FATAL ERROR: Creation of embedded database failed!
DatabaseHandler.tableFailure=FATAL ERROR: Creation of features table failed! DatabaseHandler.tableFailure=FATAL ERROR: Creation of features table failed!
DatabaseHandler.unmarshallingFailure=Loading of CityObject {} from embedded database failed! DatabaseHandler.unmarshallingFailure=Loading of CityObject {} from embedded database failed!
DatabaseSettings.invalidPath=Properties for database directory and name do not combine to a valid path. Using default value instead
DatabaseSettings.poolSizeLessThanOne=ConnectionPoolSize property was set to be less than 1. Using default value instead
DatabaseSettings.poolSizeNaN=ConnectionPoolSize property is not an integer. Using default value instead
DistanceError.distanceFromPlane=distance from plane DistanceError.distanceFromPlane=distance from plane
ErrorItemVisitor.childId=Child id ErrorItemVisitor.childId=Child id
ErrorItemVisitor.component=Component ErrorItemVisitor.component=Component
......
...@@ -6,15 +6,18 @@ CheckContainer.error=Unerwarteter Fehler bei der Ausf\u00fchrung von Pr\u00fcfun ...@@ -6,15 +6,18 @@ CheckContainer.error=Unerwarteter Fehler bei der Ausf\u00fchrung von Pr\u00fcfun
CheckDialog.availableChecksLabel=Verf\u00fcgbare Pr\u00fcfungen CheckDialog.availableChecksLabel=Verf\u00fcgbare Pr\u00fcfungen
CheckDialog.cancelBtn=Abbrechen CheckDialog.cancelBtn=Abbrechen
CheckDialog.checkBtn=Pr\u00fcfen CheckDialog.checkBtn=Pr\u00fcfen
CheckDialog.checkDescriptionsLabel=Beschreibungen der Pr\u00fcfungen sind auf der CityDoctor Homepage verf\u00fcgbar
CheckDialog.checkEnabled=Aktiv CheckDialog.checkEnabled=Aktiv
CheckDialog.checkName=Name CheckDialog.checkName=Name
CheckDialog.checksDone=Pr\u00fcfung abgeschlossen CheckDialog.checksDone=Pr\u00fcfung abgeschlossen
CheckDialog.checksReenabledAlert=Manche Pr\u00fcfungen wurden reaktiviert damit andere gewollte Pr\u00fcfungen durchgef\u00fchrt werden k\u00f6nnen\nMehr Details sind im Log geschrieben CheckDialog.checksReenabledAlert=Manche Pr\u00fcfungen wurden reaktiviert damit andere gewollte Pr\u00fcfungen durchgef\u00fchrt werden k\u00f6nnen\nMehr Details sind im Log geschrieben
CheckDialog.checksTab=Pr\u00fcfungen CheckDialog.checksTab=Pr\u00fcfungen
CheckDialog.clickHereToOpen=[Hier Klicken zum \u00d6ffnen]
CheckDialog.failedChecks=Konnte Pr\u00fcfungen nicht ausf\u00fchren CheckDialog.failedChecks=Konnte Pr\u00fcfungen nicht ausf\u00fchren
CheckDialog.filterTab=Filter CheckDialog.filterTab=Filter
CheckDialog.geometricChecksLabel=Geometrische Pr\u00fcfungen CheckDialog.geometricChecksLabel=Geometrische Pr\u00fcfungen
CheckDialog.globalParametersLabel=Globale Parameter CheckDialog.globalParametersLabel=Globale Parameter
CheckDialog.homepageHyperlink=https://transfer.hft-stuttgart.de/pages/citydoctor/citydoctorhomepage/de/requirements/
CheckDialog.noPathError=Ausgabepfad wurde nicht gesetzt! CheckDialog.noPathError=Ausgabepfad wurde nicht gesetzt!
CheckDialog.outputPathBtn=Ausw\u00e4hlen CheckDialog.outputPathBtn=Ausw\u00e4hlen
CheckDialog.outputPathLabel=Ausgabeordner (Pflichtfeld): CheckDialog.outputPathLabel=Ausgabeordner (Pflichtfeld):
...@@ -25,12 +28,14 @@ CheckDialog.schematronChooserTitle=W\u00e4hle Schematron Datei ... ...@@ -25,12 +28,14 @@ CheckDialog.schematronChooserTitle=W\u00e4hle Schematron Datei ...
CheckDialog.schematronFileLabel=Schematron Datei: CheckDialog.schematronFileLabel=Schematron Datei:
CheckDialog.schematronFileNotExisting=Schematron Datei existiert nicht, Schematron-Pr\u00fcfung wird \u00fcbersprungen CheckDialog.schematronFileNotExisting=Schematron Datei existiert nicht, Schematron-Pr\u00fcfung wird \u00fcbersprungen
CheckDialog.schematronFiles=Schematron Dateien CheckDialog.schematronFiles=Schematron Dateien
CheckDialog.selectAllChecksBtn=Alle aktivieren
CheckDialog.selectBtn=Ausw\u00e4hlen CheckDialog.selectBtn=Ausw\u00e4hlen
CheckDialog.semanticChecksLabel=Semantische Pr\u00fcfungen CheckDialog.semanticChecksLabel=Semantische Pr\u00fcfungen
CheckDialog.startingChecks=Starte Pr\u00fcfung CheckDialog.startingChecks=Starte Pr\u00fcfung
CheckDialog.streamCheckLabel=Stadtmodelle werden nicht in den Arbeitsspeicher geladen. Ergebnisse werden in der QualityADE in Kopien der Eingangsdateien gespeichert. CheckDialog.streamCheckLabel=Stadtmodelle werden nicht in den Arbeitsspeicher geladen. Ergebnisse werden in der QualityADE in Kopien der Eingangsdateien gespeichert.
CheckDialog.streamCheckOption=Niedrigen Arbeitsspeicherverbrauchsmodus aktivieren CheckDialog.streamCheckOption=Niedrigen Arbeitsspeicherverbrauchsmodus aktivieren
CheckDialog.title=Pr\u00fcfungskonfiguration CheckDialog.title=Pr\u00fcfungskonfiguration
CheckDialog.unselectAllChecksBtn=Alle deaktivieren
CheckDialog.validationConfiguration=Validierungskonfiguration CheckDialog.validationConfiguration=Validierungskonfiguration
CheckDialog.xmlReportsOption=XML-Berichte erstellen CheckDialog.xmlReportsOption=XML-Berichte erstellen
Checker.checkFeature=Pr\u00fcfe Feature: {} Checker.checkFeature=Pr\u00fcfe Feature: {}
...@@ -70,6 +75,9 @@ CityDoctorValidation.notExactlyOneOutputFile=Es muss exakt ein Ausgabedateipfad ...@@ -70,6 +75,9 @@ CityDoctorValidation.notExactlyOneOutputFile=Es muss exakt ein Ausgabedateipfad
CityDoctorValidation.notExactlyOnePDFOutput=Es muss exakt ein Ausgabedateipfad f\u00fcr den PDF-Bericht angegeben werden. CityDoctorValidation.notExactlyOnePDFOutput=Es muss exakt ein Ausgabedateipfad f\u00fcr den PDF-Bericht angegeben werden.
CityDoctorValidation.notExactlyOneXMLOutput=Es muss exakt ein Ausgabedateipfad f\u00fcr den XML-Bericht angegeben werden. CityDoctorValidation.notExactlyOneXMLOutput=Es muss exakt ein Ausgabedateipfad f\u00fcr den XML-Bericht angegeben werden.
CityDoctorValidation.wrongInputFileFormat=Eingabedatei '{}' ist keine .gml oder .xml Datei. CityDoctorValidation.wrongInputFileFormat=Eingabedatei '{}' ist keine .gml oder .xml Datei.
CityGmlFeatureMapper.crossFeatureReferencesDetected=Modell enth\u00e4lt Features mit Feature\u00fcbergreifenden Polygonreferenzen ohne eigene Duplikate
CityGmlFeatureMapper.emptyCrossFeatureReference=Polygon {} in Feature {} wird Feature\u00fcbergreifend referenziert durch Features: {}
CityGmlFeatureMapper.unresolvedReferencesDetected=Modell enth\u00e4lt Features mit Polygonreferenzen welche nicht aufgel\u00f6st werden konnten
CityGmlParser.chunkReadFailed=Konnte Datei nicht in St\u00fccken lesen, versuche komplett zu lesen CityGmlParser.chunkReadFailed=Konnte Datei nicht in St\u00fccken lesen, versuche komplett zu lesen
CityGmlParser.convertCrsToUtmZoneN=Konvertiere Koordinatensystem zu UTM Zone {}N CityGmlParser.convertCrsToUtmZoneN=Konvertiere Koordinatensystem zu UTM Zone {}N
CityGmlParser.convertCrsToUtmZoneS=Konvertiere Koordinatensystem zu UTM Zone {}S CityGmlParser.convertCrsToUtmZoneS=Konvertiere Koordinatensystem zu UTM Zone {}S
...@@ -99,6 +107,9 @@ DatabaseHandler.serializationFailure=Serialisierung des CityObject {} fehlgeschl ...@@ -99,6 +107,9 @@ DatabaseHandler.serializationFailure=Serialisierung des CityObject {} fehlgeschl
DatabaseHandler.setupFailure=KRITISCHER FEHLER: Erstellen der eingebetteten Datenbank fehlgeschlagen! DatabaseHandler.setupFailure=KRITISCHER FEHLER: Erstellen der eingebetteten Datenbank fehlgeschlagen!
DatabaseHandler.tableFailure=KRITISCHER FEHLER: Erstellen der "features" Tabelle fehlgeschlagen! DatabaseHandler.tableFailure=KRITISCHER FEHLER: Erstellen der "features" Tabelle fehlgeschlagen!
DatabaseHandler.unmarshallingFailure=Laden des CityObject {} aus der Datenbank fehlgeschlagen! DatabaseHandler.unmarshallingFailure=Laden des CityObject {} aus der Datenbank fehlgeschlagen!
DatabaseSettings.invalidPath=Einstellungen f\u00fcr Directory und Name der Datenbank bilden keinen validen Pfad. Standardwerte werden stattdessen genutzt
DatabaseSettings.poolSizeLessThanOne=ConnectionPoolSize Einstellung wurde auf unter 1 gesetzt. Standardwert wird stattdessen genutzt
DatabaseSettings.poolSizeNaN=ConnectionPoolSize Einstellung ist kein Integer. Standardwert wird stattdessen genutzt
DistanceError.distanceFromPlane=Abstand von der Ebene DistanceError.distanceFromPlane=Abstand von der Ebene
ErrorItemVisitor.childId=Kind ID ErrorItemVisitor.childId=Kind ID
ErrorItemVisitor.component=Komponente ErrorItemVisitor.component=Komponente
......
package de.hft.stuttgart.citydoctor2.database;
import org.junit.jupiter.api.Test;
public class DatabaseSettingsTest {
public void testSetLocation(){
String tempdirectory = System.getProperty("java.io.tmpdir");
DatabaseSettings.setDBLocation(tempdirectory + "/citydoctor");
}
}
...@@ -16,7 +16,6 @@ import de.hft.stuttgart.citydoctor2.parser.CityGmlParser; ...@@ -16,7 +16,6 @@ import de.hft.stuttgart.citydoctor2.parser.CityGmlParser;
import de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException; import de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import org.citygml4j.core.model.building.AbstractBuilding; import org.citygml4j.core.model.building.AbstractBuilding;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
...@@ -25,25 +24,44 @@ import java.util.List; ...@@ -25,25 +24,44 @@ import java.util.List;
import static de.hft.stuttgart.citydoctor2.database.SerializationTest.assertCityObjectEquality; import static de.hft.stuttgart.citydoctor2.database.SerializationTest.assertCityObjectEquality;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class EmbeddedDataBaseHandlerTest { public class EmbeddedDataBaseHandlerTest {
private EmbeddedDatabaseHandler handler; private final EmbeddedDatabaseHandler handler = new EmbeddedDatabaseHandler(new EmbeddedDatabaseConfiguration());
@Test
public void testTempFileConfiguration(){
EmbeddedDatabaseConfiguration tempFileconfig = new EmbeddedDatabaseConfiguration("database",
"inTempConfig",1, false,false,
false,true);
EmbeddedDatabaseHandler tempHandler = new EmbeddedDatabaseHandler(tempFileconfig);
assertTrue(tempHandler.getTempFileDBLocation().exists());
@Before
public void resetDatabase() {
try {
handler = new EmbeddedDatabaseHandler();
handler.setupFeaturesTable();
} catch (Exception e) {
fail(e.getMessage());
}
} }
@Test
public void testInMemoryConfiguration() throws CityGmlParseException, InvalidGmlFileException {
EmbeddedDatabaseConfiguration inMemoryConfig = new EmbeddedDatabaseConfiguration("database",
"irrelevant",1, true,false,
false,false);
EmbeddedDatabaseHandler memHandler = new EmbeddedDatabaseHandler(inMemoryConfig);
assertNull(memHandler.getTempFileDBLocation());
ParserConfiguration config = new ParserConfiguration(8, false);
CityDoctorModel model = CityGmlParser.nestedCityGmlFileParse("src/test/resources/SimpleSolid_SrefBS.gml", config);
Building b = model.getBuildings().toList().get(0);
assertEquals(0, memHandler.getFeatureCount());
memHandler.marshallCityObject(b);
assertEquals(1, memHandler.getFeatureCount());
CityObject co = memHandler.unmarshallCityObject(b.getGmlId());
assertNotNull(co);
assertTrue(co instanceof Building);
}
@Test @Test
public void testGetBboxIntersectingObjects() { public void testGetBboxIntersectingObjects() {
handler.setupFeaturesTable();
Building b = new Building(); Building b = new Building();
Building b2 = new Building(); Building b2 = new Building();
b2.setGmlObject(Mockito.mock(AbstractBuilding.class)); b2.setGmlObject(Mockito.mock(AbstractBuilding.class));
...@@ -124,6 +142,7 @@ public class EmbeddedDataBaseHandlerTest { ...@@ -124,6 +142,7 @@ public class EmbeddedDataBaseHandlerTest {
@Test @Test
public void testGetBboxBufferIntersectingObjects() { public void testGetBboxBufferIntersectingObjects() {
handler.setupFeaturesTable();
Building b = new Building(); Building b = new Building();
Building b2 = new Building(); Building b2 = new Building();
b2.setGmlObject(Mockito.mock(AbstractBuilding.class)); b2.setGmlObject(Mockito.mock(AbstractBuilding.class));
...@@ -210,6 +229,7 @@ public class EmbeddedDataBaseHandlerTest { ...@@ -210,6 +229,7 @@ public class EmbeddedDataBaseHandlerTest {
Building b = model.getBuildings().toList().get(0); Building b = model.getBuildings().toList().get(0);
assertNotNull(b); assertNotNull(b);
assertEquals(1, handler.getFeatureCount());
handler.marshallCityObject(b); handler.marshallCityObject(b);
assertEquals(1, handler.getFeatureCount()); assertEquals(1, handler.getFeatureCount());
......
...@@ -90,8 +90,8 @@ public class ImplicitGeometryTest { ...@@ -90,8 +90,8 @@ public class ImplicitGeometryTest {
assertFalse(lib.containsError(CheckId.C_GE_P_NON_PLANAR)); assertFalse(lib.containsError(CheckId.C_GE_P_NON_PLANAR));
igh.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); igh.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertFalse("ImplicitGeometryHolder's errors should be ignored and delegate the call to the prototype geometry", assertFalse(lib.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
lib.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); assertTrue(igh.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(lib.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); assertTrue(lib.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
...@@ -105,27 +105,39 @@ public class ImplicitGeometryTest { ...@@ -105,27 +105,39 @@ public class ImplicitGeometryTest {
@Test @Test
public void testClearAllContainedCheckResults() { public void testClearAllContainedCheckResults() {
igh.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null));
lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null)); lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null));
assertEquals(1, lib.getAllCheckResults().size()); assertEquals(1, lib.getAllCheckResults().size());
assertEquals(1, igh.getAllCheckResults().size());
lib.clearAllContainedCheckResults(); lib.clearAllContainedCheckResults();
assertTrue(lib.getAllCheckResults().isEmpty()); assertTrue(lib.getAllCheckResults().isEmpty());
assertEquals(1, igh.getAllCheckResults().size());
igh.clearAllContainedCheckResults();
assertTrue(igh.getAllCheckResults().isEmpty());
} }
@Test @Test
public void testContainsAnyError() { public void testContainsAnyError() {
assertFalse(lib.containsAnyError()); assertFalse(lib.containsAnyError());
assertFalse(igh.containsAnyError());
igh.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null)); igh.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null));
assertFalse(lib.containsAnyError()); assertFalse(lib.containsAnyError());
assertFalse(igh.containsAnyError());
lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null)); lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.OK, null));
assertFalse(lib.containsAnyError()); assertFalse(lib.containsAnyError());
assertFalse(igh.containsAnyError());
igh.addCheckResult( igh.addCheckResult(
new CheckResult(CheckId.C_GE_P_INNER_RINGS_NESTED, ResultStatus.ERROR, mock(CheckError.class))); new CheckResult(CheckId.C_GE_P_INNER_RINGS_NESTED, ResultStatus.ERROR, mock(CheckError.class)));
assertFalse(lib.containsAnyError()); assertFalse(lib.containsAnyError());
assertTrue(igh.containsAnyError());
lib.addCheckResult( lib.addCheckResult(
new CheckResult(CheckId.C_GE_P_INNER_RINGS_NESTED, ResultStatus.ERROR, mock(CheckError.class))); new CheckResult(CheckId.C_GE_P_INNER_RINGS_NESTED, ResultStatus.ERROR, mock(CheckError.class)));
assertTrue(lib.containsAnyError()); assertTrue(lib.containsAnyError());
assertTrue(igh.containsAnyError());
} }
@Test @Test
...@@ -134,19 +146,18 @@ public class ImplicitGeometryTest { ...@@ -134,19 +146,18 @@ public class ImplicitGeometryTest {
igh.addCheckResult(new CheckResult(CheckId.C_GE_P_NON_PLANAR, ResultStatus.ERROR, mock(CheckError.class))); igh.addCheckResult(new CheckResult(CheckId.C_GE_P_NON_PLANAR, ResultStatus.ERROR, mock(CheckError.class)));
igh.collectContainedErrors(errors); igh.collectContainedErrors(errors);
assertEquals("ImplicitGeometryHolder's errors should be ignored and delegate the call to the prototype geometry", assertEquals(1, errors.size());
0, errors.size()); errors.clear();
lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class))); lib.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, mock(CheckError.class)));
igh.collectContainedErrors(errors); igh.collectContainedErrors(errors);
assertEquals("ImplicitGeometryHolder's errors should be ignored and delegate the call to the prototype geometry", assertEquals(1, errors.size());
1, errors.size());
} }
@Test @Test
public void testAccept() { public void testAccept() {
int polyCount = lib.getPolygons().size(); int polyCount = igh.getPolygons().size();
AtomicInteger loCounter = new AtomicInteger(0); AtomicInteger loCounter = new AtomicInteger(0);
...@@ -157,7 +168,7 @@ public class ImplicitGeometryTest { ...@@ -157,7 +168,7 @@ public class ImplicitGeometryTest {
} }
}; };
igh.accept(c); igh.accept(c);
assertEquals("ImplicitGeometryHolder should only check polygons of prototype geometry", assertEquals("Visitors should only walk over ImplicitGeometryHolder",
polyCount, loCounter.intValue()); polyCount, loCounter.intValue());
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>de.hft.stuttgart</groupId> <groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorParent</artifactId> <artifactId>CityDoctorParent</artifactId>
<version>3.18.1</version> <version>3.18.3</version>
</parent> </parent>
<artifactId>CityDoctorValidation</artifactId> <artifactId>CityDoctorValidation</artifactId>
<name>CityDoctorValidation</name> <name>CityDoctorValidation</name>
......
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