Commit 69907f49 authored by Riegel's avatar Riegel
Browse files

Refactor: Rework BBox calculation using Visitors

parent 6aa2677f
Pipeline #11749 passed with stage
in 1 minute and 25 seconds
...@@ -20,6 +20,7 @@ package de.hft.stuttgart.citydoctor2.datastructure; ...@@ -20,6 +20,7 @@ package de.hft.stuttgart.citydoctor2.datastructure;
import de.hft.stuttgart.citydoctor2.check.CheckableUtilsVisitor; import de.hft.stuttgart.citydoctor2.check.CheckableUtilsVisitor;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckableVisitor;
import de.hft.stuttgart.citydoctor2.exceptions.CityDoctorWriteException; import de.hft.stuttgart.citydoctor2.exceptions.CityDoctorWriteException;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.writer.CityGMLWriterUtils; import de.hft.stuttgart.citydoctor2.writer.CityGMLWriterUtils;
...@@ -121,6 +122,18 @@ public class CityDoctorModel { ...@@ -121,6 +122,18 @@ public class CityDoctorModel {
tunnels.stream(), water.stream(), cityfurniture.stream(), genericObjects.stream()).flatMap(co -> co); tunnels.stream(), water.stream(), cityfurniture.stream(), genericObjects.stream()).flatMap(co -> co);
} }
public void accept(CheckableVisitor visitor) {
buildings.forEach(co -> co.accept(visitor));
vegetation.forEach(co -> co.accept(visitor));
bridges.forEach(co -> co.accept(visitor));
land.forEach(co -> co.accept(visitor));
roads.forEach(co -> co.accept(visitor));
tunnels.forEach(co -> co.accept(visitor));
water.forEach(co -> co.accept(visitor));
cityfurniture.forEach(co -> co.accept(visitor));
genericObjects.forEach(co -> co.accept(visitor));
}
public void saveAs(String file, boolean saveQualityAde) throws CityDoctorWriteException { public void saveAs(String file, boolean saveQualityAde) throws CityDoctorWriteException {
if (file.endsWith(".off")) { if (file.endsWith(".off")) {
exportAsOff(file); exportAsOff(file);
......
...@@ -5,6 +5,8 @@ import org.apache.logging.log4j.Logger; ...@@ -5,6 +5,8 @@ import org.apache.logging.log4j.Logger;
import org.citygml4j.core.model.core.AbstractGenericAttributeProperty; import org.citygml4j.core.model.core.AbstractGenericAttributeProperty;
import org.citygml4j.core.model.generics.*; import org.citygml4j.core.model.generics.*;
import java.util.List;
public class GenericAttribute { public class GenericAttribute {
...@@ -45,6 +47,22 @@ public class GenericAttribute { ...@@ -45,6 +47,22 @@ public class GenericAttribute {
} else if (attributeProperty.getObject() instanceof CodeAttribute ca) { } else if (attributeProperty.getObject() instanceof CodeAttribute ca) {
type = String.format("CodeAttribute (%s)", ca.getValue().getLanguage()); type = String.format("CodeAttribute (%s)", ca.getValue().getLanguage());
value = String.format("'''%s''' %n CodeSpace: %s", ca.getValue().getValue(), ca.getValue().getCodeSpace()); value = String.format("'''%s''' %n CodeSpace: %s", ca.getValue().getValue(), ca.getValue().getCodeSpace());
} else if (attributeProperty.getObject() instanceof GenericAttributeSet gas) {
type = "GenericAttributeSet";
List<AbstractGenericAttributeProperty> 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 { } else {
logger.warn("GenericAttribute {} is of unknown type {}", attributeProperty, attributeProperty.getObject()); logger.warn("GenericAttribute {} is of unknown type {}", attributeProperty, attributeProperty.getObject());
value = attributeProperty.getObject().getValue().toString(); value = attributeProperty.getObject().getValue().toString();
......
...@@ -29,6 +29,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.Polygon; ...@@ -29,6 +29,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex; import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.math.Vector3d; import de.hft.stuttgart.citydoctor2.math.Vector3d;
import de.hft.stuttgart.citydoctor2.utils.visitors.CityObjectCollector; 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 * Utility class for calculating axis aligned bounding boxes for different
...@@ -96,23 +97,11 @@ public class BoundingBoxCalculator { ...@@ -96,23 +97,11 @@ public class BoundingBoxCalculator {
* @return the bounding box of the model * @return the bounding box of the model
*/ */
public static BoundingBox calculateBoundingBox(CityDoctorModel model) { public static BoundingBox calculateBoundingBox(CityDoctorModel model) {
Vector3d low = new Vector3d(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); // TODO: Rework to Visitor
Vector3d high = new Vector3d(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY); MinMaxExtentVisitor mima = new MinMaxExtentVisitor();
model.accept(mima);
findMinMax(low, high, model.getBuildings()); return BoundingBox.of(mima.getMinMaxExtent());
findMinMax(low, high, model.getBridges());
findMinMax(low, high, model.getLand());
findMinMax(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);
} }
public static BoundingBox calculateBoundingBoxFromPoints(List<? extends Vector3d> points) { public static BoundingBox calculateBoundingBoxFromPoints(List<? extends Vector3d> points) {
......
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());
}
}
}
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment