entry : cacheContent.entrySet()) {
+ handler.marshallCityObject(entry.getValue());
+ }
+ }
+ }
+
+ /**
+ * Signals the cache that parsing is beginning.
+ */
+ private boolean beginParsing(){
+ return state.changeState(this, CacheState.PARSING);
+ }
+
+ /**
+ * Signals the cache that parsing has finished.
+ */
+ private void finishParsing() {
+ if (state == CacheState.PARSING && state.changeState(this, CacheState.IDLE)){
+ return;
+ }
+ throw new IllegalStateException("Cache failed to exit parsing mode");
+ }
+
+ /**
+ * Signals the cache that checking is beginning.
+ */
+ private boolean beginChecking(){
+ return state.changeState(this, CacheState.CHECKING);
+ }
+
+ /**
+ * Signals the cache that checking has finished.
+ */
+ private void finishChecking() {
+ if (state == CacheState.CHECKING && state.changeState(this, CacheState.IDLE)){
+ return;
+ }
+ throw new IllegalStateException("Cache failed to exit checking mode");
+ }
+
+ @Override
+ public AutoCloseable startParsingMode(){
+ if (this.beginParsing()){
+ return this::finishParsing;
+ } else throw new IllegalStateException("Cache is not in IDLE state, cannot start parsing mode");
+ }
+
+ @Override
+ public AutoCloseable startCheckingMode(){
+ if (this.beginChecking()){
+ return this::finishChecking;
+ } else throw new IllegalStateException("Cache is not in IDLE state, cannot start checking mode");
+ }
+
+ protected void setState(CacheState state) {
+ this.state = state;
+ }
+
+ public CacheState getState() {
+ return state;
+ }
+
+ public enum CacheState {
+ IDLE {
+ @Override
+ protected boolean changeState(FeatureCache cache, CacheState nextState) {
+ if (cache.getState() != this){
+ logger.debug("FeatureCache invoked changeState() of IDLE state while cache state is {}", cache.getState());
+ return false;
+ }
+ this.onExit(cache);
+ cache.setState(nextState);
+ nextState.onEntry(cache);
+ return true;
+ }
+
+ @Override
+ public void onEntry(FeatureCache cache) {
+ logger.trace("FeatureCache: Entering IDLE state");
+ // Idle state does nothing on entry
+ }
+
+ @Override
+ protected void onExit(FeatureCache cache) {
+ logger.trace("FeatureCache: Leaving IDLE state");
+ // Idle state does nothing on exit
+ }
+
+ }, PARSING {
+ @Override
+ protected boolean changeState(FeatureCache cache, CacheState nextState) {
+ if (cache.getState() != this){
+ logger.debug("FeatureCache invoked changeState() of PARSING state while cache state is {}", cache.getState());
+ return false;
+ }
+ boolean success = false;
+ switch (nextState){
+ case IDLE:
+ this.onExit(cache);
+ cache.setState(CacheState.IDLE);
+ success = true;
+ break;
+ case PARSING:
+ logger.debug("Tried to set cache to PARSING state while already parsing");
+ break;
+ case CHECKING:
+ logger.debug("Tried to set cache to CHECKING state while parsing");
+ break;
+ }
+ return success;
+ }
+
+ @Override
+ public void onEntry(FeatureCache cache) {
+ logger.trace("FeatureCache: Entering PARSING state");
+ cache.resetCache();
+ }
+
+ @Override
+ protected void onExit(FeatureCache cache) {
+ logger.trace("FeatureCache: Leaving PARSING state");
+ cache.synchronize();
+ }
+
+ }, CHECKING {
+ @Override
+ protected boolean changeState(FeatureCache cache, CacheState nextState) {
+ if (cache.getState() != this){
+ logger.debug("FeatureCache invoked changeState() of CHECKING state while cache state is {}", cache.getState());
+ return false;
+ }
+ boolean success = false;
+ switch (nextState){
+ case IDLE:
+ this.onExit(cache);
+ cache.setState(CacheState.IDLE);
+ success = true;
+ break;
+ case PARSING:
+ logger.debug("Tried to set cache to PARSING state while checking");
+ break;
+ case CHECKING:
+ logger.debug("Tried to set cache to CHECKING state while already checking");
+ break;
+ }
+ return success;
+ }
+
+ @Override
+ public void onEntry(FeatureCache cache) {
+ logger.trace("FeatureCache: Entering CHECKING state");
+
+ }
+
+ @Override
+ protected void onExit(FeatureCache cache) {
+ logger.trace("FeatureCache: Leaving CHECKING state");
+ cache.synchronize();
+ }
+
+
+ };
+
+ /**
+ * Signals the statemachine to change the state of the FeatureCache. Returns true if the state successfully
+ * changed, false otherwise with the FeatureCache remaining in its current state.
+ * @param cache the FeatureCache instance
+ * @param nextState the requested next state
+ * @return true if the cache successfully changed state, false otherwise
+ */
+ protected abstract boolean changeState(FeatureCache cache, CacheState nextState);
+ protected abstract void onEntry(FeatureCache cache);
+ protected abstract void onExit(FeatureCache cache);
+ }
+}
+
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/database/UnconnectedCache.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/database/UnconnectedCache.java
new file mode 100644
index 0000000000000000000000000000000000000000..8033e63461e8719c59b4946da2513db40bf9ba35
--- /dev/null
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/database/UnconnectedCache.java
@@ -0,0 +1,85 @@
+package de.hft.stuttgart.citydoctor2.database;
+
+import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
+import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
+import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Stream;
+
+/**
+ * An adapter implementation for CityObjectCache, wrapping the Interface around a simple HashMap.
+ *
+ * This class is intended to allow parsing or checking {@link CityDoctorModel CityDoctorModels} in specific cases where the model
+ * must not use the {@link FeatureCache}, like resolving of {@link de.hft.stuttgart.citydoctor2.datastructure.LibraryObject LibraryObject}
+ * files or mocking of the Interface in unit tests.
+ *
+ */
+public class UnconnectedCache implements CityObjectCache{
+
+ private final Map cache;
+ private boolean idle = true;
+
+ public UnconnectedCache() {
+ cache = new HashMap<>();
+ }
+
+ @Override
+ public void put(CityObject cityObject) {
+ cache.put(cityObject.getGmlId(), cityObject);
+ }
+
+ @Override
+ public CityObject get(GmlId id) {
+ return cache.get(id);
+ }
+
+ @Override
+ public void replace(GmlId id, CityObject cityObject) {
+ cache.put(id, cityObject);
+ }
+
+ @Override
+ public Stream getStream(List ids) {
+ return cache.values().stream().filter(c -> ids.contains(c.getGmlId()));
+ }
+
+ @Override
+ public int getTotalFeatureCount() {
+ return cache.size();
+ }
+
+ public void resetCache(){
+ cache.clear();
+ }
+
+ @Override
+ public List getErrorFeatureIds() {
+ List errorFeatureIds = new ArrayList<>();
+ cache.forEach((gmlId, cityObject) ->{
+ if (cityObject.containsAnyError()){
+ errorFeatureIds.add(cityObject.getGmlId());
+ }
+ });
+ return errorFeatureIds;
+ }
+
+ @Override
+ public AutoCloseable startParsingMode() {
+ if (idle){
+ idle = false;
+ return ()-> idle=true;
+ } else throw new IllegalStateException("Cache is not idle, could not start parsing mode");
+ }
+
+ @Override
+ public AutoCloseable startCheckingMode() {
+ if (idle){
+ idle = false;
+ return ()-> idle=true;
+ } else throw new IllegalStateException("Cache is not idle, could not start checking mode");
+ }
+}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundarySurface.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundarySurface.java
index 9fa5066c6b7917a93c983831d4a05b99df03c0c3..c3dd9d63d95482e9e1bf942bc60755c036988079 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundarySurface.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundarySurface.java
@@ -40,7 +40,7 @@ public class BoundarySurface extends CityObject {
@Serial
private static final long serialVersionUID = 8793865135393496408L;
- private SurfaceFeatureType featureType;
+
private BoundarySurfaceType type;
private final List openings = new ArrayList<>(2);
@@ -49,18 +49,14 @@ public class BoundarySurface extends CityObject {
private AbstractThematicSurface gmlObject;
public BoundarySurface(AbstractThematicSurface aco) {
- this(SurfaceFeatureType.BUILDING, BoundarySurfaceType.UNDEFINED, aco);
+ this(BoundarySurfaceType.UNDEFINED, aco);
}
- public BoundarySurface(SurfaceFeatureType featureType, BoundarySurfaceType type, AbstractThematicSurface aco) {
- this.featureType = featureType;
+ public BoundarySurface(BoundarySurfaceType type, AbstractThematicSurface aco) {
this.type = type;
gmlObject = aco;
}
- public void setFeatureType(SurfaceFeatureType featureType) {
- this.featureType = featureType;
- }
public void setType(BoundarySurfaceType type) {
this.type = type;
@@ -70,9 +66,6 @@ public class BoundarySurface extends CityObject {
this.gmlObject = gmlObject;
}
- public SurfaceFeatureType getSurfaceFeatureType() {
- return featureType;
- }
public BoundarySurfaceType getType() {
return type;
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundingBox.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundingBox.java
index f2d535fefc886a4b077859379718bf1a0323a35c..bf5ac32651cdd9f0f4c048e8dc5e6764feed8e04 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundingBox.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BoundingBox.java
@@ -20,9 +20,11 @@ package de.hft.stuttgart.citydoctor2.datastructure;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
import de.hft.stuttgart.citydoctor2.utils.BoundingBoxCalculator;
+import de.hft.stuttgart.citydoctor2.utils.visitors.MinMaxExtentVisitor;
import java.util.Collection;
import java.util.List;
+import java.util.Locale;
/**
* An axis aligned bounding box represented by its two corners
@@ -47,6 +49,12 @@ public class BoundingBox {
return BoundingBoxCalculator.calculateBoundingBoxFromPoints(points);
}
+ public static BoundingBox of(CityObject co) {
+ MinMaxExtentVisitor mima = new MinMaxExtentVisitor();
+ co.accept(mima);
+ return BoundingBox.of(mima.getMinMaxExtent());
+ }
+
/**
* Creates an axis aligned bounding box of the whole model.
*
@@ -161,4 +169,45 @@ public class BoundingBox {
public double getDiagonalLength() {
return bbox[1].getDistance(bbox[0]);
}
+
+ /**
+ * Returns whether this BoundinBox is undefined, meaning that one or all corners are infinite.
+ * @return True if the BoundingBox is undefined, false otherwise
+ */
+ public boolean isUndefined(){
+ double x1 = bbox[0].getX();
+ double y1 = bbox[0].getY();
+ double x2 = bbox[1].getX();
+ double y2 = bbox[1].getY();
+ return (Double.isInfinite(x1) || Double.isInfinite(y1) || Double.isInfinite(x2) || Double.isInfinite(y2));
+ }
+
+ /**
+ * Returns an axis-aligned 2D polygon projection of this bbox as a WKT String.
+ *
+ * An undefined bbox will return an empty polygon.
+ * @return The 2D polygon WKT for this bbox
+ */
+ public String to2DWkt() {
+ if (this.isUndefined()){
+ return "POLYGON EMPTY";
+ }
+ double x1 = bbox[0].getX();
+ double y1 = bbox[0].getY();
+ double x2 = bbox[1].getX();
+ double y2 = bbox[1].getY();
+
+ double minX = Math.min(x1, x2);
+ double minY = Math.min(y1, y2);
+ double maxX = Math.max(x1, x2);
+ double maxY = Math.max(y1, y2);
+
+ return String.format(Locale.ROOT,"POLYGON((%.3f %.3f, %.3f %.3f, %.3f %.3f, %.3f %.3f, %.3f %.3f))",
+ minX, minY,
+ maxX, minY,
+ maxX, maxY,
+ minX, maxY,
+ minX, minY
+ );
+ }
}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BridgeObject.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BridgeObject.java
index b87b232e05b2edcbb9c3d544dd78271b920c6ff1..f87d6feaabee26656fca23da56fe725f9a542681 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BridgeObject.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BridgeObject.java
@@ -61,15 +61,11 @@ public class BridgeObject extends CityObject {
private BridgeObject parent;
public BridgeObject(AbstractBridge ab) {
- this.ab = ab;
- this.type = BridgeType.BRIDGE;
- this.parent = null;
+ this(BridgeType.BRIDGE, ab, null);
}
public BridgeObject(AbstractBridge ab, BridgeObject parent) {
- this.ab = ab;
- this.type = BridgeType.BRIDGE_PART;
- this.parent = parent;
+ this(BridgeType.BRIDGE_PART, ab, parent);
}
private BridgeObject(BridgeType type, AbstractBridge ab, BridgeObject parent) {
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BuildingConstructiveElement.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BuildingConstructiveElement.java
index 06763aeb0424a67c0874014f45468214d09a18f7..8ac60a11ac54a504deddfbe30bfe603fdcaf6af1 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BuildingConstructiveElement.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/BuildingConstructiveElement.java
@@ -1,25 +1,22 @@
package de.hft.stuttgart.citydoctor2.datastructure;
-import de.hft.stuttgart.citydoctor2.check.CheckableVisitor;
-import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
-import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils;
-import javafx.scene.paint.Color;
+import java.io.Serial;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.citygml4j.core.model.core.AbstractSpaceBoundaryProperty;
-import org.citygml4j.core.model.deprecated.bridge.DeprecatedPropertiesOfBridgeConstructiveElement;
import org.citygml4j.core.util.geometry.GeometryFactory;
-import org.xmlobjects.gml.model.geometry.GeometryProperty;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
-import org.xmlobjects.gml.model.geometry.complexes.CompositeSurface;
import org.xmlobjects.gml.model.geometry.primitives.Solid;
import org.xmlobjects.gml.model.geometry.primitives.SolidProperty;
-import org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty;
-import java.io.Serial;
-import java.util.ArrayList;
-import java.util.List;
+import de.hft.stuttgart.citydoctor2.check.CheckableVisitor;
+import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
+import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils;
+import javafx.scene.paint.Color;
public class BuildingConstructiveElement extends CityObject {
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/CityDoctorModel.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/CityDoctorModel.java
index 41b2b003f4b2a7581b20a263405e6c2db74b3d17..ba0be98f219adfe4c55ff770fa05c6bdca1a70f9 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/CityDoctorModel.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/CityDoctorModel.java
@@ -20,6 +20,8 @@ package de.hft.stuttgart.citydoctor2.datastructure;
import de.hft.stuttgart.citydoctor2.check.CheckableUtilsVisitor;
import de.hft.stuttgart.citydoctor2.check.CheckError;
+import de.hft.stuttgart.citydoctor2.check.CheckableVisitor;
+import de.hft.stuttgart.citydoctor2.database.CityObjectCache;
import de.hft.stuttgart.citydoctor2.exceptions.CityDoctorWriteException;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.writer.CityGMLWriterUtils;
@@ -45,15 +47,15 @@ import java.util.stream.Stream;
public class CityDoctorModel {
private static final String COULD_NOT_FIND_FEATURE = "Could not find feature: ";
- private final List buildings;
- private final List vegetation;
- private final List bridges;
- private final List cityfurniture;
- private final List genericObjects;
- private final List land;
- private final List roads;
- private final List tunnels;
- private final List water;
+ private final List buildings;
+ private final List vegetation;
+ private final List bridges;
+ private final List cityfurniture;
+ private final List genericObjects;
+ private final List land;
+ private final List roads;
+ private final List tunnels;
+ private final List water;
private CityModel cModel;
private final ParserConfiguration config;
private final String fileName;
@@ -62,11 +64,15 @@ public class CityDoctorModel {
private boolean isValidated = false;
private ValidationPlan plan;
private CityGMLVersion cityGMLVersion;
+ private final CityObjectCache cache;
- public CityDoctorModel(ParserConfiguration config, File file) {
+ public CityDoctorModel(ParserConfiguration config, File file, CityObjectCache cache) {
if (config == null) {
throw new IllegalArgumentException("Parser configuration may not be null");
}
+ if( file == null ) {
+ throw new IllegalArgumentException("File may not be null");
+ }
this.fileName = file.getName();
this.config = config;
this.file = file;
@@ -80,6 +86,7 @@ public class CityDoctorModel {
cityfurniture = new ArrayList<>();
genericObjects = new ArrayList<>();
globalErrors = new ArrayList<>();
+ this.cache = cache;
}
public boolean isValidated() {
@@ -117,8 +124,59 @@ public class CityDoctorModel {
}
public Stream createFeatureStream() {
- return Stream.of(buildings.stream(), vegetation.stream(), bridges.stream(), land.stream(), roads.stream(),
- tunnels.stream(), water.stream(), cityfurniture.stream(), genericObjects.stream()).flatMap(co -> co);
+ return Stream.of(getBuildings(), getVegetation(), getBridges(), getLand(), getTransportation(),
+ getTunnels(), getWater(), getCityFurniture(), getOtherCityObjects()).flatMap(co -> co);
+ }
+
+ public List getFeatureIds() {
+ List featureIds = new ArrayList<>();
+ featureIds.addAll(buildings);
+ featureIds.addAll(vegetation);
+ featureIds.addAll(bridges);
+ featureIds.addAll(land);
+ featureIds.addAll(roads);
+ featureIds.addAll(tunnels);
+ featureIds.addAll(water);
+ featureIds.addAll(cityfurniture);
+ featureIds.addAll(genericObjects);
+ return featureIds;
+
+ }
+
+ public boolean containsGmlId(String id) {
+ if (id == null) {
+ return false;
+ }
+ GmlId gmlId = new GmlId(id);
+ if (buildings.contains(gmlId)) {
+ return true;
+ }
+ if (vegetation.contains(gmlId)) {
+ return true;
+ }
+ if (bridges.contains(gmlId)) {
+ return true;
+ }
+ if (land.contains(gmlId)) {
+ return true;
+ }
+ if (roads.contains(gmlId)) {
+ return true;
+ }
+ if (tunnels.contains(gmlId)) {
+ return true;
+ }
+ if (water.contains(gmlId)) {
+ return true;
+ }
+ if (cityfurniture.contains(gmlId)) {
+ return true;
+ }
+ return genericObjects.contains(gmlId);
+ }
+
+ public void accept(CheckableVisitor visitor) {
+ createFeatureStream().forEach(cityObject -> cityObject.accept(visitor));
}
public void saveAs(String file, boolean saveQualityAde) throws CityDoctorWriteException {
@@ -136,6 +194,7 @@ public class CityDoctorModel {
}
}
+
private void exportAsGML(String file) throws CityDoctorWriteException {
CityGMLWriterUtils.writeCityModel(file, this);
}
@@ -215,106 +274,201 @@ public class CityDoctorModel {
public Set collectErrors() {
List errors = new ArrayList<>();
- collectErrorsFromList(errors, buildings);
- collectErrorsFromList(errors, vegetation);
- collectErrorsFromList(errors, bridges);
- collectErrorsFromList(errors, land);
- collectErrorsFromList(errors, roads);
- collectErrorsFromList(errors, tunnels);
- collectErrorsFromList(errors, water);
- collectErrorsFromList(errors, cityfurniture);
- collectErrorsFromList(errors, genericObjects);
+ createFeatureStream().forEach(cityObject -> cityObject.collectErrors(errors));
return new HashSet<>(errors);
}
- private void collectErrorsFromList(List errors, List extends CityObject> cos) {
- for (CityObject co : cos) {
- co.collectContainedErrors(errors);
- }
- }
public String getFileName() {
return fileName;
}
- public void addBridge(BridgeObject coBridge) {
- bridges.add(coBridge);
- }
public void addBuilding(Building coBuilding) {
- buildings.add(coBuilding);
+ buildings.add(coBuilding.getGmlId());
+ cache.put(coBuilding);
}
- public List getBuildings() {
+ public void removeFeature(GmlId id){
+ buildings.remove(id);
+ vegetation.remove(id);
+ bridges.remove(id);
+ land.remove(id);
+ roads.remove(id);
+ tunnels.remove(id);
+ water.remove(id);
+ cityfurniture.remove(id);
+ genericObjects.remove(id);
+ }
+
+ public Stream getBuildings() {
+ return buildings.stream().map(co -> (Building) cache.get(co));
+ }
+
+ public List getBuildingIds() {
return buildings;
}
- public List getBridges() {
+ public int getBuildingCount(){
+ return buildings.size();
+ }
+
+ public void addBridge(BridgeObject coBridge) {
+ bridges.add(coBridge.getGmlId());
+ cache.put(coBridge);
+ }
+
+ public Stream getBridges() {
+ return bridges.stream().map(co -> (BridgeObject) cache.get(co));
+ }
+
+ public List getBridgeIds() {
return bridges;
}
- public List getCityFurniture() {
- return cityfurniture;
+ public int getBridgeCount(){
+ return bridges.size();
}
public void addCityFurniture(CityFurniture coFurniture) {
- cityfurniture.add(coFurniture);
+ cityfurniture.add(coFurniture.getGmlId());
+ cache.put(coFurniture);
+ }
+
+ public Stream getCityFurniture() {
+ return cityfurniture.stream().map(co -> (CityFurniture) cache.get(co));
+ }
+
+ public List getCityFurnitureIds() {
+ return cityfurniture;
+ }
+
+ public int getCityFurnitureCount(){
+ return cityfurniture.size();
+ }
+
+ public void addOtherCityObject(CityObject otherCityObject) {
+ genericObjects.add(otherCityObject.getGmlId());
+ cache.put(otherCityObject);
}
- public List getGenericCityObjects() {
+ public Stream getOtherCityObjects() {
+ return genericObjects.stream().map(cache::get);
+ }
+
+ public List getOtherCityObjectsIds() {
return genericObjects;
}
- public void addGenericCityObject(GenericCityObject coGenericCityObject) {
- genericObjects.add(coGenericCityObject);
+ public int getOtherCityObjectsCount(){
+ return genericObjects.size();
}
- public void setCityModel(CityModel cModel) {
- this.cModel = cModel;
+ public void addTransportation(TransportationObject to) {
+ roads.add(to.getGmlId());
+ cache.put(to);
}
- public CityModel getCityModel() {
- return cModel;
+ public Stream getTransportation() {
+ return roads.stream().map(co -> (TransportationObject) cache.get(co));
}
- public List getTransportation() {
+ public List getTransportationIds() {
return roads;
}
- public List getTunnels() {
- return tunnels;
+ public int getTransportationCount(){
+ return roads.size();
}
- public List getWater() {
- return water;
+ public void addTunnel(Tunnel tunnel) {
+ tunnels.add(tunnel.getGmlId());
+ cache.put(tunnel);
}
- public List getLand() {
- return land;
+ public Stream getTunnels() {
+ return tunnels.stream().map(co -> (Tunnel) cache.get(co));
}
- public List getVegetation() {
- return vegetation;
+ public List getTunnelIds() {
+ return tunnels;
+ }
+
+ public int getTunnelCount(){
+ return tunnels.size();
}
public void addWater(WaterObject wo) {
- water.add(wo);
+ water.add(wo.getGmlId());
+ cache.put(wo);
+ }
+
+ public Stream getWater() {
+ return water.stream().map(co -> (WaterObject) cache.get(co));
+ }
+
+ public List getWaterIds() {
+ return water;
+ }
+
+ public int getWaterCount(){
+ return water.size();
}
public void addLand(LandObject lo) {
- land.add(lo);
+ land.add(lo.getGmlId());
+ cache.put(lo);
+ }
+
+ public void addRelief(ReliefObject relief) {
+ land.add(relief.getGmlId());
+ cache.put(relief);
+ }
+
+ public void addTin(TinObject tin) {
+ land.add(tin.getGmlId());
+ cache.put(tin);
+ }
+
+ public Stream getLand() {
+ return land.stream().map(cache::get);
+ }
+
+ public List getLandIds() {
+ return land;
+ }
+
+ public int getLandCount(){
+ return land.size();
}
public void addVegetation(Vegetation veg) {
- vegetation.add(veg);
+ vegetation.add(veg.getGmlId());
+ cache.put(veg);
}
- public void addTransportation(TransportationObject to) {
- roads.add(to);
+ public Stream getVegetation() {
+ return vegetation.stream().map(co -> (Vegetation) cache.get(co));
}
- public void addTunnel(Tunnel tunnel) {
- tunnels.add(tunnel);
+ public List getVegetationIds() {
+ return vegetation;
+ }
+
+ public int getVegetationCount(){
+ return vegetation.size();
+ }
+
+ public void setCityModel(CityModel cModel) {
+ this.cModel = cModel;
+ }
+
+ public CityModel getCityModel() {
+ return cModel;
+ }
+
+ public CityObjectCache getCache(){
+ return cache;
}
public int getNumberOfFeatures() {
@@ -349,100 +503,109 @@ public class CityDoctorModel {
}
private void replaceWaterObject(CityObject currentFeature, CityObject nextFeature) {
- int index = water.indexOf(currentFeature);
+ int index = water.indexOf(currentFeature.getGmlId());
if (index == -1) {
throw new IllegalStateException(COULD_NOT_FIND_FEATURE + currentFeature + " in water objects");
}
- water.set(index, (WaterObject) nextFeature);
+ cache.replace(currentFeature.getGmlId(), nextFeature);
+ water.set(index, nextFeature.getGmlId());
}
private void replaceLandObject(CityObject currentFeature, CityObject nextFeature) {
- int index = land.indexOf(currentFeature);
+ int index = land.indexOf(currentFeature.getGmlId());
if (index == -1) {
throw new IllegalStateException(COULD_NOT_FIND_FEATURE + currentFeature + " in land objects");
}
- land.set(index, nextFeature);
+ cache.replace(currentFeature.getGmlId(), nextFeature);
+ land.set(index, nextFeature.getGmlId());
}
private void replaceVegetation(CityObject currentFeature, CityObject nextFeature) {
- int index = vegetation.indexOf(currentFeature);
+ int index = vegetation.indexOf(currentFeature.getGmlId());
if (index == -1) {
throw new IllegalStateException(COULD_NOT_FIND_FEATURE + currentFeature + " in vegetation");
}
- vegetation.set(index, (Vegetation) nextFeature);
+ cache.replace(currentFeature.getGmlId(), nextFeature);
+ vegetation.set(index, nextFeature.getGmlId());
}
private void replaceCityFurniture(CityObject currentFeature, CityObject nextFeature) {
- int index = cityfurniture.indexOf(currentFeature);
+ int index = cityfurniture.indexOf(currentFeature.getGmlId());
if (index == -1) {
throw new IllegalStateException(COULD_NOT_FIND_FEATURE + currentFeature + " in vegetation");
}
- cityfurniture.set(index, (CityFurniture) nextFeature);
+ cache.replace(currentFeature.getGmlId(), nextFeature);
+ cityfurniture.set(index, nextFeature.getGmlId());
}
private void replaceGenericCityObject(CityObject currentFeature, CityObject nextFeature) {
- int index = genericObjects.indexOf(currentFeature);
+ int index = genericObjects.indexOf(currentFeature.getGmlId());
if (index == -1) {
throw new IllegalStateException(COULD_NOT_FIND_FEATURE + currentFeature + " in generic city objects");
}
- genericObjects.set(index, (GenericCityObject) nextFeature);
+ cache.replace(currentFeature.getGmlId(), nextFeature);
+ genericObjects.set(index, nextFeature.getGmlId());
}
private void replaceTransportationObject(CityObject currentFeature, CityObject nextFeature) {
- int index = roads.indexOf(currentFeature);
+ int index = roads.indexOf(currentFeature.getGmlId());
if (index == -1) {
throw new IllegalStateException(COULD_NOT_FIND_FEATURE + currentFeature + " in transportation objects");
}
- roads.set(index, (TransportationObject) nextFeature);
+ cache.replace(currentFeature.getGmlId(), nextFeature);
+ roads.set(index, nextFeature.getGmlId());
}
private void replaceTunnel(CityObject currentFeature, CityObject nextFeature) {
- int index = tunnels.indexOf(currentFeature);
+ int index = tunnels.indexOf(currentFeature.getGmlId());
if (index == -1) {
throw new IllegalStateException(COULD_NOT_FIND_FEATURE + currentFeature + " in tunnels");
}
- tunnels.set(index, (Tunnel) nextFeature);
+ cache.replace(currentFeature.getGmlId(), nextFeature);
+ tunnels.set(index, nextFeature.getGmlId());
}
private void replaceBridge(CityObject currentFeature, CityObject nextFeature) {
- int index = bridges.indexOf(currentFeature);
+ int index = bridges.indexOf(currentFeature.getGmlId());
if (index == -1) {
throw new IllegalStateException(COULD_NOT_FIND_FEATURE + currentFeature + " in bridges");
}
- bridges.set(index, (BridgeObject) nextFeature);
+ cache.replace(currentFeature.getGmlId(), nextFeature);
+ bridges.set(index, nextFeature.getGmlId());
}
private void replaceBuilding(CityObject currentFeature, CityObject nextFeature) {
- int index = buildings.indexOf(currentFeature);
+ int index = buildings.indexOf(currentFeature.getGmlId());
if (index == -1) {
throw new IllegalStateException(COULD_NOT_FIND_FEATURE + currentFeature + " in buildings");
}
- buildings.set(index, (Building) nextFeature);
+ cache.replace(currentFeature.getGmlId(), nextFeature);
+ buildings.set(index, nextFeature.getGmlId());
}
public void addCityObject(CityObject co) {
if (co instanceof Building b) {
- buildings.add(b);
+ buildings.add(b.getGmlId());
} else if (co instanceof BridgeObject bo) {
- bridges.add(bo);
+ bridges.add(bo.getGmlId());
} else if (co instanceof TransportationObject to) {
- roads.add(to);
+ roads.add(to.getGmlId());
} else if (co instanceof Tunnel tu) {
- tunnels.add(tu);
+ tunnels.add(tu.getGmlId());
} else if (co instanceof Vegetation veg) {
- vegetation.add(veg);
+ vegetation.add(veg.getGmlId());
} else if (co instanceof LandObject lo) {
- land.add(lo);
+ land.add(lo.getGmlId());
} else if (co instanceof WaterObject wo) {
- water.add(wo);
+ water.add(wo.getGmlId());
} else if (co instanceof ReliefObject) {
- land.add(co);
+ land.add(co.getGmlId());
} else if (co instanceof TinObject) {
- land.add(co);
+ land.add(co.getGmlId());
} else if (co instanceof CityFurniture cf) {
- cityfurniture.add(cf);
+ cityfurniture.add(cf.getGmlId());
} else if (co instanceof GenericCityObject gco) {
- genericObjects.add(gco);
+ genericObjects.add(gco.getGmlId());
}
}
@@ -454,11 +617,4 @@ public class CityDoctorModel {
return cityGMLVersion;
}
- public void addRelief(ReliefObject relief) {
- addCityObject(relief);
- }
-
- public void addTin(TinObject tin) {
- addCityObject(tin);
- }
}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/FeatureType.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/FeatureType.java
index cb49e1e0be23185738391db890f127310de131c0..11a8e687b14ee8ba5a78cb68c0c2374878de7156 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/FeatureType.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/FeatureType.java
@@ -27,5 +27,5 @@ public enum FeatureType {
BUILDING, TRANSPORTATION, VEGETATION, BRIDGE, LAND, WATER, BOUNDARY_SURFACE, INSTALLATION, OPENING,
BUILDING_PART, BUILDING_SUBDIVISION, BRIDGE_CONSTRUCTION_ELEMENT, BRIDGE_INSTALLATION, ROOM, FURNITURE, CITY_FURNITURE,
- GENERIC_CITY_OBJECT, TUNNEL, TUNNEL_PART, TUNNEL_CONSTRUCTION_ELEMENT, TUNNEL_INSTALLATION,
+ OTHER_CITY_OBJECT, TUNNEL, TUNNEL_PART, TUNNEL_CONSTRUCTION_ELEMENT, TUNNEL_INSTALLATION,
}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/GenericAttribute.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/GenericAttribute.java
index 041c688b98d2a2f5cd3bb1dc7479967545dd5f68..835a0fd2b3f21875dfe6d8eeca34c8e6015b9f01 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/GenericAttribute.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/GenericAttribute.java
@@ -5,8 +5,16 @@ import org.apache.logging.log4j.Logger;
import org.citygml4j.core.model.core.AbstractGenericAttributeProperty;
import org.citygml4j.core.model.generics.*;
+import java.io.Serial;
+import java.io.Serializable;
-public class GenericAttribute {
+import java.util.List;
+
+
+public class GenericAttribute implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = -4101408947632132328L;
private static final Logger logger = LogManager.getLogger(GenericAttribute.class);
@@ -45,6 +53,22 @@ public class GenericAttribute {
} else if (attributeProperty.getObject() instanceof CodeAttribute ca) {
type = String.format("CodeAttribute (%s)", ca.getValue().getLanguage());
value = String.format("'''%s''' %n CodeSpace: %s", ca.getValue().getValue(), ca.getValue().getCodeSpace());
+ } else if (attributeProperty.getObject() instanceof GenericAttributeSet gas) {
+ type = "GenericAttributeSet";
+ List attributes = gas.getValue();
+ StringBuilder sb = new StringBuilder();
+ sb.append("{");
+ for (AbstractGenericAttributeProperty attribute : attributes) {
+ if (attribute.getObject() != null) {
+ sb.append(attribute.getObject().getName());
+ sb.append(" = ");
+ sb.append(attribute.getObject().getValue());
+ sb.append("; ");
+ }
+ }
+ sb.replace(sb.length() - 1, sb.length(), "}");
+ value = String.format("'%s'", sb);
+
} else {
logger.warn("GenericAttribute {} is of unknown type {}", attributeProperty, attributeProperty.getObject());
value = attributeProperty.getObject().getValue().toString();
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/GenericCityObject.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/GenericCityObject.java
index 34a0d022d9975433061979ff8043e724dd38f5b8..a8aa7bfb1a0c89fd3b0e3780400a7d1031d09421 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/GenericCityObject.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/GenericCityObject.java
@@ -111,7 +111,7 @@ public class GenericCityObject extends CityObject {
cgmlGos.getDeprecatedProperties().setLod4Geometry(new SolidProperty(solid));
break;
default:
- throw new IllegalStateException("Cannot add " + geom.getLod() + " solid to buildings");
+ throw new IllegalStateException("Cannot add " + geom.getLod() + " solid to generic city object");
}
}
@Override
@@ -121,7 +121,7 @@ public class GenericCityObject extends CityObject {
@Override
public FeatureType getFeatureType() {
- return FeatureType.GENERIC_CITY_OBJECT;
+ return FeatureType.OTHER_CITY_OBJECT;
}
public List getBoundarySurfaces() {
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Geometry.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Geometry.java
index d7c17240faa18fbbd5a789468956d4ac75983b18..f2c0d41942e725d652ad7e9567285902f0a78d9d 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Geometry.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Geometry.java
@@ -26,6 +26,8 @@ import de.hft.stuttgart.citydoctor2.utils.BoundingBoxCalculator;
import de.hft.stuttgart.citydoctor2.utils.SerializablePair;
import javafx.scene.paint.Color;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.io.Serial;
import java.util.*;
@@ -53,9 +55,9 @@ public class Geometry extends GmlElement {
private CityObject parent;
private final List polygons = new ArrayList<>(2);
- private List edges;
- private Map, Edge> edgeMap;
- private List vertices;
+ private transient List edges;
+ private transient Map, Edge> edgeMap;
+ private transient List vertices;
private Orientation orientation;
public Geometry(GeometryType type, Lod lod, Orientation orientation) {
@@ -344,6 +346,12 @@ public class Geometry extends GmlElement {
return false;
}
+ @Serial
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ edges = new ArrayList<>();
+ edgeMap = new HashMap<>();
+ }
public void clearMetaData() {
if (vertices != null) {
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/ImplicitGeometryHolder.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/ImplicitGeometryHolder.java
index 872725ee41cc8342b4314d99e00aaf3ba7eeee05..8285eb93603f0dee513600bb648b20d1e0c9f80b 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/ImplicitGeometryHolder.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/ImplicitGeometryHolder.java
@@ -1,8 +1,14 @@
package de.hft.stuttgart.citydoctor2.datastructure;
import java.io.Serial;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import de.hft.stuttgart.citydoctor2.check.CheckableVisitor;
+import de.hft.stuttgart.citydoctor2.database.CityObjectCache;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
import org.citygml4j.core.model.core.ImplicitGeometry;
import de.hft.stuttgart.citydoctor2.math.TransformationMatrix;
@@ -16,9 +22,15 @@ public class ImplicitGeometryHolder extends Geometry {
@Serial
private static final long serialVersionUID = -8938931081577196349L;
+ private static final Logger logger = LogManager.getLogger(ImplicitGeometryHolder.class);
- private ImplicitGeometry cgmlImplicitGeometry = null;
+ public enum PrototypeGeometryType {
+ LIBRARY_OBJECT, RELATIVE_GEOMETRY
+ }
+
+ private ImplicitGeometry cgmlImplicitGeometry = null;
+ private static ConcurrentHashMap deferredRelGeomObjects = new ConcurrentHashMap<>();
private final PrototypeGeometryType type;
private final Geometry prototypeGeometry;
@@ -38,7 +50,46 @@ public class ImplicitGeometryHolder extends Geometry {
applyTransformation();
}
+ public static ImplicitGeometryHolder deferRelativeGeomParsing(ImplicitGeometry ig, Lod lod) {
+ ImplicitGeometryHolder igh = new ImplicitGeometryHolder(lod);
+ deferredRelGeomObjects.put(igh, ig);
+ return igh;
+ }
+ public static void resolveDeferredObjects(CityObjectCache cache) {
+ Set missingGeoms = new HashSet<>();
+ if(!deferredRelGeomObjects.isEmpty()) {
+ logger.info("Resolving deferred relative geometries");
+ }
+ for (ImplicitGeometryHolder key : deferredRelGeomObjects.keySet()) {
+ ImplicitGeometry ig = deferredRelGeomObjects.get(key);
+ String hrefId = ig.getRelativeGeometry().getHref();
+ hrefId = hrefId.startsWith("#") ? hrefId.substring(1) : hrefId;
+ GmlId gmlId = new GmlId(hrefId);
+ RelativeGeometry relGeom = RelativeGeometry.of(gmlId);
+ if (relGeom != null) {
+ ImplicitGeometryHolder igh = new ImplicitGeometryHolder(ig, relGeom);
+ CityObject parent = cache.get(key.getParent().getGmlId());
+ parent.removeGeometry(igh.getLod(), igh.getType());
+ parent.addGeometry(igh);
+ } else {
+ missingGeoms.add(gmlId);
+ }
+ }
+ if (!missingGeoms.isEmpty()) {
+ logger.warn("RelativeGeometries of the following gmlIDs could not be resolved: {}", missingGeoms);
+ }
+ deferredRelGeomObjects.clear();
+ if (logger.isDebugEnabled()) {
+ logger.debug("Resolving HRef geometries finished");
+ }
+ }
+
+ private ImplicitGeometryHolder(Lod lod) {
+ super(null, lod, null);
+ type = null;
+ prototypeGeometry = new Geometry(null, lod, null);
+ }
/**
* Applies the transformation matrix of the implicit geometry to a copy of the reference geometry and copies the resulting
* transformed geometry into this object.
@@ -54,6 +105,30 @@ public class ImplicitGeometryHolder extends Geometry {
return type;
}
+ /**
+ * Resets the Object maps of {@link RelativeGeometry} and {@link LibraryObject} to prevent memory and data leaks
+ */
+ public static void resetObjectMaps() {
+ RelativeGeometry.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);
@@ -64,8 +139,5 @@ public class ImplicitGeometryHolder extends Geometry {
return prototypeGeometry.isValidated();
}
- public enum PrototypeGeometryType {
- LIBRARY_OBJECT, RELATIVE_GEOMETRY
- }
}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LibraryObject.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LibraryObject.java
index f757da769a1b138b12fed1a530cc3f0d1f3b6934..557cd3ef4fd52841d05c45c37062a0eb32778b64 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LibraryObject.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LibraryObject.java
@@ -4,7 +4,7 @@ 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;
-import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
+import de.hft.stuttgart.citydoctor2.utils.Localization;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -26,8 +26,8 @@ public class LibraryObject extends Geometry {
private static final Logger logger = LogManager.getLogger(LibraryObject.class);
@Serial
private static final long serialVersionUID = -50293435187454911L;
-
- private static Map libraryObjects = new ConcurrentHashMap<>();
+ private static boolean metadataLocked = false;
+ private static final Map libraryObjects = new ConcurrentHashMap<>();
public static LibraryObject of(Path path, ParserConfiguration config) {
if (libraryObjects.containsKey(path.toString())) {
@@ -44,22 +44,6 @@ public class LibraryObject extends Geometry {
return libOb;
}
- public static LibraryObject of(CityGmlZipEntry entry, ParserConfiguration config) {
- String fileName = entry.getEntrySubPath();
- if (libraryObjects.containsKey(fileName)){
- return libraryObjects.get(fileName);
- }
- Geometry protoGeom = parseZipEntry(entry, config);
- if (protoGeom == null) {
- return null;
- }
- LibraryObject libOb = new LibraryObject(protoGeom.getType(), protoGeom.getLod(), protoGeom.getOrientation());
- protoGeom.getPolygons().forEach(libOb::addPolygon);
- libOb.updateEdgesAndVertices();
- libraryObjects.put(fileName, libOb);
- return libOb;
- }
-
private LibraryObject(GeometryType type, Lod lod, Orientation orientation) {
super(type, lod, orientation);
}
@@ -69,31 +53,15 @@ public class LibraryObject extends Geometry {
Geometry geo = null;
if (Files.exists(path)) {
try {
- geo = getProtoGeometry(CityGmlParser.parseCityGmlFileSilently(path.toString(), config));
+ geo = getProtoGeometry(CityGmlParser.nestedCityGmlFileParse(path.toString(), config));
} catch (CityGmlParseException e) {
- logger.error(String.format(
- "Encountered an error while parsing library object %s", path));
+ logger.error(Localization.getText("LibraryObject.parsingError"), path);
logger.error(e.getStackTrace());
} catch (InvalidGmlFileException e) {
logger.error(e.getStackTrace());
}
} else {
- logger.error(String.format("Implicit geometry references non-existing library object file %s.", path));
- }
- return geo;
- }
-
- private static Geometry parseZipEntry(CityGmlZipEntry entry, ParserConfiguration config) {
- Geometry geo = null;
- try {
- entry.loadEntry(config);
- geo = getProtoGeometry(entry.getModel());
- } catch (InvalidGmlFileException e) {
- logger.error(e.getStackTrace());
- } catch (CityGmlParseException e) {
- logger.error(String.format(
- "Encountered an error while parsing library object %s", entry.getEntrySubPath()));
- logger.error(e.getStackTrace());
+ logger.error(Localization.getText("LibraryObject.fileMissing"), path);
}
return geo;
}
@@ -111,4 +79,33 @@ public class LibraryObject extends Geometry {
return objects.get(0).getHighestLodGeometry();
}
+
+ public static void resetObjectMap() {
+ 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();
+ }
+ }
+
}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Opening.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Opening.java
index b64487de6c20dc229d8e3f46debc50b5e2bc06e9..b59ab14abbeb135cf703876425eefd163381a8c5 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Opening.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Opening.java
@@ -44,17 +44,11 @@ public class Opening extends CityObject {
private BoundarySurface partOf;
private OpeningType type;
- private SurfaceFeatureType featureType;
private AbstractFillingSurface ao;
- private Opening(OpeningType type) {
- this.type = type;
- }
-
- public Opening(OpeningType type, SurfaceFeatureType featureType, BoundarySurface partOf,
+ public Opening(OpeningType type, BoundarySurface partOf,
AbstractFillingSurface ao) {
- this.featureType = featureType;
this.partOf = partOf;
this.type = type;
this.ao = ao;
@@ -96,11 +90,6 @@ public class Opening extends CityObject {
}
}
-
- public SurfaceFeatureType getSurfaceFeatureType() {
- return featureType;
- }
-
public BoundarySurface getPartOf() {
return partOf;
}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/OtherConstructionObject.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/OtherConstructionObject.java
new file mode 100644
index 0000000000000000000000000000000000000000..d29145d509a607548caf34a802286ce345c4c1e0
--- /dev/null
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/OtherConstructionObject.java
@@ -0,0 +1,142 @@
+package de.hft.stuttgart.citydoctor2.datastructure;
+
+import de.hft.stuttgart.citydoctor2.check.CheckableVisitor;
+import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
+import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.citygml4j.core.model.construction.OtherConstruction;
+import org.citygml4j.core.model.core.AbstractCityObject;
+import org.citygml4j.core.model.core.AbstractSpaceBoundaryProperty;
+import org.citygml4j.core.util.geometry.GeometryFactory;
+import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface;
+import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
+import org.xmlobjects.gml.model.geometry.primitives.Solid;
+import org.xmlobjects.gml.model.geometry.primitives.SolidProperty;
+
+import java.io.Serial;
+import java.util.ArrayList;
+import java.util.List;
+
+public class OtherConstructionObject extends CityObject{
+
+ @Serial
+ private static final long serialVersionUID = -3885206364978761701L;
+
+ private static final Logger logger = LogManager.getLogger(OtherConstructionObject.class);
+
+ private final List boundarySurfaceList = new ArrayList<>();
+ private OtherConstruction gmlObject;
+
+ @Override
+ public void accept(CheckableVisitor c) {
+ super.accept(c);
+ if (c.canExecute(this)) {
+ c.check(this);
+ }
+ for (BoundarySurface bs : boundarySurfaceList) {
+ bs.accept(c);
+ }
+ }
+
+ public void setGmlObject(OtherConstruction gmlObject) {
+ this.gmlObject = gmlObject;
+ }
+
+ @Override
+ public void rebuildGeometries(GeometryFactory factory, ParserConfiguration config) {
+ for (Geometry geom : getGeometries()) {
+ if (geom instanceof ImplicitGeometryHolder) {
+ continue;
+ }
+ if (geom.getType() == GeometryType.MULTI_SURFACE) {
+ MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config);
+ setMultiSurfaceAccordingToLod(geom, ms);
+ } else {
+ Solid solid = CityGmlUtils.createSolid(geom, factory, config);
+ setSolidAccordingToLod(geom, solid);
+ }
+ }
+ removeEmptyBoundarySurfaces();
+ }
+
+ private void removeEmptyBoundarySurfaces() {
+ for (BoundarySurface bs : boundarySurfaceList) {
+ if (bs.getGeometries().isEmpty()) {
+ for (AbstractSpaceBoundaryProperty bsp : gmlObject.getBoundaries()) {
+ if (bsp.getObject() != null && bsp.getObject() == bs.getGmlObject()) {
+ logger.warn("Found empty boundary surface: {}, removing from feature", bs.getGmlId());
+ gmlObject.getBoundaries().remove(bsp);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private void setMultiSurfaceAccordingToLod(Geometry geom, MultiSurface ms) {
+ switch (geom.getLod()) {
+ case LOD0:
+ gmlObject.setLod0MultiSurface(new MultiSurfaceProperty(ms));
+ break;
+ case LOD2:
+ gmlObject.setLod2MultiSurface(new MultiSurfaceProperty(ms));
+ break;
+ case LOD3:
+ gmlObject.setLod3MultiSurface(new MultiSurfaceProperty(ms));
+ break;
+ default:
+ throw new IllegalStateException("Cannot add " + geom.getLod() + " multi surface to other construction object");
+ }
+ }
+
+ private void setSolidAccordingToLod(Geometry geom, Solid solid) {
+ switch (geom.getLod()) {
+ case LOD1:
+ gmlObject.setLod1Solid(new SolidProperty(solid));
+ break;
+ case LOD2:
+ gmlObject.setLod2Solid(new SolidProperty(solid));
+ break;
+ case LOD3:
+ gmlObject.setLod3Solid(new SolidProperty(solid));
+ break;
+ default:
+ throw new IllegalStateException("Cannot add " + geom.getLod() + " solid to other construction object");
+ }
+ }
+
+ @Override
+ public OtherConstruction getGmlObject() {
+ return gmlObject;
+ }
+
+ @Override
+ public void unsetGmlGeometries() {
+ gmlObject.setLod0MultiSurface(null);
+ gmlObject.setLod2MultiSurface(null);
+ gmlObject.setLod3MultiSurface(null);
+ gmlObject.setLod1Solid(null);
+ gmlObject.setLod2Solid(null);
+ gmlObject.setLod3Solid(null);
+ }
+
+ @Override
+ public CityObject getTopLevelCityObject() {
+ return this;
+ }
+
+ @Override
+ public FeatureType getFeatureType() {
+ return FeatureType.OTHER_CITY_OBJECT;
+ }
+
+ public void addBoundarySurface(BoundarySurface bs) {
+ boundarySurfaceList.add(bs);
+ bs.setParent(this);
+ }
+
+ public List getBoundarySurfaces() {
+ return boundarySurfaceList;
+ }
+}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/RelativeGeometry.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/RelativeGeometry.java
index bbf61550e200a9c5311e30834649065cd55b9bf3..489fa054857e4552ca991a2499a7eec29266354b 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/RelativeGeometry.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/RelativeGeometry.java
@@ -14,20 +14,53 @@ public class RelativeGeometry extends Geometry {
@Serial
private static final long serialVersionUID = -686112245455298977L;
- private static Map relativeGeometries = new ConcurrentHashMap<>();
+ private static final Map relativeGeometries = new ConcurrentHashMap<>();
+ private static boolean metadataLocked = false;
- public static RelativeGeometry of(Geometry geom) {
- if (relativeGeometries.containsKey(geom)) {
- return relativeGeometries.get(geom);
+ public static RelativeGeometry of(GmlId gmlId, Geometry geom) {
+ if (relativeGeometries.containsKey(gmlId)) {
+ return relativeGeometries.get(gmlId);
}
RelativeGeometry relGeo = new RelativeGeometry(geom.getType(), geom.getLod(), geom.getOrientation());
geom.getPolygons().forEach(relGeo::addPolygon);
relGeo.updateEdgesAndVertices();
- relativeGeometries.put(geom, relGeo);
+ relativeGeometries.put(gmlId, relGeo);
return relGeo;
}
+ public static RelativeGeometry of(GmlId gmlId) {
+ return relativeGeometries.getOrDefault(gmlId, null);
+ }
+
private RelativeGeometry(GeometryType type, Lod lod, Orientation orientation) {
super(type, lod, orientation);
}
+
+ public static void resetObjectMap() {
+ 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();
+ }
+ }
}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TunnelPart.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TunnelPart.java
index e6c02a9974ac22f2822472d55ce2779c3458e29c..4584a999f08ed10ce09a016e8e5fdc06b32b0831 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TunnelPart.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/TunnelPart.java
@@ -9,6 +9,8 @@ public class TunnelPart extends AbstractTunnel {
private Tunnel parent;
+ private TunnelPart() {
+ }
public TunnelPart(Tunnel parent) {
this.parent = parent;
@@ -34,6 +36,4 @@ public class TunnelPart extends AbstractTunnel {
return "TunnelPart [id=" + getGmlId() + "]";
}
- private TunnelPart() {
- }
}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Vertex.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Vertex.java
index a49aec952b89baf41a61b8e29f7a340ce38ffe28..e42440072b6506f02af1d77a5001c3aa8148dd59 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Vertex.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/Vertex.java
@@ -21,6 +21,8 @@ package de.hft.stuttgart.citydoctor2.datastructure;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
import de.hft.stuttgart.citydoctor2.utils.SerializablePair;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.io.Serial;
import java.util.ArrayList;
import java.util.HashSet;
@@ -37,7 +39,7 @@ public class Vertex extends Vector3d {
@Serial
private static final long serialVersionUID = -5525361920397934892L;
- private List>> adjacentRings = new ArrayList<>(2);
+ private transient List>> adjacentRings = new ArrayList<>(2);
public Vertex(double x, double y, double z) {
super(x, y, z);
@@ -91,6 +93,12 @@ public class Vertex extends Vector3d {
throw new IllegalStateException("Requested adjacent polygons with Geometry not containing this vertex");
}
+ @Serial
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ clearAdjacentRings();
+ }
+
public Set getAdjacentPolygons(Geometry geom) {
return getAdjacentPolygonsWithoutNeighbor(geom);
}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/Citygml3FeatureMapper.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/Citygml3FeatureMapper.java
index e5f5c5435c06b98da11fb7e5a6af8c074cbb315f..e27555ca167f86cb172b6346de9db5e3ddf46aa9 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/Citygml3FeatureMapper.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/Citygml3FeatureMapper.java
@@ -24,6 +24,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import de.hft.stuttgart.citydoctor2.database.FeatureCache;
+import de.hft.stuttgart.citydoctor2.database.UnconnectedCache;
+import de.hft.stuttgart.citydoctor2.datastructure.OtherConstructionObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.citygml4j.core.model.CityGMLVersion;
@@ -45,6 +48,7 @@ import org.citygml4j.core.model.building.BuildingRoomProperty;
import org.citygml4j.core.model.building.BuildingUnit;
import org.citygml4j.core.model.building.Storey;
import org.citygml4j.core.model.construction.AbstractConstruction;
+import org.citygml4j.core.model.construction.OtherConstruction;
import org.citygml4j.core.model.core.AbstractCityObject;
import org.citygml4j.core.model.core.AbstractFeatureWithLifespan;
import org.citygml4j.core.model.core.AbstractGenericAttributeProperty;
@@ -157,35 +161,32 @@ import de.hft.stuttgart.citydoctor2.datastructure.WaterObject;
import de.hft.stuttgart.citydoctor2.math.graph.KDTree;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.utils.Localization;
-import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
public class Citygml3FeatureMapper extends ObjectWalker {
private static final Logger logger = LogManager.getLogger(Citygml3FeatureMapper.class);
+ private static FeatureCache featureCache = new FeatureCache();
private final CityDoctorModel model;
private final ParserConfiguration config;
private final Path directory;
- private final CityGmlZipEntry zipEntry;
private final double neighborDistance;
private Map polygonMap = new HashMap<>();
private Map compositeMap = new HashMap<>();
private List references = new ArrayList<>();
private Map vertexMap = new HashMap<>();
- public Citygml3FeatureMapper(ParserConfiguration config, Path path) {
+ public Citygml3FeatureMapper(ParserConfiguration config, Path path, boolean unconnected) {
this.config = config;
this.directory = path.getParent();
- model = new CityDoctorModel(config, path.toFile());
- neighborDistance = 1.8d / Math.pow(10, config.getNumberOfRoundingPlaces());
- zipEntry = null;
- }
- public Citygml3FeatureMapper(ParserConfiguration config, CityGmlZipEntry entry) {
- this.config = config;
- this.directory = null;
- this.zipEntry = entry;
- model = new CityDoctorModel(config, Path.of(entry.getEntrySubPath()).toFile());
+ if (unconnected){
+ model = new CityDoctorModel(config, path.toFile(), new UnconnectedCache());
+ } else {
+ featureCache.resetCache();
+ ImplicitGeometryHolder.resetObjectMaps();
+ model = new CityDoctorModel(config, path.toFile(), featureCache);
+ }
neighborDistance = 1.8d / Math.pow(10, config.getNumberOfRoundingPlaces());
}
@@ -203,6 +204,32 @@ public class Citygml3FeatureMapper extends ObjectWalker {
}
+ @Override
+ public void visit(OtherConstruction gmlOc){
+ OtherConstructionObject oco = new OtherConstructionObject();
+ oco.setGmlObject(gmlOc);
+ mapAbstractOccupiedSpace(gmlOc, oco, Orientation.OUTWARD);
+
+ SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
+ for (AbstractSpaceBoundaryProperty surfaceProp : gmlOc.getBoundaries()) {
+ if (!surfaceProp.isSetObject()) {
+ continue;
+ }
+ AbstractSpaceBoundary surface = surfaceProp.getObject();
+ surface.accept(surfaceMapper);
+ }
+ for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
+ oco.addBoundarySurface(bs);
+ for (Geometry geom : bs.getGeometries()) {
+ for (Polygon p : geom.getPolygons()) {
+ p.setPartOfSurface(bs);
+ }
+ }
+ }
+ finishCityObjectConstruction(oco);
+ model.addOtherCityObject(oco);
+ }
+
@Override
public void visit(org.citygml4j.core.model.cityfurniture.CityFurniture gmlCityFurniture) {
CityFurniture cf = new CityFurniture();
@@ -230,7 +257,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
}
mapAbstractOccupiedSpace(gos, gco, Orientation.OUTWARD);
finishCityObjectConstruction(gco);
- model.addGenericCityObject(gco);
+ model.addOtherCityObject(gco);
}
@Override
@@ -1024,30 +1051,39 @@ public class Citygml3FeatureMapper extends ObjectWalker {
if (directory != null){
Path libraryObjectPath = directory.resolve(ig.getLibraryObject());
libObj = LibraryObject.of(libraryObjectPath, config);
- } else {
- String libraryObjectPath = ig.getLibraryObject();
- Path loPath = zipEntry.resolveLibraryObjectPath(libraryObjectPath);
- CityGmlZipEntry libEntry = zipEntry.getArchive().getEntry(loPath.toString());
- libObj = LibraryObject.of(libEntry, config);
}
if (libObj != null) {
igh = new ImplicitGeometryHolder(ig, libObj);
}
} else if (ig.getRelativeGeometry() != null) {
AbstractGeometry aGeom = ig.getRelativeGeometry().getObject();
- Geometry geom = null;
Lod lod = Lod.values()[lodInt];
- RelativeGeometry relGeo = null;
- if (aGeom instanceof MultiSurface ms) {
- geom = parseMultiSurface(ms, lod);
- } else if (aGeom instanceof Solid s) {
- geom = parseSolid(s, lod, orientation);
- } else if (aGeom instanceof CompositeSurface cs) {
- geom = parseCompositeSurface(cs, lod);
- }
- if (geom != null) {
- relGeo = RelativeGeometry.of(geom);
- igh = new ImplicitGeometryHolder(ig, relGeo);
+ if (aGeom != null) {
+ Geometry geom = null;
+ if (aGeom instanceof MultiSurface ms) {
+ geom = parseMultiSurface(ms, lod);
+ } else if (aGeom instanceof Solid s) {
+ geom = parseSolid(s, lod, orientation);
+ } else if (aGeom instanceof CompositeSurface cs) {
+ geom = parseCompositeSurface(cs, lod);
+ }
+ if (geom != null) {
+ geom.setGmlId(new GmlId(aGeom.getId()));
+ RelativeGeometry relGeo = RelativeGeometry.of(geom.getGmlId(), geom);
+ igh = new ImplicitGeometryHolder(ig, relGeo);
+ }
+ } else if (ig.getRelativeGeometry().getHref() != null) {
+ String hrefId = ig.getRelativeGeometry().getHref();
+ hrefId = hrefId.startsWith("#") ? hrefId.substring(1) : hrefId;
+ GmlId gmlId = new GmlId(hrefId);
+ RelativeGeometry relGeo = RelativeGeometry.of(gmlId);
+ if (relGeo == null) {
+ igh = ImplicitGeometryHolder.deferRelativeGeomParsing(ig, lod);
+ } else {
+ igh = new ImplicitGeometryHolder(ig, relGeo);
+ }
+ } else {
+ logger.warn("Relative geometry of GML-ID {} has neither geometry nor an href", ig.getId());
}
} else {
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/SurfaceMapper.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/SurfaceMapper.java
index c8e8495283789b7a046d17517687595816dda05f..6b3257ad509e783b2bed7b814bc71f77159ab0cd 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/SurfaceMapper.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/SurfaceMapper.java
@@ -54,8 +54,7 @@ public class SurfaceMapper extends ObjectWalker {
@Override
public void visit(WallSurface wallSurface) {
- BoundarySurface surface = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL,
- wallSurface);
+ BoundarySurface surface = new BoundarySurface(BoundarySurfaceType.WALL, wallSurface);
handleConstructionSurface(wallSurface, surface);
surfaces.add(surface);
}
@@ -74,11 +73,11 @@ public class SurfaceMapper extends ObjectWalker {
private void readAbstractFillingSurface(AbstractFillingSurface afs, BoundarySurface cdSurface) {
Opening o;
if (afs instanceof DoorSurface ds) {
- o = new Opening(OpeningType.DOOR, SurfaceFeatureType.BUILDING, cdSurface, ds);
+ o = new Opening(OpeningType.DOOR, cdSurface, ds);
} else if (afs instanceof WindowSurface ws) {
- o = new Opening(OpeningType.WINDOW, SurfaceFeatureType.BUILDING, cdSurface, ws);
+ o = new Opening(OpeningType.WINDOW, cdSurface, ws);
} else {
- o = new Opening(OpeningType.UNKNOWN, SurfaceFeatureType.BUILDING, cdSurface, afs);
+ o = new Opening(OpeningType.UNKNOWN, cdSurface, afs);
}
cdSurface.addOpening(o);
parseAndAddMultiSurface(afs.getLod0MultiSurface(), Lod.LOD0, o);
@@ -144,64 +143,56 @@ public class SurfaceMapper extends ObjectWalker {
@Override
public void visit(FloorSurface floorSurface) {
- BoundarySurface surface = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.FLOOR,
- floorSurface);
+ BoundarySurface surface = new BoundarySurface(BoundarySurfaceType.FLOOR, floorSurface);
handleConstructionSurface(floorSurface, surface);
surfaces.add(surface);
}
@Override
public void visit(CeilingSurface ceilingSurface) {
- BoundarySurface surface = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.CEILING,
- ceilingSurface);
+ BoundarySurface surface = new BoundarySurface(BoundarySurfaceType.CEILING, ceilingSurface);
handleConstructionSurface(ceilingSurface, surface);
surfaces.add(surface);
}
@Override
public void visit(GroundSurface groundSurface) {
- BoundarySurface surface = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.GROUND,
- groundSurface);
+ BoundarySurface surface = new BoundarySurface(BoundarySurfaceType.GROUND, groundSurface);
handleConstructionSurface(groundSurface, surface);
surfaces.add(surface);
}
@Override
public void visit(InteriorWallSurface interiorWallSurface) {
- BoundarySurface surface = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.INTERIOR_WALL,
- interiorWallSurface);
+ BoundarySurface surface = new BoundarySurface(BoundarySurfaceType.INTERIOR_WALL, interiorWallSurface);
handleConstructionSurface(interiorWallSurface, surface);
surfaces.add(surface);
}
@Override
public void visit(OuterCeilingSurface outerCeilingSurface) {
- BoundarySurface surface = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.OUTER_CEILING,
- outerCeilingSurface);
+ BoundarySurface surface = new BoundarySurface(BoundarySurfaceType.OUTER_CEILING, outerCeilingSurface);
handleConstructionSurface(outerCeilingSurface, surface);
surfaces.add(surface);
}
@Override
public void visit(OuterFloorSurface outerFloorSurface) {
- BoundarySurface surface = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.OUTER_FLOOR,
- outerFloorSurface);
+ BoundarySurface surface = new BoundarySurface(BoundarySurfaceType.OUTER_FLOOR, outerFloorSurface);
handleConstructionSurface(outerFloorSurface, surface);
surfaces.add(surface);
}
@Override
public void visit(RoofSurface roofSurface) {
- BoundarySurface surface = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.ROOF,
- roofSurface);
+ BoundarySurface surface = new BoundarySurface(BoundarySurfaceType.ROOF, roofSurface);
handleConstructionSurface(roofSurface, surface);
surfaces.add(surface);
}
@Override
public void visit(ClosureSurface closureSurface) {
- BoundarySurface surface = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.CLOSURE,
- closureSurface);
+ BoundarySurface surface = new BoundarySurface(BoundarySurfaceType.CLOSURE, closureSurface);
handleThematicSurface(closureSurface, surface);
surfaces.add(surface);
}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/Triangle3d.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/Triangle3d.java
index 96ec193dec6b4b0d350789937ec01f9991318abd..4f3c2920d38c3389b5dbc0f439f83379fdbee1c1 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/Triangle3d.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/math/Triangle3d.java
@@ -87,8 +87,13 @@ public class Triangle3d implements Serializable {
Vector3d n2 = v1.cross(v2);
return new Plane(n2, p1);
}
-
+
public boolean doesIntersect(Triangle3d other) {
+ return doesIntersect(other, EPSILON);
+ }
+
+
+ public boolean doesIntersect(Triangle3d other, double epsilon) {
// plane of other triangle
Plane planeT2 = other.getPlane();
// check if all points are on one side of the plane
@@ -96,13 +101,13 @@ public class Triangle3d implements Serializable {
double distanceP2T2 = planeT2.getSignedDistance(p2);
double distanceP3T2 = planeT2.getSignedDistance(p3);
- if (Math.abs(distanceP1T2) < EPSILON) {
+ if (Math.abs(distanceP1T2) < epsilon) {
distanceP1T2 = 0.0;
}
- if (Math.abs(distanceP2T2) < EPSILON) {
+ if (Math.abs(distanceP2T2) < epsilon) {
distanceP2T2 = 0.0;
}
- if (Math.abs(distanceP3T2) < EPSILON) {
+ if (Math.abs(distanceP3T2) < epsilon) {
distanceP3T2 = 0.0;
}
@@ -123,13 +128,13 @@ public class Triangle3d implements Serializable {
double distanceP2T1 = planeT1.getSignedDistance(other.getP2());
double distanceP3T1 = planeT1.getSignedDistance(other.getP3());
- if (Math.abs(distanceP1T1) < EPSILON) {
+ if (Math.abs(distanceP1T1) < epsilon) {
distanceP1T1 = 0.0;
}
- if (Math.abs(distanceP2T1) < EPSILON) {
+ if (Math.abs(distanceP2T1) < epsilon) {
distanceP2T1 = 0.0;
}
- if (Math.abs(distanceP3T1) < EPSILON) {
+ if (Math.abs(distanceP3T1) < epsilon) {
distanceP3T1 = 0.0;
}
@@ -139,11 +144,15 @@ public class Triangle3d implements Serializable {
return false;
}
- return checkTriangleLineIntersection(other, p1, p2) || checkTriangleLineIntersection(other, p1, p3)
+ boolean intersects = checkTriangleLineIntersection(other, p1, p2) || checkTriangleLineIntersection(other, p1, p3)
|| checkTriangleLineIntersection(other, p2, p3)
|| checkTriangleLineIntersection(this, other.p1, other.p2)
|| checkTriangleLineIntersection(this, other.p1, other.p3)
|| checkTriangleLineIntersection(this, other.p2, other.p3);
+ if (intersects) {
+ System.out.println();
+ }
+ return intersects;
}
private boolean checkTriangleLineIntersection(Triangle3d other, Vector3d a, Vector3d b) {
@@ -171,7 +180,11 @@ public class Triangle3d implements Serializable {
private boolean doesIntersectCoplanarTriangle(Triangle3d other) {
Triangle2d t1 = projectTo2d();
Triangle2d t2 = other.projectTo2d();
- return t1.intersects(t2);
+ boolean intersects = t1.intersects(t2);
+ if (intersects) {
+ System.out.println();
+ }
+ return intersects;
}
public Triangle2d projectTo2d() {
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlParser.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlParser.java
index 06d42a00208f77a9d5cd43bb017d77dd3c9b02e6..d94ab7eecf5a32285c7a3feee955a4d5a5dc7eab 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlParser.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlParser.java
@@ -19,7 +19,6 @@
package de.hft.stuttgart.citydoctor2.parser;
import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -44,6 +43,8 @@ import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
+import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
+import de.hft.stuttgart.citydoctor2.datastructure.ImplicitGeometryHolder;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -78,7 +79,6 @@ import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
-import org.xml.sax.SAXParseException;
import org.xmlobjects.schema.SchemaHandler;
import org.xmlobjects.schema.SchemaHandlerException;
import org.xmlobjects.stream.XMLReader;
@@ -90,8 +90,6 @@ import de.hft.stuttgart.citydoctor2.mapper.citygml3.Citygml3FeatureMapper;
import de.hft.stuttgart.citydoctor2.mapper.citygml3.GMLValidationHandler;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
import de.hft.stuttgart.citydoctor2.utils.Localization;
-import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
-import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntryFile;
import de.hft.stuttgart.quality.QualityADEContext;
import de.hft.stuttgart.quality.QualityADEModule;
@@ -157,33 +155,111 @@ public class CityGmlParser {
ADERegistry adeRegistry = ADERegistry.getInstance();
adeRegistry.loadADE(new QualityADEContext());
} catch (CityGMLContextException e) {
- logger.fatal("Unable to create citygml4j context", e);
+ logger.fatal(Localization.getText("CityGmlParser.creating4jContextFailed"), e);
throw new IllegalStateException("Unable to create citygml4j context");
} catch (ADEException e) {
- logger.fatal("Unable to add ADE plugins to citygml4j", e);
+ logger.fatal(Localization.getText("CityGmlParser.creatingAdePluginsFailed"), e);
throw new IllegalStateException("Unable to add ADE plugins to citygml4j");
}
}
return context;
}
- public static CityDoctorModel parseCityGmlFileSilently(String file, ParserConfiguration config)
+ /**
+ * Parses a given CityGML file and collects the contained CityObject Features in a {@link CityDoctorModel}.
+ *
+ * The nested parse uses an {@link de.hft.stuttgart.citydoctor2.database.UnconnectedCache UnconnectedCache}, which
+ * is not connected to the database.
+ *
+ * Nested parsing should only be used for accessing Features in auxiliary, small CityGML files, e.g. parsing of
+ * {@link de.hft.stuttgart.citydoctor2.datastructure.LibraryObject LibraryObject} files.
+ *
+ * @param filePath String path to the file
+ * @param config Configuration of the parser
+ * @return A {@link CityDoctorModel} object with the parsed Features
+ * @throws CityGmlParseException if parsing of the CityGML-file failed
+ * @throws InvalidGmlFileException if the GMLValidationHandler found an error
+ */
+ public static CityDoctorModel nestedCityGmlFileParse(String filePath, ParserConfiguration config)
throws CityGmlParseException, InvalidGmlFileException {
- return parseCityGmlFile(file, config, null, null, false);
+ return parseCityGmlFile(filePath, config, null, null, false, true);
}
- public static CityDoctorModel parseCityGmlFile(String file, ParserConfiguration config)
+ /**
+ * Parses a given CityGML file and collects the contained CityObject Features in a {@link CityDoctorModel}.
+ *
+ * Features are held in a non-persistent, embedded Database with an in-memory upstream cache. Thus, strong references
+ * to {@link CityObject} are to be avoided, to allow for the memory management of the cache.
+ *
+ * @param filePath String path to the file
+ * @param config Configuration of the parser
+ * @return A {@link CityDoctorModel} object with the parsed Features
+ * @throws CityGmlParseException if parsing of the CityGML-file failed
+ * @throws InvalidGmlFileException if the GMLValidationHandler found an error
+ */
+ public static CityDoctorModel parseCityGmlFile(String filePath, ParserConfiguration config)
throws CityGmlParseException, InvalidGmlFileException {
- return parseCityGmlFile(file, config, null, null, true);
+ return parseCityGmlFile(filePath, config, null, null);
}
- public static CityDoctorModel parseCityGmlFile(String file, ParserConfiguration config, ProgressListener l)
+
+ /**
+ * Parses a given CityGML file and collects the contained CityObject Features in a {@link CityDoctorModel}.
+ *
+ * Features are held in a non-persistent, embedded Database with an in-memory upstream cache. Thus, strong references
+ * to {@link CityObject} are to be avoided, to allow for the memory management of the cache.
+ *
+ * @param filePath String path to the file
+ * @param config Configuration of the parser
+ * @param l Listener hook for tracking of parsing progress
+ * @return A {@link CityDoctorModel} object with the parsed Features
+ * @throws CityGmlParseException if parsing of the CityGML-file failed
+ * @throws InvalidGmlFileException if the GMLValidationHandler found an error
+ */
+ public static CityDoctorModel parseCityGmlFile(String filePath, ParserConfiguration config, ProgressListener l)
throws CityGmlParseException, InvalidGmlFileException {
- return parseCityGmlFile(file, config, l, null, true);
+ return parseCityGmlFile(filePath, config, l, null);
}
+ /**
+ * Parses a given CityGML file and collects the contained CityObject Features in a {@link CityDoctorModel}.
+ *
+ * Features are held in a non-persistent, embedded Database with an in-memory upstream cache. Thus, strong references
+ * to {@link CityObject} are to be avoided, to allow for the memory management of the cache.
+ *
+ * @param filePath String path to the file
+ * @param config Configuration of the parser
+ * @param l Listener hook for tracking of parsing progress
+ * @param handler Validation handler for GML-file validation
+ * @return A {@link CityDoctorModel} object with the parsed Features
+ * @throws CityGmlParseException if parsing of the CityGML-file failed
+ * @throws InvalidGmlFileException if the GMLValidationHandler found an error
+ */
public static CityDoctorModel parseCityGmlFile(String filePath, ParserConfiguration config, ProgressListener l,
- GMLValidationHandler handler, boolean verbose) throws CityGmlParseException, InvalidGmlFileException {
+ GMLValidationHandler handler) throws CityGmlParseException, InvalidGmlFileException {
+ return parseCityGmlFile(filePath, config, l, handler, true, false);
+ }
+
+ /**
+ * Parses a given CityGML file and collects the contained CityObject Features in a {@link CityDoctorModel}.
+ *
+ * Features are held in a non-persistent, embedded Database with an in-memory upstream cache. Thus, strong references
+ * to {@link CityObject} are to be avoided, to allow for the memory management of the cache.
+ *
+ * @param filePath String path to the file
+ * @param config Configuration of the parser
+ * @param l Listener hook for tracking of parsing progress
+ * @param handler Validation handler for GML-file validation
+ * @param verbose If verbosity is enabled the parser will write info logs to the logger
+ * @param unconnected If true the parser will use an {@link de.hft.stuttgart.citydoctor2.database.UnconnectedCache UnconnectedCache}
+ * to collect the parsed CityObjects
+ * @return A {@link CityDoctorModel} object with the parsed Features
+ * @throws CityGmlParseException if parsing of the CityGML-file failed
+ * @throws InvalidGmlFileException if the GMLValidationHandler found an error
+ */
+ private static CityDoctorModel parseCityGmlFile(String filePath, ParserConfiguration config, ProgressListener l,
+ GMLValidationHandler handler, boolean verbose, boolean unconnected)
+ throws CityGmlParseException, InvalidGmlFileException {
CityGMLContext context = getContext();
Path file = Paths.get(filePath);
if (config.getValidate()) {
@@ -194,14 +270,14 @@ public class CityGmlParser {
}
try {
- parseEpsgCodeFromFile(file, config);
+ parseEpsgCodeFromFile(file, config, verbose);
CityGMLInputFactory in = context.createCityGMLInputFactory()
.withChunking(ChunkOptions.chunkByProperties(chunkProperties).skipCityModel(false));
try (ObservedInputStream ois = new ObservedInputStream(file.toFile())) {
if (l != null) {
ois.addListener(l::updateProgress);
}
- return readAndKeepFeatures(config, file, in, ois, verbose);
+ return readAndKeepFeatures(config, file, in, ois, verbose, unconnected);
}
} catch (CityGMLReadException | IOException e) {
throw new CityGmlParseException("Failed to read CityGML file", e);
@@ -209,118 +285,6 @@ public class CityGmlParser {
}
- public static CityDoctorModel parseCityGmlZipEntry(CityGmlZipEntry entry, ParserConfiguration config)
- throws CityGmlParseException, InvalidGmlFileException, IOException {
- return parseCityGmlZipEntry(entry, config, null);
- }
-
- public static CityDoctorModel parseCityGmlZipEntry(CityGmlZipEntry entry, ParserConfiguration config, ProgressListener l)
- throws CityGmlParseException, InvalidGmlFileException, IOException {
- CityGMLContext context = getContext();
-
- if (config.getValidate()) {
- try (CityGmlZipEntryFile entryFile = new CityGmlZipEntryFile(entry)) {
- List messages = validateStream(entryFile.getInputStream(), context);
- if (!messages.isEmpty()) {
- throw new InvalidGmlFileException("Invalid GML File. First error: \n" + messages.get(0));
- }
- } catch (Exception e) {
- throw new CityGmlParseException(e);
- }
-
- }
- return decompressAndParseCityGmlEntry(entry, config, l, context);
- }
-
- public static CityDoctorModel decompressAndParseCityGmlEntry(CityGmlZipEntry entry, ParserConfiguration config, CityGMLContext context)
- throws CityGmlParseException {
- return decompressAndParseCityGmlEntry(entry, config, null, context);
- }
-
- public static CityDoctorModel decompressAndParseCityGmlEntry(CityGmlZipEntry entry, ParserConfiguration config, ProgressListener l, CityGMLContext context)
- throws CityGmlParseException {
-
- try (CityGmlZipEntryFile entryFile = new CityGmlZipEntryFile(entry)) {
- BufferedInputStream bis = new BufferedInputStream(entryFile.getInputStream());
- readEpsgCodeFromInputStream(bis, config);
- CityGMLInputFactory in = context.createCityGMLInputFactory()
- .withChunking(ChunkOptions.chunkByProperties(chunkProperties).skipCityModel(false));
- try (ObservedInputStream ois = new ObservedInputStream(bis, bis.available())) {
- if (l != null) {
- ois.addListener(l::updateProgress);
- }
- return readAndKeepFeatures(config, entry, in, ois, false);
- }
- } catch (CityGMLReadException | IOException e) {
- throw new CityGmlParseException("Failed to read CityGML file", e);
- } catch (Exception e) {
- throw new CityGmlParseException(e);
- }
- }
-
- private static CityDoctorModel readAndKeepFeatures(ParserConfiguration config, CityGmlZipEntry entry,
- CityGMLInputFactory inputFactory, ObservedInputStream ois, boolean verbose) throws CityGMLReadException {
- return readAndKeepModel(new Citygml3FeatureMapper(config, entry), inputFactory, ois, verbose);
- }
-
- private static List validateStream(InputStream vis, CityGMLContext context) throws CityGmlParseException {
- GMLValidationHandler handler = new GMLValidationHandler();
-
- try {
- BufferedInputStream bis = new BufferedInputStream(vis);
- SchemaHandler schemaHandler = new ValidationSchemaHandler(context.getDefaultSchemaHandler());
- readAdditionalSchemaDefinitions(context, bis, schemaHandler);
- Source[] schemas = schemaHandler.getSchemas();
- SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
- schemaFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
- Schema schema = schemaFactory.newSchema(schemas);
- Validator validator = schema.newValidator();
- validator.setErrorHandler(handler);
- validator.validate(new StreamSource(bis));
- return handler.getMessages();
- } catch (SchemaHandlerException | SAXException | IOException e) {
- throw new CityGmlParseException("Failed to validate CityGML file", e);
- }
- }
-
- private static void readAdditionalSchemaDefinitions(CityGMLContext context, BufferedInputStream bis, SchemaHandler schemaHandler)
- throws CityGmlParseException {
- bis.mark(Integer.MAX_VALUE);
- try (XMLReader reader = XMLReaderFactory.newInstance(context.getXMLObjects())
- .withSchemaHandler(schemaHandler)
- .createReader(bis)) {
- reader.nextTag();
- bis.reset();
- } catch (Exception e) {
- throw new CityGmlParseException("Failed to read Schema from stream.", e);
- }
- }
-
- private static void readEpsgCodeFromInputStream(BufferedInputStream bis, ParserConfiguration config) throws CityGmlParseException {
- try {
- // Mark start position of GML-"file"
- bis.mark(Integer.MAX_VALUE);
- // Buffer the first 10000 chars of the Stream, EPSG/envelope info should be found within that range
- int peekingWidth = Math.min(10000, bis.available());
- byte[] buf = new byte[peekingWidth];
- bis.read(buf, 0, peekingWidth);
- bis.reset();
- parseEpsgCodeFromBuffer(buf, config);
- } catch (ParserConfigurationException | SAXException | IOException e) {
- throw new CityGmlParseException("Failed to read CityGML file", e);
- }
-
- }
-
- public static void streamCityGml(CityGmlZipEntry entry, ParserConfiguration config, CityGmlConsumer cityObjectConsumer,
- String outputFile) throws CityGmlParseException, IOException {
- try (CityGmlZipEntryFile entryFile = new CityGmlZipEntryFile(entry)) {
- parseEpsgCodeFromStream(entryFile.getInputStream(), config);
- startReadingCityGmlZipEntry(entry, config, null, cityObjectConsumer, outputFile);
- } catch (ParserConfigurationException | SAXException | IOException e) {
- throw new CityGmlParseException("Failed to read CityGML stream", e);
- }
- }
public static void streamCityGml(String file, ParserConfiguration config, CityGmlConsumer cityObjectConsumer,
String outputFile) throws CityGmlParseException {
@@ -335,7 +299,7 @@ public class CityGmlParser {
public static void streamCityGml(Path file, ParserConfiguration config, ProgressListener l,
CityGmlConsumer cityObjectConsumer, String outputFile) throws CityGmlParseException {
- parseEpsgCodeFromFile(file, config);
+ parseEpsgCodeFromFile(file, config, true);
startReadingCityGmlFile(file, config, l, cityObjectConsumer, outputFile);
}
@@ -373,31 +337,11 @@ public class CityGmlParser {
private static void readAndDiscardFeatures(Path file, ParserConfiguration config, ObservedInputStream ois,
CityGmlConsumer cityObjectConsumer, String outputFile) throws CityGMLReadException {
- Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(config, file);
+ Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(config, file, false);
readAndDiscardModel(mapper, ois, cityObjectConsumer, outputFile);
}
- private static void startReadingCityGmlZipEntry(CityGmlZipEntry entry, ParserConfiguration config, ProgressListener l,
- CityGmlConsumer cityObjectConsumer, String outputFile) {
- try (CityGmlZipEntryFile entryFile = new CityGmlZipEntryFile(entry);
- ObservedInputStream ois = new ObservedInputStream(entryFile.getInputStream(), entry.getFileSize())) {
- if (l != null) {
- ois.addListener(l::updateProgress);
- }
- streamAndDiscardFeatures(entry, config, ois, cityObjectConsumer, outputFile);
- } catch (IOException | CityGMLReadException e) {
- logger.error(Localization.getText("CityGmlParser.errorReadingGmlFile"), e.getMessage());
- logger.catching(Level.ERROR, e);
- }
- }
-
- private static void streamAndDiscardFeatures(CityGmlZipEntry entry, ParserConfiguration config, ObservedInputStream ois,
- CityGmlConsumer cityObjectConsumer, String outputFile) throws CityGMLReadException {
- Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(config, entry);
- readAndDiscardModel(mapper, ois, cityObjectConsumer, outputFile);
- }
-
private static void readAndDiscardModel(Citygml3FeatureMapper mapper, ObservedInputStream ois,
CityGmlConsumer cityObjectConsumer, String outputFile) throws CityGMLReadException {
getContext();
@@ -484,8 +428,9 @@ public class CityGmlParser {
}
private static CityDoctorModel readAndKeepFeatures(ParserConfiguration config, Path file,
- CityGMLInputFactory inputFactory, ObservedInputStream ois, boolean verbose) throws CityGMLReadException {
- return readAndKeepModel(new Citygml3FeatureMapper(config, file), inputFactory, ois, verbose);
+ CityGMLInputFactory inputFactory, ObservedInputStream ois,
+ boolean verbose, boolean unconnected) throws CityGMLReadException {
+ return readAndKeepModel(new Citygml3FeatureMapper(config, file, unconnected), inputFactory, ois, verbose);
}
private static CityDoctorModel readAndKeepModel(Citygml3FeatureMapper mapper, CityGMLInputFactory inputFactory,
@@ -496,52 +441,75 @@ public class CityGmlParser {
// object members are replaced by href in model
// need to remove the refs and re-add unparsed objects
List acos = new ArrayList<>();
- while (reader.hasNext()) {
- AbstractFeature chunk = reader.next();
- version = CityGMLModules.getCityGMLVersion(reader.getName().getNamespaceURI());
- if (chunk instanceof CityModel cModel) {
- cModel.setCityObjectMembers(null);
- mapper.setCityModel(cModel);
- mapper.setCityGMLVersion(version);
- } else if (chunk instanceof AbstractCityObject aco) {
- acos.add(aco);
- aco.accept(mapper);
+ CityModel cgmlModel = null;
+ CityDoctorModel cdModel = mapper.getModel();
+ AutoCloseable parsingContext = cdModel.getCache().startParsingMode();
+ try (parsingContext){
+ List queuedObjects = new ArrayList<>();
+ while (reader.hasNext()) {
+ AbstractFeature chunk = reader.next();
+ version = CityGMLModules.getCityGMLVersion(reader.getName().getNamespaceURI());
+ if (chunk instanceof CityModel cModel) {
+ cModel.setCityObjectMembers(null);
+ mapper.setCityModel(cModel);
+ mapper.setCityGMLVersion(version);
+ cgmlModel = cModel;
+
+ if (!queuedObjects.isEmpty()) {
+ for (AbstractCityObject aco : queuedObjects) {
+ if (!cdModel.containsGmlId(aco.getId())) {
+ cgmlModel.getCityObjectMembers().add(new AbstractCityObjectProperty(aco));
+ }
+ }
+ }
+ } else if (chunk instanceof AbstractCityObject aco) {
+ acos.add(aco); // getid
+ String id = aco.getId();
+ aco.accept(mapper);
+ if (cgmlModel == null) {
+ // Add object to queue till the CityModel has been parsed
+ queuedObjects.add(aco);
+ }else if (!cdModel.containsGmlId(id)){
+ cgmlModel.getCityObjectMembers().add(new AbstractCityObjectProperty(aco));
+ }
+ }
}
- }
- if (mapper.getModel().getCityModel() == null) {
- // file does not contain a city model?
- // create it for now
- mapper.setCityModel(new CityModel());
- }
- CityModel cModel = mapper.getModel().getCityModel();
-
- // remove those that should have been parsed
- List parsedCityObjects = mapper.getModel().createFeatureStream()
- .map(CityObject::getGmlObject).toList();
- acos.removeAll(parsedCityObjects);
- // re-add all not parsed objects
- for (AbstractCityObject aco : acos) {
- cModel.getCityObjectMembers().add(new AbstractCityObjectProperty(aco));
- }
- if (logger.isInfoEnabled() && verbose) {
- logger.info(Localization.getText("CityGmlParser.parsedObjects"),
- mapper.getModel().getNumberOfFeatures());
+ if (mapper.getModel().getCityModel() == null) {
+ // file does not contain a city model?
+ // create it for now
+ logger.warn(Localization.getText("CityGmlParser.missingCityModel"));
+ mapper.setCityModel(new CityModel());
+ for (AbstractCityObject aco : queuedObjects) {
+ if (!cdModel.containsGmlId(aco.getId())) {
+ mapper.getModel().getCityModel().getCityObjectMembers().add(new AbstractCityObjectProperty(aco));
+ }
+ }
+ }
+
+ ImplicitGeometryHolder.resolveDeferredObjects(mapper.getModel().getCache());
+ if (logger.isInfoEnabled() && verbose) {
+ logger.info(Localization.getText("CityGmlParser.parsedObjects"),
+ mapper.getModel().getNumberOfFeatures());
+ }
+ mapper.setCityGMLVersion(version);
+ return mapper.getModel();
+ } catch (Exception e) {
+ throw new CityGMLReadException(e);
}
- mapper.setCityGMLVersion(version);
- return mapper.getModel();
+
}
}
- private static void parseEpsgCodeFromFile(Path file, ParserConfiguration config) throws CityGmlParseException {
+ private static void parseEpsgCodeFromFile(Path file, ParserConfiguration config, boolean verbose) throws CityGmlParseException {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file.toFile()))) {
- parseEpsgCodeFromStream(bis, config);
+ parseEpsgCodeFromStream(bis, config, verbose);
} catch (ParserConfigurationException | SAXException | IOException e) {
throw new CityGmlParseException("Failed to read CityGML file", e);
}
}
- private static void parseEpsgCodeFromStream(InputStream is, ParserConfiguration config)
+ private static void parseEpsgCodeFromStream(InputStream is, ParserConfiguration config, boolean verbose)
throws ParserConfigurationException, SAXException {
SAXParser parser = FACTORY.newSAXParser();
CityGmlHandler handler = new CityGmlHandler();
@@ -549,46 +517,19 @@ public class CityGmlParser {
parser.parse(new InputSource(is), handler);
} catch (EnvelopeFoundException e) {
try {
- parseCoordinateSystem(config, handler);
+ parseCoordinateSystem(config, handler, verbose);
} catch (Exception e2) {
logEpsgParseError(e2);
}
} catch (Exception e) {
logEpsgParseError(e);
}
- if (handler.getEpsg() == null && logger.isInfoEnabled()) {
+ if (handler.getEpsg() == null && logger.isInfoEnabled() && verbose) {
logger.info(Localization.getText("CityGmlParser.missingEPSGCode"));
}
}
- private static void parseEpsgCodeFromBuffer(byte[] buffer, ParserConfiguration config)
- throws ParserConfigurationException, SAXException {
- InputStream is = new ByteArrayInputStream(buffer);
- SAXParser parser = FACTORY.newSAXParser();
- CityGmlHandler handler = new CityGmlHandler();
- try {
- parser.parse(new InputSource(is), handler);
- } catch (EnvelopeFoundException e) {
- try {
- parseCoordinateSystem(config, handler);
-
- } catch (Exception e2) {
- logEpsgParseError(e2);
- }
- } catch (SAXParseException spe) {
- // suppress XML document structure warning
- if (!spe.getMessage().matches("XML document structures must start and end within the same entity.")) {
- logEpsgParseError(spe);
- }
- } catch (Exception e) {
- logEpsgParseError(e);
- }
- if (handler.getEpsg() == null && logger.isInfoEnabled()) {
- logger.info(Localization.getText("CityGmlParser.missingEPSGCode"));
- }
- }
-
private static void logEpsgParseError(Exception e) {
logger.debug("Exception while parsing for EPSG code", e);
if (logger.isWarnEnabled()) {
@@ -596,7 +537,7 @@ public class CityGmlParser {
}
}
- private static void parseCoordinateSystem(ParserConfiguration config, CityGmlHandler handler) {
+ private static void parseCoordinateSystem(ParserConfiguration config, CityGmlHandler handler, boolean verbose) {
if (handler.getEpsg() == null) {
return;
}
@@ -604,14 +545,14 @@ public class CityGmlParser {
if (crs == null) {
// could not find a coordinate system for srsName
// assuming metric system
- if (logger.isInfoEnabled()) {
+ if (logger.isInfoEnabled() && verbose) {
logger.info(Localization.getText("CityGmlParser.missingEPSGCode"));
}
return;
}
if (crs.getProjection().getUnits() == Units.METRES) {
// coordinate system is in meters, do not convert
- if (logger.isInfoEnabled()) {
+ if (logger.isInfoEnabled() && verbose) {
logger.info(Localization.getText("CityGmlParser.noConversionNeeded"));
}
return;
@@ -636,11 +577,15 @@ public class CityGmlParser {
CoordinateReferenceSystem utm;
if (centerLat < 0) {
// south
- logger.info("Converting coordiante system to UTM zone {}S", zone);
+ if (logger.isInfoEnabled() && verbose) {
+ logger.info(Localization.getText("CityGmlParser.convertCrsToUtmZoneS"), zone);
+ }
utm = CRS_FACTORY.createFromParameters("UTM", "+proj=utm +ellps=WGS84 +units=m +zone=" + zone + " +south");
} else {
// north
- logger.info("Converting coordiante system to UTM zone {}N", zone);
+ if (logger.isInfoEnabled() && verbose) {
+ logger.info(Localization.getText("CityGmlParser.convertCrsToUtmZoneN"), zone);
+ }
utm = CRS_FACTORY.createFromParameters("UTM", "+proj=utm +ellps=WGS84 +units=m +zone=" + zone);
}
config.setCoordinateSystem(crs, utm);
@@ -756,22 +701,14 @@ public class CityGmlParser {
}
private static void drainCityModel(CityDoctorModel model, CityGmlConsumer cityObjectConsumer) {
- drainCityObjectList(model.getBuildings(), cityObjectConsumer);
- drainCityObjectList(model.getBridges(), cityObjectConsumer);
- drainCityObjectList(model.getVegetation(), cityObjectConsumer);
- drainCityObjectList(model.getLand(), cityObjectConsumer);
- drainCityObjectList(model.getTransportation(), cityObjectConsumer);
- drainCityObjectList(model.getWater(), cityObjectConsumer);
- drainCityObjectList(model.getTunnels(), cityObjectConsumer);
- drainCityObjectList(model.getCityFurniture(), cityObjectConsumer);
- drainCityObjectList(model.getGenericCityObjects(), cityObjectConsumer);
- }
-
- private static void drainCityObjectList(List extends CityObject> objects, CityGmlConsumer cityObjectConsumer) {
- for (CityObject co : objects) {
+ List id = new ArrayList<>();
+ model.createFeatureStream().forEach(co -> {
cityObjectConsumer.accept(co);
- }
- objects.clear();
+ id.add(co.getGmlId());
+ });
+ id.forEach(model::removeFeature);
+
}
+
}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/tesselation/EarcutTesselator.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/tesselation/EarcutTesselator.java
index acfc90f753a0b01a18f94ff71b0664389d4e5962..a3cfb759e826d2950aedf4c0913825e5d04f0e73 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/tesselation/EarcutTesselator.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/tesselation/EarcutTesselator.java
@@ -49,6 +49,15 @@ public class EarcutTesselator {
start = addRingToArray(innerRing, vertices, start, axis);
}
+ // center vertices?
+// double[] projectedCenter = new double[2];
+// Geometry geometry = p.getParent();
+// Vector3d center = geometry.getCenter();
+// axis.writeCoordinatesOfVectorInArray(center, projectedCenter, 0);
+// for (int i = 0; i < vertices.length; i++) {
+// vertices[i] = vertices[i] - projectedCenter[i % 2];
+// }
+
// triangulation
List indices = Earcut.earcut(vertices, holeStart, 2);
List triangles = new ArrayList<>();
@@ -56,14 +65,15 @@ public class EarcutTesselator {
throw new IllegalStateException();
}
for (int i = 0; i < indices.size(); i = i + 3) {
- Triangle3d t = new Triangle3d(vertexObjects.get(indices.get(i + 0)),
- vertexObjects.get(indices.get(i + 1)),
- vertexObjects.get(indices.get(i + 2)));
+ Vertex v1 = vertexObjects.get(indices.get(i + 0));
+ Vertex v2 = vertexObjects.get(indices.get(i + 1));
+ Vertex v3 = vertexObjects.get(indices.get(i + 2));
+ Triangle3d t = new Triangle3d(v1, v2, v3);
triangles.add(t);
}
return new TesselatedPolygon(triangles, p);
}
-
+
private static void addVerticesToList(LinearRing ring, List vertexObjects) {
List vertices = ring.getVertices();
for (int i = 0; i < vertices.size() - 1; i++) {
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/ArchivePacker.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/ArchivePacker.java
deleted file mode 100644
index feadacb3175f2e7e61bbf1d04f41e8c0eefbb030..0000000000000000000000000000000000000000
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/ArchivePacker.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package de.hft.stuttgart.citydoctor2.utils;
-
-import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
-import de.hft.stuttgart.citydoctor2.zip.CityGmlZipArchive;
-import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import java.io.*;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-public class ArchivePacker {
-
- private static final Logger logger = LogManager.getLogger(ArchivePacker.class);
-
- private ArchivePacker(){}
-
- public static void packArchive(String targetPath, CityGmlZipArchive archive){
- Path outputPath = Path.of(targetPath);
- outputPath = outputPath.getParent().resolve(
- FilenameUtils.removeExtension(outputPath.getFileName().toString()) + ".zip");
- Path tmpDir = null;
- try{
- tmpDir = Files.createTempDirectory("zipTmp");
- tmpDir.toFile().deleteOnExit();
- for (CityGmlZipEntry entry : archive.getEntries()) {
- if (entry.getErrorType() != null || !entry.isLoaded()) {
- continue;
- }
- CityDoctorModel model = entry.getModel();
- Path filePath = tmpDir.resolve(entry.getEntrySubPath());
- Files.createDirectories(filePath.getParent());
- model.saveAs(filePath.toString(), model.isValidated());
- }
- zipFolder(tmpDir.toFile(), outputPath.toFile());
-
- }catch (Exception e){
- logger.error(e);
- } finally {
- if (tmpDir != null) {
- try {
- FileUtils.deleteDirectory(tmpDir.toFile());
- } catch (IOException e) {
- logger.error(e);
- }
- }
- }
- }
-
-
- public static void zipFolder(File folder, File zipFile) throws IOException {
- zipFolder(folder, new FileOutputStream(zipFile));
- }
-
- public static void zipFolder(File folder, OutputStream outputStream) throws IOException {
- try (ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
- processFolder(folder, zipOutputStream, folder.getPath().length() + 1);
- }
- }
-
- private static void processFolder(File folder, ZipOutputStream zipOutputStream, int prefixLength)
- throws IOException {
- for (File file : folder.listFiles()) {
- if (file.isFile()) {
- ZipEntry zipEntry = new ZipEntry(file.getPath().substring(prefixLength));
- zipOutputStream.putNextEntry(zipEntry);
- try (FileInputStream inputStream = new FileInputStream(file)) {
- IOUtils.copy(inputStream, zipOutputStream);
- }
- zipOutputStream.closeEntry();
- } else if (file.isDirectory()) {
- processFolder(file, zipOutputStream, prefixLength);
- }
- }
- }
-
- public static void packAndDeleteDirectory(String directoryPath) throws IOException {
- Path sourcePath = Path.of(directoryPath);
- if (!Files.exists(sourcePath)) {
- throw new IllegalStateException("Directory " + directoryPath + " does not exist");
- }
-
- if (!Files.isDirectory(sourcePath)) {
- throw new IllegalStateException("Path " + directoryPath + " is not a directory");
- }
- Path outputPath = sourcePath.getParent().resolve(sourcePath.getFileName() + ".zip");
- zipFolder(sourcePath.toFile(), outputPath.toFile());
-
- FileUtils.deleteDirectory(sourcePath.toFile());
- }
-
-}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/BoundingBoxCalculator.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/BoundingBoxCalculator.java
index 94a65d45c1c497343cf56f271cdd745aef0fdbc3..1285b0c741c3abed146f215f8edb082f2e0aff8f 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/BoundingBoxCalculator.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/BoundingBoxCalculator.java
@@ -26,12 +26,10 @@ import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
-import de.hft.stuttgart.citydoctor2.datastructure.TopLevelTransportFeature;
-import de.hft.stuttgart.citydoctor2.datastructure.TrafficSpaceObject;
-import de.hft.stuttgart.citydoctor2.datastructure.TransportationObject;
-import de.hft.stuttgart.citydoctor2.datastructure.TransportationSpace;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
+import de.hft.stuttgart.citydoctor2.utils.visitors.CityObjectCollector;
+import de.hft.stuttgart.citydoctor2.utils.visitors.MinMaxExtentVisitor;
/**
* Utility class for calculating axis aligned bounding boxes for different
@@ -99,24 +97,10 @@ public class BoundingBoxCalculator {
* @return the bounding box of the model
*/
public static BoundingBox calculateBoundingBox(CityDoctorModel model) {
- Vector3d low = new Vector3d(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
- Vector3d high = new Vector3d(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
+ MinMaxExtentVisitor mima = new MinMaxExtentVisitor();
+ model.accept(mima);
- //TODO: Rework this using visitors
- findMinMax(low, high, model.getBuildings());
- findMinMax(low, high, model.getBridges());
- findMinMax(low, high, model.getLand());
- findMinMaxTransport(low, high, model.getTransportation());
- findMinMax(low, high, model.getWater());
- findMinMax(low, high, model.getVegetation());
- findMinMax(low, high, model.getTunnels());
- findMinMax(low, high, model.getCityFurniture());
- findMinMax(low, high, model.getGenericCityObjects());
-
- Vector3d[] result = new Vector3d[2];
- result[0] = low;
- result[1] = high;
- return BoundingBox.of(result);
+ return BoundingBox.of(mima.getMinMaxExtent());
}
public static BoundingBox calculateBoundingBoxFromPoints(List extends Vector3d> points) {
@@ -159,47 +143,39 @@ public class BoundingBoxCalculator {
}
}
- //TODO: Implement this properly with visitor. Quick and dirty fix for the renderer
- private static void findMinMaxTransport(Vector3d low, Vector3d high, List extends TransportationObject> features) {
- for (TransportationObject to : features) {
- findMinMax(low, high, to);
- if (to instanceof TransportationSpace ts) {
- findMinMaxTransport(low, high, ts.getTrafficSpaces());
- findMinMaxTransport(low, high, ts.getAuxTrafficSpaces());
- if (to instanceof TopLevelTransportFeature top) {
- findMinMaxTransport(low, high, top.getSections());
- findMinMaxTransport(low, high, top.getIntersections());
+
+ private static void findMinMax(Vector3d low, Vector3d high, CityObject co) {
+ CityObjectCollector collector = new CityObjectCollector();
+ co.accept(collector);
+ for (CityObject object : collector.getCityObjects()) {
+ for (Geometry geom : object.getGeometries()) {
+ if (geom.getVertices() == null) {
+ geom.updateVertices();
}
- } else if (to instanceof TrafficSpaceObject tso) {
- findMinMaxTransport(low, high, tso.getTrafficAreas());
+ findMinMax(low, high, geom);
}
}
}
- private static void findMinMax(Vector3d low, Vector3d high, CityObject co) {
- for (Geometry geom : co.getGeometries()) {
- if (geom.getVertices() == null) {
- geom.updateVertices();
+ private static void findMinMax(Vector3d low, Vector3d high, Geometry geom) {
+ for (Vertex v : geom.getVertices()) {
+ if (v.getX() < low.getX()) {
+ low.setX(v.getX());
}
- for (Vertex v : geom.getVertices()) {
- if (v.getX() < low.getX()) {
- low.setX(v.getX());
- }
- if (v.getX() > high.getX()) {
- high.setX(v.getX());
- }
- if (v.getY() < low.getY()) {
- low.setY(v.getY());
- }
- if (v.getY() > high.getY()) {
- high.setY(v.getY());
- }
- if (v.getZ() < low.getZ()) {
- low.setZ(v.getZ());
- }
- if (v.getZ() > high.getZ()) {
- high.setZ(v.getZ());
- }
+ if (v.getX() > high.getX()) {
+ high.setX(v.getX());
+ }
+ if (v.getY() < low.getY()) {
+ low.setY(v.getY());
+ }
+ if (v.getY() > high.getY()) {
+ high.setY(v.getY());
+ }
+ if (v.getZ() < low.getZ()) {
+ low.setZ(v.getZ());
+ }
+ if (v.getZ() > high.getZ()) {
+ high.setZ(v.getZ());
}
}
}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/TimeFormatter.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/TimeFormatter.java
new file mode 100644
index 0000000000000000000000000000000000000000..509bdfaa3a81bba4831de362d7937dfd159c8f54
--- /dev/null
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/TimeFormatter.java
@@ -0,0 +1,62 @@
+package de.hft.stuttgart.citydoctor2.utils;
+
+import java.text.ChoiceFormat;
+
+public final class TimeFormatter {
+
+ private TimeFormatter(){}
+
+ private static final String LESS_THAN_A_SECOND =
+ Localization.getText("TimeFormatter.lessThanASecond");
+
+ private static final ChoiceFormat SECONDS =
+ new ChoiceFormat(
+ new double[]{1, 2},
+ new String[]{Localization.getText("TimeFormatter.oneSecond"),
+ Localization.getText("TimeFormatter.seconds")}
+ );
+
+ private static final ChoiceFormat MINUTES =
+ new ChoiceFormat(
+ new double[]{1, 2},
+ new String[]{Localization.getText("TimeFormatter.oneMinute"),
+ Localization.getText("TimeFormatter.minutes")}
+ );
+
+ private static final ChoiceFormat HOURS =
+ new ChoiceFormat(
+ new double[] {1, 2},
+ new String[]{Localization.getText("TimeFormatter.oneHour"),
+ Localization.getText("TimeFormatter.hours")}
+ );
+
+ /**
+ * Formats a time measurement in milliseconds as a localized String representation.
+ *
+ *
+ * The String representation will return the time as a rounded down integer of the biggest fitting TimeUnit
+ * (seconds, minutes or hours), returning "< 1 second" for times under a second.
+ *
+ * @param millis
+ * @return A localized String representation of the timespan
+ */
+ public static String format(long millis) {
+ if (millis < 1000) {
+ return LESS_THAN_A_SECOND;
+ }else if (millis < 60_000) {
+ long seconds = millis / 1000;
+ String pattern = SECONDS.format(seconds);
+ return pattern.replace("{0}", Long.toString(seconds));
+ }else if (millis < 3_600_000){
+ long minutes = millis / 60_000;
+ String pattern = MINUTES.format(minutes);
+ return pattern.replace("{0}", Long.toString(minutes));
+ } else {
+ long hours = millis / 3_600_000;
+ String pattern = HOURS.format(hours);
+ return pattern.replace("{0}", Long.toString(hours));
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/visitors/MinMaxExtentVisitor.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/visitors/MinMaxExtentVisitor.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ba58ac031dab02b572b90ec4532d5c0d6e0af6f
--- /dev/null
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/visitors/MinMaxExtentVisitor.java
@@ -0,0 +1,57 @@
+package de.hft.stuttgart.citydoctor2.utils.visitors;
+
+import de.hft.stuttgart.citydoctor2.check.Checkable;
+import de.hft.stuttgart.citydoctor2.check.CheckableUtilsVisitor;
+import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
+import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
+import de.hft.stuttgart.citydoctor2.datastructure.ImplicitGeometryHolder;
+import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
+import de.hft.stuttgart.citydoctor2.math.Vector3d;
+
+public class MinMaxExtentVisitor extends CheckableUtilsVisitor {
+
+ Vector3d low;
+ Vector3d high;
+
+ public MinMaxExtentVisitor() {
+ low = new Vector3d(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
+ high = new Vector3d(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
+ }
+
+ public Vector3d[] getMinMaxExtent() {
+ Vector3d[] result = new Vector3d[2];
+ result[0] = low;
+ result[1] = high;
+ return result;
+ }
+
+ @Override
+ public void check(CityObject co) {
+ for (Geometry geom : co.getGeometries()) {
+ if (geom.getVertices() == null) {
+ geom.updateVertices();
+ }
+ for (Vertex v : geom.getVertices()) {
+ if (v.getX() < low.getX()) {
+ low.setX(v.getX());
+ }
+ if (v.getX() > high.getX()) {
+ high.setX(v.getX());
+ }
+ if (v.getY() < low.getY()) {
+ low.setY(v.getY());
+ }
+ if (v.getY() > high.getY()) {
+ high.setY(v.getY());
+ }
+ if (v.getZ() < low.getZ()) {
+ low.setZ(v.getZ());
+ }
+ if (v.getZ() > high.getZ()) {
+ high.setZ(v.getZ());
+ }
+ }
+ }
+ }
+
+}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/writer/CityGMLWriterUtils.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/writer/CityGMLWriterUtils.java
index 4069621e5d79b0386bb5f9d4885ef4243b1d482a..e3b9cbfb9cfba0e2eed6f3dbaa57e6a93cf15f71 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/writer/CityGMLWriterUtils.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/writer/CityGMLWriterUtils.java
@@ -22,12 +22,12 @@ import java.io.File;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Stream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -92,7 +92,7 @@ public class CityGMLWriterUtils {
storeCityObjects(model.getTransportation(), gmlFactory, model, cModel, val);
storeCityObjects(model.getWater(), gmlFactory, model, cModel, val);
storeCityObjects(model.getCityFurniture(), gmlFactory, model, cModel, val);
- storeCityObjects(model.getGenericCityObjects(), gmlFactory, model, cModel, val);
+ storeCityObjects(model.getOtherCityObjects(), gmlFactory, model, cModel, val);
storeCityObjects(model.getTunnels(), gmlFactory, model, cModel, val);
writer.write(cModel);
@@ -135,12 +135,13 @@ public class CityGMLWriterUtils {
de.hft.stuttgart.quality.model.enums.ErrorId adeId = QualityADEUtils.mapErrorIdToAdeId(e.getKey());
if (adeId == null) {
// error that is not part of the ade standard
- logger.warn("Found error {} that cannot be converted to ADE error. It will not be written", e.getKey());
+ logger.warn(Localization.getText("CityGmlWriterUtils.unknownADEError"), e.getKey());
continue;
}
stats.setName(adeId);
statistics.getErrors().add(new ErrorProperty(stats));
}
+ // TODO: Quality ADE update to CityGML 3.0
statistics.setNumErrorBuildings(new FeatureStatisticsProperty(countValidatedCityObjects(model.getBuildings())));
statistics.setNumErrorBridgeObjects(new FeatureStatisticsProperty(countValidatedCityObjects(model.getBridges())));
statistics.setNumErrorLandObjects(new FeatureStatisticsProperty(countValidatedCityObjects(model.getLand())));
@@ -152,29 +153,30 @@ public class CityGMLWriterUtils {
return val;
}
- private static FeatureStatistics countValidatedCityObjects(List extends CityObject> cos) {
- int numChecked = 0;
- int numError = 0;
- for (CityObject co : cos) {
+ private static FeatureStatistics countValidatedCityObjects(Stream extends CityObject> cos) {
+ AtomicInteger numChecked = new AtomicInteger();
+ AtomicInteger numError = new AtomicInteger();
+ cos.forEach(co -> {
if (co.isValidated()) {
- numChecked++;
+ numChecked.getAndIncrement();
if (co.containsAnyError()) {
- numError++;
+ numError.getAndIncrement();
}
}
- }
- return new FeatureStatistics(numChecked, numError);
+ });
+ return new FeatureStatistics(numChecked.get(), numError.get());
}
- private static void storeCityObjects(List extends CityObject> cos, GeometryFactory gmlFactory, CityDoctorModel model, CityModel cModel, Validation val) {
- for (CityObject co : cos) {
+ private static void storeCityObjects(Stream extends CityObject> cos, GeometryFactory gmlFactory, CityDoctorModel model, CityModel cModel, Validation val) {
+ cos.forEach(co -> {
if (model.isValidated() && val != null) {
QualityADEUtils.writeQualityAde(co, val);
}
co.reCreateGeometries(gmlFactory, model.getParserConfig());
cModel.getCityObjectMembers().add(new AbstractCityObjectProperty(co.getGmlObject()));
- }
+ });
+
}
}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/CityGmlZipArchive.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/CityGmlZipArchive.java
deleted file mode 100644
index be6e4cda33b7f24ea127a9f14ed48ae55fa21b27..0000000000000000000000000000000000000000
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/CityGmlZipArchive.java
+++ /dev/null
@@ -1,151 +0,0 @@
-package de.hft.stuttgart.citydoctor2.zip;
-
-import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
-import de.hft.stuttgart.citydoctor2.utils.ArchivePacker;
-import de.hft.stuttgart.citydoctor2.utils.Localization;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.Serial;
-import java.io.Serializable;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-import java.util.zip.ZipInputStream;
-
-/**
- * This class serves as a representation of a ZIP-archive containing CityGml files. The contained files are represented
- * by {@link CityGmlZipEntry} objects.
- */
-public class CityGmlZipArchive implements Serializable {
-
- private static final Logger logger = LogManager.getLogger(CityGmlZipArchive.class);
-
- @Serial
- private static final long serialVersionUID = 2168389511043362615L;
-
- private List entries;
- private final Path archivePath;
- private final String archiveNameRE;
-
- /**
- * Registers a ZIP-file as an archive. All contained XML and GML files will be registered as {@link CityGmlZipEntry} objects.
- *
- * @param zipFile path of the ZIP-file
- * @return A {@link CityGmlZipArchive} object representing the archive, or null if read-access for the ZIP-file was denied
- * @throws MalformedZipFileException if the ZIP-file has encoding errors
- */
- public static CityGmlZipArchive register(String zipFile) throws MalformedZipFileException {
- ArrayList archiveEntries = new ArrayList<>();
- CityGmlZipArchive cgmlArchive = new CityGmlZipArchive(Path.of(zipFile));
- try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {
- ZipEntry ze;
- while ((ze = zis.getNextEntry()) != null) {
- if (ze.isDirectory()) {
- continue;
- }
- if (ze.getName().endsWith(".gml") || ze.getName().endsWith(".xml")) {
- // Ignore report files generated by CityDoctor
- if (ze.getName().endsWith("_report.xml")) {
- continue;
- }
- archiveEntries.add(CityGmlZipEntry.register(ze, cgmlArchive));
- }
- }
- cgmlArchive.setEntries(archiveEntries);
- return cgmlArchive;
- } catch (IOException e) {
- logger.error(Localization.getText("CityGmlZipArchive.ioError"));
- logger.debug(e.getMessage(), e);
- return null;
- } catch (IllegalArgumentException e) {
- logger.error(Localization.getText("CityGmlZipArchive.malformedZipFile"));
- throw new MalformedZipFileException(Localization.getText("CityGmlZipArchive.malformedZipFile"));
- } catch (Exception e) {
- logger.error(Localization.getText("CityGmlZipArchive.generalException"));
- logger.debug(e.getMessage(), e);
- throw (e);
- }
- }
-
- /**
- * Attempts to load all contained {@link CityGmlZipEntry} objects into memory.
- *
- * @param config Parser configuration for the entries
- */
- public void mountArchive(ParserConfiguration config) {
- try (ZipFile zip = new ZipFile(archivePath.toFile())) {
- for (CityGmlZipEntry entry : entries) {
- entry.loadEntry(config);
- }
- } catch (IOException e) {
- logger.error(e);
- }
- }
-
- private CityGmlZipArchive(Path archivePath) {
- this.archivePath = archivePath;
- this.archiveNameRE = archivePath.getFileName().toString().replace(".zip", "") + File.separator;
- }
-
- private void setEntries(List entries) {
- this.entries = entries;
- }
-
- /**
- * Saves this archive as a ZIP-file.
- * @param path target path for the export
- */
- public void exportToZipFile(String path) {
- ArchivePacker.packArchive(path, this);
- }
-
- /**
- * Gets an entry in this archive by its subpath.
- *
- * @param subpath subpath to the entry from this archive's root directory
- * @return the corresponding entry, or null if entry could not be found
- */
- public CityGmlZipEntry getEntry(String subpath) {
- subpath = stripArchivePath(subpath);
- for (CityGmlZipEntry entry : entries) {
- String entryName = stripArchivePath(entry.getEntrySubPath());
- if (entryName.equals(subpath)) {
- return entry;
- }
- }
- return null;
- }
-
- /**
- * Strips the root directory name of this archive from an entry subpath.
- * @param path the relative path to the entry
- * @return String of the path without the root directory
- */
- private String stripArchivePath(String path) {
- Path systemPath = Path.of(path);
- return systemPath.toString().replace(archiveNameRE, "");
- }
-
- /**
- * Gets the path to the ZIP-file associated with this archive.
- * @return path of the ZIP-file
- */
- public Path getArchivePath() {
- return archivePath;
- }
-
- /**
- * Gets the entry list of this archive.
- * @return the entry list
- */
- public List getEntries() {
- return entries;
- }
-
-}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/CityGmlZipEntry.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/CityGmlZipEntry.java
deleted file mode 100644
index d9a86770b90e4f6e5703bf1a31adfda17080d9bd..0000000000000000000000000000000000000000
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/CityGmlZipEntry.java
+++ /dev/null
@@ -1,211 +0,0 @@
-package de.hft.stuttgart.citydoctor2.zip;
-
-import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
-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;
-import de.hft.stuttgart.citydoctor2.parser.ProgressListener;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import java.io.IOException;
-import java.io.Serial;
-import java.io.Serializable;
-import java.nio.file.Path;
-import java.util.zip.ZipEntry;
-
-/**
- * This class serves as a representation of a CityGml file in a ZIP archive.
- *
- * The {@link CityDoctorModel} of the associated file can only be accessed after loading the corresponding entry.
- */
-public class CityGmlZipEntry implements Serializable {
-
- private static final Logger logger = LogManager.getLogger(CityGmlZipEntry.class);
- @Serial
- private static final long serialVersionUID = -5732913269959043262L;
-
- private final Path filePath;
- private final String fileName;
- private final String displayName;
- private transient CityDoctorModel model;
- private CityGmlZipArchive parentArchive;
- private boolean inMemory;
- private long fileSize = -1L;
- private static final long MB = 1024 * 1024L;
- private ZipEntryErrorType errorType = null;
-
-
- /**
- * Attempts to parse the CityGML model associated with this entry and loads it into memory.
- *
- * In the event of a parsing error, the entry will be flagged by assigning the appropriate
- * {@link ZipEntryErrorType} to the errorType field.
- *
- * @param config Parser configuration for this model
- */
- public void loadEntry(ParserConfiguration config) {
- loadEntry(config, null);
- }
-
- /**
- * Attempts to parse the CityGML model associated with this entry and loads it into memory.
- *
- * In the event of a parsing error, the entry will be flagged by assigning the appropriate
- * {@link ZipEntryErrorType} to the errorType field.
- *
- * @param config Parser configuration for this model
- * @param l ProgressListener for tracking parsing progress
- */
- public void loadEntry(ParserConfiguration config, ProgressListener l) {
- if (inMemory) {
- return;
- }
- if (errorType != null) {
- logger.warn("Tried loading erroneous CityGmlZipEntry");
- return;
- }
- try {
- this.model = CityGmlParser.parseCityGmlZipEntry(this, config, l);
- this.inMemory = true;
- } catch (CityGmlParseException | InvalidGmlFileException e) {
- logger.error(e);
- this.errorType = ZipEntryErrorType.INVALID_CITY_GML_FILE;
- } catch (IOException e) {
- logger.error(e);
- this.errorType = ZipEntryErrorType.IO_ERROR;
- }
- }
-
- /**
- * Registers a {@link ZipEntry ZipEntry} in a ZIP-archive as a {@link CityGmlZipEntry}.
- *
- * If the filesize of the associated file exceeds the total available system memory, or read access is denied,
- * the entry will be flagged by assigning the appropriate {@link ZipEntryErrorType} to the errorType field.
- *
- * @param entry The ZipEntry object
- * @param parentArchive The parent archive for this entry
- * @return A corresponding CityGmlZipEntry object
- */
- public static CityGmlZipEntry register(ZipEntry entry, CityGmlZipArchive parentArchive) {
- CityGmlZipEntry cgzEntry = new CityGmlZipEntry(entry, parentArchive, false);
- try {
- if (!cgzEntry.entrySizeWithinMemoryLimits()) {
- cgzEntry.errorType = ZipEntryErrorType.EXCESSIVE_FILESIZE;
- }
- } catch (IOException e) {
- logger.error(e);
- cgzEntry.errorType = ZipEntryErrorType.IO_ERROR;
- }
- return cgzEntry;
- }
-
- /**
- * Checks if the filesize of this entry would exceed the system's available memory.
- *
- * @return true if within limits, false otherwise
- * @throws IOException if read access to the ZIP-archive is denied
- */
- private boolean entrySizeWithinMemoryLimits() throws IOException {
- long memoryLimit = (long) Math.ceil(((double) Runtime.getRuntime().maxMemory() / MB) * 0.9);
- if (fileSize == -1L) {
- try (CityGmlZipEntryFile entryFile = new CityGmlZipEntryFile(this)) {
- long filesize = entryFile.getFileSize();
- if (filesize != -1) {
- this.fileSize = filesize;
- } else {
- return false;
- }
- } catch (Exception e) {
- throw new IOException(e);
- }
- }
- return memoryLimit > (fileSize / MB);
- }
-
- private CityGmlZipEntry(ZipEntry entry, CityGmlZipArchive parentArchive, boolean inMemory) {
- this.fileName = entry.getName();
- this.filePath = Path.of(entry.getName());
- this.displayName = filePath.getFileName().toString();
- if (entry.getSize() != -1) {
- this.fileSize = entry.getSize();
- }
- this.model = null;
- this.inMemory = inMemory;
- this.parentArchive = parentArchive;
- }
-
- /**
- * Gets the parent archive of this entry.
- * @return the archive
- */
- public CityGmlZipArchive getArchive() {
- return parentArchive;
- }
-
- /**
- * Gets the sub-path in the archive of the file associated with this entry.
- *
- * @return the relative sub-path from the archive root directory
- */
- public String getEntrySubPath() {
- return fileName;
- }
-
- /**
- * Gets the name of the file associated with this entry.
- * @return the filename
- */
- public String getDisplayName() {
- return displayName;
- }
-
- /**
- * Gets the {@link ZipEntryErrorType} of this entry.
- * @return the error type, or null if this entry is not erroneous
- */
- public ZipEntryErrorType getErrorType() {
- return errorType;
- }
-
- /**
- * Gets the {@link CityDoctorModel} of this entry.
- * @return The model, or null if the entry has not been loaded or is erroneous
- */
- public CityDoctorModel getModel() {
- return model;
- }
-
- public void setFileSize(long size) {
- fileSize = size;
- }
-
- /**
- * Resolves the reference path of a {@link de.hft.stuttgart.citydoctor2.datastructure.LibraryObject LibraryObject}
- * in the {@link CityDoctorModel} of this entry.
- * @param libraryObjectPath The reference path to the LibraryObject's CityGml file
- * @return Relative sub-path within the archive to the CityGml file
- */
- public Path resolveLibraryObjectPath(String libraryObjectPath) {
- return filePath.getParent().resolve(libraryObjectPath);
- }
-
- /**
- * Checks if the {@link CityDoctorModel} of this entry has been loaded into memory.
- *
- * @return true if it is loaded, false otherwise
- */
- public boolean isLoaded() {
- return inMemory;
- }
-
- /**
- * Returns the estimated uncompressed filesize of this entry.
- *
- * @return filesize in bytes, -1L if filesize is unknown
- */
- public long getFileSize() {
- return fileSize;
- }
-}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/CityGmlZipEntryFile.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/CityGmlZipEntryFile.java
deleted file mode 100644
index 3bf82fe00a2490d9eef2eb715ef6edc5a4a14786..0000000000000000000000000000000000000000
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/CityGmlZipEntryFile.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package de.hft.stuttgart.citydoctor2.zip;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * This class serves as a resource for read-access to the file that is being represented by
- * a CityGmlZipEntry object.
- *
- * Does not decompress the file or the parent ZIP-archive.
- */
-public class CityGmlZipEntryFile implements AutoCloseable {
-
- private final ZipFile zip;
- private final ZipEntry zipEntry;
- private final CityGmlZipEntry cgmlZipEntry;
- private boolean closed = false;
-
- /**
- * Creates a {@link CityGmlZipEntryFile} for a {@link CityGmlZipEntry} object's referenced file.
- *
- * @param entry the requested entry
- * @throws IOException if read access to the ZIP-archive is denied.
- */
- public CityGmlZipEntryFile(CityGmlZipEntry entry) throws IOException {
- CityGmlZipArchive archive = entry.getArchive();
- zip = new ZipFile(archive.getArchivePath().toFile());
- zipEntry = zip.getEntry(entry.getEntrySubPath());
- this.cgmlZipEntry = entry;
- }
-
- /**
- * Gets a new InputStream of this file.
- *
- * Returned streams are independent of each other, but will all be closed when the {@link CityGmlZipEntryFile} object
- * is closed.
- * @return an InputStream of this file.
- * @throws IOException when this method is called after the file has been closed.
- */
- public InputStream getInputStream() throws IOException {
- if (closed){
- throw new IOException("CityGmlZipEntryFile closed");
- }
- return zip.getInputStream(zipEntry);
- }
-
- /**
- * Gets an estimation of this file's filesize.
- * @return filesize in bytes, -1L if unknown
- * @throws IOException when this method is called after the file has been closed.
- */
- public long getFileSize() throws IOException {
- if (closed){
- throw new IOException("CityGmlZipEntryFile closed");
- }
- if (cgmlZipEntry.getFileSize() == -1L) {
- if (zipEntry.getSize() == -1) {
- long bytes = 0;
- InputStream is = new BufferedInputStream(this.getInputStream());
- for (int i = is.read(); i != -1; i = is.read()) {
- bytes++;
- }
- cgmlZipEntry.setFileSize(bytes);
- } else {
- cgmlZipEntry.setFileSize(zipEntry.getSize());
- }
- }
- return cgmlZipEntry.getFileSize();
- }
-
- @Override
- public void close() throws IOException {
- zip.close();
- closed = true;
- }
-}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/MalformedZipFileException.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/MalformedZipFileException.java
deleted file mode 100644
index 759fbe6bffca2ee965fbbb0b84a35b6202398084..0000000000000000000000000000000000000000
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/MalformedZipFileException.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package de.hft.stuttgart.citydoctor2.zip;
-
-import java.util.zip.ZipException;
-
-/**
- * Signals that a ZIP-file is corrupted and couldn't be parsed.
- */
-public class MalformedZipFileException extends ZipException {
-
- public MalformedZipFileException() {
- super();
- }
-
- public MalformedZipFileException(String message) {
- super(message);
- }
-}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/ZipEntryErrorType.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/ZipEntryErrorType.java
deleted file mode 100644
index 7dec72b42b00da211c994f85d05005916e9430bf..0000000000000000000000000000000000000000
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/ZipEntryErrorType.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package de.hft.stuttgart.citydoctor2.zip;
-
-/**
- * Error types for {@link CityGmlZipEntry} objects.
- */
-public enum ZipEntryErrorType {
- INVALID_CITY_GML_FILE, EXCESSIVE_FILESIZE, IO_ERROR
-}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/ZipParser.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/ZipParser.java
deleted file mode 100644
index e65d96b82ad2b8f3d29109348ccf6bb22107de2e..0000000000000000000000000000000000000000
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/zip/ZipParser.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package de.hft.stuttgart.citydoctor2.zip;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-public class ZipParser {
-
- private static final Logger logger = LogManager.getLogger(ZipParser.class);
-
-
-
-}
diff --git a/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization.properties b/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization.properties
index 78349133d6520a64c71648949f2205e4c513add6..59ecf4ef6cf2cbcb46cf92569781ccb940c2ff54 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization.properties
+++ b/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization.properties
@@ -1,173 +1,201 @@
-CityDoctorValidation.Version=${versionString}
-DistanceError.distanceFromPlane=distance from plane
-AboutDialog.developedBy=Developed by
+AboutDialog.closeBtn=Close
AboutDialog.contact=Contact
+AboutDialog.developedBy=Developed by
AboutDialog.title=CityDoctor 3 - About
-AboutDialog.closeBtn=Close
-CheckDialog.title=Check Configuration
-CheckDialog.schematronFiles=Schematron Files
-CheckDialog.schematronChooserTitle=Choose schematron file..
-CheckDialog.validationConfiguration=Validation Configuration
-CheckDialog.startingChecks=Starting checks
-CheckDialog.checksDone=Checks done
-CheckDialog.failedChecks=Failed to execute checks
-CheckDialog.schematronFileNotExisting=Schematron file does not exist, ignoring
+CheckContainer.error=Unexpected exception while executing check: {}
+CheckDialog.availableChecksLabel=Available Checks
+CheckDialog.cancelBtn=Cancel
+CheckDialog.checkBtn=Check
CheckDialog.checkEnabled=Enabled
CheckDialog.checkName=Name
-CheckDialog.parameterValue=Value
+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.checksTab=Checks
+CheckDialog.failedChecks=Failed to execute checks
+CheckDialog.filterTab=Filter
+CheckDialog.geometricChecksLabel=Geometric Checks
+CheckDialog.globalParametersLabel=Global Parameters
+CheckDialog.noPathError=Output path is missing!
+CheckDialog.outputPathBtn=Select
+CheckDialog.outputPathLabel=Output directory (Required):
CheckDialog.parameterUnit=Unit
+CheckDialog.parameterValue=Value
+CheckDialog.pdfReportsOption=Create PDF reports
+CheckDialog.schematronChooserTitle=Choose schematron file ...
+CheckDialog.schematronFileLabel=Schematron File:
+CheckDialog.schematronFileNotExisting=Schematron file does not exist, Schematron will be skipped
+CheckDialog.schematronFiles=Schematron Files
+CheckDialog.selectBtn=Select
+CheckDialog.semanticChecksLabel=Semantic 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.streamCheckOption=Use low memory mode
+CheckDialog.title=Check Configuration
+CheckDialog.validationConfiguration=Validation Configuration
+CheckDialog.xmlReportsOption=Create XML reports
+Checker.checkFeature=Checking feature: {}
+Checker.checksFinished=Finished executing checks. Total time: {0}
+Checker.dbStillUnresponsive=Checker still unable to load some CityObjects from database!
+Checker.dbUnresponsive=Checker could not load some CityObjects from database!
+Checker.executeCheck=Executing check: {}
+Checker.failPdf=Failed to write PDF Report.
+Checker.failReports=Failed to write reports.
+Checker.failXml=Failed to write XML Error Report.
+Checker.finishedSchematron=Finished Schematron validation
+Checker.futuresCheckFailures=Encountered check failures due to the following errors:
+Checker.noCheckSatisfiesRequirement=Could not find any check that satisfies requirement {}, it will not be checked
+Checker.schematronCompleted=Schematron completed
+Checker.schematronFileNotFound=Schematron file {} could not be found
+Checker.schematronInterrupted=Main Thread was interrupted while waiting for Schematron
+Checker.schematronStillRunning=Schematron is still running. Waiting for completion, this may take some time
+Checker.schematronValidation=Schematron-validation thread started
+Checker.shutdownInterrupted=Main Thread got interrupted during ThreadPool shutdown
+Checker.validationInterrupted=Validation aborted: Checker got interrupted
+Checker.waitAndRetry=Waiting a second before retrying...
+Checks.missingCheck=Could not find check for id: {}
+CityDoctorController.exportSuccess=Successfully exported feature
CityDoctorController.noDatamodel=Datamodel is null, no checks could be done
CityDoctorController.noSourceFile=Source file is null, no checks could be done
CityDoctorController.noZipFile=ZIP archive is null, no checks could be done
-CityDoctorController.exportSuccess=Successfully exported feature
CityDoctorController.saveZipArchiveReports=Successfully exported validation reports!
+CityDoctorValidation.Version=${versionString}
+CityDoctorValidation.inputFileNotExisting= Input file '{}' does not exist.
+CityDoctorValidation.loadingDefaultConfig=No configuration file given, loading default configuration
+CityDoctorValidation.noConfig=No configuration file specified with -config [FILE]
+CityDoctorValidation.noInputFile=No input file specified. (-in [FILE])
+CityDoctorValidation.noOutputFile=No output file specified. (-out [FILE])
+CityDoctorValidation.notExactlyOneConfigFile=Specify exactly one file as configuration
+CityDoctorValidation.notExactlyOneInputFile=Specify exactly one file as input.
+CityDoctorValidation.notExactlyOneOutputFile=Specify exactly one file as output.
+CityDoctorValidation.notExactlyOnePDFOutput=Specify exactly one file as pdfReport
+CityDoctorValidation.notExactlyOneXMLOutput=Specify exactly one file as xmlReport
+CityDoctorValidation.wrongInputFileFormat=Input file '{}' does not end with .gml or .xml
+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.convertCrsToUtmZoneS=Converting coordinate system to UTM zone {}S
+CityGmlParser.creating4jContextFailed=Unable to create citygml4j context
+CityGmlParser.creatingAdePluginsFailed=Unable to add ADE plugins to citygml4j
+CityGmlParser.errorReadingGmlFile=Error while reading city gml file\n{}
+CityGmlParser.errorWritingGmlFile=Error while writing city gml file\n{}
+CityGmlParser.failedEPSGParse=Could not read EPSG code, fallback to metric system
+CityGmlParser.missingCityModel=File does not contain a CityModel definition! Temporary CityModel will be created.
+CityGmlParser.missingEPSGCode=No EPSG code found, assuming metric system
+CityGmlParser.noConversionNeeded=Coordinate system is in meters, no conversion done
+CityGmlParser.notValidGmlFile=This is not a valid GML-File\n
+CityGmlParser.parsedObjects=Parsed model with {} objects
+CityGmlWriterUtils.unknownADEError= Found error {} that cannot be converted to ADE error. It will not be written
+CityGmlZipArchive.generalException=Encountered an unexpected error while reading the ZIP archive
+CityGmlZipArchive.ioError=Accessing the ZIP archive failed
+CityGmlZipArchive.malformedZipFile=Parsing of ZIP archive aborted, ZIP file is malformed!
+DatabaseHandler.batchCommitFailure=Batch-commit aborted: Critical failure while trying to write CityObject {} to database!
+DatabaseHandler.connectionFailure=Connection to embedded database could not be opened!
+DatabaseHandler.fetchErrorIdsFailure=Fetching list of GmlIDs of CityObjects with errors failed!
+DatabaseHandler.getAllCityObjectsFailure=Fetching of all CityObjects failed!
+DatabaseHandler.getBBoxIntersectFailure= Connection to database failed while trying to fetch bbox intersecting objects of CityObject {}
+DatabaseHandler.getBufferIntersectFailure=Connection to database failed while trying to fetch buffer intersecting objects of CityObject {}
+DatabaseHandler.getFeatureCountFailure=Connection to database failed while trying to get count of CityObjects!
+DatabaseHandler.marshallingFailure=Writing CityObject {} to database failed!
+DatabaseHandler.serializationFailure=Serialization of CityObject {} failed!
+DatabaseHandler.setupFailure=FATAL ERROR: Creation of embedded database failed!
+DatabaseHandler.tableFailure=FATAL ERROR: Creation of features table failed!
+DatabaseHandler.unmarshallingFailure=Loading of CityObject {} from embedded database failed!
+DistanceError.distanceFromPlane=distance from plane
+ErrorItemVisitor.childId=Child id
+ErrorItemVisitor.component=Component
+ErrorItemVisitor.degeneratedRing=Degenerated ring
+ErrorItemVisitor.deviation=Deviation
+ErrorItemVisitor.distance=Distance
+ErrorItemVisitor.intersection=Intersection
+ErrorItemVisitor.nameOfAttribute=Name of attribute
+ErrorItemVisitor.pointTouchesEdge=Point touches edge
+ErrorItemVisitor.triangles=Triangles
ExceptionDialog.stacktrace=The exception stacktrace was:
-FilterPane.buildings=Buildings
+FeatureMapper.polygonUnreferenced=Polygon {} is referenced but not found in feature polygons
FilterPane.bridges=Bridges
+FilterPane.buildings=Buildings
FilterPane.landUse=Land Use
FilterPane.transportation=Transportation
FilterPane.vegetation=Vegetation
FilterPane.water=Water
-MainToolBar.wireframe=Show/Hide Wireframe
+GeometryMapper.emptyPolygon=Found polygon without exterior ring, ignoring
+LibraryObject.fileMissing=Implicit geometry references non-existing library object file {}
+LibraryObject.parsingError=Encountered an error while parsing library object {}
MainToolBar.culling=Enable/Disable Culling
-MainToolBar.writeReports=Write Reports
MainToolBar.executeChecks=Execute Checks
-MainToolBar.showWorld=Show entire city model
-MainToolBar.resetCamera=Reset view
MainToolBar.hideRoof=Show/Hide roof BoundarySurfaces
+MainToolBar.resetCamera=Reset view
+MainToolBar.showWorld=Show entire city model
+MainToolBar.wireframe=Show/Hide Wireframe
+MainToolBar.writeReports=Write Reports
MainToolBar.zip=Open zip-entry selection window
-MainWindow.missingConfig=Could not find configuration file.
-MainWindow.loadGivenFile=Loading given file, please wait
-MainWindow.finishedLoading=Finished loading
-MainWindow.checking=Checking, please wait
-MainWindow.writeXml=Writing xml report
-MainWindow.finishedXml=Finished xml report
-MainWindow.writePdf=Writing pdf report
-MainWindow.finishedPdf=Finished pdf report
-MainWindow.loadFailed=Failed to load given gml file: {}
MainWindow.all=All
-MainWindow.withErrors=With errors
-MainWindow.export=Export feature
+MainWindow.attributeTab=Attributes
+MainWindow.availableLabel=Available:
+MainWindow.bridgeTab=Bridges
+MainWindow.buildingsTab=Buildings
+MainWindow.checking=Checking, please wait
+MainWindow.cityfurnitureTab=CityFurniture
+MainWindow.clearBtn=Clear
MainWindow.copyId=Copy GML-ID
MainWindow.delete=Delete feature
-MainWindow.infoTopLevelExport=Only top-level object can be exported!
+MainWindow.edgesTab=Edges
+MainWindow.errorsTab=Errors
+MainWindow.export=Export feature
+MainWindow.finishedLoading=Finished loading
+MainWindow.finishedPdf=Finished pdf report
+MainWindow.finishedXml=Finished xml report
+MainWindow.focusCityObject=Focus object
+MainWindow.globalErrorsTab=Global Errors
MainWindow.infoTopLevelCopyID=GML-ID can only be copied from top-level object!
-mainWindow.warnCopyIdFailed=Could not copy GML-ID!
-OpenFileDialog.select=Select CityGML file
+MainWindow.infoTopLevelExport=Only top-level object can be exported!
MainWindow.languageChange=For the change in language to apply, restart CityDoctor2.
-MainWindow.buildingsTab=Buildings
-MainWindow.vegetationTab=Vegetation
-MainWindow.transportationTab=Transportation
-MainWindow.tunnelTab=Tunnels
-MainWindow.bridgeTab=Bridges
-MainWindow.waterTab=Water
-MainWindow.terrainTab=Terrain
-MainWindow.cityfurnitureTab=CityFurniture
+MainWindow.loadFailed=Failed to load given gml file: {}
+MainWindow.loadGivenFile=Loading given file, please wait
+MainWindow.logTab=Log
+MainWindow.memoryLabel=Memory:
+MainWindow.missingConfig=Could not find configuration file.
MainWindow.otherObjectsTab=Other
-MainWindow.viewLabel=View
-MainWindow.showLabel=Show:
-MainWindow.searchLabel=Search:
-MainWindow.searchBtn=Search
-MainWindow.clearBtn=Clear
-MainWindow.errorsTab=Errors
MainWindow.polygonsTab=Polygons
-MainWindow.edgesTab=Edges
+MainWindow.searchBtn=Search
+MainWindow.searchLabel=Search:
+MainWindow.showLabel=Show:
+MainWindow.terrainTab=Terrain
+MainWindow.transportationTab=Transportation
+MainWindow.tunnelTab=Tunnels
+MainWindow.vegetationTab=Vegetation
MainWindow.verticesTab=Vertices
-MainWindow.attributeTab=Attributes
-MainWindow.logTab=Log
-MainWindow.globalErrorsTab=Global Errors
-MainWindow.focusCityObject=Focus object
+MainWindow.viewLabel=View
+MainWindow.warnCopyIdFailed=Could not copy GML-ID!
+MainWindow.waterTab=Water
+MainWindow.withErrors=With errors
+MainWindow.writePdf=Writing pdf report
+MainWindow.writeXml=Writing xml report
+OpenFileDialog.cancelBtn=Cancel
OpenFileDialog.fileLabel=File:
-OpenFileDialog.selectBtn=Select
OpenFileDialog.loadBtn=Load
-OpenFileDialog.settingsPane=Parser Preferences
+OpenFileDialog.loadFailed=Failed to load CityGML File
+OpenFileDialog.lowMemoryLabel=Low Memory Consumption Mode
OpenFileDialog.roundingPlacesLabel=NumberOfRoundingPlaces
+OpenFileDialog.select=Select CityGML file
+OpenFileDialog.selectBtn=Select
+OpenFileDialog.settingsPane=Parser Preferences
OpenFileDialog.xmlValidationLabel=Use XML Validation
-Checker.failXml=Failed to write XML Error Report.
-Checker.failPdf=Failed to write PDF Report.
-Checker.checksFinished=Finished executing checks
-Checker.schematronValidation=Starting Schematron validation
-Checker.finishedSchematron=Finished Schematron validation
-Checker.failReports=Failed to write reports.
-Checker.checkFeature=Checking feature: {}
-Checker.executeCheck=Executing check: {}
-ValidationConfiguration.reenable={} has been disabled but {} depends on it, reenabling
+TimeFormatter.hours={0} hours
+TimeFormatter.lessThanASecond=< 1 second
+TimeFormatter.minutes={0} minutes
+TimeFormatter.oneHour=1 hour
+TimeFormatter.oneMinute=1 minute
+TimeFormatter.oneSecond=1 second
+TimeFormatter.seconds={0} seconds
+Unit.Degree=Degree
+Unit.Radian=Radian
ValidationConfiguration.missingSchematron={} is not an existing file, disabling schematron check
-CheckContainer.error=Unexpected exception while executing check: {}
-Checks.missingCheck=Could not find check for id: {}
-OpenFileDialog.cancelBtn=Cancel
-CheckDialog.checksTab=Checks
-CheckDialog.filterTab=Filter
-CheckDialog.globalParametersLabel=Global Parameters
-CheckDialog.availableChecksLabel=Available Checks
-CheckDialog.geometricChecksLabel=Geometric Checks
-CheckDialog.semanticChecksLabel=Semantic Checks
-CheckDialog.schematronFileLabel=Schematron File:
-CheckDialog.selectBtn=Select
-CheckDialog.checkBtn=Check
-CheckDialog.cancelBtn=Cancel
-CheckDialog.streamCheckOption=Use low memory mode
-CheckDialog.streamCheckLabel=Citymodels are not loaded and kept in memory. Check results are saved to the QualityADE in copies of the input files.
-CheckDialog.outputPathLabel=Output directory (Required):
-CheckDialog.outputPathBtn=Select
-CheckDialog.pdfReportsOption=Create PDF reports
-CheckDialog.xmlReportsOption=Create XML reports
-CheckDialog.noPathError=Output path is missing!
-ZipEntryManager.title=Zip-entry manager
-ZipEntryManager.entryListTitle=Zip-entries
-ZipEntryManager.metadata=Metadata
-ZipEntryManager.subpathLbl=Subpath:
-ZipEntryManager.erroneousLbl=Erroneous:
-ZipEntryManager.excessiveFileSize=Filesize exceeds memory
-ZipEntryManager.invalidCityGml=Invalid CityGML file
-ZipEntryManager.ioError=Unable to access file
-ZipEntryManager.filesizeLbl=Filesize:
-ZipEntryManager.validatedLbl=Validated:
-ZipEntryManager.objectCountLbl=Object count:
-ZipEntryManager.loadBtn=Load CityGML model
-ZipEntryManager.decompressBtn=Unpack file
-ZipEntryManager.decompressAllBtn=Unpack all files
-ZipEntryManager.checkAllBtn=Check all files
-ZipEntryManager.showReportBtn=Show error statistic
-ZipEntryManager.saveBtn=Export validation results
-ZipEntryManager.cancelBtn=Cancel
-ZipEntryManager.unknownValue=N/A
-ZipEntryManager.yes=Yes
-ZipEntryManager.no=No
-CityGmlZipArchive.ioError=Accessing the ZIP archive failed
-CityGmlZipArchive.malformedZipFile=Parsing of ZIP archive aborted, ZIP file is malformed!
-CityGmlZipArchive.generalException=Encountered an unexpected error while reading the ZIP archive
-WriteReportDialog.writeBtn=Save
+ValidationConfiguration.reenable={} has been disabled but {} depends on it, reenabling
WriteReportDialog.cancelBtn=Cancel
WriteReportDialog.errorStatisticsLabel=Error Statistics
WriteReportDialog.saveImageBtn=Save Image...
WriteReportDialog.selectPdfBtn=Select
WriteReportDialog.selectXmlFile=Select
+WriteReportDialog.writeBtn=Save
WriteReportDialog.xAxisLabel=Error
-WriteReportDialog.yAxisLabel=Count
-Unit.Radian=Radian
-Unit.Degree=Degree
-FeatureMapper.polygonUnreferenced=Polygon {} is referenced but not found in feature polygons
-GeometryMapper.emptyPolygon=Found polygon without exterior ring, ignoring
-CityGmlParser.parsedObjects=Parsed model with {} objects
-CityGmlParser.chunkReadFailed=Failed to read GML file in chunks, falling back to reading the complete file
-CityGmlParser.notValidGmlFile=This is not a valid GML-File\n
-CityGmlParser.errorReadingGmlFile=Error while reading city gml file\n{}
-CityGmlParser.errorWritingGmlFile=Error while writing city gml file\n{}
-CityGmlParser.noConversionNeeded=Coordinate system is in meters, no conversion done
-CityGmlParser.failedEPSGParse=Could not read EPSG code, fallback to metric system
-CityGmlParser.missingEPSGCode=No EPSG code found, assuming metric system
-OpenFileDialog.loadFailed=Failed to load CityGML File
-MainWindow.memoryLabel=Memory:
-CheckDialog.checksReenabledAlert=Some checks have been reenabled so that other wanted checks can be executed\nSee the log for more information.
-MainWindow.availableLabel=Available:
-OpenFileDialog.lowMemoryLabel=Low Memory Consumption Mode
-ErrorItemVisitor.intersection=Intersection
-ErrorItemVisitor.component=Component
-ErrorItemVisitor.nameOfAttribute=Name of attribute
-ErrorItemVisitor.childId=Child id
-ErrorItemVisitor.distance=Distance
-ErrorItemVisitor.pointTouchesEdge=Point touches edge
-ErrorItemVisitor.degeneratedRing=Degenerated ring
-ErrorItemVisitor.deviation=Deviation
-ErrorItemVisitor.triangles=Triangles
\ No newline at end of file
+WriteReportDialog.yAxisLabel=Count
\ No newline at end of file
diff --git a/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization_de.properties b/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization_de.properties
index 864c13b7b84e9974f1bd6c2b2ab9c6d5e3b45129..e9c1f7b68d35cda5c4a329698fe8801e4d8f31ba 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization_de.properties
+++ b/CityDoctorParent/CityDoctorModel/src/main/resources/CityDoctorLocalization_de.properties
@@ -1,171 +1,201 @@
-DistanceError.distanceFromPlane=Abstand von der Ebene
-AboutDialog.developedBy=Entwickelt von
+AboutDialog.closeBtn=Schlie\u00DFen
AboutDialog.contact=Kontakt
+AboutDialog.developedBy=Entwickelt von
AboutDialog.title=CityDoctor 3 - \u00DCber
-AboutDialog.closeBtn=Schlie\u00DFen
-CheckDialog.title=Pr\u00fcfungskonfiguration
-CheckDialog.schematronFiles=Schematron Dateien
-CheckDialog.schematronChooserTitle=W\u00e4hle Schematron Datei..
-CheckDialog.validationConfiguration=Validierungs Konfiguration
-CheckDialog.startingChecks=Starte Pr\u00fcfung
+CheckContainer.error=Unerwarteter Fehler bei der Ausf\u00fchrung von Pr\u00fcfung: {}
+CheckDialog.availableChecksLabel=Verf\u00fcgbare Pr\u00fcfungen
+CheckDialog.cancelBtn=Abbrechen
+CheckDialog.checkBtn=Pr\u00fcfen
+CheckDialog.checkEnabled=Aktiv
+CheckDialog.checkName=Name
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.checksTab=Pr\u00fcfungen
CheckDialog.failedChecks=Konnte Pr\u00fcfungen nicht ausf\u00fchren
-CheckDialog.schematronFileNotExisting=Schematron Datei existiert nicht, ignoriere
-CheckDialog.checkEnabled=Aktiv
-CheckDialog.parameterValue=Wert
+CheckDialog.filterTab=Filter
+CheckDialog.geometricChecksLabel=Geometrische Pr\u00fcfungen
+CheckDialog.globalParametersLabel=Globale Parameter
+CheckDialog.noPathError=Ausgabepfad wurde nicht gesetzt!
+CheckDialog.outputPathBtn=Ausw\u00e4hlen
+CheckDialog.outputPathLabel=Ausgabeordner (Pflichtfeld):
CheckDialog.parameterUnit=Einheit
-CityDoctorController.noDatamodel=Datenmodell ist null, keine Pr\u00fcfungen konnten ausgef\u00fchrt werden
-CityDoctorController.noSourceFile=Quelldatei ist null, keine Pr\u00fcfungen konnten ausgef\u00fchrt werden
-CityDoctorController.noZipFile=ZIP-Archiv ist null, keine Pr\u00fcfungen konnten ausgef\u00fchrt werden
-CityDoctorController.exportSuccess=Feature export erfolgreich abgeschlossen
+CheckDialog.parameterValue=Wert
+CheckDialog.pdfReportsOption=PDF-Berichte erstellen
+CheckDialog.schematronChooserTitle=W\u00e4hle Schematron Datei ...
+CheckDialog.schematronFileLabel=Schematron Datei:
+CheckDialog.schematronFileNotExisting=Schematron Datei existiert nicht, Schematron-Pr\u00fcfung wird \u00fcbersprungen
+CheckDialog.schematronFiles=Schematron Dateien
+CheckDialog.selectBtn=Ausw\u00e4hlen
+CheckDialog.semanticChecksLabel=Semantische Pr\u00fcfungen
+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.streamCheckOption=Niedrigen Arbeitsspeicherverbrauchsmodus aktivieren
+CheckDialog.title=Pr\u00fcfungskonfiguration
+CheckDialog.validationConfiguration=Validierungskonfiguration
+CheckDialog.xmlReportsOption=XML-Berichte erstellen
+Checker.checkFeature=Pr\u00fcfe Feature: {}
+Checker.checksFinished=Durchf\u00fchrung der Pr\u00fcfungen abgeschlossen. Gesamtzeit: {0}
+Checker.dbStillUnresponsive=Pr\u00fcfung konnte weiterhin einige CityObjects nicht aus der Datenbank laden!
+Checker.dbUnresponsive=Pr\u00fcfung konnte einige CityObjects nicht aus der Datenbank laden!
+Checker.executeCheck=F\u00fchre Pr\u00fcfung aus: {}
+Checker.failPdf=Konnte PDF-Fehlerbericht nicht schreiben.
+Checker.failReports=Konnte Pr\u00fcfberichte nicht schreiben.
+Checker.failXml=Konnte XML-Fehlerbericht nicht schreiben.
+Checker.finishedSchematron=Schematron-Pr\u00fcfung abgeschlossen
+Checker.futuresCheckFailures=Einige Pr\u00fcfungen sind aufgrund folgender Fehler fehlgeschlagen:
+Checker.noCheckSatisfiesRequirement=Keine Pr\u00fcfung erf\u00fcllt die Anforderung {}, Anforderung wird nicht gepr\u00fcft
+Checker.schematronCompleted=Schematron-Pr\u00fcfung abgeschlossen
+Checker.schematronFileNotFound=Schematron Datei {} konnte nicht gefunden werden
+Checker.schematronInterrupted=Main Thread hat Interrupt-Befehl w\u00e4hrend dem Warten auf Schematron Abschluss erhalten!
+Checker.schematronStillRunning=Schematron-Pr\u00fcfung ist noch nicht abgeschlossen. Warten auf Abschluss der Pr\u00fcfung, dies kann einiges an Zeit beanspruchen
+Checker.schematronValidation=Schematron-Pr\u00fcfung gestartet
+Checker.shutdownInterrupted=Main-Thread hat einen Interrupt-Befehl w\u00e4hrend dem ThreadPool shutdown erhalten
+Checker.validationInterrupted=Validierung abgebrochen: Pr\u00fcfung hat Interrupt-Befehl erhalten
+Checker.waitAndRetry=Wiederhole Pr\u00fcfung nach kurzer Wartezeit ...
+Checks.missingCheck=Konnte keine Pr\u00fcfung f\u00fcr id {} finden
+CityDoctorController.exportSuccess=Exportieren des Features erfolgreich abgeschlossen
+CityDoctorController.noDatamodel=Datenmodell ist NULL, keine Pr\u00fcfungen konnten ausgef\u00fchrt werden
+CityDoctorController.noSourceFile=Quelldatei ist NULL, keine Pr\u00fcfungen konnten ausgef\u00fchrt werden
+CityDoctorController.noZipFile=ZIP-Archiv ist NULL, keine Pr\u00fcfungen konnten ausgef\u00fchrt werden
CityDoctorController.saveZipArchiveReports=Validierungsberichte erfolgreich exportiert!
+CityDoctorValidation.Version=${versionString}
+CityDoctorValidation.inputFileNotExisting=Eingabedatei '{}' existiert nicht.
+CityDoctorValidation.loadingDefaultConfig=Keine Konfigurationsdatei angegeben, Standardkonfiguration wird geladen.
+CityDoctorValidation.noConfig=Keine Konfigurationsdatei angegeben. (-config [DATEIPFAD])
+CityDoctorValidation.noInputFile=Keine Eingabedatei angegeben. (-in [DATEIPFAD])
+CityDoctorValidation.noOutputFile=Keinen Ausgabedateipfad angegeben. (-out [DATEIPFAD])
+CityDoctorValidation.notExactlyOneConfigFile=Es muss exakt eine Konfigurationsdatei angegeben werden.
+CityDoctorValidation.notExactlyOneInputFile=Es muss exakt eine Eingabedatei angegeben werden.
+CityDoctorValidation.notExactlyOneOutputFile=Es muss exakt ein Ausgabedateipfad 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.wrongInputFileFormat=Eingabedatei '{}' ist keine .gml oder .xml Datei.
+CityGmlParser.chunkReadFailed=Konnte Datei nicht in St\u00fccken lesen, versuche komplett zu lesen
+CityGmlParser.convertCrsToUtmZoneN=Konvertiere Koordinatensystem zu UTM Zone {}N
+CityGmlParser.convertCrsToUtmZoneS=Konvertiere Koordinatensystem zu UTM Zone {}S
+CityGmlParser.creating4jContextFailed=Erstellen des Citygml4j Kontext fehlgeschlagen
+CityGmlParser.creatingAdePluginsFailed=Erstellen des ADE Plugins f\u00fcr citygml4j fehlgeschlagen
+CityGmlParser.errorReadingGmlFile=Fehler beim lesen der CityGML Datei\n{}
+CityGmlParser.errorWritingGmlFile=Fehler beim schreiben der CityGML Datei\n{}
+CityGmlParser.failedEPSGParse=Lesen des EPSG-Codes fehlgeschlagen, greife auf metrisches System zur\u00fcck
+CityGmlParser.missingCityModel=Datei enth\u00e4lt kein CityModel! Tempor\u00e4res CityModel wird erstellt.
+CityGmlParser.missingEPSGCode=Kein EPSG-Code wurde gefunden! Gehe von metrischem System aus
+CityGmlParser.noConversionNeeded=Koordinatensystem in Metern, keine Konvertierung notwendig
+CityGmlParser.notValidGmlFile=Dies ist keine korrekte CityGML Datei
+CityGmlParser.parsedObjects=Modell mit {} Objekten gelesen
+CityGmlWriterUtils.unknownADEError= Fehler {} kann nicht zu einem ADE-Fehler konvertiert werden. Fehler wird nicht ausgegeben
+CityGmlZipArchive.generalException=Unerwarteter Fehler beim Einlesen des ZIP-Archivs
+CityGmlZipArchive.ioError=Zugriff auf ZIP-Datei fehlgeschlagen
+CityGmlZipArchive.malformedZipFile=Einlesen des ZIP-Archivs abgebrochen, ZIP-Datei ist fehlerhaft!
+DatabaseHandler.batchCommitFailure=Batch-commit abgebrochen: Auftreten eines kritischen Fehlers beim Versuch CityObject {} in die Datenbank zu schreiben!
+DatabaseHandler.connectionFailure=Verbindung zur eingebetteten Datenbank konnte nicht hergestellt werden!
+DatabaseHandler.fetchErrorIdsFailure=Abfragen der Liste von CityObjects mit Fehlern ist fehlgeschlagen!
+DatabaseHandler.getAllCityObjectsFailure=Abfragen der Liste aller CityObjects ist fehlgeschlagen!
+DatabaseHandler.getBBoxIntersectFailure=Verbindung zur Datenbank konnte nicht hergestellt werden, abfragen der BoundingBox-\u00dcberschneidungen von CityObject {} fehlgeschlagen!
+DatabaseHandler.getBufferIntersectFailure=Verbindung zur Datenbank konnte nicht hergestellt werden, abfragen der Buffer-\u00dcberschneidungen von CityObject {} fehlgeschlagen!
+DatabaseHandler.getFeatureCountFailure=Verbindung zur Datenbank konnte nicht hergestellt werden, abfragen der Anzahl an CityObjects fehlgeschlagen!
+DatabaseHandler.marshallingFailure=Schreiben des CityObject {} in die Datenbank fehlgeschlagen!
+DatabaseHandler.serializationFailure=Serialisierung des CityObject {} fehlgeschlagen!
+DatabaseHandler.setupFailure=KRITISCHER FEHLER: Erstellen der eingebetteten Datenbank fehlgeschlagen!
+DatabaseHandler.tableFailure=KRITISCHER FEHLER: Erstellen der "features" Tabelle fehlgeschlagen!
+DatabaseHandler.unmarshallingFailure=Laden des CityObject {} aus der Datenbank fehlgeschlagen!
+DistanceError.distanceFromPlane=Abstand von der Ebene
+ErrorItemVisitor.childId=Kind ID
+ErrorItemVisitor.component=Komponente
+ErrorItemVisitor.degeneratedRing=Degenerierter Ring
+ErrorItemVisitor.deviation=Abweichung
+ErrorItemVisitor.distance=Distanz
+ErrorItemVisitor.intersection=Verschneidung
+ErrorItemVisitor.nameOfAttribute=Name des Attributs
+ErrorItemVisitor.pointTouchesEdge=Punkt ber\u00fchrt Kante
+ErrorItemVisitor.triangles=Dreiecke
ExceptionDialog.stacktrace=Der Stacktrace des Fehlers war:
-FilterPane.buildings=Geb\u00e4ude
+FeatureMapper.polygonUnreferenced=Polygon {} wurde referenziert, konnte aber nicht gefunden werden!
FilterPane.bridges=Br\u00fccken
+FilterPane.buildings=Geb\u00e4ude
FilterPane.landUse=Landnutzung
FilterPane.transportation=Transport
FilterPane.vegetation=Vegetation
FilterPane.water=Wasser
-MainToolBar.wireframe=Zeige/Verstecke Gitternetz
-MainToolBar.culling=Aktiviere/Deaktiviere Entfernen der R\u00fcckseiten
-MainToolBar.writeReports=Schreibe Reports
+GeometryMapper.emptyPolygon=Polygon ohne externen Ring gefunden. Polygon wird ignoriert
+LibraryObject.fileMissing=Die ImplicitGeometry eines Features verweist auf eine nicht vorhandene LibraryObject-Datei {}
+LibraryObject.parsingError=LibraryObject-Datei {} konnte aufgrund eines Fehlers nicht ausgelesen werden
+MainToolBar.culling=Aktiviere/Deaktiviere Entfernen der Polygon-R\u00fcckseiten
MainToolBar.executeChecks=F\u00fchre Pr\u00fcfungen aus
-MainToolBar.showWorld=Gesamtes Stadtmodell anzeigen
-MainToolBar.resetCamera=Ansicht zur\u00fccksetzen
-MainToolBar.hideRoof=Zeige/Verstecke Dach BoundarySurfaces
+MainToolBar.hideRoof=Zeige/Verstecke Dach-BoundarySurfaces
+MainToolBar.resetCamera=Kamera-Ansicht zur\u00fccksetzen
+MainToolBar.showWorld=Zeige gesamtes Stadtmodell an
+MainToolBar.wireframe=Aktiviere/Deaktiviere Gitternetz-Modus
+MainToolBar.writeReports=Schreibe Berichte
MainToolBar.zip=Zip-eintrag Auswahlfenster \u00f6ffnen
-MainWindow.missingConfig=Konnte Konfigurationsdatei nicht finden.
-MainWindow.loadGivenFile=Lade vorhandene Datei, bitte warten
-MainWindow.finishedLoading=Fertig geladen
-MainWindow.checking=Pr\u00fcfe, bitte warten
-MainWindow.writeXml=Schreibe Xml Report
-MainWindow.finishedXml=Xml Report abgeschlossen
-MainWindow.writePdf=Schreibe Pdf Report
-MainWindow.finishedPdf=Pdf Report abgeschlossen
-MainWindow.loadFailed=Konnte GML-Datei nicht laden: {}
MainWindow.all=Alle
-MainWindow.withErrors=Mit Fehlern
-MainWindow.export=Feature Exportieren
+MainWindow.attributeTab=Attribute
+MainWindow.availableLabel=Verf\u00fcgbar:
+MainWindow.bridgeTab=Br\u00fccken
+MainWindow.buildingsTab=Geb\u00e4ude
+MainWindow.checking=Pr\u00fcfe, bitte warten
+MainWindow.cityfurnitureTab=Stadtm\u00f6bel
+MainWindow.clearBtn=Leeren
MainWindow.copyId=GML-ID kopieren
MainWindow.delete=Feature L\u00f6schen
-MainWindow.infoTopLevelExport=Export ist nur f\u00fcr Featureobjekt basis m\u00f6glich!
+MainWindow.edgesTab=Kanten
+MainWindow.errorsTab=Fehler
+MainWindow.export=Feature Exportieren
+MainWindow.finishedLoading=Fertig geladen
+MainWindow.finishedPdf=Pdf-Bericht abgeschlossen
+MainWindow.finishedXml=Xml-Bericht abgeschlossen
+MainWindow.focusCityObject=Objekt fokussieren
+MainWindow.globalErrorsTab=Globale Fehler
MainWindow.infoTopLevelCopyID=GML-ID kann nur von Featureobjekt basis kopiert werden!
-mainWindow.warnCopyIdFailed=Kopieren der ID fehlgeschlagen!
-OpenFileDialog.select=W\u00e4hle CityGML Datei aus
+MainWindow.infoTopLevelExport=Export ist nur f\u00fcr Featureobjekt basis m\u00f6glich!
MainWindow.languageChange=Um die Spracheinstellung zu \u00fcbernehmen muss CityDoctor2 neugestartet werden.
-MainWindow.buildingsTab=Geb\u00e4ude
-MainWindow.vegetationTab=Vegetation
-MainWindow.transportationTab=Verkehrsobjekte
-MainWindow.tunnelTab=Tunnel
-MainWindow.bridgeTab=Br\u00fccken
-MainWindow.waterTab=Gew\u00e4sser
-MainWindow.terrainTab=Gel\u00e4nde
-MainWindow.cityfurnitureTab=Stadtm\u00f6bel
+MainWindow.loadFailed=Konnte GML-Datei nicht laden: {}
+MainWindow.loadGivenFile=Lade vorhandene Datei, bitte warten
+MainWindow.logTab=Log
+MainWindow.memoryLabel=Speicher:
+MainWindow.missingConfig=Konnte Konfigurationsdatei nicht finden.
MainWindow.otherObjectsTab=Andere
-MainWindow.viewLabel=Ansicht
-MainWindow.showLabel=Zeige:
-MainWindow.searchLabel=Suche:
-MainWindow.searchBtn=Suche
-MainWindow.clearBtn=Leeren
-MainWindow.errorsTab=Fehler
MainWindow.polygonsTab=Polygone
-MainWindow.edgesTab=Kanten
+MainWindow.searchBtn=Suche
+MainWindow.searchLabel=Suche:
+MainWindow.showLabel=Zeige:
+MainWindow.terrainTab=Gel\u00e4nde
+MainWindow.transportationTab=Verkehrsobjekte
+MainWindow.tunnelTab=Tunnel
+MainWindow.vegetationTab=Vegetation
MainWindow.verticesTab=Punkte
-MainWindow.attributeTab=Attribute
-MainWindow.logTab=Log
-MainWindow.globalErrorsTab=Globale Fehler
-MainWindow.focusCityObject=Objekt fokussieren
+MainWindow.viewLabel=Ansicht
+MainWindow.warnCopyIdFailed=Kopieren der ID fehlgeschlagen!
+MainWindow.waterTab=Gew\u00e4sser
+MainWindow.withErrors=Mit Fehlern
+MainWindow.writePdf=Schreibe Pdf-Bericht
+MainWindow.writeXml=Schreibe Xml-Bericht
+OpenFileDialog.cancelBtn=Abbrechen
OpenFileDialog.fileLabel=Datei:
-OpenFileDialog.selectBtn=Ausw\u00e4hlen
OpenFileDialog.loadBtn=Laden
+OpenFileDialog.loadFailed=Konnte CityGML Datei nicht laden
+OpenFileDialog.lowMemoryLabel=Reduzierter Speicherverbrauchsmodus
+OpenFileDialog.roundingPlacesLabel=Anzahl der Rundungsstellen
+OpenFileDialog.select=W\u00e4hle CityGML Datei aus
+OpenFileDialog.selectBtn=Ausw\u00e4hlen
OpenFileDialog.settingsPane=Parser Einstellungen
-OpenFileDialog.roundingPlacesLabel=NumberOfRoundingPlaces
OpenFileDialog.xmlValidationLabel=F\u00fchre XML-Validierung aus
-Checker.failXml=Konnte XML Fehlerbericht nicht schreiben.
-Checker.failPdf=Konnte PDF Fehlerbericht nicht schreiben.
-Checker.checksFinished=Pr\u00fcfungen beendet
-Checker.schematronValidation=Starte Schematron Pr\u00fcfung
-Checker.finishedSchematron=Schematron Pr\u00fcfung abgeschlossen
-Checker.failReports=Konnte Pr\u00fcfberichte nicht schreiben.
-Checker.checkFeature=Pr\u00fcfe Feature: {}
-Checker.executeCheck=F\u00fchre Pr\u00fcfung aus: {}
-ValidationConfiguration.reenable={} ist deaktiviert wird aber von {} ben\u00f6tigt, reaktiviere
+TimeFormatter.hours={0} Stunden
+TimeFormatter.lessThanASecond=< 1 Sekunde
+TimeFormatter.minutes={0} Minuten
+TimeFormatter.oneHour=1 Stunde
+TimeFormatter.oneMinute=1 Minute
+TimeFormatter.oneSecond=1 Sekunde
+TimeFormatter.seconds={0} Sekunden
+Unit.Degree=Grad
+Unit.Radian=Radiant
ValidationConfiguration.missingSchematron={} existiert nicht, deaktiviere Schematron Pr\u00fcfung
-CheckContainer.error=Unerwarteter Fehler bei der Ausf\u00fchrung von Pr\u00fcfung: {}
-Checks.missingCheck=Konnte keine Pr\u00fcfung f\u00fcr id {} finden
-OpenFileDialog.cancelBtn=Abbrechen
-CheckDialog.checksTab=Pr\u00fcfungen
-CheckDialog.filterTab=Filter
-CheckDialog.globalParametersLabel=Globale Parameter
-CheckDialog.availableChecksLabel=Verf\u00fcgbare Pr\u00fcfungen
-CheckDialog.geometricChecksLabel=Geometrische Pr\u00fcfungen
-CheckDialog.semanticChecksLabel=Semantische Pr\u00fcfungen
-CheckDialog.schematronFileLabel=Schematron Datei
-CheckDialog.selectBtn=Ausw\u00e4hlen
-CheckDialog.checkBtn=Pr\u00fcfen
-CheckDialog.cancelBtn=Abbrechen
-CheckDialog.streamCheckOption=Niedrigen Arbeitsspeicherverbrauchsmodus aktivieren
-CheckDialog.streamCheckLabel=Stadtmodelle werden nicht in den Arbeitsspeicher geladen. Ergebnisse werden in der QualityADE in Kopien der Eingangsdateien gespeichert.
-CheckDialog.outputPathLabel=Ausgabeordner (Pflichtfeld):
-CheckDialog.outputPathBtn=Ausw\u00e4hlen
-CheckDialog.pdfReportsOption=PDF Berichte erstellen
-CheckDialog.xmlReportsOption=XML Berichte erstellen
-CheckDialog.noPathError=Ausgabepfad wurde nicht gesetzt!
-ZipEntryManager.title=Zipeintrag Manager
-ZipEntryManager.entryListTitle=Zipeintr\u00e4ge
-ZipEntryManager.metadata=Metadaten
-ZipEntryManager.subpathLbl=Unterpfad:
-ZipEntryManager.erroneousLbl=Fehlerhaft:
-ZipEntryManager.excessiveFileSize=Datei zu gro\u00DF
-ZipEntryManager.invalidCityGml=Ung\u00fcltige CityGML Datei
-ZipEntryManager.ioError=Dateizugriff fehlgeschlagen
-ZipEntryManager.filesizeLbl=Dateigr\u00f6\u00DFe:
-ZipEntryManager.validatedLbl=Validiert:
-ZipEntryManager.objectCountLbl=Objektanzahl:
-ZipEntryManager.loadBtn=CityGML Modell laden
-ZipEntryManager.decompressBtn=Datei entpacken
-ZipEntryManager.decompressAllBtn=Alle Dateien entpacken
-ZipEntryManager.checkAllBtn=Alle Dateien pr\u00fcfen
-ZipEntryManager.showReportBtn=Fehlerstatistik anzeigen
-ZipEntryManager.saveBtn=Validierungsergebnisse exportieren
-ZipEntryManager.cancelBtn=Abbruch
-ZipEntryManager.unknownValue=Unbekannt
-ZipEntryManager.yes=Ja
-ZipEntryManager.no=Nein
-CityGmlZipArchive.ioError=Zugriff auf ZIP-Datei fehlgeschlagen
-CityGmlZipArchive.malformedZipFile=Einlesen des ZIP-Archivs abgebrochen, ZIP-Datei ist fehlerhaft!
-CityGmlZipArchive.generalException=Unerwarteter Fehler beim Einlesen des ZIP-Archivs
-WriteReportDialog.writeBtn=Speichern
+ValidationConfiguration.reenable={} ist deaktiviert wird aber von {} ben\u00f6tigt, reaktiviere
WriteReportDialog.cancelBtn=Abbrechen
WriteReportDialog.errorStatisticsLabel=Fehler Statistik
WriteReportDialog.saveImageBtn=Bild Speichern
WriteReportDialog.selectPdfBtn=Ausw\u00e4hlen
WriteReportDialog.selectXmlFile=Ausw\u00e4hlen
+WriteReportDialog.writeBtn=Speichern
WriteReportDialog.xAxisLabel=Fehler
-WriteReportDialog.yAxisLabel=Anzahl
-Unit.Radian=Radiant
-Unit.Degree=Grad
-FeatureMapper.polygonUnreferenced=Polygon {} ist referenziert, konnte aber nicht gefunden werden
-GeometryMapper.emptyPolygon=Polygon ohne externen Ring gefunden, ignoriere
-CityGmlParser.parsedObjects=Modell mit {} Objekten gelesen
-CityGmlParser.chunkReadFailed=Konnte Datei nicht in St\u00fccken lesen, versuche komplett zu lesen
-CityGmlParser.notValidGmlFile=Dies ist keine korrekte CityGML Datei\n
-CityGmlParser.errorReadingGmlFile=Fehler beim lesen der CityGML Datei\n{}
-CityGmlParser.errorWritingGmlFile=Fehler beim schreiben der CityGML Datei\n{}
-CityGmlParser.noConversionNeeded=Koordinatensystem in Metern, keine Konvertierung notwendig
-CityGmlParser.failedEPSGParse=Lesen des EPSG Codes fehlgeschlagen, greife auf metrisches System zur\u00fcck
-CityGmlParser.missingEPSGCode=Kein EPSG Code gefunden, nehme metrisches System an
-OpenFileDialog.loadFailed=Konnte CityGML Datei nicht laden
-MainWindow.memoryLabel=Speicher:
-CheckDialog.checksReenabledAlert=Manche Pr\u00fcfungen wurden reaktiviert damit andere gewollte Pr\u00fcfungen durchgef\u00fchrt werden k\u00f6nnen\nMehr Details sind im Log geschrieben
-MainWindow.availableLabel=Verf\u00fcgbar:
-OpenFileDialog.lowMemoryLabel=Reduzierter Speicherverbrauchsmodus
-ErrorItemVisitor.intersection=Verschneidung
-ErrorItemVisitor.component=Komponente
-ErrorItemVisitor.nameOfAttribute=Name des Attributs
-ErrorItemVisitor.childId=Kind ID
-ErrorItemVisitor.distance=Distanz
-ErrorItemVisitor.pointTouchesEdge=Punkt ber\u00fchrt Kante
-ErrorItemVisitor.degeneratedRing=Degenerierter Ring
-ErrorItemVisitor.deviation=Abweichung
-ErrorItemVisitor.triangles=Dreiecke
\ No newline at end of file
+WriteReportDialog.yAxisLabel=Anzahl
\ No newline at end of file
diff --git a/CityDoctorParent/CityDoctorModel/src/main/resources/log4j2.xml b/CityDoctorParent/CityDoctorModel/src/main/resources/log4j2.xml
index 4e951d6be8c184c776c0a02290cc32671d09c3de..d398aaaa8f5b4f31148c1c39d67d47b85690b9d9 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/resources/log4j2.xml
+++ b/CityDoctorParent/CityDoctorModel/src/main/resources/log4j2.xml
@@ -14,5 +14,8 @@
+
+
+
\ No newline at end of file
diff --git a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/database/EmbeddedDataBaseHandlerTest.java b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/database/EmbeddedDataBaseHandlerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..06c0bb6e713a27cd1593503520cc2005905d776b
--- /dev/null
+++ b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/database/EmbeddedDataBaseHandlerTest.java
@@ -0,0 +1,244 @@
+package de.hft.stuttgart.citydoctor2.database;
+
+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.ConcretePolygon;
+import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
+import de.hft.stuttgart.citydoctor2.datastructure.GeometryTestUtils;
+import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
+import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
+import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
+import de.hft.stuttgart.citydoctor2.datastructure.Lod;
+import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
+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;
+import org.citygml4j.core.model.building.AbstractBuilding;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.List;
+
+import static de.hft.stuttgart.citydoctor2.database.SerializationTest.assertCityObjectEquality;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+public class EmbeddedDataBaseHandlerTest {
+
+ private EmbeddedDatabaseHandler handler;
+
+ @Before
+ public void resetDatabase() {
+ try {
+ handler = new EmbeddedDatabaseHandler();
+ handler.setupFeaturesTable();
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+
+ @Test
+ public void testGetBboxIntersectingObjects() {
+ Building b = new Building();
+ Building b2 = new Building();
+ b2.setGmlObject(Mockito.mock(AbstractBuilding.class));
+ Building b3 = new Building();
+ Building b4 = new Building();
+ b4.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.SOLID, Lod.LOD0));
+
+ Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD0, Geometry.Orientation.OUTWARD);
+ ConcretePolygon polygon = new ConcretePolygon();
+ geom.getPolygons().add(polygon);
+ polygon.setParent(geom);
+ LinearRing lr = new LinearRing(LinearRing.LinearRingType.EXTERIOR);
+ polygon.setExteriorRing(lr);
+ Vertex v1 = new Vertex(10, 10, 8);
+ lr.getVertices().add(v1);
+ Vertex v2 = new Vertex(14, 15, 7);
+ lr.getVertices().add(v2);
+ Vertex v3 = new Vertex(14, 15, 3);
+ lr.getVertices().add(v3);
+ Vertex v4 = new Vertex(10, 10, 3);
+ lr.getVertices().add(v4);
+ lr.getVertices().add(v1);
+ geom.updateEdgesAndVertices();
+ b.addGeometry(geom);
+
+
+ Geometry geom2 = new Geometry(GeometryType.SOLID, Lod.LOD0, Geometry.Orientation.OUTWARD);
+ ConcretePolygon polygon2 = new ConcretePolygon();
+ geom2.getPolygons().add(polygon2);
+ polygon2.setParent(geom2);
+ LinearRing lr2 = new LinearRing(LinearRing.LinearRingType.EXTERIOR);
+ polygon2.setExteriorRing(lr2);
+ Vertex v1b2 = new Vertex(6, 6, 8);
+ lr2.getVertices().add(v1b2);
+ Vertex v2b2 = new Vertex(11, 13, 7);
+ lr2.getVertices().add(v2b2);
+ Vertex v3b2 = new Vertex(11, 13, 3);
+ lr2.getVertices().add(v3b2);
+ Vertex v4b2 = new Vertex(6, 6, 3);
+ lr2.getVertices().add(v4b2);
+ lr2.getVertices().add(v1b2);
+ geom2.updateEdgesAndVertices();
+ b2.addGeometry(geom2);
+
+ Geometry geom3 = new Geometry(GeometryType.SOLID, Lod.LOD0, Geometry.Orientation.OUTWARD);
+ ConcretePolygon polygon3 = new ConcretePolygon();
+ geom3.getPolygons().add(polygon3);
+ polygon3.setParent(geom3);
+ LinearRing lr3 = new LinearRing(LinearRing.LinearRingType.EXTERIOR);
+ polygon3.setExteriorRing(lr3);
+ Vertex v1b3 = new Vertex(6, 6, 8);
+ lr3.getVertices().add(v1b3);
+ Vertex v2b3 = new Vertex(10, 9.999, 7);
+ lr3.getVertices().add(v2b3);
+ Vertex v3b3 = new Vertex(10, 9.999, 3);
+ lr3.getVertices().add(v3b3);
+ Vertex v4b3 = new Vertex(6, 6, 3);
+ lr3.getVertices().add(v4b3);
+ lr3.getVertices().add(v1b3);
+ geom3.updateEdgesAndVertices();
+ b3.addGeometry(geom3);
+
+ handler.marshallCityObject(b);
+ handler.marshallCityObject(b2);
+ handler.marshallCityObject(b3);
+ handler.marshallCityObject(b4);
+ assertEquals(4, handler.getFeatureCount());
+
+ List objects = handler.getGeometryCollisionCandidates(b);
+ assertEquals(1, objects.size());
+ assertEquals(4, handler.getFeatureCount());
+
+ CityObject co = handler.unmarshallCityObject(objects.get(0));
+ assertNotNull(co);
+ assertCityObjectEquality(b2, co);
+
+ }
+
+ @Test
+ public void testGetBboxBufferIntersectingObjects() {
+ Building b = new Building();
+ Building b2 = new Building();
+ b2.setGmlObject(Mockito.mock(AbstractBuilding.class));
+ Building b3 = new Building();
+ Building b4 = new Building();
+ b4.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.SOLID, Lod.LOD0));
+
+
+ Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD0, Geometry.Orientation.OUTWARD);
+ ConcretePolygon polygon = new ConcretePolygon();
+ geom.getPolygons().add(polygon);
+ polygon.setParent(geom);
+ LinearRing lr = new LinearRing(LinearRing.LinearRingType.EXTERIOR);
+ polygon.setExteriorRing(lr);
+ Vertex v1 = new Vertex(10, 10, 8);
+ lr.getVertices().add(v1);
+ Vertex v2 = new Vertex(14, 15, 7);
+ lr.getVertices().add(v2);
+ Vertex v3 = new Vertex(14, 15, 3);
+ lr.getVertices().add(v3);
+ Vertex v4 = new Vertex(10, 10, 3);
+ lr.getVertices().add(v4);
+ lr.getVertices().add(v1);
+ geom.updateEdgesAndVertices();
+ b.addGeometry(geom);
+
+
+ Geometry geom2 = new Geometry(GeometryType.SOLID, Lod.LOD0, Geometry.Orientation.OUTWARD);
+ ConcretePolygon polygon2 = new ConcretePolygon();
+ geom2.getPolygons().add(polygon2);
+ polygon2.setParent(geom2);
+ LinearRing lr2 = new LinearRing(LinearRing.LinearRingType.EXTERIOR);
+ polygon2.setExteriorRing(lr2);
+ Vertex v1b2 = new Vertex(6, 6, 8);
+ lr2.getVertices().add(v1b2);
+ Vertex v2b2 = new Vertex(9, 9, 7);
+ lr2.getVertices().add(v2b2);
+ Vertex v3b2 = new Vertex(9, 9, 3);
+ lr2.getVertices().add(v3b2);
+ Vertex v4b2 = new Vertex(6, 6, 3);
+ lr2.getVertices().add(v4b2);
+ lr2.getVertices().add(v1b2);
+ geom2.updateEdgesAndVertices();
+ b2.addGeometry(geom2);
+
+ Geometry geom3 = new Geometry(GeometryType.SOLID, Lod.LOD0, Geometry.Orientation.OUTWARD);
+ ConcretePolygon polygon3 = new ConcretePolygon();
+ geom3.getPolygons().add(polygon3);
+ polygon3.setParent(geom3);
+ LinearRing lr3 = new LinearRing(LinearRing.LinearRingType.EXTERIOR);
+ polygon3.setExteriorRing(lr3);
+ Vertex v1b3 = new Vertex(4, 4, 8);
+ lr3.getVertices().add(v1b3);
+ Vertex v2b3 = new Vertex(8.999, 8.999, 7);
+ lr3.getVertices().add(v2b3);
+ Vertex v3b3 = new Vertex(8.999, 8.999, 3);
+ lr3.getVertices().add(v3b3);
+ Vertex v4b3 = new Vertex(4, 4, 3);
+ lr3.getVertices().add(v4b3);
+ lr3.getVertices().add(v1b3);
+ geom3.updateEdgesAndVertices();
+ b3.addGeometry(geom3);
+
+ handler.marshallCityObject(b);
+ handler.marshallCityObject(b2);
+ handler.marshallCityObject(b3);
+ handler.marshallCityObject(b4);
+ assertEquals(4, handler.getFeatureCount());
+
+ List objects = handler.getBufferCollisionCandidates(b, Math.sqrt(2));
+ assertEquals(1, objects.size());
+ assertEquals(4, handler.getFeatureCount());
+
+ CityObject co = handler.unmarshallCityObject(objects.get(0));
+ assertNotNull(co);
+ assertCityObjectEquality(b2, co);
+
+ }
+
+ @Test
+ public void testMarshallingRoundTripSimpleSolid() throws InvalidGmlFileException, CityGmlParseException {
+ ParserConfiguration config = new ParserConfiguration(8, false);
+ CityDoctorModel model = CityGmlParser.parseCityGmlFile("src/test/resources/SimpleSolid_SrefBS.gml", config);
+
+ Building b = model.getBuildings().toList().get(0);
+ assertNotNull(b);
+ handler.marshallCityObject(b);
+ assertEquals(1, handler.getFeatureCount());
+
+ CityObject b2 = handler.unmarshallCityObject(b.getGmlId());
+ assertNotNull(b2);
+ assertEquals(1, handler.getFeatureCount());
+
+ assertCityObjectEquality(b, b2);
+
+ }
+
+
+ @Test
+ public void testMarshallingRoundTripFzk() throws InvalidGmlFileException, CityGmlParseException {
+ ParserConfiguration config = new ParserConfiguration(8, false);
+ CityDoctorModel model = CityGmlParser.parseCityGmlFile("src/test/resources/FZK_haus.gml", config);
+
+ Building b = model.getBuildings().toList().get(0);
+ assertNotNull(b);
+ assertEquals(1, handler.getFeatureCount());
+ handler.marshallCityObject(b);
+ assertEquals(1, handler.getFeatureCount());
+
+ CityObject b2 = handler.unmarshallCityObject(b.getGmlId());
+ assertNotNull(b2);
+ assertEquals(1, handler.getFeatureCount());
+
+ assertCityObjectEquality(b, b2);
+
+ }
+
+}
diff --git a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/database/FeatureCacheTest.java b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/database/FeatureCacheTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b17640f6d451cfda19f802703dba394ce570e27c
--- /dev/null
+++ b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/database/FeatureCacheTest.java
@@ -0,0 +1,99 @@
+package de.hft.stuttgart.citydoctor2.database;
+
+import de.hft.stuttgart.citydoctor2.datastructure.*;
+import org.citygml4j.core.model.building.AbstractBuilding;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.mockito.Mockito.mock;
+
+public class FeatureCacheTest {
+
+
+
+ @Test
+ public void testPut(){
+ FeatureCache cache = new FeatureCache();
+
+ Building b = new Building();
+ b.setGmlObject(mock(AbstractBuilding.class));
+ b.setGmlId(new GmlId("test"));
+ b.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.SOLID, Lod.LOD0));
+
+ assertEquals(0, cache.getTotalFeatureCount());
+ cache.put(b);
+ cache.synchronize();
+
+ assertEquals(1, cache.getTotalFeatureCount());
+ }
+
+ @Test
+ public void testGet(){
+ FeatureCache cache = new FeatureCache();
+
+ assertNull(cache.get(new GmlId("test")));
+ Building b = new Building();
+
+ b.setGmlObject(mock(AbstractBuilding.class));
+ b.setGmlId(new GmlId("test"));
+ b.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.SOLID, Lod.LOD0));
+ assertEquals(0, cache.getTotalFeatureCount());
+ cache.put(b);
+ cache.synchronize();
+
+ CityObject b2 = cache.get(new GmlId("test"));
+ assertEquals(b.getGmlId(), b2.getGmlId());
+ }
+
+ @Test
+ public void testStateHandlingFromIdle(){
+ FeatureCache cache = new FeatureCache();
+ assertEquals(FeatureCache.CacheState.IDLE, cache.getState());
+
+ AutoCloseable parsingContext = cache.startParsingMode();
+ try(parsingContext){
+ assertEquals(FeatureCache.CacheState.PARSING, cache.getState());
+ } catch (Exception e){
+ throw new RuntimeException(e);
+ }
+ assertEquals(FeatureCache.CacheState.IDLE, cache.getState());
+
+ AutoCloseable checkingContext = cache.startCheckingMode();
+ try(checkingContext){
+ assertEquals(FeatureCache.CacheState.CHECKING, cache.getState());
+ } catch (Exception e){
+ throw new RuntimeException(e);
+ }
+ assertEquals(FeatureCache.CacheState.IDLE, cache.getState());
+ }
+
+ @Test
+ public void testCheckingModeStateCollision(){
+ FeatureCache cache = new FeatureCache();
+ assertEquals(FeatureCache.CacheState.IDLE, cache.getState());
+ AutoCloseable checkingContext = cache.startCheckingMode();
+ try(checkingContext){
+ assertEquals(FeatureCache.CacheState.CHECKING, cache.getState());
+ assertThrows(IllegalStateException.class, cache::startParsingMode);
+ } catch (Exception e){
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Test
+ public void testParsingModeStateCollision(){
+ FeatureCache cache = new FeatureCache();
+ assertEquals(FeatureCache.CacheState.IDLE, cache.getState());
+ AutoCloseable parsingContext = cache.startParsingMode();
+ try(parsingContext){
+ assertEquals(FeatureCache.CacheState.PARSING, cache.getState());
+ assertThrows(IllegalStateException.class, cache::startCheckingMode);
+ } catch (Exception e){
+ throw new RuntimeException(e);
+ }
+ }
+
+
+}
diff --git a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/database/SerializationTest.java b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/database/SerializationTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..d664d6603d6ebd22f8290c440253a4589fb820ae
--- /dev/null
+++ b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/database/SerializationTest.java
@@ -0,0 +1,59 @@
+package de.hft.stuttgart.citydoctor2.database;
+
+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.parser.CityGmlParseException;
+import de.hft.stuttgart.citydoctor2.parser.CityGmlParser;
+import de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException;
+import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
+import de.hft.stuttgart.citydoctor2.utils.visitors.CityObjectCollector;
+import org.apache.commons.lang3.SerializationUtils;
+import org.junit.Test;
+
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class SerializationTest {
+
+ static void assertCityObjectEquality(CityObject c1, CityObject c2) {
+ assertEquals(c1.getGmlId(), c2.getGmlId());
+ assertEquals(c1.getFeatureType(), c2.getFeatureType());
+ assertEquals(c1.getGmlObject().getId(), c2.getGmlObject().getId());
+
+ CityObjectCollector collector = new CityObjectCollector();
+ c1.accept(collector);
+ Set coB = collector.getCityObjects();
+ collector = new CityObjectCollector();
+ c2.accept(collector);
+ Set coB2 = collector.getCityObjects();
+ assertEquals(coB.size(), coB2.size());
+ }
+
+ @Test
+ public void testRoundtripSimpleSolid() throws CityGmlParseException, InvalidGmlFileException {
+ ParserConfiguration config = new ParserConfiguration(8, false);
+ CityDoctorModel model = CityGmlParser.parseCityGmlFile("src/test/resources/SimpleSolid_SrefBS.gml", config);
+ Building b = model.getBuildings().toList().get(0);
+ assertNotNull(b);
+ Building b2 = SerializationUtils.roundtrip(b);
+ assertNotNull(b2);
+
+ assertCityObjectEquality(b, b2);
+ }
+
+
+ @Test
+ public void testRoundtripFzk() throws CityGmlParseException, InvalidGmlFileException {
+ ParserConfiguration config = new ParserConfiguration(8, false);
+ CityDoctorModel model = CityGmlParser.parseCityGmlFile("src/test/resources/FZK_haus.gml", config);
+ Building b = model.getBuildings().toList().get(0);
+ assertNotNull(b);
+ Building b2 = SerializationUtils.roundtrip(b);
+
+ assertCityObjectEquality(b, b2);
+ }
+
+}
diff --git a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/BoundarySurfaceTest.java b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/BoundarySurfaceTest.java
index 1275cc857af29974dfcd4e6a959f63b7c3297f82..c08b1ad7cede13dbb1522e5bcab5081630b9564d 100644
--- a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/BoundarySurfaceTest.java
+++ b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/BoundarySurfaceTest.java
@@ -51,11 +51,9 @@ import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
public class BoundarySurfaceTest {
- //Todo: Check this class for rework potential with the new Visitors
-
@Test
public void testVisitorPropagation() {
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, null);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, null);
Opening oMock = Mockito.mock(Opening.class);
bs.addOpening(oMock);
@@ -68,7 +66,7 @@ public class BoundarySurfaceTest {
@Test
public void testAccept() {
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, null);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, null);
Opening oMock = Mockito.mock(Opening.class);
bs.addOpening(oMock);
AtomicInteger bsCounter = new AtomicInteger(0);
@@ -86,7 +84,7 @@ public class BoundarySurfaceTest {
@Test
public void testAcceptWithoutFittingCheck() {
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, null);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, null);
Opening oMock = Mockito.mock(Opening.class);
bs.addOpening(oMock);
AtomicInteger bsCounter = new AtomicInteger(0);
@@ -104,7 +102,7 @@ public class BoundarySurfaceTest {
@Test
public void testPrepareForChecking() {
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, null);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, null);
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, Lod.LOD2, Orientation.OUTWARD);
Geometry spyGeom = Mockito.spy(geom);
bs.addGeometry(spyGeom);
@@ -114,7 +112,7 @@ public class BoundarySurfaceTest {
@Test
public void testContainsError() {
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, null);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, null);
assertFalse(bs.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
bs.addCheckResult(
new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, Mockito.mock(CheckError.class)));
@@ -124,9 +122,9 @@ public class BoundarySurfaceTest {
@Test
public void testContainsErrorInOpening() {
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, null);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, null);
assertFalse(bs.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
- Opening o = new Opening(OpeningType.WINDOW, SurfaceFeatureType.BUILDING, bs, null);
+ Opening o = new Opening(OpeningType.WINDOW, bs, null);
bs.addOpening(o);
o.addCheckResult(
new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, Mockito.mock(CheckError.class)));
@@ -136,7 +134,7 @@ public class BoundarySurfaceTest {
@Test
public void testClearAllContainedCheckResults() {
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, null);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, null);
Opening oMock = Mockito.mock(Opening.class);
bs.addCheckResult(
new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, Mockito.mock(CheckError.class)));
@@ -149,7 +147,7 @@ public class BoundarySurfaceTest {
@Test
public void testContainsAnyError() {
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, null);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, null);
assertFalse(bs.containsAnyError());
bs.addCheckResult(
new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, Mockito.mock(CheckError.class)));
@@ -159,19 +157,18 @@ public class BoundarySurfaceTest {
@Test
public void testCollectContainedErrors() {
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, null);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, null);
bs.addCheckResult(
new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, Mockito.mock(CheckError.class)));
List errors = new ArrayList<>();
bs.collectContainedErrors(errors);
assertEquals(1, errors.size());
- ;
}
@Test
public void testReCreateGeometriesWithoutId() {
WallSurface ws = new WallSurface();
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, ws);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, ws);
bs.reCreateGeometries(GeometryFactory.newInstance(), new ParserConfiguration(8, false));
assertNotNull(ws.getId());
}
@@ -180,7 +177,7 @@ public class BoundarySurfaceTest {
public void testReCreateGeometriesWithId() {
WallSurface ws = new WallSurface();
ws.setId("test");
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, ws);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, ws);
bs.reCreateGeometries(GeometryFactory.newInstance(), new ParserConfiguration(8, false));
// nothing has changed
assertEquals("test", ws.getId());
@@ -190,89 +187,52 @@ public class BoundarySurfaceTest {
}
@Test
- public void testReCreateGeometriesMultiSurfaceLod2() {
- WallSurface ws = new WallSurface();
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, ws);
- bs.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE));
- bs.reCreateGeometries(GeometryFactory.newInstance(), new ParserConfiguration(8, false));
- assertNotNull(ws.getLod2MultiSurface());
- assertNull(ws.getLod3MultiSurface());
- assertNull(ws.getDeprecatedProperties().getLod4MultiSurface());
- }
-
- @Test
- public void testReCreateGeometriesMultiSurfaceBridgeLod2() {
- WallSurface ws = new WallSurface();
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BRIDGE, BoundarySurfaceType.WALL, ws);
- bs.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE));
- bs.reCreateGeometries(GeometryFactory.newInstance(), new ParserConfiguration(8, false));
- assertNotNull(ws.getLod2MultiSurface());
- assertNull(ws.getLod3MultiSurface());
- assertNull(ws.getDeprecatedProperties().getLod4MultiSurface());
- }
-
- @Test
- public void testReCreateGeometriesMultiSurfaceBridgeLod3() {
+ public void testReCreateGeometriesMultiSurfaceLod0() {
WallSurface ws = new WallSurface();
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BRIDGE, BoundarySurfaceType.WALL, ws);
- bs.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3));
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, ws);
+ bs.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD0));
bs.reCreateGeometries(GeometryFactory.newInstance(), new ParserConfiguration(8, false));
+ assertNotNull(ws.getLod0MultiSurface());
+ assertNull(ws.getLod1MultiSurface());
assertNull(ws.getLod2MultiSurface());
- assertNotNull(ws.getLod3MultiSurface());
+ assertNull(ws.getLod3MultiSurface());
assertNull(ws.getDeprecatedProperties().getLod4MultiSurface());
}
@Test
- public void testReCreateGeometriesMultiSurfaceBridgeLod4() {
+ public void testReCreateGeometriesMultiSurfaceLod1() {
WallSurface ws = new WallSurface();
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BRIDGE, BoundarySurfaceType.WALL, ws);
- bs.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD4));
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, ws);
+ bs.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD1));
bs.reCreateGeometries(GeometryFactory.newInstance(), new ParserConfiguration(8, false));
+ assertNull(ws.getLod0MultiSurface());
+ assertNotNull(ws.getLod1MultiSurface());
assertNull(ws.getLod2MultiSurface());
assertNull(ws.getLod3MultiSurface());
- assertNotNull(ws.getDeprecatedProperties().getLod4MultiSurface());
+ assertNull(ws.getDeprecatedProperties().getLod4MultiSurface());
}
@Test
- public void testReCreateGeometriesMultiSurfaceTunnelLod2() {
+ public void testReCreateGeometriesMultiSurfaceLod2() {
WallSurface ws = new WallSurface();
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.TUNNEL, BoundarySurfaceType.WALL, ws);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, ws);
bs.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE));
bs.reCreateGeometries(GeometryFactory.newInstance(), new ParserConfiguration(8, false));
+ assertNull(ws.getLod0MultiSurface());
+ assertNull(ws.getLod1MultiSurface());
assertNotNull(ws.getLod2MultiSurface());
assertNull(ws.getLod3MultiSurface());
assertNull(ws.getDeprecatedProperties().getLod4MultiSurface());
}
- @Test
- public void testReCreateGeometriesMultiSurfaceTunnelLod3() {
- WallSurface ws = new WallSurface();
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.TUNNEL, BoundarySurfaceType.WALL, ws);
- bs.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3));
- bs.reCreateGeometries(GeometryFactory.newInstance(), new ParserConfiguration(8, false));
- assertNull(ws.getLod2MultiSurface());
- assertNotNull(ws.getLod3MultiSurface());
- assertNull(ws.getDeprecatedProperties().getLod4MultiSurface());
- }
-
- @Test
- public void testReCreateGeometriesMultiSurfaceTunnelLod4() {
- WallSurface ws = new WallSurface();
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.TUNNEL, BoundarySurfaceType.WALL, ws);
- bs.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD4));
- bs.reCreateGeometries(GeometryFactory.newInstance(), new ParserConfiguration(8, false));
- assertNull(ws.getLod2MultiSurface());
- assertNull(ws.getLod3MultiSurface());
- assertNotNull(ws.getDeprecatedProperties().getLod4MultiSurface());
- }
-
@Test
public void testReCreateGeometriesMultiSurfaceLod3() {
WallSurface ws = new WallSurface();
- ws.setId("test");
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, ws);
+ BoundarySurface bs = new BoundarySurface( BoundarySurfaceType.WALL, ws);
bs.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD3));
bs.reCreateGeometries(GeometryFactory.newInstance(), new ParserConfiguration(8, false));
+ assertNull(ws.getLod0MultiSurface());
+ assertNull(ws.getLod1MultiSurface());
assertNull(ws.getLod2MultiSurface());
assertNotNull(ws.getLod3MultiSurface());
assertNull(ws.getDeprecatedProperties().getLod4MultiSurface());
@@ -281,30 +241,21 @@ public class BoundarySurfaceTest {
@Test
public void testReCreateGeometriesMultiSurfaceLod4() {
WallSurface ws = new WallSurface();
- ws.setId("test");
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, ws);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, ws);
bs.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD4));
bs.reCreateGeometries(GeometryFactory.newInstance(), new ParserConfiguration(8, false));
+ assertNull(ws.getLod0MultiSurface());
+ assertNull(ws.getLod1MultiSurface());
assertNull(ws.getLod2MultiSurface());
assertNull(ws.getLod3MultiSurface());
assertNotNull(ws.getDeprecatedProperties().getLod4MultiSurface());
}
- @Test
- public void testReCreateGeometriesMultiSurfaceLod0() {
- WallSurface ws = new WallSurface();
- ws.setId("test");
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, ws);
- bs.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD0));
- bs.reCreateGeometries(GeometryFactory.newInstance(), new ParserConfiguration(8, false));
- assertNotNull(ws.getLod0MultiSurface());
- }
@Test(expected = IllegalStateException.class)
public void testReCreateGeometriesSolid() {
WallSurface ws = new WallSurface();
- ws.setId("test");
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, ws);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, ws);
bs.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.SOLID));
bs.reCreateGeometries(GeometryFactory.newInstance(), new ParserConfiguration(8, false));
}
@@ -312,8 +263,7 @@ public class BoundarySurfaceTest {
@Test
public void testReCreateGeometriesOpenings() {
WallSurface ws = new WallSurface();
- ws.setId("test");
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, ws);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, ws);
Opening oMock = Mockito.mock(Opening.class);
bs.addOpening(oMock);
GeometryFactory factory = GeometryFactory.newInstance();
@@ -325,7 +275,7 @@ public class BoundarySurfaceTest {
@Test
public void testGetGmlObject() {
WallSurface ws = new WallSurface();
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, ws);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, ws);
assertEquals(ws, bs.getGmlObject());
}
@@ -338,7 +288,7 @@ public class BoundarySurfaceTest {
assertNotNull(ws.getLod2MultiSurface());
assertNotNull(ws.getLod3MultiSurface());
assertNotNull(ws.getDeprecatedProperties().getLod4MultiSurface());
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, ws);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, ws);
Opening oMock = Mockito.mock(Opening.class);
bs.addOpening(oMock);
bs.accept(new UnsetGeometriesVisitor());
@@ -348,41 +298,9 @@ public class BoundarySurfaceTest {
assertNull(ws.getDeprecatedProperties().getLod4MultiSurface());
}
- @Test
- public void testUnsetGmlGeometriesBridge() {
- WallSurface ws = new WallSurface();
- ws.setLod2MultiSurface(new MultiSurfaceProperty());
- ws.setLod3MultiSurface(new MultiSurfaceProperty());
- ws.getDeprecatedProperties().setLod4MultiSurface(new MultiSurfaceProperty());
- assertNotNull(ws.getLod2MultiSurface());
- assertNotNull(ws.getLod3MultiSurface());
- assertNotNull(ws.getDeprecatedProperties().getLod4MultiSurface());
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BRIDGE, BoundarySurfaceType.WALL, ws);
- bs.unsetGmlGeometries();
- assertNull(ws.getLod2MultiSurface());
- assertNull(ws.getLod3MultiSurface());
- assertNull(ws.getDeprecatedProperties().getLod4MultiSurface());
- }
-
- @Test
- public void testUnsetGmlGeometriesTunnel() {
- WallSurface ws = new WallSurface();
- ws.setLod2MultiSurface(new MultiSurfaceProperty());
- ws.setLod3MultiSurface(new MultiSurfaceProperty());
- ws.getDeprecatedProperties().setLod4MultiSurface(new MultiSurfaceProperty());
- assertNotNull(ws.getLod2MultiSurface());
- assertNotNull(ws.getLod3MultiSurface());
- assertNotNull(ws.getDeprecatedProperties().getLod4MultiSurface());
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.TUNNEL, BoundarySurfaceType.WALL, ws);
- bs.unsetGmlGeometries();
- assertNull(ws.getLod2MultiSurface());
- assertNull(ws.getLod3MultiSurface());
- assertNull(ws.getDeprecatedProperties().getLod4MultiSurface());
- }
-
@Test
public void testGetFeatureType() {
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.TUNNEL, BoundarySurfaceType.WALL, null);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, null);
assertEquals(FeatureType.BOUNDARY_SURFACE, bs.getFeatureType());
}
@@ -392,17 +310,11 @@ public class BoundarySurfaceTest {
BoundarySurface bs = new BoundarySurface(aco);
assertEquals(aco, bs.getGmlObject());
}
-
- @Test
- public void testSetFeatureType() {
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.TUNNEL, BoundarySurfaceType.WALL, null);
- bs.setFeatureType(SurfaceFeatureType.BRIDGE);
- assertEquals(SurfaceFeatureType.BRIDGE, bs.getSurfaceFeatureType());
- }
+
@Test
public void testSetType() {
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.TUNNEL, BoundarySurfaceType.WALL, null);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, null);
bs.setType(BoundarySurfaceType.ROOF);
assertEquals(BoundarySurfaceType.ROOF, bs.getType());
}
diff --git a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/BridgeObjectTest.java b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/BridgeObjectTest.java
index d185d272673832131bfd175d24d84cb43161a643..931ce45c4daf8176200c0aa68071fbf85743c75b 100644
--- a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/BridgeObjectTest.java
+++ b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/BridgeObjectTest.java
@@ -51,7 +51,6 @@ import de.hft.stuttgart.citydoctor2.utils.visitors.UnsetGeometriesVisitor;
public class BridgeObjectTest {
- //TODO: Rework this class with the new Visitors
@Test
public void testAccept() {
diff --git a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/BuildingTest.java b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/BuildingTest.java
index a27eee4343fe5532d21b52b972e779275295417b..21d897faca604266bdf25a662d05ba0abc78a0ee 100644
--- a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/BuildingTest.java
+++ b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/BuildingTest.java
@@ -64,7 +64,7 @@ public class BuildingTest {
b.setCityGmlBuilding(createCityGmlBuilding());
RoofSurface rs = new RoofSurface();
rs.setId("testRoof");
- BoundarySurface surface = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.ROOF, rs);
+ BoundarySurface surface = new BoundarySurface(BoundarySurfaceType.ROOF, rs);
Geometry geomSurface = new Geometry(GeometryType.MULTI_SURFACE, Lod.LOD2, Orientation.OUTWARD);
geomSurface.addPolygon(new LinkedPolygon(p, geomSurface));
geomSurface.updateEdgesAndVertices();
@@ -75,7 +75,8 @@ public class BuildingTest {
assertNotSame(b, copy);
assertEquals(b.getGmlId(), copy.getGmlId());
-
+
+ copy.prepareForChecking();
Geometry copyGeom = copy.getGeometries().get(0);
assertNotSame(geom, copyGeom);
diff --git a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/CityDoctorModelTest.java b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/CityDoctorModelTest.java
index 7eeee2897303efc7f89d28f3d3431b98273c69a9..b535500a2481ebc4398d7568f6b7cb1219165ac1 100644
--- a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/CityDoctorModelTest.java
+++ b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/CityDoctorModelTest.java
@@ -27,11 +27,14 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
+import de.hft.stuttgart.citydoctor2.database.FeatureCache;
+import de.hft.stuttgart.citydoctor2.database.UnconnectedCache;
import org.citygml4j.core.ade.ADEException;
import org.citygml4j.core.model.CityGMLVersion;
import org.citygml4j.core.model.core.AbstractFeatureProperty;
import org.citygml4j.core.model.core.CityModel;
import org.citygml4j.xml.writer.CityGMLWriteException;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -63,28 +66,40 @@ import de.hft.stuttgart.quality.model.types.ValidationPlan;
public class CityDoctorModelTest {
+ private File mockFile;
+ private ParserConfiguration config;
+ private CityDoctorModel model;
+ private final FeatureCache featureCache = new FeatureCache();
+ @Before
+ public void setUp(){
+ mockFile = Mockito.mock(File.class);
+ Mockito.when(mockFile.getName()).thenReturn("test");
+ config = new ParserConfiguration(8, false);
+ featureCache.resetCache();
+ model = new CityDoctorModel(config, mockFile, featureCache);
+ }
+
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@Test(expected = IllegalArgumentException.class)
public void testCityDoctorModelNoConfig() {
- new CityDoctorModel(null, null);
+ new CityDoctorModel(null, mockFile, new UnconnectedCache());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCityDoctorModelNoFile() {
+ new CityDoctorModel(config, null, new UnconnectedCache());
}
@Test
public void testSetValidated() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
model.setValidated(Mockito.mock(ValidationPlan.class));
assertTrue(model.isValidated());
}
@Test
public void testAddGlobalError() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
CheckError err = Mockito.mock(CheckError.class);
model.addGlobalError(err);
assertEquals(err, model.getGlobalErrors().get(0));
@@ -92,9 +107,6 @@ public class CityDoctorModelTest {
@Test
public void testAddGlobalErrors() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
CheckError err1 = Mockito.mock(CheckError.class);
CheckError err2 = Mockito.mock(CheckError.class);
List errors = new ArrayList<>();
@@ -107,19 +119,15 @@ public class CityDoctorModelTest {
@Test
public void testGetFile() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
- assertEquals(f, model.getFile());
+ assertEquals(mockFile, model.getFile());
}
@Test
public void testCreateFeatureStream() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
Building b = Mockito.mock(Building.class);
+ Mockito.when(b.getGmlId()).thenReturn(new GmlId("b"));
Vegetation v = Mockito.mock(Vegetation.class);
+ Mockito.when(v.getGmlId()).thenReturn(new GmlId("v"));
model.addBuilding(b);
model.addVegetation(v);
assertTrue(model.createFeatureStream().anyMatch(c -> c == b));
@@ -129,9 +137,6 @@ public class CityDoctorModelTest {
@Test
public void testSaveAsWithoutValidation() throws CityGMLWriteException, ADEException,
IOException, CityGmlParseException, InvalidGmlFileException, CityDoctorWriteException {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
model.setParsedCityGMLVersion(CityGMLVersion.v2_0);
CityModel cModel = new CityModel();
model.setCityModel(cModel);
@@ -147,7 +152,7 @@ public class CityDoctorModelTest {
assertTrue(saveFile.length() > 0);
CityDoctorModel parsedModel = CityGmlParser.parseCityGmlFile(saveFile.getAbsolutePath(), config);
- Building parsedBuilding = parsedModel.getBuildings().get(0);
+ Building parsedBuilding = parsedModel.getBuildings().toList().get(0);
assertEquals("testId", parsedBuilding.getGmlId().getGmlString());
assertEquals(1, parsedBuilding.getGeometries().size());
}
@@ -155,9 +160,7 @@ public class CityDoctorModelTest {
@Test
public void testSaveAsWithValidation() throws CityGMLWriteException, ADEException,
IOException, CityGmlParseException, InvalidGmlFileException, CityDoctorWriteException {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
+
model.setParsedCityGMLVersion(CityGMLVersion.v2_0);
CityModel cModel = new CityModel();
ValidationPlan plan = new ValidationPlan();
@@ -214,7 +217,7 @@ public class CityDoctorModelTest {
assertTrue(saveFile.length() > 0);
CityDoctorModel parsedModel = CityGmlParser.parseCityGmlFile(saveFile.getAbsolutePath(), config);
- Building parsedBuilding = parsedModel.getBuildings().get(0);
+ Building parsedBuilding = parsedModel.getBuildings().toList().get(0);
assertEquals("testId", parsedBuilding.getGmlId().getGmlString());
assertEquals(1, parsedBuilding.getGeometries().size());
List props = parsedBuilding.getGmlObject().getADEProperties(CityObjectProperties.class);
@@ -234,9 +237,6 @@ public class CityDoctorModelTest {
@Test
public void testCollectErrors() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
Building b = new Building();
model.addBuilding(b);
CheckError error = Mockito.mock(CheckError.class);
@@ -247,18 +247,12 @@ public class CityDoctorModelTest {
@Test
public void testGetFileName() {
- File f = new File("test");
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
assertEquals("test", model.getFileName());
- assertEquals(f, model.getFile());
+ assertEquals(mockFile, model.getFile());
}
@Test
public void testSetCityModel() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
CityModel cModel = Mockito.mock(CityModel.class);
model.setCityModel(cModel);
assertEquals(cModel, model.getCityModel());
@@ -266,111 +260,99 @@ public class CityDoctorModelTest {
@Test
public void testAddBuilding() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
Building b = Mockito.mock(Building.class);
+ Mockito.when(b.getGmlId()).thenReturn(new GmlId("b"));
model.addBuilding(b);
- assertEquals(b, model.getBuildings().get(0));
+ assertEquals(b, model.getBuildings().toList().get(0));
}
@Test
public void testAddBridge() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
BridgeObject b = Mockito.mock(BridgeObject.class);
+ Mockito.when(b.getGmlId()).thenReturn(new GmlId("b"));
model.addBridge(b);
- assertEquals(b, model.getBridges().get(0));
+ assertEquals(b, model.getBridges().toList().get(0));
}
@Test
public void testAddVegetation() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
Vegetation veg = Mockito.mock(Vegetation.class);
+ Mockito.when(veg.getGmlId()).thenReturn(new GmlId("v"));
model.addVegetation(veg);
- assertEquals(veg, model.getVegetation().get(0));
+ assertEquals(veg, model.getVegetation().toList().get(0));
}
@Test
public void testAddTunnel() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
Tunnel tunnel = Mockito.mock(Tunnel.class);
+ Mockito.when(tunnel.getGmlId()).thenReturn(new GmlId("t"));
model.addTunnel(tunnel);
- assertEquals(tunnel, model.getTunnels().get(0));
+ assertEquals(tunnel, model.getTunnels().toList().get(0));
}
@Test
public void testAddTransportation() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
TransportationObject trans = Mockito.mock(TransportationObject.class);
+ Mockito.when(trans.getGmlId()).thenReturn(new GmlId("t"));
model.addTransportation(trans);
- assertEquals(trans, model.getTransportation().get(0));
+ assertEquals(trans, model.getTransportation().toList().get(0));
}
@Test
public void testAddLand() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
LandObject land = Mockito.mock(LandObject.class);
+ Mockito.when(land.getGmlId()).thenReturn(new GmlId("l"));
model.addLand(land);
- assertEquals(land, model.getLand().get(0));
+ assertEquals(land, model.getLand().toList().get(0));
}
@Test
public void testAddWater() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
WaterObject water = Mockito.mock(WaterObject.class);
+ Mockito.when(water.getGmlId()).thenReturn(new GmlId("w"));
model.addWater(water);
- assertEquals(water, model.getWater().get(0));
+ assertEquals(water, model.getWater().toList().get(0));
}
@Test
public void testAddCityFurniture() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
CityFurniture cf = Mockito.mock(CityFurniture.class);
+ Mockito.when(cf.getGmlId()).thenReturn(new GmlId("cf"));
model.addCityFurniture(cf);
- assertEquals(cf, model.getCityFurniture().get(0));
+ assertEquals(cf, model.getCityFurniture().toList().get(0));
}
@Test
- public void testAddGenericCityObject() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
+ public void testAddOtherCityObject() {
GenericCityObject gen = Mockito.mock(GenericCityObject.class);
- model.addGenericCityObject(gen);
- assertEquals(gen, model.getGenericCityObjects().get(0));
+ Mockito.when(gen.getGmlId()).thenReturn(new GmlId("g"));
+ model.addOtherCityObject(gen);
+ assertEquals(gen, model.getOtherCityObjects().toList().get(0));
}
@Test
public void testGetNumberOfFeatures() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
Building b = Mockito.mock(Building.class);
+ Mockito.when(b.getGmlId()).thenReturn(new GmlId("b"));
BridgeObject bo = Mockito.mock(BridgeObject.class);
+ Mockito.when(bo.getGmlId()).thenReturn(new GmlId("bo"));
Vegetation veg = Mockito.mock(Vegetation.class);
+ Mockito.when(veg.getGmlId()).thenReturn(new GmlId("ve"));
Tunnel tunnel = Mockito.mock(Tunnel.class);
+ Mockito.when(tunnel.getGmlId()).thenReturn(new GmlId("t"));
TransportationObject trans = Mockito.mock(TransportationObject.class);
+ Mockito.when(trans.getGmlId()).thenReturn(new GmlId("tr"));
LandObject land = Mockito.mock(LandObject.class);
+ Mockito.when(land.getGmlId()).thenReturn(new GmlId("l"));
WaterObject water = Mockito.mock(WaterObject.class);
+ Mockito.when(water.getGmlId()).thenReturn(new GmlId("w"));
CityFurniture cf = Mockito.mock(CityFurniture.class);
+ Mockito.when(cf.getGmlId()).thenReturn(new GmlId("cf"));
GenericCityObject generic = Mockito.mock(GenericCityObject.class);
+ Mockito.when(generic.getGmlId()).thenReturn(new GmlId("g"));
model.addBuilding(b);
model.addBridge(bo);
@@ -380,7 +362,7 @@ public class CityDoctorModelTest {
model.addLand(land);
model.addWater(water);
model.addCityFurniture(cf);
- model.addGenericCityObject(generic);
+ model.addOtherCityObject(generic);
assertEquals(9, model.getNumberOfFeatures());
@@ -388,31 +370,25 @@ public class CityDoctorModelTest {
@Test
public void testGetParserConfig() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
assertEquals(config, model.getParserConfig());
}
@Test
public void testReplaceBuilding() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
Building b1 = Mockito.mock(Building.class);
+ Mockito.when(b1.getGmlId()).thenReturn(new GmlId("b1"));
Building b2 = Mockito.mock(Building.class);
+ Mockito.when(b2.getGmlId()).thenReturn(new GmlId("b2"));
+
model.addBuilding(b1);
- assertEquals(b1, model.getBuildings().get(0));
+ assertEquals(b1, model.getBuildings().toList().get(0));
model.replaceFeature(b1, b2);
- assertEquals(b2, model.getBuildings().get(0));
- assertEquals(1, model.getBuildings().size());
+ assertEquals(b2, model.getBuildings().toList().get(0));
+ assertEquals(1, model.getBuildings().toList().size());
}
@Test(expected = IllegalStateException.class)
public void testReplaceBuildingMissing() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
Building b1 = Mockito.mock(Building.class);
Building b2 = Mockito.mock(Building.class);
model.replaceFeature(b1, b2);
@@ -420,23 +396,19 @@ public class CityDoctorModelTest {
@Test
public void testReplaceBridge() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
BridgeObject b1 = Mockito.mock(BridgeObject.class);
+ Mockito.when(b1.getGmlId()).thenReturn(new GmlId("b1"));
BridgeObject b2 = Mockito.mock(BridgeObject.class);
+ Mockito.when(b2.getGmlId()).thenReturn(new GmlId("b2"));
model.addBridge(b1);
- assertEquals(b1, model.getBridges().get(0));
+ assertEquals(b1, model.getBridges().toList().get(0));
model.replaceFeature(b1, b2);
- assertEquals(b2, model.getBridges().get(0));
- assertEquals(1, model.getBridges().size());
+ assertEquals(b2, model.getBridges().toList().get(0));
+ assertEquals(1, model.getBridges().toList().size());
}
@Test(expected = IllegalStateException.class)
public void testReplaceBridgeMissing() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
BridgeObject b1 = Mockito.mock(BridgeObject.class);
BridgeObject b2 = Mockito.mock(BridgeObject.class);
model.replaceFeature(b1, b2);
@@ -444,23 +416,20 @@ public class CityDoctorModelTest {
@Test
public void testReplaceVegetation() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
Vegetation v1 = Mockito.mock(Vegetation.class);
+ Mockito.when(v1.getGmlId()).thenReturn(new GmlId("v1"));
Vegetation v2 = Mockito.mock(Vegetation.class);
+ Mockito.when(v2.getGmlId()).thenReturn(new GmlId("v2"));
+
model.addVegetation(v1);
- assertEquals(v1, model.getVegetation().get(0));
+ assertEquals(v1, model.getVegetation().toList().get(0));
model.replaceFeature(v1, v2);
- assertEquals(v2, model.getVegetation().get(0));
- assertEquals(1, model.getVegetation().size());
+ assertEquals(v2, model.getVegetation().toList().get(0));
+ assertEquals(1, model.getVegetation().toList().size());
}
@Test(expected = IllegalStateException.class)
public void testReplaceVegetationMissing() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
Vegetation v1 = Mockito.mock(Vegetation.class);
Vegetation v2 = Mockito.mock(Vegetation.class);
model.replaceFeature(v1, v2);
@@ -468,23 +437,20 @@ public class CityDoctorModelTest {
@Test
public void testReplaceTunnel() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
Tunnel t1 = Mockito.mock(Tunnel.class);
+ Mockito.when(t1.getGmlId()).thenReturn(new GmlId("t1"));
Tunnel t2 = Mockito.mock(Tunnel.class);
+ Mockito.when(t2.getGmlId()).thenReturn(new GmlId("t2"));
+
model.addTunnel(t1);
- assertEquals(t1, model.getTunnels().get(0));
+ assertEquals(t1, model.getTunnels().toList().get(0));
model.replaceFeature(t1, t2);
- assertEquals(t2, model.getTunnels().get(0));
- assertEquals(1, model.getTunnels().size());
+ assertEquals(t2, model.getTunnels().toList().get(0));
+ assertEquals(1, model.getTunnels().toList().size());
}
@Test(expected = IllegalStateException.class)
public void testReplaceTunnelMissing() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
Tunnel t1 = Mockito.mock(Tunnel.class);
Tunnel t2 = Mockito.mock(Tunnel.class);
model.replaceFeature(t1, t2);
@@ -492,23 +458,20 @@ public class CityDoctorModelTest {
@Test
public void testReplaceTransportation() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
TransportationObject t1 = Mockito.mock(TransportationObject.class);
+ Mockito.when(t1.getGmlId()).thenReturn(new GmlId("t1"));
TransportationObject t2 = Mockito.mock(TransportationObject.class);
+ Mockito.when(t2.getGmlId()).thenReturn(new GmlId("t2"));
+
model.addTransportation(t1);
- assertEquals(t1, model.getTransportation().get(0));
+ assertEquals(t1, model.getTransportation().toList().get(0));
model.replaceFeature(t1, t2);
- assertEquals(t2, model.getTransportation().get(0));
- assertEquals(1, model.getTransportation().size());
+ assertEquals(t2, model.getTransportation().toList().get(0));
+ assertEquals(1, model.getTransportation().toList().size());
}
@Test(expected = IllegalStateException.class)
public void testReplaceTransportationMissing() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
TransportationObject t1 = Mockito.mock(TransportationObject.class);
TransportationObject t2 = Mockito.mock(TransportationObject.class);
model.replaceFeature(t1, t2);
@@ -516,23 +479,20 @@ public class CityDoctorModelTest {
@Test
public void testReplaceLand() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
LandObject lo1 = Mockito.mock(LandObject.class);
+ Mockito.when(lo1.getGmlId()).thenReturn(new GmlId("lo1"));
LandObject lo2 = Mockito.mock(LandObject.class);
+ Mockito.when(lo2.getGmlId()).thenReturn(new GmlId("lo2"));
+
model.addLand(lo1);
- assertEquals(lo1, model.getLand().get(0));
+ assertEquals(lo1, model.getLand().toList().get(0));
model.replaceFeature(lo1, lo2);
- assertEquals(lo2, model.getLand().get(0));
- assertEquals(1, model.getLand().size());
+ assertEquals(lo2, model.getLand().toList().get(0));
+ assertEquals(1, model.getLand().toList().size());
}
@Test(expected = IllegalStateException.class)
public void testReplaceLandMissing() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
LandObject lo1 = Mockito.mock(LandObject.class);
LandObject lo2 = Mockito.mock(LandObject.class);
model.replaceFeature(lo1, lo2);
@@ -540,23 +500,20 @@ public class CityDoctorModelTest {
@Test
public void testReplaceWater() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
WaterObject t1 = Mockito.mock(WaterObject.class);
+ Mockito.when(t1.getGmlId()).thenReturn(new GmlId("t1"));
WaterObject t2 = Mockito.mock(WaterObject.class);
+ Mockito.when(t2.getGmlId()).thenReturn(new GmlId("t2"));
+
model.addWater(t1);
- assertEquals(t1, model.getWater().get(0));
+ assertEquals(t1, model.getWater().toList().get(0));
model.replaceFeature(t1, t2);
- assertEquals(t2, model.getWater().get(0));
- assertEquals(1, model.getWater().size());
+ assertEquals(t2, model.getWater().toList().get(0));
+ assertEquals(1, model.getWater().toList().size());
}
@Test(expected = IllegalStateException.class)
public void testReplaceWaterMissing() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
WaterObject t1 = Mockito.mock(WaterObject.class);
WaterObject t2 = Mockito.mock(WaterObject.class);
model.replaceFeature(t1, t2);
@@ -564,23 +521,20 @@ public class CityDoctorModelTest {
@Test
public void testReplaceCityFurniture() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
CityFurniture cf1 = Mockito.mock(CityFurniture.class);
+ Mockito.when(cf1.getGmlId()).thenReturn(new GmlId("cf1"));
CityFurniture cf2 = Mockito.mock(CityFurniture.class);
+ Mockito.when(cf2.getGmlId()).thenReturn(new GmlId("cf2"));
+
model.addCityFurniture(cf1);
- assertEquals(cf1, model.getCityFurniture().get(0));
+ assertEquals(cf1, model.getCityFurniture().toList().get(0));
model.replaceFeature(cf1, cf2);
- assertEquals(cf2, model.getCityFurniture().get(0));
- assertEquals(1, model.getCityFurniture().size());
+ assertEquals(cf2, model.getCityFurniture().toList().get(0));
+ assertEquals(1, model.getCityFurniture().toList().size());
}
@Test(expected = IllegalStateException.class)
public void testReplaceCityFurnitureMissing() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
CityFurniture cf1 = Mockito.mock(CityFurniture.class);
CityFurniture cf2 = Mockito.mock(CityFurniture.class);
model.replaceFeature(cf1, cf2);
@@ -588,23 +542,20 @@ public class CityDoctorModelTest {
@Test
public void testReplaceGenericCityObject() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
GenericCityObject gco1 = Mockito.mock(GenericCityObject.class);
+ Mockito.when(gco1.getGmlId()).thenReturn(new GmlId("gco1"));
GenericCityObject gco2 = Mockito.mock(GenericCityObject.class);
- model.addGenericCityObject(gco1);
- assertEquals(gco1, model.getGenericCityObjects().get(0));
+ Mockito.when(gco2.getGmlId()).thenReturn(new GmlId("gco2"));
+
+ model.addOtherCityObject(gco1);
+ assertEquals(gco1, model.getOtherCityObjects().toList().get(0));
model.replaceFeature(gco1, gco2);
- assertEquals(gco2, model.getGenericCityObjects().get(0));
- assertEquals(1, model.getGenericCityObjects().size());
+ assertEquals(gco2, model.getOtherCityObjects().toList().get(0));
+ assertEquals(1, model.getOtherCityObjects().toList().size());
}
@Test(expected = IllegalStateException.class)
public void testReplaceGenericCityObjectMissing() {
- File f = Mockito.mock(File.class);
- ParserConfiguration config = new ParserConfiguration(8, false);
- CityDoctorModel model = new CityDoctorModel(config, f);
GenericCityObject gco1 = Mockito.mock(GenericCityObject.class);
GenericCityObject gco2 = Mockito.mock(GenericCityObject.class);
model.replaceFeature(gco1, gco2);
diff --git a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/CompositePolygonTest.java b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/CompositePolygonTest.java
index 7aa9ad7763c3c949010b4464d2567ffc94d12042..9c306ab34964f5cba514843072d70110439109d3 100644
--- a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/CompositePolygonTest.java
+++ b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/CompositePolygonTest.java
@@ -16,7 +16,7 @@ public class CompositePolygonTest {
ParserConfiguration config = new ParserConfiguration(8, false);
CityDoctorModel m = CityGmlParser.parseCityGmlFile("src/test/resources/FZK_haus.gml", config);
- Building b = m.getBuildings().get(0);
+ Building b = m.getBuildings().toList().get(0);
assertNotNull(b);
assertFalse(b.getBoundarySurfaces().isEmpty());
for (BoundarySurface bs : b.getBoundarySurfaces()) {
diff --git a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/GeometryTest.java b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/GeometryTest.java
index a37077ae28fbca4d79961e9bb2a5141afabdbe79..5c8b97cff5c28a6c4b8b9e1308253988999b70f3 100644
--- a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/GeometryTest.java
+++ b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/GeometryTest.java
@@ -96,7 +96,7 @@ public class GeometryTest {
public void testRemovePolygonConcreteWithLink() {
ParserConfiguration config = new ParserConfiguration(4, false);
AbstractConstructionSurface abs = new WallSurface();
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, abs);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, abs);
var gmlBi = new org.citygml4j.core.model.building.BuildingInstallation();
Installation bi = new Installation();
bi.setGmlObject(gmlBi);
@@ -133,7 +133,7 @@ public class GeometryTest {
public void testRemovePolygonOnlyConcrete() {
ParserConfiguration config = new ParserConfiguration(4, false);
AbstractConstructionSurface abs = new WallSurface();
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, abs);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, abs);
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, Lod.LOD2, Orientation.OUTWARD);
ConcretePolygon p = new ConcretePolygon();
@@ -156,7 +156,7 @@ public class GeometryTest {
public void testRemovePolygonLinked() {
ParserConfiguration config = new ParserConfiguration(4, false);
AbstractConstructionSurface abs = new WallSurface();
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, abs);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, abs);
var gmlBi = new org.citygml4j.core.model.building.BuildingInstallation();
Installation bi = new Installation();
bi.setGmlObject(gmlBi);
@@ -193,7 +193,7 @@ public class GeometryTest {
public void testReplacePolygon() {
ParserConfiguration config = new ParserConfiguration(4, false);
AbstractConstructionSurface abs = new WallSurface();
- BoundarySurface bs = new BoundarySurface(SurfaceFeatureType.BUILDING, BoundarySurfaceType.WALL, abs);
+ BoundarySurface bs = new BoundarySurface(BoundarySurfaceType.WALL, abs);
var gmlBi = new org.citygml4j.core.model.building.BuildingInstallation();
Installation bi = new Installation();
bi.setGmlObject(gmlBi);
diff --git a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/VegetationTest.java b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/VegetationTest.java
index 5f9c97a3f29f5bb6dd70e7ed4cdb3df3c51dd964..4df104691c64bb4c5f1535ea058b9ac285172a50 100644
--- a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/VegetationTest.java
+++ b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/datastructure/VegetationTest.java
@@ -26,7 +26,6 @@ import static org.mockito.Mockito.mock;
public class VegetationTest {
- //TODO: Recreate geometries tests
@Test
public void testContainsError() {
diff --git a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/mapper/FeatureMapperTest.java b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/mapper/FeatureMapperTest.java
index a4d8f261a8a6f70f685dbb5d9b64592ca5708849..456d40124bc646f364c306016fc84c5a80177a68 100644
--- a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/mapper/FeatureMapperTest.java
+++ b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/mapper/FeatureMapperTest.java
@@ -63,20 +63,20 @@ public class FeatureMapperTest {
public void testVisitWaterBody() {
WaterBody body = new WaterBody();
Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(mock(ParserConfiguration.class),
- new File("").toPath());
+ new File("").toPath(), false);
mapper.visit(body);
- assertEquals(1, mapper.getModel().getWater().size());
+ assertEquals(1, mapper.getModel().getWater().toList().size());
body.setId("test1");
mapper.visit(body);
- assertEquals(2, mapper.getModel().getWater().size());
- WaterObject waterObject = mapper.getModel().getWater().get(1);
+ assertEquals(2, mapper.getModel().getWater().toList().size());
+ WaterObject waterObject = mapper.getModel().getWater().toList().get(1);
assertEquals("test1", waterObject.getGmlId().getGmlString());
body.getDeprecatedProperties().setLod1MultiSurface(createDummyMsp());
mapper.visit(body);
- assertEquals(3, mapper.getModel().getWater().size());
+ assertEquals(3, mapper.getModel().getWater().toList().size());
assertNull(body.getDeprecatedProperties().getLod1MultiSurface());
- Geometry geometry = mapper.getModel().getWater().get(2).getGeometries().get(0);
+ Geometry geometry = mapper.getModel().getWater().toList().get(2).getGeometries().get(0);
assertEquals(1, geometry.getPolygons().size());
assertEquals(Lod.LOD1, geometry.getLod());
assertEquals(GeometryType.MULTI_SURFACE, geometry.getType());
@@ -86,7 +86,7 @@ public class FeatureMapperTest {
public void testVisitPlantCover() {
PlantCover cover = new PlantCover();
Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(mock(ParserConfiguration.class),
- new File("").toPath());
+ new File("").toPath(), false);
mapper.visit(cover);
}
@@ -124,12 +124,12 @@ public class FeatureMapperTest {
body.getDeprecatedProperties().setLod1MultiSurface(new MultiSurfaceProperty(ms));
ParserConfiguration config = new ParserConfiguration(8, false);
- Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(config, folder.newFile().toPath());
+ Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(config, folder.newFile().toPath(), false);
mapper.visit(body);
CityDoctorModel model = mapper.getModel();
- assertEquals(1, model.getWater().size());
- WaterObject waterObject = model.getWater().get(0);
+ assertEquals(1, model.getWater().toList().size());
+ WaterObject waterObject = model.getWater().toList().get(0);
Geometry geometry = waterObject.getGeometries().get(0);
assertEquals(1, geometry.getVertices().size());
Vertex vertex = geometry.getVertices().get(0);
@@ -152,12 +152,12 @@ public class FeatureMapperTest {
body.getDeprecatedProperties().setLod1MultiSurface(new MultiSurfaceProperty(ms));
ParserConfiguration config = new ParserConfiguration(8, false);
- Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(config, folder.newFile().toPath());
+ Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(config, folder.newFile().toPath(), false);
mapper.visit(body);
CityDoctorModel model = mapper.getModel();
- assertEquals(1, model.getWater().size());
- WaterObject waterObject = model.getWater().get(0);
+ assertEquals(1, model.getWater().toList().size());
+ WaterObject waterObject = model.getWater().toList().get(0);
Geometry geometry = waterObject.getGeometries().get(0);
assertEquals(2, geometry.getVertices().size());
Vertex vertex = geometry.getVertices().get(0);
@@ -199,12 +199,12 @@ public class FeatureMapperTest {
body.getDeprecatedProperties().setLod1MultiSurface(new MultiSurfaceProperty(ms));
ParserConfiguration config = new ParserConfiguration(8, false);
- Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(config, folder.newFile().toPath());
+ Citygml3FeatureMapper mapper = new Citygml3FeatureMapper(config, folder.newFile().toPath(), false);
mapper.visit(body);
CityDoctorModel model = mapper.getModel();
- assertEquals(1, model.getWater().size());
- WaterObject waterObject = model.getWater().get(0);
+ assertEquals(1, model.getWater().toList().size());
+ WaterObject waterObject = model.getWater().toList().get(0);
Geometry geometry = waterObject.getGeometries().get(0);
assertEquals(7, geometry.getVertices().size());
assertEquals(8, geometry.getEdges().size());
diff --git a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/parser/CityGml3ParserTest.java b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/parser/CityGml3ParserTest.java
index cbc926f156477550c15a2256c742e161ada87269..88b958f4f01ef0083bb0bb8ed262e8ca71b3e0bb 100644
--- a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/parser/CityGml3ParserTest.java
+++ b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/parser/CityGml3ParserTest.java
@@ -49,7 +49,7 @@ public class CityGml3ParserTest {
ParserConfiguration config = new ParserConfiguration(8, false);
CityDoctorModel model = CityGmlParser.parseCityGmlFile("src/test/resources/SimpleSolid_SrefBS.gml", config);
assertNotNull(model);
- List buildings = model.getBuildings();
+ List buildings = model.getBuildings().toList();
assertEquals(1, buildings.size());
Building building = buildings.get(0);
assertEquals("_Simple_BD.1", building.getGmlId().getGmlString());
diff --git a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/zip/ZipTest.java b/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/zip/ZipTest.java
deleted file mode 100644
index cb9b8e2b612c3f80c136da4df1962f487ba14d8c..0000000000000000000000000000000000000000
--- a/CityDoctorParent/CityDoctorModel/src/test/java/de/hft/stuttgart/citydoctor2/zip/ZipTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package de.hft.stuttgart.citydoctor2.zip;
-
-import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
-import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
-import org.apache.commons.io.FileUtils;
-import org.junit.Test;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-public class ZipTest {
-
- ParserConfiguration config = new ParserConfiguration(8, false);
-
-
- @Test
- public void testUnzipping() throws MalformedZipFileException {
- CityGmlZipArchive cgmlArch = CityGmlZipArchive.register("src/test/resources/zip/mock_archive.zip");
- assertNotNull(cgmlArch);
- cgmlArch.mountArchive(config);
-
- checkMockArchive(cgmlArch);
- }
-
- private void checkMockArchive(CityGmlZipArchive cgmlArch) {
- assertEquals(5, cgmlArch.getEntries().size());
- for (CityGmlZipEntry entry : cgmlArch.getEntries()) {
- assertNotNull(entry);
- assertTrue(entry.getEntrySubPath().matches("^mock[1-5].gml$"));
- assertNull(entry.getErrorType());
- assertNotNull(entry.getModel());
- assertEquals(1, entry.getModel().getNumberOfFeatures());
- }
- }
-
- @Test
- public void testZipping() throws IOException {
- CityGmlZipArchive cgmlArch = CityGmlZipArchive.register("src/test/resources/zip/mock_archive.zip");
- assertNotNull(cgmlArch);
- cgmlArch.mountArchive(config);
-
- Path tmpDir = null;
- try {
- tmpDir = Files.createTempDirectory("testTmp");
- tmpDir.toFile().deleteOnExit();
- String expPath = tmpDir + "/export.zip";
-
- cgmlArch.exportToZipFile(expPath);
- CityGmlZipArchive cgmlExport = CityGmlZipArchive.register(expPath);
- assertNotNull(cgmlExport);
- cgmlExport.mountArchive(config);
-
- checkMockArchive(cgmlExport);
- } finally {
- if (tmpDir != null) {
- FileUtils.deleteDirectory(tmpDir.toFile());
- }
- }
- }
-
- @Test
- public void testEpsgParsing() throws MalformedZipFileException {
- CityGmlZipArchive cgmlArch = CityGmlZipArchive.register("src/test/resources/zip/epsg.zip");
- assertNotNull(cgmlArch);
- cgmlArch.mountArchive(config);
-
- CityGmlZipEntry entry = cgmlArch.getEntry("epsg1.gml");
- assertNotNull(entry);
- String srsName = entry.getModel().getCityModel().getBoundedBy().getEnvelope().getSrsName().split(":")[6];
- assertEquals("25832", srsName);
-
- entry = cgmlArch.getEntry("epsg2.gml");
- assertNotNull(entry);
- srsName = entry.getModel().getCityModel().getBoundedBy().getEnvelope().getSrsName().split(":")[6];
- assertEquals("7415", srsName);
- }
-
- @Test
- public void testXMLValidation() throws MalformedZipFileException {
- ParserConfiguration valConfig = new ParserConfiguration(8, true);
- CityGmlZipArchive cgmlArch = CityGmlZipArchive.register("src/test/resources/zip/validate.zip");
- assertNotNull(cgmlArch);
- cgmlArch.mountArchive(valConfig);
-
- assertNull(cgmlArch.getEntry("valCorrect.gml").getErrorType());
- assertEquals(ZipEntryErrorType.INVALID_CITY_GML_FILE, cgmlArch.getEntry("valFaulty.gml").getErrorType());
- }
-
-
- @Test
- public void testImplicitParsing() throws MalformedZipFileException {
- CityGmlZipArchive cgmlArch = CityGmlZipArchive.register("src/test/resources/zip/implicit.zip");
- assertNotNull(cgmlArch);
- cgmlArch.mountArchive(config);
-
- CityDoctorModel mainModel = cgmlArch.getEntry("Main_model.gml").getModel();
- assertEquals(18, mainModel.getGenericCityObjects().size());
- }
-
-}
diff --git a/CityDoctorParent/CityDoctorModel/src/test/resources/04-FZK-Haus-LoD2-Tex-Storey-CG30-V01-InteriorSurface.gml b/CityDoctorParent/CityDoctorModel/src/test/resources/04-FZK-Haus-LoD2-Tex-Storey-CG30-V01-InteriorSurface.gml
new file mode 100644
index 0000000000000000000000000000000000000000..da8303f785cdf9dbd703cde6d8717e64c3fafa2b
--- /dev/null
+++ b/CityDoctorParent/CityDoctorModel/src/test/resources/04-FZK-Haus-LoD2-Tex-Storey-CG30-V01-InteriorSurface.gml
@@ -0,0 +1,1655 @@
+
+
+
+
+
+
+
+
+ FZK-Haus
+
+
+ 458900.0 5438785.0 113.5
+ 458912.0 5438795.0 120.017691
+
+
+
+
+ KIT Test Building FZK-Haus adapted for CityGML 3.0
+ KIT Test Building FZK-Haus for CityGML 3.0
+
+
+ @cityeditor:layer
+ LoD2-Ausgeblendet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ projected
+
+
+ highestRoofEdge
+ lowestGroundPoint
+ measured
+ 6.52
+
+
+
+
+ 2
+
+
+
+
+ Ground Floor
+
+
+ Ground
+
+
+
+
+
+
+ 458912.0 5438785.0
+ 113.5 458900.0 5438785.0 113.5 458900.0 5438795.0
+ 113.5 458912.0 5438795.0 113.5 458912.0 5438785.0
+ 113.5
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Wall East
+
+
+
+
+
+
+ 458912.0 5438795.0
+ 113.5 458912.0 5438795.0 116.4 458912.0 5438785.0
+ 116.4 458912.0 5438785.0 113.5 458912.0 5438795.0
+ 113.5
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Wall South
+
+
+
+
+
+
+ 458912.0 5438785.0
+ 113.5 458912.0 5438785.0 116.4 458900.0 5438785.0
+ 116.4 458900.0 5438785.0 113.5 458912.0 5438785.0
+ 113.5
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Wall West
+
+
+
+
+
+
+ 458900.0 5438785.0
+ 113.5 458900.0 5438785.0 116.4 458900.0 5438795.0
+ 116.4 458900.0 5438795.0 113.5 458900.0 5438785.0
+ 113.5
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Wall North
+
+
+
+
+
+
+ 458900.0 5438795.0
+ 113.5 458900.0 5438795.0 116.4 458912.0 5438795.0
+ 116.4 458912.0 5438795.0 113.5 458900.0 5438795.0
+ 113.5
+
+
+
+
+
+
+
+
+
+
+ 02 Ground Floor - Kitchen
+
+
+ Ground Floor / Kitchen / Closure Surface North
+
+
+
+
+
+
+ 458904.695
+ 5438789.01 116.2 458903.8 5438789.01 116.2
+ 458903.8 5438789.01 113.7 458904.695 5438789.01
+ 113.7 458904.695 5438789.01 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Kitchen / Closure Surface East
+
+
+
+
+
+
+ 458904.695
+ 5438789.01 116.2 458904.695 5438789.01 113.7
+ 458904.695 5438785.3 113.7 458904.695 5438785.3
+ 116.2 458904.695 5438789.01 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Kitchen / Ceiling
+
+
+
+
+
+
+ 458900.3 5438785.3
+ 116.2 458900.3 5438789.01 116.2 458903.8
+ 5438789.01 116.2 458904.695 5438789.01 116.2
+ 458904.695 5438785.3 116.2 458900.3 5438785.3
+ 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Kitchen / Interior Wall West
+
+
+
+
+
+
+ 458900.3 5438785.3
+ 116.2 458900.3 5438785.3 113.7 458900.3 5438789.01
+ 113.7 458900.3 5438789.01 116.2 458900.3 5438785.3
+ 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Kitchen / Interior Wall South
+
+
+
+
+
+
+ 458904.695 5438785.3
+ 116.2 458904.695 5438785.3 113.7 458900.3
+ 5438785.3 113.7 458900.3 5438785.3 116.2
+ 458904.695 5438785.3 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Kitchen / Interior Wall North
+
+
+
+
+
+
+ 458900.3 5438789.01
+ 113.7 458903.8 5438789.01 113.7 458903.8
+ 5438789.01 116.2 458900.3 5438789.01 116.2
+ 458900.3 5438789.01 113.7
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Kitchen / Floor
+
+
+
+
+
+
+ 458903.8 5438789.01
+ 113.7 458900.3 5438789.01 113.7 458900.3 5438785.3
+ 113.7 458904.695 5438785.3 113.7 458904.695
+ 5438789.01 113.7 458903.8 5438789.01
+ 113.7
+
+
+
+
+
+
+
+
+
+
+
+
+ 03 Ground Floor - Corridor
+
+
+ Ground Floor / Corridor / Closure Surface South
+
+
+
+
+
+
+ 458907.41 5438789.01
+ 113.7 458904.695 5438789.01 113.7 458904.695
+ 5438789.01 116.2 458907.41 5438789.01 116.2
+ 458907.41 5438789.01 113.7
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Corridor / Closure Surface South
+
+
+
+
+
+
+ 458903.8 5438789.01
+ 116.2 458904.695 5438789.01 116.2 458904.695
+ 5438789.01 113.7 458903.8 5438789.01 113.7
+ 458903.8 5438789.01 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Corridor / Ceiling
+
+
+
+
+
+
+ 458903.8 5438789.25
+ 116.2 458900.3 5438789.25 116.2 458900.3
+ 5438790.75 116.2 458907.41 5438790.75 116.2
+ 458907.41 5438789.01 116.2 458904.695 5438789.01
+ 116.2 458903.8 5438789.01 116.2 458903.8
+ 5438789.25 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Corridor / Wall East
+
+
+
+
+
+
+ 458907.41 5438790.75
+ 116.2 458907.41 5438790.75 113.7 458907.41
+ 5438789.01 113.7 458907.41 5438789.01 116.2
+ 458907.41 5438790.75 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Corridor / Wall North
+
+
+
+
+
+
+ 458900.3 5438790.75
+ 113.7 458907.41 5438790.75 113.7 458907.41
+ 5438790.75 116.2 458900.3 5438790.75 116.2
+ 458900.3 5438790.75 113.7
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Corridor / Wall West I
+
+
+
+
+
+
+ 458900.3 5438789.25
+ 113.7 458900.3 5438790.75 113.7 458900.3
+ 5438790.75 116.2 458900.3 5438789.25 116.2
+ 458900.3 5438789.25 113.7
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Corridor / Wall South
+
+
+
+
+
+
+ 458903.8 5438789.25
+ 113.7 458900.3 5438789.25 113.7 458900.3
+ 5438789.25 116.2 458903.8 5438789.25 116.2
+ 458903.8 5438789.25 113.7
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Corridor / Wall West II
+
+
+
+
+
+
+ 458903.8 5438789.01
+ 113.7 458903.8 5438789.25 113.7 458903.8
+ 5438789.25 116.2 458903.8 5438789.01 116.2
+ 458903.8 5438789.01 113.7
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Corridor / Floor
+
+
+
+
+
+
+ 458903.8 5438789.01
+ 113.7 458904.695 5438789.01 113.7 458907.41
+ 5438789.01 113.7 458907.41 5438790.75 113.7
+ 458900.3 5438790.75 113.7 458900.3 5438789.25
+ 113.7 458903.8 5438789.25 113.7 458903.8
+ 5438789.01 113.7
+
+
+
+
+
+
+
+
+
+
+
+
+ 04 Ground Floor - Living Room
+
+
+ Ground Floor / Living Room / Closure Surface West
+
+
+
+
+
+
+ 458904.695 5438785.3
+ 116.2 458904.695 5438785.3 113.7 458904.695
+ 5438789.01 113.7 458904.695 5438789.01 116.2
+ 458904.695 5438785.3 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Living Room / Closure Surface North
+
+
+
+
+
+
+ 458904.695
+ 5438789.01 113.7 458907.41 5438789.01 113.7
+ 458907.41 5438789.01 116.2 458904.695 5438789.01
+ 116.2 458904.695 5438789.01 113.7
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Living Room / Ceiling
+
+
+
+
+
+
+ 458904.695
+ 5438789.01 116.2 458907.41 5438789.01 116.2
+ 458911.7 5438789.01 116.2 458911.7 5438785.3 116.2
+ 458904.695 5438785.3 116.2 458904.695 5438789.01
+ 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Living Room / Interior Wall North
+
+
+
+
+
+
+ 458911.7 5438789.01
+ 116.2 458907.41 5438789.01 116.2 458907.41
+ 5438789.01 113.7 458911.7 5438789.01 113.7
+ 458911.7 5438789.01 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Living Room / Interior Wall South
+
+
+
+
+
+
+ 458911.7 5438785.3
+ 116.2 458911.7 5438785.3 113.7 458904.695
+ 5438785.3 113.7 458904.695 5438785.3 116.2
+ 458911.7 5438785.3 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Living Room / Interior Wall East
+
+
+
+
+
+
+ 458911.7 5438789.01
+ 116.2 458911.7 5438789.01 113.7 458911.7 5438785.3
+ 113.7 458911.7 5438785.3 116.2 458911.7 5438789.01
+ 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Living Room / Floor
+
+
+
+
+
+
+ 458904.695 5438785.3
+ 113.7 458911.7 5438785.3 113.7 458911.7 5438789.01
+ 113.7 458907.41 5438789.01 113.7 458904.695
+ 5438789.01 113.7 458904.695 5438785.3
+ 113.7
+
+
+
+
+
+
+
+
+
+
+
+
+ 05 Ground Floor - Bedroom
+
+
+ Ground Floor / Bedroom / Ceiling
+
+
+
+
+
+
+ 458911.7 5438789.25
+ 116.2 458907.65 5438789.25 116.2 458907.65
+ 5438794.7 116.2 458911.7 5438794.7 116.2 458911.7
+ 5438789.25 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Bedroom / Interior Wall West
+
+
+
+
+
+
+ 458907.65 5438789.25
+ 116.2 458907.65 5438789.25 113.7 458907.65
+ 5438794.7 113.7 458907.65 5438794.7 116.2
+ 458907.65 5438789.25 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Bedroom / Interior Wall South
+
+
+
+
+
+
+ 458911.7 5438789.25
+ 116.2 458911.7 5438789.25 113.7 458907.65
+ 5438789.25 113.7 458907.65 5438789.25 116.2
+ 458911.7 5438789.25 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Bedroom / Interior Wall North
+
+
+
+
+
+
+ 458907.65 5438794.7
+ 116.2 458907.65 5438794.7 113.7 458911.7 5438794.7
+ 113.7 458911.7 5438794.7 116.2 458907.65 5438794.7
+ 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Bedroom / Interior Wall East
+
+
+
+
+
+
+ 458911.7 5438794.7
+ 116.2 458911.7 5438794.7 113.7 458911.7 5438789.25
+ 113.7 458911.7 5438789.25 116.2 458911.7 5438794.7
+ 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Bedroom / Floor
+
+
+
+
+
+
+ 458911.7 5438789.25
+ 113.7 458911.7 5438794.7 113.7 458907.65 5438794.7
+ 113.7 458907.65 5438789.25 113.7 458911.7
+ 5438789.25 113.7
+
+
+
+
+
+
+
+
+
+
+
+
+ 06 Ground Floor - Bathroom
+
+
+ Ground Floor / Bathroom / Ceiling
+
+
+
+
+
+
+ 458907.41 5438790.99
+ 116.2 458904.04 5438790.99 116.2 458904.04
+ 5438794.7 116.2 458907.41 5438794.7 116.2
+ 458907.41 5438790.99 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Bathroom / Interior Wall West
+
+
+
+
+
+
+ 458904.04 5438790.99
+ 116.2 458904.04 5438790.99 113.7 458904.04
+ 5438794.7 113.7 458904.04 5438794.7 116.2
+ 458904.04 5438790.99 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Bathroom / Interior Wall South
+
+
+
+
+
+
+ 458907.41 5438790.99
+ 116.2 458907.41 5438790.99 113.7 458904.04
+ 5438790.99 113.7 458904.04 5438790.99 116.2
+ 458907.41 5438790.99 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Bathroom / Interior Wall North
+
+
+
+
+
+
+ 458904.04 5438794.7
+ 116.2 458904.04 5438794.7 113.7 458907.41
+ 5438794.7 113.7 458907.41 5438794.7 116.2
+ 458904.04 5438794.7 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Bathroom / Interior Wall East
+
+
+
+
+
+
+ 458907.41 5438794.7
+ 116.2 458907.41 5438794.7 113.7 458907.41
+ 5438790.99 113.7 458907.41 5438790.99 116.2
+ 458907.41 5438794.7 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Bathroom / Floor
+
+
+
+
+
+
+ 458907.41 5438790.99
+ 113.7 458907.41 5438794.7 113.7 458904.04
+ 5438794.7 113.7 458904.04 5438790.99 113.7
+ 458907.41 5438790.99 113.7
+
+
+
+
+
+
+
+
+
+
+
+
+ 07 Ground Floor - Office
+
+
+ Ground Floor / Office / Ceiling
+
+
+
+
+
+
+ 458903.8 5438790.99
+ 116.2 458900.3 5438790.99 116.2 458900.3 5438794.7
+ 116.2 458903.8 5438794.7 116.2 458903.8 5438790.99
+ 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Office / Interior Wall West
+
+
+
+
+
+
+ 458900.3 5438790.99
+ 116.2 458900.3 5438790.99 113.7 458900.3 5438794.7
+ 113.7 458900.3 5438794.7 116.2 458900.3 5438790.99
+ 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Office / Interior Wall South
+
+
+
+
+
+
+ 458903.8 5438790.99
+ 116.2 458903.8 5438790.99 113.7 458900.3
+ 5438790.99 113.7 458900.3 5438790.99 116.2
+ 458903.8 5438790.99 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Office / Interior Wall North
+
+
+
+
+
+
+ 458900.3 5438794.7
+ 116.2 458900.3 5438794.7 113.7 458903.8 5438794.7
+ 113.7 458903.8 5438794.7 116.2 458900.3 5438794.7
+ 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Office / Interior Wall East
+
+
+
+
+
+
+ 458903.8 5438794.7
+ 116.2 458903.8 5438794.7 113.7 458903.8 5438790.99
+ 113.7 458903.8 5438790.99 116.2 458903.8 5438794.7
+ 116.2
+
+
+
+
+
+
+
+
+
+
+ Ground Floor / Office / Floor
+
+
+
+
+
+
+ 458903.8 5438790.99
+ 113.7 458903.8 5438794.7 113.7 458900.3 5438794.7
+ 113.7 458900.3 5438790.99 113.7 458903.8
+ 5438790.99 113.7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Second Floor
+
+
+ Second Floor / Roof South
+
+
+
+
+
+
+ 458912.0 5438790.0
+ 120.017691 458900.0 5438790.0 120.017691 458900.0
+ 5438785.0 117.13094 458912.0 5438785.0 117.13094
+ 458912.0 5438790.0 120.017691
+
+
+
+
+
+
+
+
+
+
+ Second Floor / Roof North
+
+
+
+
+
+
+ 458900.0 5438790.0
+ 120.017691 458912.0 5438790.0 120.017691 458912.0
+ 5438795.0 117.13094 458900.0 5438795.0 117.13094
+ 458900.0 5438790.0 120.017691
+
+
+
+
+
+
+
+
+
+
+ Second Floor / Wall South
+
+
+
+
+
+
+ 458900.0 5438785.0
+ 117.13094 458900.0 5438785.0 116.4 458912.0
+ 5438785.0 116.4 458912.0 5438785.0 117.13094
+ 458900.0 5438785.0 117.13094
+
+
+
+
+
+
+
+
+
+
+ Second Floor / Wall West
+
+
+
+
+
+
+ 458900.0 5438795.0
+ 117.13094 458900.0 5438795.0 116.4 458900.0
+ 5438785.0 116.4 458900.0 5438785.0 117.13094
+ 458900.0 5438790.0 120.017691 458900.0 5438795.0
+ 117.13094
+
+
+
+
+
+
+
+
+
+
+ Second Floor / Wall East
+
+
+
+
+
+
+ 458912.0 5438785.0
+ 117.13094 458912.0 5438785.0 116.4 458912.0
+ 5438795.0 116.4 458912.0 5438795.0 117.13094
+ 458912.0 5438790.0 120.017691 458912.0 5438785.0
+ 117.13094
+
+
+
+
+
+
+
+
+
+
+ Second Floor / Wall North
+
+
+
+
+
+
+ 458912.0 5438795.0
+ 117.13094 458912.0 5438795.0 116.4 458900.0
+ 5438795.0 116.4 458900.0 5438795.0 117.13094
+ 458912.0 5438795.0 117.13094
+
+
+
+
+
+
+
+
+
+
+ 01 Second Floor - Galery
+
+
+ Second Floor / Galery / Ceiling North
+
+
+
+
+
+
+ 458900.3 5438794.7
+ 117.073205 458911.7 5438794.7 117.073205 458911.7
+ 5438790.0 119.786751 458900.3 5438790.0 119.786751
+ 458900.3 5438794.7 117.073205
+
+
+
+
+
+
+
+
+
+
+ Second Floor / Galery / Ceiling South
+
+
+
+
+
+
+ 458900.3 5438785.3
+ 117.073205 458900.3 5438790.0 119.786751 458911.7
+ 5438790.0 119.786751 458911.7 5438785.3 117.073205
+ 458900.3 5438785.3 117.073205
+
+
+
+
+
+
+
+
+
+
+ Second Floor / Galery / Interior Wall North
+
+
+
+
+
+
+ 458911.7 5438794.7
+ 116.4 458911.7 5438794.7 117.073205 458900.3
+ 5438794.7 117.073205 458900.3 5438794.7 116.4
+ 458911.7 5438794.7 116.4
+
+
+
+
+
+
+
+
+
+
+ Second Floor / Galery / Interior Wall East
+
+
+
+
+
+
+ 458911.7 5438794.7
+ 117.073205 458911.7 5438794.7 116.4 458911.7
+ 5438785.3 116.4 458911.7 5438785.3 117.073205
+ 458911.7 5438790.0 119.786751 458911.7 5438794.7
+ 117.073205
+
+
+
+
+
+
+
+
+
+
+ Second Floor / Galery / Interior Wall West
+
+
+
+
+
+
+ 458900.3 5438790.0
+ 119.786751 458900.3 5438785.3 117.073205 458900.3
+ 5438785.3 116.4 458900.3 5438794.7 116.4 458900.3
+ 5438794.7 117.073205 458900.3 5438790.0
+ 119.786751
+
+
+
+
+
+
+
+
+
+
+ Second Floor / Galery / Interior Wall South
+
+
+
+
+
+
+ 458900.3 5438785.3
+ 116.4 458900.3 5438785.3 117.073205 458911.7
+ 5438785.3 117.073205 458911.7 5438785.3 116.4
+ 458900.3 5438785.3 116.4
+
+
+
+
+
+
+
+
+
+
+ Second Floor / Galery / Floor
+
+
+
+
+
+
+ 458911.7 5438785.3
+ 116.4 458911.7 5438794.7 116.4 458900.3 5438794.7
+ 116.4 458900.3 5438785.3 116.4 458911.7 5438785.3
+ 116.4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ textures/FZK-Haus-Front.png
+ wrap
+
+
+ #KIT-Test-Building-01_PG.nfWbzHM5j2MqtisYAjgV
+
+
+ -6.01592849610218e-17 1.000011046207786
+ -3.0079642480510886e-17 0.7987000468203478
+ 1.0000000000000002 0.7987000468203478 1.0000000000000002
+ 1.000011046207786 -6.01592849610218e-17
+ 1.000011046207786
+ #KIT-Test-Building-01_LR.l5vPQsQlvAxe0PfGrItK
+
+
+
+
+
+
+ #KIT-Test-Building-01_PG.8Oi6zRMGuUdvjDA3942O
+
+
+ 1.0000000000000002
+ -4.454490602082857e-31 1.0000000000000002 0.7987000468203478
+ -3.007964248051091e-17 0.7987000468203478 0.0
+ -5.359579389737923e-47 1.0000000000000002
+ -4.454490602082857e-31
+ #KIT-Test-Building-01_LR.dQRaAbGZocTDsiXUS3Wo
+
+
+
+
+
+
+
+
+ textures/FZK-Haus-Right.png
+ wrap
+
+
+ #KIT-Test-Building-01_PG.ioJ6HX4PnhWvLSYhPA7h
+
+
+ 7.560328766851198e-17
+ 0.5570891737385654 5.087501393878691e-16 0.444942234223729
+ 1.0000000000000004 0.44494223422372897 1.0000000000000004
+ 0.5570891737385655 0.49999999999999994 0.9999986887435715
+ 7.560328766851198e-17 0.5570891737385654
+ #KIT-Test-Building-01_LR.VpCnRrYqLGD4bFFZLmWC
+
+
+
+
+
+
+ #KIT-Test-Building-01_PG.WH3ZPoThoidUosBGLd28
+
+
+ 1.0000000000000004
+ -2.907494171674344e-16 1.0000000000000004
+ 0.44494223422372897 5.087501393878691e-16 0.444942234223729
+ 7.560328766851198e-17 -2.907494171674344e-16
+ 1.0000000000000004
+ -2.907494171674344e-16
+ #KIT-Test-Building-01_LR.kb6UBRDjXdQhuZgyrrXF
+
+
+
+
+
+
+
+
+ textures/FZK-Haus-Left.png
+ wrap
+
+
+ #KIT-Test-Building-01_PG.VdnPNlkOAJHnTVZL5R37
+
+
+ -1.0 0.5570891737385658
+ -0.9999999999999996 0.44494223422372936
+ 4.331468517193571e-16 0.44494223422372936
+ 4.331468517193571e-16 0.5570891737385657
+ -0.49999999999999944 0.9999986887435719 -1.0
+ 0.5570891737385658
+ #KIT-Test-Building-01_LR.CWPcEAowucw9pxGFPH3S
+
+
+
+
+
+
+ #KIT-Test-Building-01_PG.87LG6xx5gYYjprCeHCDY
+
+
+ 4.331468517193571e-16
+ -1.1157709843049066e-47 4.331468517193571e-16
+ 0.44494223422372936 -0.9999999999999996 0.44494223422372936
+ -1.0 -8.368282382286802e-48 4.331468517193571e-16
+ -1.1157709843049066e-47
+ #KIT-Test-Building-01_LR.z42J72DCA0DG7fsjO1iJ
+
+
+
+
+
+
+
+
+ textures/Roofing_Shingles_GAF_Estates.jpg
+ wrap
+
+
+ #KIT-Test-Building-01_PG.as933cYedpVOQ8Wqm9j7
+
+
+ 21.47458840372227 18.00558453022584
+ 1.8506199769767277e-15 18.00558453022584
+ -1.2918958832001822e-15 4.124469685250767 21.47458840372227
+ 4.124469685250767 21.47458840372227 18.00558453022584
+ #KIT-Test-Building-01_LR.FJ2G4jJFUVmWcdGG3gyw
+
+
+
+
+
+
+ #KIT-Test-Building-01_PG.CUXCVrNXAnCgCUjdXnY1
+
+
+ -2.0055287249601352e-15
+ -2.816087737236785 -21.47458840372227 -2.816087737236785
+ -21.47458840372227 -16.697202582211872
+ 1.8024740244805496e-15 -16.697202582211872
+ -2.0055287249601352e-15 -2.816087737236785
+ #KIT-Test-Building-01_LR.cYvvi9l6K4nl9jeHjt03
+
+
+
+
+
+
+
+
+ textures/FZK-Haus-Back.png
+ wrap
+
+
+ #KIT-Test-Building-01_PG.cdHLpEJXgkf3Hq9x6PF7
+
+
+ -1.0000000000000002 1.000011046207795
+ -1.0000000000000002 0.7987000468203566
+ 2.7071678232459823e-16 0.7987000468203567
+ 3.007964248051091e-16 1.000011046207795 -1.0000000000000002
+ 1.000011046207795
+ #KIT-Test-Building-01_LR.ODQPptDGkQ9xxB6LArAA
+
+
+
+
+
+
+ #KIT-Test-Building-01_PG.Y4DuK1eWWjbSOQxjL75Z
+
+
+ 3.0079642480510913e-16
+ -1.4416909618544142e-15 2.707167823245983e-16
+ 0.7987000468203463 -1.0000000000000002 0.7987000468203463
+ -1.0000000000000002 -1.4416909618544138e-15
+ 3.0079642480510913e-16 -1.4416909618544142e-15
+ #KIT-Test-Building-01_LR.CvfxHmYhr7DvEJeZnfKH
+
+
+
+
+
+
+
+
+ 0.2
+ 0.4666666666666667 0.34509803921568627
+ 0.21176470588235294
+ 0.0 0.0 0.0
+ 1.0 1.0 1.0
+ 0.2
+ 0.0
+ false
+ #KIT-Test-Building-01_PG.B9OH2yr4U3AkPsKWbFy2
+
+
+
+
+
diff --git a/CityDoctorParent/CityDoctorValidation/pom.xml b/CityDoctorParent/CityDoctorValidation/pom.xml
index 48329e28a6d195e3d605b2a8052b3adceae93f8a..6cd0386295bb343dc7714a176c38058d7581c16f 100644
--- a/CityDoctorParent/CityDoctorValidation/pom.xml
+++ b/CityDoctorParent/CityDoctorValidation/pom.xml
@@ -4,7 +4,7 @@
de.hft.stuttgart
CityDoctorParent
- 3.17.3
+ 3.18.0
CityDoctorValidation
CityDoctorValidation
diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/CityDoctorValidation.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/CityDoctorValidation.java
index 5b73190bff2699949f020a921782e01e5d369988..ec2d0df09e0c2e858d747670c34b9df74f5b79d7 100644
--- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/CityDoctorValidation.java
+++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/CityDoctorValidation.java
@@ -21,13 +21,11 @@ package de.hft.stuttgart.citydoctor2;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.nio.file.Path;
import java.util.List;
-import de.hft.stuttgart.citydoctor2.zip.CityGmlZipArchive;
+import de.hft.stuttgart.citydoctor2.utils.Localization;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import org.citygml4j.core.ade.ADEException;
import de.hft.stuttgart.citydoctor2.check.Checker;
import de.hft.stuttgart.citydoctor2.check.ValidationConfiguration;
@@ -83,12 +81,12 @@ public class CityDoctorValidation {
if (optional) {
return null;
}
- logger.error("No output file specified. (-out [FILE])");
+ logger.error(Localization.getText("CityDoctorValidation.noOutputFile"));
System.exit(11);
}
List outFiles = argParser.getValues("out");
if (outFiles.size() != 1) {
- logger.error("Specify exactly one file as output.");
+ logger.error(Localization.getText("CityDoctorValidation.notExactlyOneOutputFile"));
System.exit(12);
}
outputFile = outFiles.get(0);
@@ -157,15 +155,13 @@ public class CityDoctorValidation {
ValidationConfiguration config, String outputFile) throws CityDoctorWriteException, CityGmlParseException, IOException, InvalidGmlFileException {
File inputFile = new File(input);
if (!inputFile.exists()) {
- logger.error("Input file '{}' does not exist.", input);
+ logger.error(Localization.getText("CityDoctorValidation.inputFileNotExisting"), input);
System.exit(1);
}
if (inputFile.getName().endsWith(".gml") || inputFile.getName().endsWith(".xml")) {
startFileValidation(inputFile, xmlOutput, pdfOutput, config, outputFile);
- } else if (inputFile.getName().endsWith(".zip")) {
- startZipValidation(input, xmlOutput, pdfOutput, config, outputFile);
} else {
- logger.error("Input file '{}' does not end with .gml or .xml and is not a zip archive.", input);
+ logger.error(Localization.getText("CityDoctorValidation.wrongInputFileFormat"), input);
System.exit(1);
}
}
@@ -179,10 +175,11 @@ public class CityDoctorValidation {
* @param pdfOutput the output path for the pdf report (optional)
* @param config the configuration path for the validation plan
* @param outputFile storing the validated gml file with quality ade
- * @throws CityDoctorWriteException if something goes wrong while writing the gml
- * file
- * @throws CityGMLBuilderException
- * @throws ADEException
+ *
+ * @throws IOException When an exception while writing the report files happens.
+ * @throws CityGmlParseException When an error while parsing the cityGML file happens.
+ * @throws InvalidGmlFileException If the cityGML file is not valid according to the cityGML schema.
+ * @throws CityDoctorWriteException If something goes wrong while writing the output gml file
*/
public static void startFileValidation(File inputFile, String xmlOutput, String pdfOutput,
ValidationConfiguration config, String outputFile) throws IOException, CityGmlParseException,
@@ -201,34 +198,11 @@ public class CityDoctorValidation {
}
}
- public static void startZipValidation(String inputZipFile, String xmlOutput, String pdfOutput,
- ValidationConfiguration config, String outputFile) throws CityGmlParseException, IOException {
- xmlOutput = toDirectoryPath(xmlOutput);
- pdfOutput = toDirectoryPath(pdfOutput);
- outputFile = toDirectoryPath(outputFile);
- if (xmlOutput == null && pdfOutput == null && outputFile == null) {
- logger.warn("No output locations specified, results of validation will not be saved");
- }
- CityGmlZipArchive archive = CityGmlZipArchive.register(inputZipFile);
- Checker.streamCheck(archive, xmlOutput, pdfOutput, config, outputFile);
- }
-
- public static String toDirectoryPath(String input) {
- if (input == null) {
- return null;
- }
- String parentDirectory = Path.of(input).getParent().toString() + File.separator;
- String name = Path.of(input).getFileName().toString().replaceFirst("\\..+", "") + File.separator;
- File f = new File(parentDirectory + name);
- f.mkdir();
- return f.getPath() + File.separator;
- }
-
public static String getPdfOutput(ArgumentParser argParser) {
if (argParser.containsOption("pdfreport")) {
List reportFiles = argParser.getValues("pdfreport");
if (reportFiles.size() != 1) {
- logger.error("Specify exactly one file as pdfReport");
+ logger.error(Localization.getText("CityDoctorValidation.notExactlyOnePDFOutput"));
System.exit(6);
}
return reportFiles.get(0);
@@ -240,7 +214,7 @@ public class CityDoctorValidation {
if (argParser.containsOption("xmlreport")) {
List reportFiles = argParser.getValues("xmlreport");
if (reportFiles.size() != 1) {
- logger.error("Specify exactly one file as xmlReport");
+ logger.error(Localization.getText("CityDoctorValidation.notExactlyOneXMLOutput"));
System.exit(5);
}
return reportFiles.get(0);
@@ -257,16 +231,16 @@ public class CityDoctorValidation {
if (argParser.containsOption("config")) {
List configFiles = argParser.getValues("config");
if (configFiles.size() != 1) {
- logger.error("Specify exactly one file as configuration");
+ logger.error(Localization.getText("CityDoctorValidation.notExactlyOneConfigFile"));
System.exit(4);
}
return ValidationConfiguration.loadValidationConfig(configFiles.get(0));
} else {
if (optional) {
- logger.warn("No configuration file given, loading default configuration");
+ logger.warn(Localization.getText("CityDoctorValidation.loadingDefaultConfig"));
return ValidationConfiguration.loadStandardValidationConfig();
} else {
- logger.error("No configuration file specified with -config [FILE]");
+ logger.error(Localization.getText("CityDoctorValidation.noConfig"));
System.exit(7);
return null;
}
@@ -278,7 +252,7 @@ public class CityDoctorValidation {
if (argParser.containsOption("out")) {
List outFiles = argParser.getValues("out");
if (outFiles.size() != 1) {
- logger.error("Specify exactly one file as output.");
+ logger.error(Localization.getText("CityDoctorValidation.multipleOutputFiles"));
System.exit(3);
}
return outFiles.get(0);
@@ -297,12 +271,12 @@ public class CityDoctorValidation {
if (optional) {
return null;
}
- logger.error("No input file specified. (-in [FILE])");
+ logger.error(Localization.getText("CityDoctorValidation.noInputFile"));
System.exit(1);
}
List inFiles = argParser.getValues("in");
if (inFiles.size() != 1) {
- logger.error("Specify exactly one file as input.");
+ logger.error(Localization.getText("CityDoctorValidation.notExactlyOneInputFile"));
System.exit(2);
}
inputFile = inFiles.get(0);
diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/CityDoctorValidationCLI.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/CityDoctorValidationCLI.java
index 505c5eb54a7d32e60cee219350bb1795a859868f..9003eb7b97bcfeb67cafb5f0ae002312cfa46af8 100644
--- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/CityDoctorValidationCLI.java
+++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/CityDoctorValidationCLI.java
@@ -1,12 +1,19 @@
package de.hft.stuttgart.citydoctor2;
-import java.util.concurrent.Callable;
+import de.hft.stuttgart.citydoctor2.check.ValidationConfiguration;
+import de.hft.stuttgart.citydoctor2.exceptions.CityDoctorWriteException;
+import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException;
+import de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException;
+import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
+import java.io.File;
+import java.io.IOException;
+
@Command(name = "citydoctor2", mixinStandardHelpOptions = true, description = "Validates CityGML files according to a provided validation-plan.")
-public class CityDoctorValidationCLI implements Callable {
+public class CityDoctorValidationCLI implements Runnable {
@Option(names = {"-i" , "--in" , "--input"},
description = "Filepath of the CityGML file.",
@@ -15,23 +22,41 @@ public class CityDoctorValidationCLI implements Callable {
@Option(names = {"-c" , "--config" , "--configuration", "--plan"},
description = "Filepath of the validation configuration .yml",
- required = true)
- private String config;
+ defaultValue = Option.NULL_VALUE)
+ private File config;
@Option(names = {"-x" , "--xml" , "--xmlReport"},
- description = "Create a XML validation report at target location")
+ description = "Create a XML validation report at target location",
+ defaultValue = Option.NULL_VALUE)
private String xmlReport;
@Option(names = {"-p" , "--pdf" , "--pdfReport"},
- description = "Create a PDF validation report at target location")
+ description = "Create a PDF validation report at target location",
+ defaultValue = Option.NULL_VALUE)
private String pdfReport;
@Option(names = {"-o" , "--out" , "--output"},
- description = "Create a validated copy of the CityGML input with QualityADE at target location.")
+ description = "Create a validated copy of the CityGML input with QualityADE at target location.",
+ defaultValue = Option.NULL_VALUE)
private String output;
@Override
- public Integer call() throws Exception {
- return 0;
+ public void run(){
+ try {
+ ValidationConfiguration valConfig;
+ if(config == null){
+ valConfig=ValidationConfiguration.loadStandardValidationConfig();
+ } else{
+ valConfig=ValidationConfiguration.loadValidationConfig(config.getAbsolutePath());
+ }
+ CityDoctorValidation.startValidationProcess(input, xmlReport, pdfReport, valConfig,output);
+ } catch (CityDoctorWriteException | CityGmlParseException | IOException | InvalidGmlFileException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void main(String[] args) {
+ int exitCode = new CommandLine(new CityDoctorValidationCLI()).execute(args);
+ System.exit(exitCode);
}
}
diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java
index 061e4184ca9c36eb99b6e61d5fe35c81c9b30e56..c863720e40b70668737309eaa2148ce5cc42e9f4 100644
--- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java
+++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java
@@ -28,9 +28,14 @@ import de.hft.stuttgart.citydoctor2.checks.CheckPrototype;
import de.hft.stuttgart.citydoctor2.checks.Checks;
import de.hft.stuttgart.citydoctor2.checks.SvrlContentHandler;
import de.hft.stuttgart.citydoctor2.checks.util.FeatureCheckedListener;
+import de.hft.stuttgart.citydoctor2.database.CityObjectCache;
+import de.hft.stuttgart.citydoctor2.database.CityObjectCache;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.FeatureType;
+import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
+import de.hft.stuttgart.citydoctor2.datastructure.ImplicitGeometryHolder;
+import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
import de.hft.stuttgart.citydoctor2.parser.CityGmlConsumer;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParser;
@@ -42,11 +47,8 @@ import de.hft.stuttgart.citydoctor2.reporting.XmlStreamReporter;
import de.hft.stuttgart.citydoctor2.reporting.XmlValidationReporter;
import de.hft.stuttgart.citydoctor2.reporting.pdf.PdfReporter;
import de.hft.stuttgart.citydoctor2.reporting.pdf.PdfStreamReporter;
-import de.hft.stuttgart.citydoctor2.utils.ArchivePacker;
import de.hft.stuttgart.citydoctor2.utils.Localization;
-import de.hft.stuttgart.citydoctor2.zip.CityGmlZipArchive;
-import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
-import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntryFile;
+import de.hft.stuttgart.citydoctor2.utils.TimeFormatter;
import de.hft.stuttgart.quality.model.enums.RequirementId;
import de.hft.stuttgart.quality.model.enums.TopLevelFeatureType;
import de.hft.stuttgart.quality.model.properties.CheckingProperty;
@@ -57,7 +59,6 @@ import de.hft.stuttgart.quality.model.properties.RequirementProperty;
import de.hft.stuttgart.quality.model.types.Checking;
import de.hft.stuttgart.quality.model.types.Parameter;
import de.hft.stuttgart.quality.model.types.ValidationPlan;
-import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -79,6 +80,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
@@ -89,7 +91,8 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import java.util.stream.Stream;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* The main container class for checking. It contains the logic for validation,
@@ -191,38 +194,93 @@ public class Checker {
if (config == null) {
config = ValidationConfiguration.loadStandardValidationConfig();
}
- checkCityModel(model, l);
- if (logger.isInfoEnabled()) {
- logger.info(Localization.getText("Checker.checksFinished"));
+ AutoCloseable checkingContext = model.getCache().startCheckingMode();
+ try(checkingContext){
+ Callable schematronThread = () -> executeSchematronValidationIfAvailable(config, model.getFile());
+ ExecutorService executor = Executors.newSingleThreadExecutor();
+ Future handlerFuture = executor.submit(schematronThread);
+ executor.shutdown();
+
+ checkCityModel(model, l);
+ getSchematronResults(handlerFuture, l);
+
+ model.setValidated(createValidationPlan());
+ } catch (Exception e){
+ logger.error("Validation failed due to encountering error", e);
+ }
+ }
+
+ private void getSchematronResults(Future handlerFuture, ProgressListener l) {
+ if (!handlerFuture.isDone()) {
+ if (logger.isInfoEnabled()) {
+ logger.info(Localization.getText("Checker.schematronStillRunning"));
+ }
+ if(l !=null){
+ l.updateProgress(-0.5f);
+ }
}
- SvrlContentHandler handler = executeSchematronValidationIfAvailable(config, model.getFile());
- if (handler != null) {
- handleSchematronResults(handler);
+ try {
+ SvrlContentHandler handler = handlerFuture.get();
+ if (handler != null) {
+ handleSchematronResults(handler);
+ }
+ } catch (ExecutionException e) {
+ logger.error(e);
+ } catch (InterruptedException e) {
+ logger.error(Localization.getText("Checker.schematronInterrupted"), e);
+ Thread.currentThread().interrupt();
}
- model.setValidated(createValidationPlan());
}
private void handleSchematronResults(SvrlContentHandler handler) {
- model.addGlobalErrors(handler.getGeneralErrors());
+ CityObjectCache cache = model.getCache();
+ handleSchematronErrorsGlobal(handler.getGeneralErrors());
Map featureMap = new HashMap<>();
- model.createFeatureStream().forEach(f -> featureMap.put(f.getGmlId().getGmlString(), f));
+ boolean onlySchematron = execLayers.isEmpty();
+ if (onlySchematron) {
+ CheckableUtilsVisitor visitor = new CheckableUtilsVisitor() {
+ @Override
+ public void check(Checkable checkable) {
+ checkable.setValidated(true);
+ }
+ };
+ model.createFeatureStream().forEach(f -> {
+ featureMap.put(f.getGmlId().getGmlString(), f);
+ f.accept(visitor);
+ });
+ } else {
+ model.createFeatureStream().forEach(f -> featureMap.put(f.getGmlId().getGmlString(), f));
+ }
handler.getFeatureErrors().forEach((k, v) -> {
- if (k.trim().isEmpty()) {
- // missing gml id, ignore?
- return;
- }
- CityObject co = featureMap.get(k);
+ String trimmedId = k.trim();
+ CityObject co = cache.get(new GmlId(k));
if (co == null) {
// gml id reported by schematron was not found, add to general errors
- for (SchematronError se : v) {
- model.addGlobalError(se);
- }
+ handleSchematronErrorsGlobal(v);
} else {
handleSchematronErrorsForCityObject(v, co);
+ co.setValidated(true);
}
});
}
+ private void handleSchematronErrorsGlobal(List v) {
+ for (SchematronError se : v) {
+ CheckError err;
+ if (AttributeMissingError.ID.getIdString().equals(se.getErrorIdString())) {
+ err = new AttributeMissingError(null, se.getChildId(), se.getNameOfAttribute());
+ } else if (AttributeValueWrongError.ID.getIdString().equals(se.getErrorIdString())) {
+ err = new AttributeValueWrongError(null, se.getChildId(), se.getNameOfAttribute());
+ } else if (AttributeInvalidError.ID.getIdString().equals(se.getErrorIdString())) {
+ err = new AttributeInvalidError(null, se.getChildId(), se.getNameOfAttribute());
+ } else {
+ throw new IllegalStateException(
+ "Unknown error ID was given in schematron file: " + se.getErrorIdString());
+ }
+ model.addGlobalError(err);
+ }
+ }
+
public static void handleSchematronErrorsForCityObject(List v, CityObject co) {
int count = 0;
for (SchematronError se : v) {
@@ -435,13 +493,16 @@ public class Checker {
}
}
- @SuppressWarnings("resource")
public static SvrlContentHandler executeSchematronValidationIfAvailable(ValidationConfiguration config,
InputStream in) {
if (config.getSchematronFilePath() != null && !config.getSchematronFilePath().isEmpty()) {
if (logger.isInfoEnabled()) {
logger.info(Localization.getText("Checker.schematronValidation"));
}
+ if (!Files.exists(Path.of(config.getSchematronFilePath()))) {
+ logger.warn(Localization.getText("Checker.schematronFileNotFound"), config.getSchematronFilePath());
+ return null;
+ }
try {
TransformerFactory transformerFactory = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl", Checker.class.getClassLoader());
@@ -559,7 +620,7 @@ public class Checker {
for (Entry e : config.getRequirements().entrySet()) {
de.hft.stuttgart.citydoctor2.check.Requirement req = Checks.getAvailableRequirements().get(e.getKey());
if (req == null) {
- logger.warn("Could not find any check that satisfies requirement {}, it will not be checked",
+ logger.warn(Localization.getText("Checker.noCheckSatisfiesRequirement"),
e.getKey());
} else {
if (e.getValue().isEnabled()) {
@@ -626,31 +687,110 @@ public class Checker {
}
}
- private void checkCityModel(CityDoctorModel model, ProgressListener l) {
- Stream features = model.createFeatureStream();
- float featureSum = model.getNumberOfFeatures();
+ private void checkCityModel(CityDoctorModel model, ProgressListener l){
+ List features = model.getFeatureIds();
+
+ AtomicInteger checkedCount = new AtomicInteger(0);
// clear global errors
model.getGlobalErrors().clear();
-
- // stupid lamda with final variable restrictions
- int[] currentFeature = new int[1];
- features.forEach(co -> {
- if (config.getParserConfiguration().useLowMemoryConsumption()) {
- // no edges have been created yet, create them
- co.prepareForChecking();
+ CityObjectCache cache = model.getCache();
+ logger.trace("Setting up ThreadPool");
+ int threadCount = Runtime.getRuntime().availableProcessors() * 5;
+ ExecutorService exec = new ThreadPoolExecutor
+ (threadCount, threadCount, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
+ try{
+ long startTime = System.nanoTime();
+ ImplicitGeometryHolder.preparePrototypeGeometriesForChecking();
+
+ List> futures = runChecksOnFeatures(exec, cache, features, checkedCount, l);
+ List missedFeatures = getMissedFeatures(futures);
+
+ ImplicitGeometryHolder.clearMetaDataOfPrototypeGeometries();
+ if (!missedFeatures.isEmpty()){
+ logger.error(Localization.getText("Checker.dbUnresponsive"));
+ if (logger.isDebugEnabled()){
+ logger.debug(missedFeatures.toString());
+ }
}
- // check every feature
- executeChecksForCityObject(co);
+ long endTime = System.nanoTime();
+ if (logger.isInfoEnabled()){
+ long totalTime = (endTime - startTime) / 1_000_000; // Convert ns to ms
+ String messageString = Localization.getText("Checker.checksFinished");
+ String timeString = TimeFormatter.format(totalTime);
+ messageString = messageString.replace("{0}", timeString);
+ logger.info(messageString);
+ }
+ } catch (InterruptedException e){
+ // No interrupts implemented, so this block should actually never be entered
+ logger.error(Localization.getText("Checker.validationInterrupted"), e);
+ Thread.currentThread().interrupt();
+
+ } finally {
+ exec.shutdown();
+ try {
+ if(!exec.awaitTermination(1, TimeUnit.MINUTES)){
+ exec.shutdownNow();
+ }
- if (config.getParserConfiguration().useLowMemoryConsumption()) {
- // low memory consumption, remove edges again
- co.clearMetaInformation();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ logger.error(Localization.getText("Checker.shutdownInterrupted"));
}
- if (l != null) {
- currentFeature[0]++;
- l.updateProgress(currentFeature[0] / featureSum);
+ }
+ }
+
+ private List> runChecksOnFeatures(ExecutorService exec, CityObjectCache cache, List ids, AtomicInteger checkedCount,
+ ProgressListener l)
+ throws InterruptedException {
+ float featureSum = ids.size() + (float) checkedCount.get();
+
+ logger.trace("Queueing up Checker tasks");
+ List> tasks = new ArrayList<>();
+ for (GmlId id : ids) {
+ tasks.add(()->{
+ CityObject co = cache.get(id);
+ if (co == null) {
+ return id;
+ }
+ if(Thread.interrupted()){
+ Thread.currentThread().interrupt();
+ return null;
+ }
+ co.prepareForChecking();
+ executeChecksForCityObject(co);
+ co.clearMetaInformation();
+ cache.put(co);
+ checkedCount.incrementAndGet();
+ if (l!=null){
+ l.updateProgress((checkedCount.get()) / featureSum);
+ }
+ return null;
+ });
+ }
+ logger.trace("Queueing up finished, invoking all tasks");
+ return exec.invokeAll(tasks);
+ }
+
+ private List getMissedFeatures(List> futures) throws InterruptedException{
+ List missedList = new ArrayList<>();
+ Set errors = new HashSet<>();
+ for (Future future : futures) {
+ try{
+ GmlId gmlId = future.get();
+ if (gmlId != null) {
+ missedList.add(gmlId);
+ }
+ } catch (ExecutionException e){
+ logger.debug("A Task failed due to an unexpected exception", e);
+ logger.debug(e.getCause());
+ errors.add(e);
}
- });
+ }
+ if (!errors.isEmpty()) {
+ logger.error(Localization.getText("Checker.futuresCheckFailures"));
+ logger.error(errors.toString());
+ }
+ return missedList;
}
private boolean filterObject(CityObject co) {
@@ -756,73 +896,6 @@ public class Checker {
return hasUnusedDependency;
}
- public static void streamCheck(CityGmlZipArchive archive, String xmlDirectory, String pdfDirectory, ValidationConfiguration config,
- String outputDirectory) throws IOException, CityGmlParseException {
- streamCheck(archive, xmlDirectory, pdfDirectory, config, null, outputDirectory);
- }
-
- public static void streamCheck(CityGmlZipArchive archive, String xmlDirectory, String pdfDirectory, ValidationConfiguration config,
- FeatureCheckedListener l, String outputDirectory) throws IOException, CityGmlParseException {
-
-
- for (CityGmlZipEntry entry : archive.getEntries()) {
- String entryName = FilenameUtils.removeExtension(entry.getDisplayName());
- String xmlOutput = null;
- String pdfOutput = null;
- String outputFile = null;
- if (xmlDirectory != null) {
- xmlOutput = Path.of(xmlDirectory).resolve(entryName + "_report.xml").toString();
- }
- if (pdfDirectory != null) {
- pdfOutput = Path.of(pdfDirectory).resolve(entryName + "_report.pdf").toString();
- }
- if (outputDirectory != null) {
- outputFile = Path.of(outputDirectory).resolve(entryName + "_validated.gml").toString();
- }
-
- streamCheck(entry, xmlOutput, pdfOutput, config, l, outputFile);
-
-
- }
- if (outputDirectory != null) {
- ArchivePacker.packAndDeleteDirectory(outputDirectory);
- }
- }
-
-
- public static void streamCheck(CityGmlZipEntry entry, String xmlOutput, String pdfOutput, ValidationConfiguration config,
- String outputFile) throws IOException, CityGmlParseException {
- streamCheck(entry, xmlOutput, pdfOutput, config, null, outputFile);
- }
-
- public static void streamCheck(CityGmlZipEntry entry, String xmlOutput, String pdfOutput, ValidationConfiguration config,
- FeatureCheckedListener l, String outputFile) throws IOException, CityGmlParseException {
- try (BufferedOutputStream xmlBos = getXmlOutputMaybe(xmlOutput);
- BufferedOutputStream pdfBos = getPdfOutputMaybe(pdfOutput)) {
- Checker c = new Checker(config, null);
- String fileName = entry.getEntrySubPath();
-
- // create reporter if available
- XmlStreamReporter xmlReporter = getXmlReporter(config, xmlBos, fileName);
- PdfStreamReporter pdfReporter = getPdfReporter(config, pdfBos, fileName);
-
- // execute schematron first
- try (CityGmlZipEntryFile entryFile = new CityGmlZipEntryFile(entry)) {
- SvrlContentHandler handler = executeSchematronValidationIfAvailable(config, entryFile.getInputStream());
-
- CityGmlConsumer con = new StreamCityGmlConsumer(c, xmlReporter, pdfReporter, handler, config, l);
- // parse and validate
- CityGmlParser.streamCityGml(entry, config.getParserConfiguration(), con, outputFile);
-
- // write reports if available
- writeReport(xmlReporter);
- writeReport(pdfReporter);
- }
- } catch (CheckReportWriteException e) {
- logger.error(Localization.getText("Checker.failReports"), e);
- }
- }
-
public static void streamCheck(File inputFile, String xmlOutput, String pdfOutput, ValidationConfiguration config,
String outputFile) throws IOException, CityGmlParseException {
streamCheck(inputFile, xmlOutput, pdfOutput, config, null, outputFile);
diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/StreamCityGmlConsumer.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/StreamCityGmlConsumer.java
index c3ff365c3980e47e729bb0d2d940938cd3dcb7f0..1c542e653354490735d652f30f8ecf3f81f39d64 100644
--- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/StreamCityGmlConsumer.java
+++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/StreamCityGmlConsumer.java
@@ -134,7 +134,7 @@ public class StreamCityGmlConsumer implements CityGmlConsumer {
pdfReporter.report(co);
}
- // TODO: Update QualityADE to be compatible with CityGML 3.0 or deprecate it, unhandled top-level feature types are just skipped for now
+ // TODO: Update QualityADE to be compatible with CityGML 3.0, unhandled top-level feature types are just skipped for now
if (!(co instanceof AbstractTunnel || co instanceof CityFurniture || co instanceof GenericCityObject)) {
// store quality ade datastructures in cityobject
QualityADEUtils.writeQualityAde(co, val);
diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/CheckContainer.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/CheckContainer.java
index 8b6f2943b8f19e88a65a52fe5c41eca1cdf9ea00..7e628940ea3053a8e1dc3ff0d15d9586bde08e4c 100644
--- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/CheckContainer.java
+++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/CheckContainer.java
@@ -230,6 +230,24 @@ public class CheckContainer extends Check {
}
}
+ @Override
+ public void check(TinObject to) {
+ try {
+ check.check(to);
+ }catch (Exception e) {
+ handleException(e, to);
+ }
+ }
+
+ @Override
+ public void check(ReliefObject ro) {
+ try {
+ check.check(ro);
+ }catch (Exception e) {
+ handleException(e, ro);
+ }
+ }
+
@Override
public void check(CityFurniture cf){
try {
@@ -248,6 +266,15 @@ public class CheckContainer extends Check {
}
}
+ @Override
+ public void check(OtherConstructionObject oco) {
+ try {
+ check.check(oco);
+ }catch (Exception e) {
+ handleException(e, oco);
+ }
+ }
+
@Override
public RequirementType getType() {
return check.getType();
diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/SvrlContentHandler.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/SvrlContentHandler.java
index 78189eb9d156cec92beec11ffed6d5d9552f967b..07c583dc48ea7dfe27e73738b5c079dd828c272d 100644
--- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/SvrlContentHandler.java
+++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/SvrlContentHandler.java
@@ -106,12 +106,12 @@ public class SvrlContentHandler implements ContentHandler {
throw new IllegalStateException(
"Schematron File is not formed according to specification for CityDoctor.");
}
- String gmlId = split[0];
+ String gmlId = split[0].strip();
String childId = split[1];
String errorId = split[2];
String nameOfAttribute = split[3];
SchematronError err = new SchematronError(errorId, gmlId, childId, nameOfAttribute);
- if (gmlId == null || gmlId.isEmpty()) {
+ if (gmlId == null || gmlId.isBlank()) {
// general error
generalErrors.add(err);
} else {
diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PlanarCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PlanarCheck.java
index 560f78b5d65876a42ae9a41932f0050e342c19dd..af6dd4cc83280a9a4b454c5807339138ec15dbcf 100644
--- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PlanarCheck.java
+++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/PlanarCheck.java
@@ -57,10 +57,12 @@ import de.hft.stuttgart.citydoctor2.tesselation.TesselatedPolygon;
*/
public class PlanarCheck extends Check {
- private static final String DISTANCE = "distance";
- private static final String DISTANCE_TOLERANCE = "distanceTolerance";
+ public static final String ANGLE = "angle";
+ public static final String DISTANCE = "distance";
+ public static final String BOTH = "both";
+ public static final String DISTANCE_TOLERANCE = "distanceTolerance";
private static final String ANGLE_TOLERANCE = "angleTolerance";
- private static final String TYPE = "type";
+ public static final String TYPE = "type";
private static final List dependencies;
@@ -97,7 +99,7 @@ public class PlanarCheck extends Check {
public void check(Polygon p) {
if (DISTANCE.equals(planarCheckType)) {
planarDistance(p);
- } else if ("angle".equals(planarCheckType)) {
+ } else if (ANGLE.equals(planarCheckType)) {
planarNormalDeviation(p);
} else if ("both".equals(planarCheckType)) {
planarDistance(p);
diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheck.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheck.java
index 0eefd3498e4f95f4b290be5e3c193252e5eee90e..c911a1d7e525c8a613ff2199e8d432b52e1c17c5 100644
--- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheck.java
+++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheck.java
@@ -21,13 +21,13 @@ package de.hft.stuttgart.citydoctor2.checks.geometry;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult;
-import de.hft.stuttgart.citydoctor2.check.GeometrySelfIntersection;
import de.hft.stuttgart.citydoctor2.check.Requirement;
import de.hft.stuttgart.citydoctor2.check.RequirementType;
import de.hft.stuttgart.citydoctor2.check.ResultStatus;
@@ -36,6 +36,7 @@ import de.hft.stuttgart.citydoctor2.checks.util.CollectionUtils;
import de.hft.stuttgart.citydoctor2.checks.util.SelfIntersectionUtil;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
+import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.utils.PolygonIntersection;
/**
@@ -47,7 +48,9 @@ import de.hft.stuttgart.citydoctor2.utils.PolygonIntersection;
public class SolidSelfIntCheck extends Check {
private static final List dependencies;
-
+
+ private double delta = 0.01;
+
static {
ArrayList deps = new ArrayList<>();
dependencies = Collections.unmodifiableList(deps);
@@ -68,6 +71,13 @@ public class SolidSelfIntCheck extends Check {
deps.add(CheckId.C_GE_S_NON_MANIFOLD_VERTEX);
deps.add(CheckId.C_GE_S_POLYGON_WRONG_ORIENTATION);
}
+
+ @Override
+ public void init(Map parameters, ParserConfiguration config) {
+ if (parameters.containsKey(PlanarCheck.DISTANCE_TOLERANCE)) {
+ delta = Double.parseDouble(parameters.get(PlanarCheck.DISTANCE_TOLERANCE));
+ }
+ }
@Override
public void check(Geometry g) {
@@ -75,7 +85,7 @@ public class SolidSelfIntCheck extends Check {
return;
}
CheckResult cr;
- List intersections = SelfIntersectionUtil.calculateSolidSelfIntersection(g);
+ List intersections = SelfIntersectionUtil.calculateSolidSelfIntersection(g, delta);
if (intersections.isEmpty()) {
cr = new CheckResult(this, ResultStatus.OK, null);
} else {
@@ -85,18 +95,6 @@ public class SolidSelfIntCheck extends Check {
g.addCheckResult(cr);
}
- @SuppressWarnings("unused")
- private CheckResult oldIntersectionAlgorithm(Geometry g) {
- CheckResult cr;
- GeometrySelfIntersection intersect = SelfIntersectionUtil.doesSolidSelfIntersect(g);
- if (intersect != null) {
- cr = new CheckResult(this, ResultStatus.ERROR, null);
- } else {
- cr = new CheckResult(this, ResultStatus.OK, null);
- }
- return cr;
- }
-
@Override
public List getDependencies() {
return dependencies;
diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/util/SelfIntersectionUtil.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/util/SelfIntersectionUtil.java
index 602eb04545a19a7052a10e30eda1f7f72d45a1ca..30c5787867fc6aab977b7f2e702c9e6ac877bb72 100644
--- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/util/SelfIntersectionUtil.java
+++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/checks/util/SelfIntersectionUtil.java
@@ -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;
@@ -39,6 +40,8 @@ import org.locationtech.jts.geom.impl.CoordinateArraySequence;
import org.locationtech.jts.operation.overlay.OverlayOp;
import org.locationtech.jts.operation.overlay.snap.SnapIfNeededOverlayOp;
+import Jama.EigenvalueDecomposition;
+import Jama.Matrix;
import de.hft.stuttgart.citydoctor2.check.GeometrySelfIntersection;
import de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
@@ -50,8 +53,10 @@ import de.hft.stuttgart.citydoctor2.edge.EdgePolygon;
import de.hft.stuttgart.citydoctor2.edge.IntersectPlanarPolygons;
import de.hft.stuttgart.citydoctor2.edge.MeshSurface;
import de.hft.stuttgart.citydoctor2.edge.PolygonPolygonIntersection;
+import de.hft.stuttgart.citydoctor2.math.CovarianceMatrix;
import de.hft.stuttgart.citydoctor2.math.MovedPolygon;
import de.hft.stuttgart.citydoctor2.math.MovedRing;
+import de.hft.stuttgart.citydoctor2.math.OrthogonalRegressionPlane;
import de.hft.stuttgart.citydoctor2.math.Plane;
import de.hft.stuttgart.citydoctor2.math.PlaneSegmentIntersection;
import de.hft.stuttgart.citydoctor2.math.PlaneSegmentIntersection.Type;
@@ -83,18 +88,37 @@ public class SelfIntersectionUtil {
private SelfIntersectionUtil() {
}
-
- public static List calculateSolidSelfIntersection(Geometry g) {
+
+ public static List calculateSolidSelfIntersection(Geometry g, double delta) {
List tesselatedPolygons = new ArrayList<>();
for (Polygon p : g.getPolygons()) {
- tesselatedPolygons.add(EarcutTesselator.tesselatePolygon(p));
+ TesselatedPolygon tessPolygon = EarcutTesselator.tesselatePolygon(p);
+ for (Iterator iterator = tessPolygon.getTriangles().iterator(); iterator.hasNext();) {
+ Triangle3d t = iterator.next();
+ List vertices = new ArrayList<>(3);
+ vertices.add(t.getP1());
+ vertices.add(t.getP2());
+ vertices.add(t.getP3());
+ Vector3d centroid = CovarianceMatrix.getCentroid(vertices);
+ EigenvalueDecomposition ed = OrthogonalRegressionPlane.decompose(vertices, centroid);
+ Matrix eigenValues = ed.getD();
+ double[] eigenValuesArray = new double[3];
+ eigenValuesArray[0] = eigenValues.get(0, 0);
+ eigenValuesArray[1] = eigenValues.get(1, 1);
+ eigenValuesArray[2] = eigenValues.get(2, 2);
+ if (eigenValuesArray[1] < delta) {
+ iterator.remove();
+ }
+ }
+ tesselatedPolygons.add(tessPolygon);
}
+
List 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()));
}
@@ -103,8 +127,8 @@ 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 doesSolidSelfIntersect2(Geometry g) {
@@ -404,7 +428,7 @@ public class SelfIntersectionUtil {
return sign != 0;
}
- private static GeometrySelfIntersection selfIntersectionJava(Geometry g) {
+ private static GeometrySelfIntersection selfIntersectionJava(Geometry g, double epsilon) {
List tessPolys = new ArrayList<>();
for (Polygon p : g.getPolygons()) {
tessPolys.add(JoglTesselator.tesselatePolygon(p));
@@ -413,7 +437,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 +446,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++) {
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());
diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/XmlValidationReporter.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/XmlValidationReporter.java
index 5bf19ad3c957cb2495c1e5c27316175d1dac80f0..3c5503835fda1730e561ff6d7e6d8668c6933dcc 100644
--- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/XmlValidationReporter.java
+++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/reporting/XmlValidationReporter.java
@@ -45,33 +45,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);
- }
- for (Tunnel tunnel : model.getTunnels()) {
- streamReporter.report(tunnel);
- }
- for (CityFurniture cf : model.getCityFurniture()) {
- streamReporter.report(cf);
- }
- for (GenericCityObject gco : model.getGenericCityObjects()) {
- streamReporter.report(gco);
- }
+ model.createFeatureStream().forEach(streamReporter::report);
+
for (CheckError err : model.getGlobalErrors()) {
streamReporter.reportGlobalError(err);
}
diff --git a/CityDoctorParent/CityDoctorValidation/src/main/resources/log4j2.xml b/CityDoctorParent/CityDoctorValidation/src/main/resources/log4j2.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1b1a09f31c1dea7e13e9f9a70aa5b80703e4a8d0
--- /dev/null
+++ b/CityDoctorParent/CityDoctorValidation/src/main/resources/log4j2.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java
index 799b27307361491671017a36ef2a3b328ef713dd..cbc489abf908279d7d8e193f47b2db258495141b 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java
@@ -24,7 +24,6 @@ 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.checks.util.FeatureCheckedListener;
import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.exceptions.CityDoctorWriteException;
@@ -32,8 +31,6 @@ 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;
-import de.hft.stuttgart.citydoctor2.zip.CityGmlZipArchive;
-import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
import org.apache.commons.io.FileUtils;
import org.junit.Rule;
import org.junit.Test;
@@ -68,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 {
@@ -128,76 +125,6 @@ public class CheckerTest {
}
}
- @Test
- public void testCliZipChecking() throws IOException, CityDoctorWriteException, CityGmlParseException, InvalidGmlFileException {
- String output = folder.getRoot().toPath() + File.separator + "test";
- String pdfOutput = folder.getRoot().toPath() + File.separator + "pdf" + File.separator;
- String xmlOutput = folder.getRoot().toPath() + File.separator + "xml" + File.separator;
- try {
- String[] args = new String[10];
- args[0] = "-in";
- args[1] = "src/test/resources/zipArchive.zip";
- args[2] = "-config";
- args[3] = "src/test/resources/testConfigWithStreaming.yml";
- args[4] = "-pdfReport";
- args[5] = pdfOutput;
- args[6] = "-xmlReport";
- args[7] = xmlOutput;
- args[8] = "-out";
- args[9] = output + File.separator;
- CityDoctorValidation.main(args);
- File zipFile = new File(output + ".zip");
- File pdfDir = new File(pdfOutput);
- File xmlDir = new File(xmlOutput);
- assertTrue(zipFile.exists());
- assertTrue(pdfDir.exists());
- assertTrue(xmlDir.exists());
-
- assertTrue(pdfDir.isDirectory());
- assertTrue(xmlDir.isDirectory());
- assertEquals(5, pdfDir.listFiles().length);
- assertEquals(5, xmlDir.listFiles().length);
-
- CityGmlZipArchive cgmlArch = CityGmlZipArchive.register(output + ".zip");
- assertNotNull(cgmlArch);
- cgmlArch.mountArchive(new ParserConfiguration(8, true));
- assertEquals(5, cgmlArch.getEntries().size());
- for (CityGmlZipEntry entry : cgmlArch.getEntries()) {
- assertNotNull(entry);
- assertNull(entry.getErrorType());
- }
-
- } catch (CityGmlParseException | IOException | InvalidGmlFileException | CityDoctorWriteException e) {
- throw e;
- }
- }
-
- @Test
- public void testZipEntryChecking() throws CityGmlParseException, IOException {
- CityGmlZipArchive cgmlArch = CityGmlZipArchive.register("src/test/resources/zipArchive.zip");
- assertNotNull(cgmlArch);
- cgmlArch.mountArchive(new ParserConfiguration(8, false));
- ValidationConfiguration config = ValidationConfiguration.loadStandardValidationConfig();
- FeatureCheckedListener l = co -> {
- assertTrue("CityObject should be validated", co.isValidated());
- };
- for (CityGmlZipEntry entry : cgmlArch.getEntries()) {
- Checker.streamCheck(entry, null, null, config, l, null);
- }
- }
-
- @Test
- public void testZipArchiveChecking() throws CityGmlParseException, IOException {
- CityGmlZipArchive cgmlArch = CityGmlZipArchive.register("src/test/resources/zipArchive.zip");
- assertNotNull(cgmlArch);
- cgmlArch.mountArchive(new ParserConfiguration(8, false));
- ValidationConfiguration config = ValidationConfiguration.loadStandardValidationConfig();
- FeatureCheckedListener l = co -> {
- assertTrue(co.isValidated());
- };
- Checker.streamCheck(cgmlArch, null, null, config, l, null);
- }
-
@Test
public void testReportCreation() throws IOException, CityGmlParseException, InvalidGmlFileException {
Path tmpDir = null;
@@ -207,7 +134,7 @@ public class CheckerTest {
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.parseCityGmlFileSilently(
+ CityDoctorModel model = CityGmlParser.nestedCityGmlFileParse(
features.toString(), new ParserConfiguration(8, false));
assertNotNull(model);
Checker checker = new Checker(model);
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/FilterTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/FilterTest.java
index f3c096f0b3cb08f021f194840600b68a3ebb98bf..b8c2d3674a44ca8bef7df547432184510de971bd 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/FilterTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/FilterTest.java
@@ -45,12 +45,12 @@ public class FilterTest {
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());
@@ -65,12 +65,12 @@ public class FilterTest {
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());
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/DegeneratedPolygonCheckTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/DegeneratedPolygonCheckTest.java
index 98669c4056f985bc14c0f1e834afb584f6182bb3..7859eb72d23b80b5b4586048b7297afc1b6ce733 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/DegeneratedPolygonCheckTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/DegeneratedPolygonCheckTest.java
@@ -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;
@@ -44,6 +45,7 @@ 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 {
@@ -68,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();
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheckFalsePositiveBigMeshTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheckFalsePositiveBigMeshTest.java
index d79fed452bec668bfba03968c8bb20f24ddfde8a..20ad29a1dc48c0afc2920fb491255a60f414d072 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheckFalsePositiveBigMeshTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheckFalsePositiveBigMeshTest.java
@@ -35,7 +35,7 @@ public class SolidSelfIntCheckFalsePositiveBigMeshTest {
CityDoctorModel m = CityGmlParser.parseCityGmlFile(gml_filepath, config.getParserConfiguration());
Checker c = new Checker(config, m);
c.runChecks();
- Building building = m.getBuildings().get(0);
+ Building building = m.getBuildings().toList().get(0);
/*
* The examples have no actual self-intersections, but can contain other actual model defects.
* If an error is detected, it is thus required to check if the
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheckTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheckTest.java
index 847de23fb231a38b6160cf06f45a707edbc3a475..7531268e16c20e9ad90704c0258859877af339ac 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheckTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/SolidSelfIntCheckTest.java
@@ -25,14 +25,18 @@ import static org.junit.Assert.assertNotNull;
import org.junit.Assert;
import org.junit.Test;
+import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.Checker;
import de.hft.stuttgart.citydoctor2.check.ResultStatus;
import de.hft.stuttgart.citydoctor2.check.ValidationConfiguration;
+import de.hft.stuttgart.citydoctor2.check.error.NonPlanarPolygonDistancePlaneError;
import de.hft.stuttgart.citydoctor2.checks.util.GeometryTestUtils;
import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
+import de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
+import de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException;
@@ -45,6 +49,22 @@ import de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException;
*
*/
public class SolidSelfIntCheckTest {
+
+ @Test
+ public void testDependencyChecking() {
+ Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD2, Orientation.OUTWARD);
+
+ ConcretePolygon p = new ConcretePolygon();
+ geom.addPolygon(p);
+ NonPlanarPolygonDistancePlaneError err = new NonPlanarPolygonDistancePlaneError(p, 2, null, null);
+ CheckResult cr = new CheckResult(CheckId.C_GE_P_NON_PLANAR, ResultStatus.ERROR, err);
+ p.addCheckResult(cr);
+
+ SolidSelfIntCheck selfIntCheck = new SolidSelfIntCheck();
+
+ boolean canExecute = selfIntCheck.canExecute(geom);
+ assertFalse(canExecute);
+ }
@Test
public void testGoodGeometry() {
@@ -75,7 +95,7 @@ public class SolidSelfIntCheckTest {
CityDoctorModel m = CityGmlParser.parseCityGmlFile("src/test/resources/SolidSelfIntTest1.gml", config.getParserConfiguration());
Checker c = new Checker(config, m);
c.runChecks();
- assertFalse(m.getBuildings().get(0).containsAnyError());
+ assertFalse(m.getBuildings().toList().get(0).containsAnyError());
}
@@ -85,7 +105,7 @@ public class SolidSelfIntCheckTest {
CityDoctorModel m = CityGmlParser.parseCityGmlFile(gml_filepath, config.getParserConfiguration());
Checker c = new Checker(config, m);
c.runChecks();
- Building building = m.getBuildings().get(0);
+ Building building = m.getBuildings().toList().get(0);
/*
* The examples have no actual self-intersections, but can contain other actual model defects.
* If an error is detected, it is thus required to check if the
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/AllPolygonWrongOrientedTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/AllPolygonWrongOrientedTest.java
index e941df1946461dc80fc2d51912529b4e535f4cf5..e96b4e45f807843d4c9e921572e605cc9184e136 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/AllPolygonWrongOrientedTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/AllPolygonWrongOrientedTest.java
@@ -48,7 +48,7 @@ public class AllPolygonWrongOrientedTest {
Checker c = new Checker(config, model);
c.runChecks();
- Building b = model.getBuildings().get(0);
+ Building b = model.getBuildings().toList().get(0);
assertFalse(b.containsError(CheckId.C_GE_S_ALL_POLYGONS_WRONG_ORIENTATION));
}
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/ConCompCheckTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/ConCompCheckTest.java
index 2a8c1317fd1397912446ca11abac4c2e899376f1..b9a508095bc3da244bc2e932b787c30a976fc877 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/ConCompCheckTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/ConCompCheckTest.java
@@ -51,7 +51,7 @@ public class ConCompCheckTest extends TestCleanUp {
Checker c = new Checker(m);
c.runChecks();
- Geometry geom = m.getBuildings().get(0).getGeometries().get(0);
+ Geometry geom = m.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = geom.getCheckResult(CheckId.C_GE_S_MULTIPLE_CONNECTED_COMPONENTS);
assertNotNull(cr);
assertEquals(ResultStatus.ERROR, cr.getResultStatus());
@@ -65,7 +65,7 @@ public class ConCompCheckTest extends TestCleanUp {
Checker c = new Checker(m);
c.runChecks();
- Geometry geom = m.getBuildings().get(0).getGeometries().get(0);
+ Geometry geom = m.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = geom.getCheckResult(CheckId.C_GE_S_MULTIPLE_CONNECTED_COMPONENTS);
assertNotNull(cr);
assertEquals(ResultStatus.ERROR, cr.getResultStatus());
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/DupPointsCheckTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/DupPointsCheckTest.java
index 924c651ee8c38889a9f2887df4176de0c6475883..2720b0114a11b59726ebc232f82d8d92b3261b53 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/DupPointsCheckTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/DupPointsCheckTest.java
@@ -79,7 +79,7 @@ public class DupPointsCheckTest {
@Test
public void testDupPoints3() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel m = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS.gml");
- for (Polygon p : m.getBuildings().get(0).getGeometries().get(0).getPolygons()) {
+ for (Polygon p : m.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
LinearRing r = p.getExteriorRing();
CheckResult cr = r.getCheckResult(CheckId.C_GE_R_DUPLICATE_POINT);
assertEquals(ResultStatus.OK, cr.getResultStatus());
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/HoleOutsideSystemTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/HoleOutsideSystemTest.java
index 89072edcdf00906f4b6635788ae09b49ad4b85dc..dd603053ca7d71ec338650570a4989b8e03442c5 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/HoleOutsideSystemTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/HoleOutsideSystemTest.java
@@ -43,7 +43,7 @@ public class HoleOutsideSystemTest {
@Test
public void testHoleOutside1() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0001-T0002.gml");
- for (Polygon p : c.getBuildings().get(0).getGeometries().get(0).getPolygons()) {
+ for (Polygon p : c.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
CheckResult cr = p.getCheckResult(CheckId.C_GE_P_HOLE_OUTSIDE);
assertEquals(ResultStatus.OK, cr.getResultStatus());
}
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/InnerRingsNestedSystemTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/InnerRingsNestedSystemTest.java
index 6ae1d4784e4694fca61c2728298ab73ecfaae070..ca2982e97cb2eb608b6d5d647e73d5e8adf88178 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/InnerRingsNestedSystemTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/InnerRingsNestedSystemTest.java
@@ -43,7 +43,7 @@ public class InnerRingsNestedSystemTest {
@Test
public void innerRingsNested1() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0001-T0002.gml");
- for (Polygon p : c.getBuildings().get(0).getGeometries().get(0).getPolygons()) {
+ for (Polygon p : c.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
CheckResult cr = p.getCheckResult(CheckId.C_GE_P_INNER_RINGS_NESTED);
assertEquals(ResultStatus.OK, cr.getResultStatus());
}
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/InteriorDisconnectedSystemTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/InteriorDisconnectedSystemTest.java
index 4ddd49c4c80c84e52affbea83eb11ee17edffe3e..9d7ac4466eebb596fd1b1613417469896156535c 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/InteriorDisconnectedSystemTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/InteriorDisconnectedSystemTest.java
@@ -43,7 +43,7 @@ public class InteriorDisconnectedSystemTest {
@Test
public void testInteriorDisconnected1() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0001-T0002.gml");
- for (Polygon p : c.getBuildings().get(0).getGeometries().get(0).getPolygons()) {
+ for (Polygon p : c.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
CheckResult cr = p.getCheckResult(CheckId.C_GE_P_INTERIOR_DISCONNECTED);
assertEquals(ResultStatus.OK, cr.getResultStatus());
}
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/MultipleComponentTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/MultipleComponentTest.java
index 33aaafbd829182bd8152eb799c73c212f783bdaf..f958a9e023b454ea27fa45704913fc418fa23919 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/MultipleComponentTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/MultipleComponentTest.java
@@ -43,7 +43,7 @@ public class MultipleComponentTest {
@Test
public void testNoMultipleComponents() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS.gml");
- Geometry g = c.getBuildings().get(0).getGeometries().get(0);
+ Geometry g = c.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = g.getCheckResult(CheckId.C_GE_S_MULTIPLE_CONNECTED_COMPONENTS);
assertEquals(ResultStatus.OK, cr.getResultStatus());
}
@@ -51,7 +51,7 @@ public class MultipleComponentTest {
@Test
public void testMultipleComponents() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-SO-0005-T0001.gml");
- Geometry g = c.getBuildings().get(0).getGeometries().get(0);
+ Geometry g = c.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = g.getCheckResult(CheckId.C_GE_S_MULTIPLE_CONNECTED_COMPONENTS);
assertEquals(ResultStatus.ERROR, cr.getResultStatus());
assertEquals(ErrorId.GE_S_MULTIPLE_CONNECTED_COMPONENTS, cr.getError().getErrorId());
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NonManifoldEdgeSystemTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NonManifoldEdgeSystemTest.java
index 66e121b26da26a57fe8ad9d8026d41cbfcefa56e..597bd46268887d78054d80c6a751f5e2d2bc3221 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NonManifoldEdgeSystemTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NonManifoldEdgeSystemTest.java
@@ -46,7 +46,7 @@ public class NonManifoldEdgeSystemTest {
@Test
public void testNonManifoldEdge1() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS.gml");
- Geometry g = c.getBuildings().get(0).getGeometries().get(0);
+ Geometry g = c.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = g.getCheckResult(CheckId.C_GE_S_NON_MANIFOLD_EDGE);
assertEquals(ResultStatus.OK, cr.getResultStatus());
}
@@ -59,7 +59,7 @@ public class NonManifoldEdgeSystemTest {
paramMap.put(RequirementId.R_GE_P_NON_PLANAR.toString(), parameter);
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-SO-0004-T0001.gml",
paramMap);
- Geometry g = c.getBuildings().get(0).getGeometries().get(0);
+ Geometry g = c.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = g.getCheckResult(CheckId.C_GE_S_NON_MANIFOLD_EDGE);
assertEquals(ResultStatus.ERROR, cr.getResultStatus());
assertEquals(ErrorId.GE_S_NON_MANIFOLD_EDGE, cr.getError().getErrorId());
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NonManifoldVertexSystemTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NonManifoldVertexSystemTest.java
index 127745410d707602a3238b97d3f377516ed9bb0e..9ab2e229831157a09dd6652d0163384f88169fcd 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NonManifoldVertexSystemTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NonManifoldVertexSystemTest.java
@@ -43,7 +43,7 @@ public class NonManifoldVertexSystemTest {
@Test
public void testNonManifoldVertex1() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS.gml");
- Geometry g = c.getBuildings().get(0).getGeometries().get(0);
+ Geometry g = c.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = g.getCheckResult(CheckId.C_GE_S_NON_MANIFOLD_VERTEX);
assertEquals(ResultStatus.OK, cr.getResultStatus());
}
@@ -51,7 +51,7 @@ public class NonManifoldVertexSystemTest {
@Test
public void testNonManifoldVertex2() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-SO-0003-T0001.gml");
- Geometry g = c.getBuildings().get(0).getGeometries().get(0);
+ Geometry g = c.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = g.getCheckResult(CheckId.C_GE_S_NON_MANIFOLD_VERTEX);
assertEquals(ResultStatus.ERROR, cr.getResultStatus());
assertEquals(ErrorId.GE_S_NON_MANIFOLD_VERTEX, cr.getError().getErrorId());
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NumPointsCheckTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NumPointsCheckTest.java
index 2a1a6b37d2d32728b0de55f5583988365cbc5225..22c2c426a3a148e5380d8b36992e0086f6e1904d 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NumPointsCheckTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/NumPointsCheckTest.java
@@ -80,7 +80,7 @@ public class NumPointsCheckTest {
public void testNumPoints3() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS.gml");
- for (Polygon p : c.getBuildings().get(0).getGeometries().get(0).getPolygons()) {
+ for (Polygon p : c.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
LinearRing r = p.getExteriorRing();
assertEquals(ResultStatus.OK, r.getCheckResult(CheckId.C_GE_R_TOO_FEW_POINTS).getResultStatus());
}
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/OrientationSameSystemTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/OrientationSameSystemTest.java
index 687871312622bfb2d9e62a02b078ccb39272e1ce..1e3b3a5654224f008766778db5619aafc79af121 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/OrientationSameSystemTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/OrientationSameSystemTest.java
@@ -43,7 +43,7 @@ public class OrientationSameSystemTest {
@Test
public void testOrientationSame1() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0001-T0002.gml");
- for (Polygon p : c.getBuildings().get(0).getGeometries().get(0).getPolygons()) {
+ for (Polygon p : c.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
CheckResult cr = p.getCheckResult(CheckId.C_GE_P_ORIENTATION_RINGS_SAME);
assertEquals(ResultStatus.OK, cr.getResultStatus());
}
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/OuterEdgeCheckTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/OuterEdgeCheckTest.java
index 2b6af2fbd2a172f34a39a5514fc09cdc49535a99..08e88d65c4dcfaff34f514a871c7ec49b683a84c 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/OuterEdgeCheckTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/OuterEdgeCheckTest.java
@@ -71,7 +71,7 @@ public class OuterEdgeCheckTest {
expectedErrorEdges.add(new Vertex(1.0, 0.0, 3.5));
expectedErrorEdges.add(new Vertex(2.0, 0.0, 3.0));
- Geometry geom = m.getBuildings().get(0).getGeometries().get(0);
+ Geometry geom = m.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = geom.getCheckResult(CheckId.C_GE_S_NOT_CLOSED);
Assert.assertEquals(ResultStatus.ERROR, cr.getResultStatus());
}
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/PlanarTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/PlanarTest.java
index f15f12899d9e5fe4fa7de10e8c0bfbb2cc1e8927..34d69e7adf6cab6e945571b2308cb9a1d1ecbea9 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/PlanarTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/PlanarTest.java
@@ -31,6 +31,7 @@ import de.hft.stuttgart.citydoctor2.check.CheckResult;
import de.hft.stuttgart.citydoctor2.check.Checker;
import de.hft.stuttgart.citydoctor2.check.ErrorId;
import de.hft.stuttgart.citydoctor2.check.ResultStatus;
+import de.hft.stuttgart.citydoctor2.checks.geometry.PlanarCheck;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.parser.CityGmlParseException;
@@ -106,7 +107,7 @@ public class PlanarTest {
@Test
public void testPlanarPolygon3() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0001-T0002.gml");
- for (Polygon p : c.getBuildings().get(0).getGeometries().get(0).getPolygons()) {
+ for (Polygon p : c.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
CheckResult cr = p.getCheckResult(CheckId.C_GE_P_NON_PLANAR);
assertEquals(ResultStatus.OK, cr.getResultStatus());
}
@@ -142,7 +143,7 @@ public class PlanarTest {
public void testPlanarPolygon6() throws CityGmlParseException, IOException, InvalidGmlFileException {
Map> paramMap = new HashMap<>();
Map parameter = new HashMap<>();
- parameter.put("type", "both");
+ parameter.put(PlanarCheck.TYPE, PlanarCheck.BOTH);
parameter.put("distanceTolerance", "0.5");
paramMap.put(RequirementId.R_GE_P_NON_PLANAR.toString(), parameter);
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0002-T0002.gml", paramMap);
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/PolygonIntersectingRingsTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/PolygonIntersectingRingsTest.java
index a4dadfb38a6e97e1c956ef6cd60103e5860eb76c..a18ed09e06bc2c145e9dec3f36f4a0a7db8d5e8c 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/PolygonIntersectingRingsTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/PolygonIntersectingRingsTest.java
@@ -43,7 +43,7 @@ public class PolygonIntersectingRingsTest {
@Test
public void testSelfIntPolygon1() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS.gml");
- for (Polygon p : c.getBuildings().get(0).getGeometries().get(0).getPolygons()) {
+ for (Polygon p : c.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
CheckResult cr = p.getCheckResult(CheckId.C_GE_P_INTERSECTING_RINGS);
assertEquals(ResultStatus.OK, cr.getResultStatus());
}
@@ -52,7 +52,7 @@ public class PolygonIntersectingRingsTest {
@Test
public void testSelfIntPolygon2() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-PO-0001-T0002.gml");
- for (Polygon p : c.getBuildings().get(0).getGeometries().get(0).getPolygons()) {
+ for (Polygon p : c.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
CheckResult cr = p.getCheckResult(CheckId.C_GE_P_INTERSECTING_RINGS);
assertEquals(ResultStatus.OK, cr.getResultStatus());
}
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/RingClosedCheckTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/RingClosedCheckTest.java
index 7cdf629c77a367b0710818316998cda025922d23..9be6709e7073afe043ecd108f50b45cdb5cb11da 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/RingClosedCheckTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/RingClosedCheckTest.java
@@ -91,7 +91,7 @@ public class RingClosedCheckTest extends TestCleanUp {
@Test
public void testClosedRing3() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS.gml");
- for (Polygon p : c.getBuildings().get(0).getGeometries().get(0).getPolygons()) {
+ for (Polygon p : c.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
LinearRing r = p.getExteriorRing();
CheckResult cr = r.getCheckResult(CheckId.C_GE_R_NOT_CLOSED);
assertEquals(ResultStatus.OK, cr.getResultStatus());
@@ -111,7 +111,7 @@ public class RingClosedCheckTest extends TestCleanUp {
@Test
public void testClosedRing5() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-LR-0003-T0002.gml", 1);
- for (Polygon p : c.getBuildings().get(0).getGeometries().get(0).getPolygons()) {
+ for (Polygon p : c.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
LinearRing r = p.getExteriorRing();
CheckResult cr = r.getCheckResult(CheckId.C_GE_R_NOT_CLOSED);
assertEquals(ResultStatus.OK, cr.getResultStatus());
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/RingSelfIntersectionTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/RingSelfIntersectionTest.java
index 9b9da948f78a732cdc34a8845c9eff50d0a0b7b0..76e04e9678c57217d1498bab03555ff071a4a200 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/RingSelfIntersectionTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/RingSelfIntersectionTest.java
@@ -101,7 +101,7 @@ public class RingSelfIntersectionTest {
@Test
public void testSelfIntPoints4() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS.gml");
- for (Polygon p : c.getBuildings().get(0).getGeometries().get(0).getPolygons()) {
+ for (Polygon p : c.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
LinearRing r = p.getExteriorRing();
CheckResult cr = r.getCheckResult(CheckId.C_GE_R_SELF_INTERSECTION);
assertEquals(ResultStatus.OK, cr.getResultStatus());
@@ -131,7 +131,7 @@ public class RingSelfIntersectionTest {
@Test
public void testSelfIntPoints7() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-LR-0004-T0005.gml", 2);
- for (Polygon p : c.getBuildings().get(0).getGeometries().get(0).getPolygons()) {
+ for (Polygon p : c.getBuildings().toList().get(0).getGeometries().get(0).getPolygons()) {
LinearRing r = p.getExteriorRing();
CheckResult cr = r.getCheckResult(CheckId.C_GE_R_SELF_INTERSECTION);
assertEquals(ResultStatus.OK, cr.getResultStatus());
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/ShellNotClosedSystemTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/ShellNotClosedSystemTest.java
index e26695bc98e1efd20b3b4a24e5bc4ca679621f65..f51002491191f94c40fc8c6c78075c8b9c45fa94 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/ShellNotClosedSystemTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/ShellNotClosedSystemTest.java
@@ -43,7 +43,7 @@ public class ShellNotClosedSystemTest {
@Test
public void testShellNotClosed1() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS.gml");
- Geometry g = c.getBuildings().get(0).getGeometries().get(0);
+ Geometry g = c.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = g.getCheckResult(CheckId.C_GE_S_NOT_CLOSED);
assertEquals(ResultStatus.OK, cr.getResultStatus());
}
@@ -51,7 +51,7 @@ public class ShellNotClosedSystemTest {
@Test
public void testShellNotClosed2() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-SO-0002-T0001.gml");
- Geometry g = c.getBuildings().get(0).getGeometries().get(0);
+ Geometry g = c.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = g.getCheckResult(CheckId.C_GE_S_NOT_CLOSED);
assertEquals(ResultStatus.ERROR, cr.getResultStatus());
assertEquals(ErrorId.GE_S_NOT_CLOSED, cr.getError().getErrorId());
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/TestUtil.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/TestUtil.java
index f1dd8d201d058926dd928d853bb6ebd597ed94aa..48e82e8da7de8706294bfe7d1a34c7d14c7ddb5a 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/TestUtil.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/TestUtil.java
@@ -22,6 +22,7 @@ import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Optional;
import de.hft.stuttgart.citydoctor2.check.Checker;
import de.hft.stuttgart.citydoctor2.check.ValidationConfiguration;
@@ -89,15 +90,16 @@ public class TestUtil {
if (gmlId == null) {
return null;
}
- Polygon result = getPolygonById(gmlId, model.getBuildings());
+ Polygon result = getPolygonById(gmlId, model.getBuildings().toList());
+
if (result != null) {
return result;
}
- result = getPolygonById(gmlId, model.getVegetation());
+ result = getPolygonById(gmlId, model.getVegetation().toList());
if (result != null) {
return result;
}
- return getPolygonById(gmlId, model.getTransportation());
+ return getPolygonById(gmlId, model.getTransportation().toList());
}
private static Polygon getPolygonById(String gmlId, List extends CityObject> features) {
@@ -136,22 +138,17 @@ public class TestUtil {
if (featureId == null) {
return null;
}
- for (CityObject co : model.getBuildings()) {
- if (featureId.equals(co.getGmlId().getGmlString())) {
- return co;
- }
+ Optional extends CityObject> result = null;
+ result = model.getBuildings().filter(b -> featureId.equals(b.getGmlId().toString())).findFirst();
+ if (result.isPresent()){
+ return result.get();
}
- for (CityObject co : model.getTransportation()) {
- if (featureId.equals(co.getGmlId().getGmlString())) {
- return co;
- }
+ result = model.getTransportation().filter(t-> featureId.equals(t.getGmlId().toString())).findFirst();
+ if (result.isPresent()){
+ return result.get();
}
- for (CityObject co : model.getVegetation()) {
- if (featureId.equals(co.getGmlId().getGmlString())) {
- return co;
- }
- }
- return null;
- }
+ result = model.getVegetation().filter(t-> featureId.equals(t.getGmlId().toString())).findFirst();
+ return result.orElse(null);
+ }
}
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/TooFewPolygonsSystemTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/TooFewPolygonsSystemTest.java
index 4cf0caa6bbcaf7691a942e00a674f678f9c19ca9..0bf43727b8b99291d8df8a2d6c16e25f758fa486 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/TooFewPolygonsSystemTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/systemtest/TooFewPolygonsSystemTest.java
@@ -43,7 +43,7 @@ public class TooFewPolygonsSystemTest {
@Test
public void testTooFewPolygons1() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS.gml");
- Geometry g = c.getBuildings().get(0).getGeometries().get(0);
+ Geometry g = c.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = g.getCheckResult(CheckId.C_GE_S_TOO_FEW_POLYGONS);
assertEquals(ResultStatus.OK, cr.getResultStatus());
}
@@ -51,7 +51,7 @@ public class TooFewPolygonsSystemTest {
@Test
public void testTooFewPolygons2() throws CityGmlParseException, IOException, InvalidGmlFileException {
CityDoctorModel c = TestUtil.loadAndCheckCityModel("src/test/resources/SimpleSolid_SrefBS-GE-gml-SO-0001-T0001.gml");
- Geometry g = c.getBuildings().get(0).getGeometries().get(0);
+ Geometry g = c.getBuildings().toList().get(0).getGeometries().get(0);
CheckResult cr = g.getCheckResult(CheckId.C_GE_S_TOO_FEW_POLYGONS);
assertEquals(ResultStatus.ERROR, cr.getResultStatus());
assertEquals(ErrorId.GE_S_TOO_FEW_POLYGONS, cr.getError().getErrorId());
diff --git a/CityDoctorParent/Extensions/CityDoctorAutoPro/pom.xml b/CityDoctorParent/Extensions/CityDoctorAutoPro/pom.xml
index 52eb30300a1e7c9c0e4598c22aad858328aedfee..ec1f300cee9974e688d6e4f4f7c4f9b11953cd7a 100644
--- a/CityDoctorParent/Extensions/CityDoctorAutoPro/pom.xml
+++ b/CityDoctorParent/Extensions/CityDoctorAutoPro/pom.xml
@@ -6,7 +6,7 @@
de.hft.stuttgart
CityDoctorParent
- 3.17.3
+ 3.18.0
../../pom.xml
CityDoctorAutoPro
diff --git a/CityDoctorParent/Extensions/CityDoctorGUI/pom.xml b/CityDoctorParent/Extensions/CityDoctorGUI/pom.xml
index 2b07c026a5b412210ccdb584563acf42de815420..01e74c250d42360399c1b8c6ba2c73ee5ed30856 100644
--- a/CityDoctorParent/Extensions/CityDoctorGUI/pom.xml
+++ b/CityDoctorParent/Extensions/CityDoctorGUI/pom.xml
@@ -6,7 +6,7 @@
de.hft.stuttgart
CityDoctorParent
- 3.17.3
+ 3.18.0
../../pom.xml
CityDoctorGUI
diff --git a/CityDoctorParent/Extensions/CityDoctorGUI/src/assembly/lin/start.sh b/CityDoctorParent/Extensions/CityDoctorGUI/src/assembly/lin/start.sh
index 7066c344eb2e03374306ed7d4516f62581120c98..90ce022066ddab661b7acb4f12e3bc86ec60930c 100644
--- a/CityDoctorParent/Extensions/CityDoctorGUI/src/assembly/lin/start.sh
+++ b/CityDoctorParent/Extensions/CityDoctorGUI/src/assembly/lin/start.sh
@@ -1,2 +1,2 @@
-#!/bin/sh
-./runtime/bin/java -classpath app/*:plugin/* de.hft.stuttgart.citydoctor2.gui.CityDoctorGUIStarter
\ No newline at end of file
+#! /usr/bin/env sh
+java -classpath "app/*:plugin/*" de.hft.stuttgart.citydoctor2.gui.CityDoctorGUIStarter
diff --git a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/CheckDialog.java b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/CheckDialog.java
index 23ae6271bcbd5cd62f8fde072e25fd3ad19ac852..fdfd46aa8bd4cf48fccf75346bf64936d7bd1a9d 100644
--- a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/CheckDialog.java
+++ b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/CheckDialog.java
@@ -11,6 +11,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import de.hft.stuttgart.citydoctor2.parser.ProgressListener;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.Alert;
@@ -139,8 +140,6 @@ public class CheckDialog {
@FXML
private Label schematronFileLabel;
- @FXML
- private VBox zipArchiveOptionsVBox;
@FXML
private CheckBox streamCheckOption;
@FXML
@@ -161,7 +160,6 @@ public class CheckDialog {
private CityDoctorController controller;
private FilterPane filterPane;
private MainWindow window;
- private boolean zipArchiveMode;
public CheckDialog(MainWindow window, Window parent, CityDoctorController controller) throws IOException {
this.window = window;
@@ -181,7 +179,6 @@ public class CheckDialog {
}
public void initialize() {
- setupZipArchiveOptions();
createEnableColumn(geometricTable);
createNameColumn(geometricTable);
@@ -286,46 +283,6 @@ public class CheckDialog {
});
}
- private void setupZipArchiveOptions() {
- streamCheckOption.selectedProperty().addListener(new ChangeListener() {
- @Override
- public void changed(ObservableValue extends Boolean> observable, Boolean oldValue, Boolean newValue) {
- streamCheckParametersVBox.setDisable(!streamCheckOption.isSelected());
- }
- });
-
- outputPathBtn.setOnAction(e -> {
- DirectoryChooser directoryChooser = new DirectoryChooser();
- directoryChooser.setInitialDirectory(Path.of(Settings.get(Settings.LAST_OPEN_FOLDER)).getParent().toFile());
- File f = directoryChooser.showDialog(stage.getOwner());
- if (f != null) {
- outputPathTextField.setText(f.getAbsolutePath());
- Settings.set(Settings.LAST_OPEN_FOLDER, f.getAbsolutePath());
- }
-
-
- });
-
- streamCheckOption.setText(Localization.getText("CheckDialog.streamCheckOption"));
- streamCheckLabel.setTooltip(new Tooltip(Localization.getText("CheckDialog.streamCheckLabel")));
- outputPathLabel.setText(Localization.getText("CheckDialog.outputPathLabel"));
- outputPathBtn.setText(Localization.getText("CheckDialog.outputPathBtn"));
- pdfReportsOption.setText(Localization.getText("CheckDialog.pdfReportsOption"));
- xmlReportsOption.setText(Localization.getText("CheckDialog.xmlReportsOption"));
-
- showZipArchiveOptions(false);
- }
-
- /**
- * Shows the option panel for ZIP-Archive checking and enables the ZIP-Archive checking mode for this dialog.
- *
- * @param enabled
- */
- public void showZipArchiveOptions(boolean enabled) {
- zipArchiveOptionsVBox.setDisable(!enabled);
- zipArchiveOptionsVBox.setVisible(enabled);
- zipArchiveMode = enabled;
- }
private void setupSelectButton() {
selectBtn.setOnAction(ae -> {
@@ -494,25 +451,13 @@ public class CheckDialog {
String startingChecks = Localization.getText("CheckDialog.startingChecks");
logger.info(startingChecks);
}
- if (zipArchiveMode) {
- Path outputPath = null;
- if (streamCheckOption.isSelected()) {
- if (outputPathTextField.getText().isEmpty()) {
- Alert warning = new Alert(Alert.AlertType.ERROR);
- warning.setTitle("Error");
- warning.setContentText(Localization.getText("CheckDialog.noPathError"));
- warning.showAndWait();
- return;
- }
- outputPath = Path.of(outputPathTextField.getText());
- Platform.runLater(() -> progress.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS));
+ ProgressListener l = new ProgressListener() {
+ @Override
+ public void updateProgress(float state) {
+ Platform.runLater(() -> progress.setProgress(state));
}
- controller.startZipFileChecks(config, progress::setProgress, streamCheckOption.isSelected(),
- outputPath, pdfReportsOption.isSelected(),
- xmlReportsOption.isSelected());
- } else {
- controller.startChecks(config, progress::setProgress);
- }
+ };
+ controller.startChecks(config, l);
if (logger.isInfoEnabled()) {
String checksDone = Localization.getText("CheckDialog.checksDone");
diff --git a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/CityDoctorController.java b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/CityDoctorController.java
index fd4320d151d592a80b308899e5d09ac3a3d691fe..3d68b2fc379bdc485c302cccebcafe16ae69f9b1 100644
--- a/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/CityDoctorController.java
+++ b/CityDoctorParent/Extensions/CityDoctorGUI/src/main/java/de/hft/stuttgart/citydoctor2/gui/CityDoctorController.java
@@ -5,6 +5,7 @@ import de.hft.stuttgart.citydoctor2.check.Checker;
import de.hft.stuttgart.citydoctor2.check.ErrorId;
import de.hft.stuttgart.citydoctor2.check.ValidationConfiguration;
import de.hft.stuttgart.citydoctor2.check.error.SchematronError;
+import de.hft.stuttgart.citydoctor2.database.UnconnectedCache;
import de.hft.stuttgart.citydoctor2.datastructure.*;
import de.hft.stuttgart.citydoctor2.exceptions.CityDoctorWriteException;
import de.hft.stuttgart.citydoctor2.gui.table.ErrorStat;
@@ -16,15 +17,11 @@ import de.hft.stuttgart.citydoctor2.gui.tree.node.OpeningNode;
import de.hft.stuttgart.citydoctor2.gui.tree.node.TopLevelCityObjectNode;
import de.hft.stuttgart.citydoctor2.mapper.citygml3.GMLValidationHandler;
import de.hft.stuttgart.citydoctor2.parser.*;
-import de.hft.stuttgart.citydoctor2.utils.ArchivePacker;
import de.hft.stuttgart.citydoctor2.utils.Localization;
-import de.hft.stuttgart.citydoctor2.zip.CityGmlZipArchive;
-import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
-import de.hft.stuttgart.citydoctor2.zip.MalformedZipFileException;
+import de.hft.stuttgart.quality.adapter.types.ErrorAdapter;
import javafx.application.Platform;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
-import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.TreeItem;
@@ -32,22 +29,18 @@ import javafx.scene.control.TreeView;
import javafx.scene.paint.Color;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.citygml4j.core.model.core.CityModel;
import org.xml.sax.SAXParseException;
-import java.awt.*;
import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
import java.util.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
public class CityDoctorController {
@@ -60,9 +53,7 @@ public class CityDoctorController {
private CityDoctorModel model;
private ParserConfiguration currentConfig;
private String sourceFile;
- private CityGmlZipArchive zipArchive;
- private ZipEntryManager currentZipEntryManager;
- private HashMap previousCheckers = null;
+
private Checker currentChecker;
private HighlightController highlightController;
@@ -77,7 +68,9 @@ public class CityDoctorController {
private AtomicInteger waterChunkNr = new AtomicInteger(0);
private AtomicInteger landChunkNr = new AtomicInteger(0);
private AtomicInteger cityFurnitureChunkNr = new AtomicInteger(0);
- private AtomicInteger genericCityObjectsChunkNr = new AtomicInteger(0);
+ private AtomicInteger otherCityObjectsChunkNr = new AtomicInteger(0);
+
+
public CityDoctorController(MainWindow mainWindow, HighlightController highlightController, Renderer renderer) {
this.mainWindow = mainWindow;
@@ -95,7 +88,7 @@ public class CityDoctorController {
try {
Platform.runLater(() -> {
mainWindow.getOpenBtn().setDisable(true);
- mainWindow.getZipManagerBtn().setDisable(true);
+
mainWindow.getWriteReportButton().setDisable(true);
mainWindow.getMeshGroup().getChildren().clear();
@@ -103,12 +96,6 @@ public class CityDoctorController {
mainWindow.resetSearchBar();
mainWindow.resetFilterComboBox();
});
- if (path.endsWith(".zip")) {
- loadCityGmlZipFile(path, numberOfRoundingPlaces, useValidation, lowMemory);
- return;
- }
- currentZipEntryManager = null;
- previousCheckers = null;
currentChecker = null;
currentConfig = new ParserConfiguration(numberOfRoundingPlaces, useValidation, lowMemory);
GMLValidationHandler handler = null;
@@ -135,7 +122,7 @@ public class CityDoctorController {
}
};
}
- model = CityGmlParser.parseCityGmlFile(path, currentConfig, l, handler, true);
+ model = CityGmlParser.parseCityGmlFile(path, currentConfig, l, handler);
if (!validationIssues.isEmpty()) {
StringJoiner sj = new StringJoiner("\n");
validationIssues.stream().forEach(sj::add);
@@ -155,120 +142,30 @@ public class CityDoctorController {
mainWindow.getSaveBtn().setDisable(false);
mainWindow.getResetCameraBtn().setDisable(false);
mainWindow.getHideRoofBtn().setDisable(false);
- mainWindow.getZipManagerBtn().setDisable(true);
- mainWindow.getNorthArrow().setVisible(true);
- mainWindow.alignNorthArrow();
- setupFeatureTabs();
- buildTrees();
- });
- } finally {
- Platform.runLater(() -> mainWindow.getOpenBtn().setDisable(false));
- }
- }
-
- private void loadCityGmlZipFile(String path, int numberOfRoundingPlaces, boolean useValidation,
- boolean lowMemory) {
-
- currentConfig = new ParserConfiguration(numberOfRoundingPlaces, useValidation, lowMemory);
- try {
- zipArchive = CityGmlZipArchive.register(path);
- } catch (MalformedZipFileException e) {
- Platform.runLater(() -> {
- Alert alert = new Alert(Alert.AlertType.ERROR, e.getMessage());
- alert.showAndWait();
- });
- } catch (Exception e) {
- Platform.runLater(() -> {
- ExceptionDialog exDialog = new ExceptionDialog();
- exDialog.show(e);
- });
- }
-
- if (zipArchive != null) {
- previousCheckers = new HashMap<>();
- Platform.runLater(() -> {
- try {
- currentZipEntryManager = new ZipEntryManager(mainWindow.getMainStage(), this);
- currentZipEntryManager.show();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- });
- }
- }
-
- public void decompressZipEntry(CityGmlZipEntry entry, ProgressListener l) {
- entry.loadEntry(currentConfig, l);
- }
-
- public CityGmlZipArchive getZipArchive() {
- return zipArchive;
- }
-
- public void loadZipEntry(CityGmlZipEntry entry) {
- if (!entry.isLoaded()) {
- entry.loadEntry(currentConfig);
- }
- if (entry.getErrorType() != null) {
- throw new IllegalArgumentException("Attempted to load erroneous zip entry");
- }
- try {
- Platform.runLater(() -> {
- mainWindow.getOpenBtn().setDisable(true);
- mainWindow.getZipManagerBtn().setDisable(true);
- mainWindow.getWriteReportButton().setDisable(true);
- mainWindow.getMeshGroup().getChildren().clear();
- clearTrees();
- mainWindow.resetSearchBar();
- mainWindow.resetFilterComboBox();
- });
-
-
- model = entry.getModel();
- currentChecker = previousCheckers.getOrDefault(model, null);
- mainWindow.getClickHandler().setConfig(currentConfig);
- sourceFile = entry.getArchive().getArchivePath().toString();
- renderer.reset();
-
- Platform.runLater(() -> {
- mainWindow.addFileNameToTitle(entry.getArchive().getArchivePath().toString());
- mainWindow.getCheckButton().setDisable(false);
- mainWindow.getLod1Btn().setDisable(false);
- mainWindow.getLod2Btn().setDisable(false);
- mainWindow.getLod3Btn().setDisable(false);
- mainWindow.getLod4Btn().setDisable(false);
- mainWindow.getWorldBtn().setDisable(false);
- mainWindow.getSaveBtn().setDisable(false);
- mainWindow.getResetCameraBtn().setDisable(false);
- mainWindow.getHideRoofBtn().setDisable(false);
- mainWindow.getZipManagerBtn().setDisable(false);
mainWindow.getNorthArrow().setVisible(true);
mainWindow.alignNorthArrow();
setupFeatureTabs();
buildTrees();
- updateFeatureTrees();
- mainWindow.getWriteReportButton().setDisable(currentChecker == null);
});
} finally {
Platform.runLater(() -> mainWindow.getOpenBtn().setDisable(false));
}
-
}
- public void showZipManager() {
- Platform.runLater(() -> currentZipEntryManager.show());
+ public static int getMaxFeaturesPerChunk(){
+ return MAX_FEATURES_PER_CHUNK;
}
private void setupFeatureTabs() {
- mainWindow.setDisableOfFeatureTab(FeatureType.BUILDING, model.getBuildings().isEmpty());
- mainWindow.setDisableOfFeatureTab(FeatureType.VEGETATION, model.getVegetation().isEmpty());
- mainWindow.setDisableOfFeatureTab(FeatureType.TRANSPORTATION, model.getTransportation().isEmpty());
- mainWindow.setDisableOfFeatureTab(FeatureType.TUNNEL, model.getTunnels().isEmpty());
- mainWindow.setDisableOfFeatureTab(FeatureType.BRIDGE, model.getBridges().isEmpty());
- mainWindow.setDisableOfFeatureTab(FeatureType.WATER, model.getWater().isEmpty());
- mainWindow.setDisableOfFeatureTab(FeatureType.LAND, model.getLand().isEmpty());
- mainWindow.setDisableOfFeatureTab(FeatureType.CITY_FURNITURE, model.getCityFurniture().isEmpty());
- mainWindow.setDisableOfFeatureTab(FeatureType.GENERIC_CITY_OBJECT, model.getGenericCityObjects().isEmpty());
+ mainWindow.setDisableOfFeatureTab(FeatureType.BUILDING, model.getBuildingCount() == 0);
+ mainWindow.setDisableOfFeatureTab(FeatureType.VEGETATION, model.getVegetationCount() == 0);
+ mainWindow.setDisableOfFeatureTab(FeatureType.TRANSPORTATION, model.getTransportationCount() == 0);
+ mainWindow.setDisableOfFeatureTab(FeatureType.TUNNEL, model.getTunnelCount() == 0);
+ mainWindow.setDisableOfFeatureTab(FeatureType.BRIDGE, model.getBridgeCount() == 0);
+ mainWindow.setDisableOfFeatureTab(FeatureType.WATER, model.getWaterCount() == 0);
+ mainWindow.setDisableOfFeatureTab(FeatureType.LAND, model.getLandCount() == 0);
+ mainWindow.setDisableOfFeatureTab(FeatureType.CITY_FURNITURE, model.getCityFurnitureCount() == 0);
+ mainWindow.setDisableOfFeatureTab(FeatureType.OTHER_CITY_OBJECT, model.getOtherCityObjectsCount() == 0);
}
public void buildTrees() {
@@ -281,7 +178,7 @@ public class CityDoctorController {
buildWater(model);
buildLand(model);
buildCityFurniture(model);
- buildOtherCityObjects(model);
+ buildGenericCityObjects(model);
buildTunnel(model);
}
@@ -294,126 +191,134 @@ public class CityDoctorController {
waterChunkNr.set(0);
landChunkNr.set(0);
cityFurnitureChunkNr.set(0);
- genericCityObjectsChunkNr.set(0);
+ otherCityObjectsChunkNr.set(0);
}
private void buildLand(CityDoctorModel model) {
- if (model.getLand().isEmpty()) {
+ if (model.getLandCount() == 0) {
return;
}
TreeView landView = mainWindow.getTerrainView();
- TreeItem landRoot = new TreeItem<>(new CityObjectGroupNode(model.getLand(), "Land",
+ TreeItem landRoot = new TreeItem<>(new CityObjectGroupNode(Collections.emptyList(), "Land",
Color.BROWN));
landRoot.setExpanded(true);
landView.setRoot(landRoot);
- buildLandFromList(model.getLand(), landView.getRoot());
- addMoreButtonIfNecessary(model.getLand(), landView, landRoot, landChunkNr);
+ Supplier> supply = model::getLand;
+ buildLandTreeFromList(supply, landView.getRoot());
+ addMoreButtonForLand(landView, landRoot, landChunkNr, supply, model.getLandCount());
}
- private void buildLandFromList(List list, TreeItem root) {
+ private void buildLandTreeFromList(Supplier> supply, TreeItem root) {
int landChunk = landChunkNr.get();
- for (int i = landChunk * MAX_FEATURES_PER_CHUNK; i < (landChunk + 1) * MAX_FEATURES_PER_CHUNK
- && i < list.size(); i++) {
- CityObject land = list.get(i);
+ supply.get().skip((long) landChunk * MAX_FEATURES_PER_CHUNK).limit(MAX_FEATURES_PER_CHUNK).forEach(land ->{
CityObjectNode node = new CityObjectNode(land);
TreeItem item = new TreeItem<>(node);
item.setExpanded(true);
root.getChildren().add(item);
createGeometryNodes(land, item);
-
- }
+ });
}
private void buildCityFurniture(CityDoctorModel model) {
- if (model.getCityFurniture().isEmpty()) {
+ if (model.getCityFurnitureCount() == 0) {
return;
}
TreeView cityFurnitureView = mainWindow.getCityFurnitureView();
- TreeItem cityFurnitureRoot = new TreeItem<>(new CityObjectGroupNode(model.getCityFurniture(),
+ TreeItem cityFurnitureRoot = new TreeItem<>(new CityObjectGroupNode(Collections.emptyList(),
"City Furniture", Color.BLUEVIOLET));
cityFurnitureRoot.setExpanded(true);
cityFurnitureView.setRoot(cityFurnitureRoot);
- buildCityFurnitureTreeFromList(model.getCityFurniture(), cityFurnitureView.getRoot());
- addMoreButtonIfNecessary(model.getCityFurniture(), cityFurnitureView, cityFurnitureRoot, cityFurnitureChunkNr);
+ Supplier> supply = model::getCityFurniture;
+ buildCityFurnitureTreeFromList(supply, cityFurnitureView.getRoot());
+ addMoreButtonForCityFurniture(cityFurnitureView, cityFurnitureRoot, cityFurnitureChunkNr, supply,
+ model.getCityFurnitureCount());
}
- private void buildOtherCityObjects(CityDoctorModel model) {
- if (model.getGenericCityObjects().isEmpty()) {
+ private void buildGenericCityObjects(CityDoctorModel model) {
+ if (model.getOtherCityObjectsCount() == 0) {
return;
}
- TreeView otherObjectsView = mainWindow.getGenericCityObjectView();
- TreeItem otherObjectsRoot = new TreeItem<>(new CityObjectGroupNode(model.getGenericCityObjects(),
+ TreeView otherObjectsView = mainWindow.getOtherCityObjectView();
+ TreeItem otherObjectsRoot = new TreeItem<>(new CityObjectGroupNode(Collections.emptyList(),
"Generic CityObjects", Color.DARKGRAY));
otherObjectsRoot.setExpanded(true);
otherObjectsView.setRoot(otherObjectsRoot);
- buildGenericCityObjectTreeFromList(model.getGenericCityObjects(), otherObjectsView.getRoot());
- addMoreButtonIfNecessary(model.getGenericCityObjects(), otherObjectsView, otherObjectsRoot, genericCityObjectsChunkNr);
+ Supplier> supply = model::getOtherCityObjects;
+ buildOtherCityObjectsTreeFromList(supply, otherObjectsView.getRoot());
+ addMoreButtonForOtherCityObjects( otherObjectsView, otherObjectsRoot, otherCityObjectsChunkNr, supply,
+ model.getOtherCityObjectsCount());
}
private void buildWater(CityDoctorModel model) {
- if (model.getWater().isEmpty()) {
+ if (model.getWaterCount() == 0) {
return;
}
TreeView waterView = mainWindow.getWaterView();
- TreeItem waterRoot = new TreeItem<>(new CityObjectGroupNode(model.getWater(), "Water",
+ TreeItem waterRoot = new TreeItem<>(new CityObjectGroupNode(Collections.emptyList(), "Water",
Color.LIGHTSKYBLUE));
waterRoot.setExpanded(true);
waterView.setRoot(waterRoot);
- buildWaterTreeFromList(model.getWater(), waterRoot);
- addMoreButtonIfNecessary(model.getWater(), waterView, waterRoot, waterChunkNr);
+ Supplier> supply = model::getWater;
+ buildWaterTreeFromList(supply, waterRoot);
+ addMoreButtonForWater(waterView, waterRoot, waterChunkNr, supply, model.getWaterCount());
}
private void buildBridges(CityDoctorModel model) {
- if (model.getBridges().isEmpty()) {
+ if (model.getBridgeCount() == 0) {
return;
}
TreeView bridgeView = mainWindow.getBridgeView();
- TreeItem bridgeRoot = new TreeItem<>(new CityObjectGroupNode(model.getBridges(), "Bridges",
+ TreeItem bridgeRoot = new TreeItem<>(new CityObjectGroupNode(Collections.emptyList(), "Bridges",
Color.CORAL));
bridgeRoot.setExpanded(true);
bridgeView.setRoot(bridgeRoot);
- buildBridgeTreeFromList(model.getBridges(), bridgeView.getRoot());
- addMoreButtonIfNecessary(model.getBridges(), bridgeView, bridgeRoot, bridgeChunkNr);
+ Supplier> supply = model::getBridges;
+ buildBridgeTreeFromList(supply, bridgeView.getRoot());
+ addMoreButtonForBridges(bridgeView, bridgeRoot, bridgeChunkNr, supply, model.getBridgeCount());
}
private void buildTransportation(CityDoctorModel model) {
- if (model.getTransportation().isEmpty()) {
+ if (model.getTransportationCount() == 0) {
return;
}
TreeView transView = mainWindow.getTransportationView();
- TreeItem transRoot = new TreeItem<>(new CityObjectGroupNode(model.getTransportation(),
+ TreeItem transRoot = new TreeItem<>(new CityObjectGroupNode(Collections.emptyList(),
"Transportation", Color.YELLOW));
transRoot.setExpanded(true);
transView.setRoot(transRoot);
- buildTransportationTreeFromList(model.getTransportation(), transView.getRoot());
- addMoreButtonIfNecessary(model.getTransportation(), transView, transRoot, transportationChunkNr);
+ Supplier> supply = model::getTransportation;
+ buildTransportationTreeFromList(supply, transView.getRoot());
+ addMoreButtonForTransportation(transView, transRoot, transportationChunkNr, supply,
+ model.getTransportationCount());
}
private void buildTunnel(CityDoctorModel model) {
- if (model.getTunnels().isEmpty()) {
+ if (model.getTunnelCount() == 0) {
return;
}
TreeView tunnelView = mainWindow.getTunnelView();
- TreeItem tunnelRoot = new TreeItem<>(new CityObjectGroupNode(model.getTunnels(), "Tunnel",
+ TreeItem tunnelRoot = new TreeItem<>(new CityObjectGroupNode(Collections.emptyList(), "Tunnel",
Color.SLATEGRAY));
tunnelRoot.setExpanded(true);
tunnelView.setRoot(tunnelRoot);
- buildTunnelTreeFromList(model.getTunnels(), tunnelRoot);
- addMoreButtonIfNecessary(model.getTunnels(), tunnelView, tunnelRoot, tunnelChunkNr);
+ Supplier> supply = model::getTunnels;
+ buildTunnelTreeFromList(supply, tunnelRoot);
+ addMoreButtonForTunnel(tunnelView, tunnelRoot, tunnelChunkNr, supply, model.getTunnelCount());
}
private void buildVegetation(CityDoctorModel model) {
- if (model.getVegetation().isEmpty()) {
+ if (model.getVegetationCount() == 0) {
return;
}
TreeView vegetationsView = mainWindow.getVegetationView();
- TreeItem vegRoot = new TreeItem<>(new CityObjectGroupNode(model.getVegetation(),
+ TreeItem vegRoot = new TreeItem<>(new CityObjectGroupNode(Collections.emptyList(),
"Vegetation", Color.LIGHTGREEN));
vegRoot.setExpanded(true);
vegetationsView.setRoot(vegRoot);
- buildVegetationTreeFromList(model.getVegetation(), vegRoot);
- addMoreButtonIfNecessary(model.getVegetation(), vegetationsView, vegRoot, vegetationChunkNr);
+ Supplier> supply = model::getVegetation;
+ buildVegetationTreeFromList(supply, vegRoot);
+ addMoreButtonForVegetation(vegetationsView, vegRoot, vegetationChunkNr, supply, model.getVegetationCount());
}
private void addMoreButtonIfNecessary(List extends CityObject> list, TreeView view,
@@ -429,7 +334,7 @@ public class CityDoctorController {
chunkCounter.incrementAndGet();
int visibleFeatures = countVisibleNodes(view);
- buildTreeFromList(list, root, chunkCounter);
+// buildTreeFromList(list, root, chunkCounter);
updateTree(root);
if (selectedIndex >= 0) {
view.getSelectionModel().select(selectedIndex);
@@ -445,17 +350,34 @@ public class CityDoctorController {
}
}
+ private void moreButton(CityDoctorModel model, TreeView view, TreeItem root,
+ AtomicInteger chunkCounter, Supplier> streamSupplier){
+ int featureCount = model.getBuildingCount();
+ if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < featureCount) {
+ AddMoreButtonRunnable run = new AddMoreButtonRunnable(featureCount, view, root, chunkCounter) {
+ @Override
+ public void buildNodeTreeCall() {
+ buildTreeFromList(streamSupplier, root, chunkCounter);
+ updateTree(root);
+ }
+ };
+ //add button
+ root.getChildren().add(new TreeItem<>(new ButtonRenderable(run)));
+ }
+ }
+
private void buildBuildings(CityDoctorModel model) {
- if (model.getBuildings().isEmpty()) {
+ if (model.getBuildingCount() == 0) {
return;
}
TreeView buildingsView = mainWindow.getBuildingsView();
- TreeItem root = new TreeItem<>(new CityObjectGroupNode(model.getBuildings(), "Buildings",
+ TreeItem root = new TreeItem<>(new CityObjectGroupNode(Collections.emptyList(), "Buildings",
Color.WHITE));
root.setExpanded(true);
buildingsView.setRoot(root);
- buildBuildingTreeFromList(model.getBuildings(), root);
- addMoreButtonToBuildingsIfNecessary(model.getBuildings(), buildingsView, root, buildingChunkNr);
+ Supplier> supply = model::getBuildings;
+ buildBuildingTreeFromList(supply, root);
+ addMoreButtonForBuildings(buildingsView, root, buildingChunkNr, supply, model.getBuildingCount());
}
@@ -471,7 +393,7 @@ public class CityDoctorController {
root.getChildren().remove(root.getChildren().size() - 1);
chunkCounter.getAndIncrement();
int visibleFeatures = countVisibleNodes(view);
- buildBuildingTreeFromList(list, root);
+// buildBuildingTreeFromList(list, root);
updateTree(root);
if (selectedIndex >= 0) {
view.getSelectionModel().select(selectedIndex);
@@ -487,6 +409,141 @@ public class CityDoctorController {
}
}
+ private void addMoreButtonForBuildings(TreeView view, TreeItem root,
+ AtomicInteger chunkCounter, Supplier> supply, int featureCount) {
+ if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < featureCount) {
+ AddMoreButtonRunnable run = new AddMoreButtonRunnable(featureCount, view, root, chunkCounter) {
+ @Override
+ public void buildNodeTreeCall() {
+ buildBuildingTreeFromList(supply, root);
+ updateTree(root);
+ }
+ };
+ //add button
+ root.getChildren().add(new TreeItem<>(new ButtonRenderable(run)));
+ }
+ }
+
+ private void addMoreButtonForBridges(TreeView view, TreeItem root,
+ AtomicInteger chunkCounter, Supplier> supply, int featureCount){
+ if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < featureCount) {
+ AddMoreButtonRunnable run = new AddMoreButtonRunnable(featureCount, view, root, chunkCounter) {
+ @Override
+ public void buildNodeTreeCall() {
+ buildBridgeTreeFromList(supply, root);
+ updateTree(root);
+ }
+ };
+ //add button
+ root.getChildren().add(new TreeItem<>(new ButtonRenderable(run)));
+ }
+ }
+
+ private void addMoreButtonForVegetation(TreeView view, TreeItem root,
+ AtomicInteger chunkCounter, Supplier> supply, int featureCount){
+ if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < featureCount) {
+ AddMoreButtonRunnable run = new AddMoreButtonRunnable(featureCount, view, root, chunkCounter) {
+ @Override
+ public void buildNodeTreeCall() {
+ buildVegetationTreeFromList(supply, root);
+ updateTree(root);
+ }
+ };
+ //add button
+ root.getChildren().add(new TreeItem<>(new ButtonRenderable(run)));
+ }
+ }
+
+ private void addMoreButtonForTunnel(TreeView view, TreeItem root,
+ AtomicInteger chunkCounter, Supplier> supply, int featureCount){
+ if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < featureCount) {
+ AddMoreButtonRunnable run = new AddMoreButtonRunnable(featureCount, view, root, chunkCounter) {
+ @Override
+ public void buildNodeTreeCall() {
+ buildTunnelTreeFromList(supply, root);
+ updateTree(root);
+ }
+ };
+ //add button
+ root.getChildren().add(new TreeItem<>(new ButtonRenderable(run)));
+ }
+ }
+
+ private void addMoreButtonForTransportation(TreeView view, TreeItem root,
+ AtomicInteger chunkCounter, Supplier> supply, int featureCount){
+ if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < featureCount) {
+ AddMoreButtonRunnable run = new AddMoreButtonRunnable(featureCount, view, root, chunkCounter) {
+ @Override
+ public void buildNodeTreeCall() {
+ buildTransportationTreeFromList(supply, root);
+ updateTree(root);
+ }
+ };
+ //add button
+ root.getChildren().add(new TreeItem<>(new ButtonRenderable(run)));
+ }
+ }
+
+ private void addMoreButtonForLand(TreeView view, TreeItem root,
+ AtomicInteger chunkCounter, Supplier> supply, int featureCount){
+ if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < featureCount) {
+ AddMoreButtonRunnable run = new AddMoreButtonRunnable(featureCount, view, root, chunkCounter) {
+ @Override
+ public void buildNodeTreeCall() {
+ buildLandTreeFromList(supply, root);
+ updateTree(root);
+ }
+ };
+ //add button
+ root.getChildren().add(new TreeItem<>(new ButtonRenderable(run)));
+ }
+ }
+
+ private void addMoreButtonForWater(TreeView view, TreeItem root,
+ AtomicInteger chunkCounter, Supplier> supply, int featureCount){
+ if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < featureCount) {
+ AddMoreButtonRunnable run = new AddMoreButtonRunnable(featureCount, view, root, chunkCounter) {
+ @Override
+ public void buildNodeTreeCall() {
+ buildWaterTreeFromList(supply, root);
+ updateTree(root);
+ }
+ };
+ //add button
+ root.getChildren().add(new TreeItem<>(new ButtonRenderable(run)));
+ }
+ }
+
+ private void addMoreButtonForCityFurniture(TreeView view, TreeItem root,
+ AtomicInteger chunkCounter, Supplier> supply, int featureCount){
+ if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < featureCount) {
+ AddMoreButtonRunnable run = new AddMoreButtonRunnable(featureCount, view, root, chunkCounter) {
+ @Override
+ public void buildNodeTreeCall() {
+ buildCityFurnitureTreeFromList(supply, root);
+ updateTree(root);
+ }
+ };
+ //add button
+ root.getChildren().add(new TreeItem<>(new ButtonRenderable(run)));
+ }
+ }
+
+ private void addMoreButtonForOtherCityObjects(TreeView view, TreeItem root,
+ AtomicInteger chunkCounter, Supplier> supply, int featureCount){
+ if ((chunkCounter.get() + 1) * MAX_FEATURES_PER_CHUNK < featureCount) {
+ AddMoreButtonRunnable run = new AddMoreButtonRunnable(featureCount, view, root, chunkCounter) {
+ @Override
+ public void buildNodeTreeCall() {
+ buildOtherCityObjectsTreeFromList(supply, root);
+ updateTree(root);
+ }
+ };
+ //add button
+ root.getChildren().add(new TreeItem<>(new ButtonRenderable(run)));
+ }
+ }
+
private static int countVisibleNodes(TreeView view) {
return countVisibleNodes(view.getRoot()) + 1;
}
@@ -501,17 +558,16 @@ public class CityDoctorController {
return visibleFeatures;
}
- private void buildTreeFromList(List extends CityObject> cos, TreeItem root,
+ private void buildTreeFromList(Supplier> supply, TreeItem root,
AtomicInteger chunkCounter) {
- int chunk = chunkCounter.get();
- for (int i = chunk * MAX_FEATURES_PER_CHUNK; i < (chunk + 1) * MAX_FEATURES_PER_CHUNK && i < cos.size(); i++) {
- CityObject co = cos.get(i);
+ int buildingChunk = buildingChunkNr.get();
+ supply.get().skip((long) buildingChunk * MAX_FEATURES_PER_CHUNK).limit(MAX_FEATURES_PER_CHUNK).forEach(co ->{
CityObjectNode node = new CityObjectNode(co);
TreeItem