"...vocoach.git" did not exist on "8fb81ab99634bb38a4f550da9b4be28c939ac7c4"
Commit ad2e1a75 authored by Riegel's avatar Riegel
Browse files

Merge branch 'refs/heads/dev' into dev_embedded_geodb

# Conflicts:
#	CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/GenericAttribute.java
parents aa17c02e 9c97175d
...@@ -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);
......
...@@ -48,9 +48,6 @@ public class Edge implements Serializable { ...@@ -48,9 +48,6 @@ public class Edge implements Serializable {
this.to = to; this.to = to;
} }
private Edge() {
}
public Vertex getFrom() { public Vertex getFrom() {
return from; return from;
} }
......
...@@ -8,6 +8,8 @@ import org.citygml4j.core.model.generics.*; ...@@ -8,6 +8,8 @@ import org.citygml4j.core.model.generics.*;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
public class GenericAttribute implements Serializable { public class GenericAttribute implements Serializable {
...@@ -51,6 +53,22 @@ public class GenericAttribute implements Serializable { ...@@ -51,6 +53,22 @@ public class GenericAttribute implements Serializable {
} 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();
......
...@@ -41,6 +41,10 @@ public class Geometry extends GmlElement { ...@@ -41,6 +41,10 @@ public class Geometry extends GmlElement {
@Serial @Serial
private static final long serialVersionUID = 2539031030917731575L; private static final long serialVersionUID = 2539031030917731575L;
public enum Orientation {
INWARD, OUTWARD
}
private static final Random r = new Random(); private static final Random r = new Random();
private GeometryType type; private GeometryType type;
...@@ -52,10 +56,19 @@ public class Geometry extends GmlElement { ...@@ -52,10 +56,19 @@ public class Geometry extends GmlElement {
private List<Edge> edges; private List<Edge> edges;
private Map<SerializablePair<Vertex, Vertex>, Edge> edgeMap; private Map<SerializablePair<Vertex, Vertex>, Edge> edgeMap;
private List<Vertex> vertices; private List<Vertex> vertices;
private Orientation orientation;
public Geometry(GeometryType type, Lod lod) { public Geometry(GeometryType type, Lod lod, Orientation orientation) {
this.lod = lod; this.lod = lod;
this.type = type; this.type = type;
if (type == GeometryType.SOLID) {
Objects.requireNonNull(orientation);
}
this.orientation = orientation;
}
public Orientation getOrientation() {
return orientation;
} }
void setParent(CityObject parent) { void setParent(CityObject parent) {
......
package de.hft.stuttgart.citydoctor2.datastructure; package de.hft.stuttgart.citydoctor2.datastructure;
import java.io.Serial; 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.check.CheckableVisitor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.citygml4j.core.model.core.ImplicitGeometry; import org.citygml4j.core.model.core.ImplicitGeometry;
import de.hft.stuttgart.citydoctor2.math.TransformationMatrix; import de.hft.stuttgart.citydoctor2.math.TransformationMatrix;
...@@ -16,14 +21,16 @@ public class ImplicitGeometryHolder extends Geometry { ...@@ -16,14 +21,16 @@ public class ImplicitGeometryHolder extends Geometry {
@Serial @Serial
private static final long serialVersionUID = -8938931081577196349L; private static final long serialVersionUID = -8938931081577196349L;
private static final Logger logger = LogManager.getLogger(ImplicitGeometryHolder.class);
private ImplicitGeometry cgmlImplicitGeometry = null;
private ImplicitGeometry cgmlImplicitGeometry = null;
private static ConcurrentHashMap<ImplicitGeometryHolder, ImplicitGeometry> deferredRelGeomObjects = new ConcurrentHashMap<>();
private final PrototypeGeometryType type; private final PrototypeGeometryType type;
private final Geometry prototypeGeometry; private final Geometry prototypeGeometry;
public ImplicitGeometryHolder(ImplicitGeometry cgmlImplicitGeometry, LibraryObject libObject) { public ImplicitGeometryHolder(ImplicitGeometry cgmlImplicitGeometry, LibraryObject libObject) {
super(libObject.getType(), libObject.getLod()); super(libObject.getType(), libObject.getLod(), libObject.getOrientation());
prototypeGeometry = libObject; prototypeGeometry = libObject;
type = PrototypeGeometryType.LIBRARY_OBJECT; type = PrototypeGeometryType.LIBRARY_OBJECT;
this.cgmlImplicitGeometry = cgmlImplicitGeometry; this.cgmlImplicitGeometry = cgmlImplicitGeometry;
...@@ -31,14 +38,47 @@ public class ImplicitGeometryHolder extends Geometry { ...@@ -31,14 +38,47 @@ public class ImplicitGeometryHolder extends Geometry {
} }
public ImplicitGeometryHolder(ImplicitGeometry cgmlImplicitGeometry, RelativeGeometry relativeGeometry) { public ImplicitGeometryHolder(ImplicitGeometry cgmlImplicitGeometry, RelativeGeometry relativeGeometry) {
super(relativeGeometry.getType(), relativeGeometry.getLod()); super(relativeGeometry.getType(), relativeGeometry.getLod(), relativeGeometry.getOrientation());
prototypeGeometry = relativeGeometry; prototypeGeometry = relativeGeometry;
type = PrototypeGeometryType.RELATIVE_GEOMETRY; type = PrototypeGeometryType.RELATIVE_GEOMETRY;
this.cgmlImplicitGeometry = cgmlImplicitGeometry; this.cgmlImplicitGeometry = cgmlImplicitGeometry;
applyTransformation(); applyTransformation();
} }
public static ImplicitGeometryHolder deferRelativeGeomParsing(ImplicitGeometry ig, Lod lod) {
ImplicitGeometryHolder igh = new ImplicitGeometryHolder(lod);
deferredRelGeomObjects.put(igh, ig);
return igh;
}
public static void resolveDeferredObjects() {
Set<GmlId> missingGeoms = new HashSet<>();
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 = key.getParent();
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();
}
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 * Applies the transformation matrix of the implicit geometry to a copy of the reference geometry and copies the resulting
* transformed geometry into this object. * transformed geometry into this object.
......
...@@ -37,7 +37,7 @@ public class LibraryObject extends Geometry { ...@@ -37,7 +37,7 @@ public class LibraryObject extends Geometry {
if (protoGeom == null) { if (protoGeom == null) {
return null; return null;
} }
LibraryObject libOb = new LibraryObject(protoGeom.getType(), protoGeom.getLod()); LibraryObject libOb = new LibraryObject(protoGeom.getType(), protoGeom.getLod(), protoGeom.getOrientation());
protoGeom.getPolygons().forEach(libOb::addPolygon); protoGeom.getPolygons().forEach(libOb::addPolygon);
libOb.updateEdgesAndVertices(); libOb.updateEdgesAndVertices();
libraryObjects.put(path.toString(), libOb); libraryObjects.put(path.toString(), libOb);
...@@ -53,15 +53,15 @@ public class LibraryObject extends Geometry { ...@@ -53,15 +53,15 @@ public class LibraryObject extends Geometry {
if (protoGeom == null) { if (protoGeom == null) {
return null; return null;
} }
LibraryObject libOb = new LibraryObject(protoGeom.getType(), protoGeom.getLod()); LibraryObject libOb = new LibraryObject(protoGeom.getType(), protoGeom.getLod(), protoGeom.getOrientation());
protoGeom.getPolygons().forEach(libOb::addPolygon); protoGeom.getPolygons().forEach(libOb::addPolygon);
libOb.updateEdgesAndVertices(); libOb.updateEdgesAndVertices();
libraryObjects.put(fileName, libOb); libraryObjects.put(fileName, libOb);
return libOb; return libOb;
} }
private LibraryObject(GeometryType type, Lod lod) { private LibraryObject(GeometryType type, Lod lod, Orientation orientation) {
super(type, lod); super(type, lod, orientation);
} }
......
...@@ -44,9 +44,6 @@ public class LinkedPolygon extends Polygon { ...@@ -44,9 +44,6 @@ public class LinkedPolygon extends Polygon {
private Geometry parent; private Geometry parent;
private ConcretePolygon poly; private ConcretePolygon poly;
private LinkedPolygon() {
}
/** /**
* @param poly polygon this is linked to * @param poly polygon this is linked to
* @param parent the parent of the linked polygon * @param parent the parent of the linked polygon
......
...@@ -14,20 +14,24 @@ public class RelativeGeometry extends Geometry { ...@@ -14,20 +14,24 @@ public class RelativeGeometry extends Geometry {
@Serial @Serial
private static final long serialVersionUID = -686112245455298977L; private static final long serialVersionUID = -686112245455298977L;
private static Map<Geometry, RelativeGeometry> relativeGeometries = new ConcurrentHashMap<>(); private static final Map<GmlId, RelativeGeometry> relativeGeometries = new ConcurrentHashMap<>();
public static RelativeGeometry of(Geometry geom) { public static RelativeGeometry of(GmlId gmlId, Geometry geom) {
if (relativeGeometries.containsKey(geom)) { if (relativeGeometries.containsKey(gmlId)) {
return relativeGeometries.get(geom); return relativeGeometries.get(gmlId);
} }
RelativeGeometry relGeo = new RelativeGeometry(geom.getType(), geom.getLod()); RelativeGeometry relGeo = new RelativeGeometry(geom.getType(), geom.getLod(), geom.getOrientation());
geom.getPolygons().forEach(relGeo::addPolygon); geom.getPolygons().forEach(relGeo::addPolygon);
relGeo.updateEdgesAndVertices(); relGeo.updateEdgesAndVertices();
relativeGeometries.put(geom, relGeo); relativeGeometries.put(gmlId, relGeo);
return relGeo; return relGeo;
} }
private RelativeGeometry(GeometryType type, Lod lod) { public static RelativeGeometry of(GmlId gmlId) {
super(type, lod); return relativeGeometries.getOrDefault(gmlId, null);
}
private RelativeGeometry(GeometryType type, Lod lod, Orientation orientation) {
super(type, lod, orientation);
} }
} }
...@@ -111,7 +111,6 @@ public class Citygml3GeometryMapper extends GeometryWalker { ...@@ -111,7 +111,6 @@ public class Citygml3GeometryMapper extends GeometryWalker {
conc.addInteriorRing(currentRing); conc.addInteriorRing(currentRing);
} }
collection.addPatchMember(conc); collection.addPatchMember(conc);
polygons.add(conc);
} }
private void parsePolygon(String id, AbstractRingProperty exterior, List<AbstractRingProperty> interior) { private void parsePolygon(String id, AbstractRingProperty exterior, List<AbstractRingProperty> interior) {
......
...@@ -107,7 +107,7 @@ public class SurfaceMapper extends ObjectWalker { ...@@ -107,7 +107,7 @@ public class SurfaceMapper extends ObjectWalker {
} }
private Geometry parseMultiSurface(MultiSurface ms, Lod lod) { private Geometry parseMultiSurface(MultiSurface ms, Lod lod) {
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, lod); Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, lod, null);
Citygml3GeometryMapper geometryMapper = new Citygml3GeometryMapper(config, vertexMap); Citygml3GeometryMapper geometryMapper = new Citygml3GeometryMapper(config, vertexMap);
readSurfaceMember(geom, geometryMapper, ms.getSurfaceMember()); readSurfaceMember(geom, geometryMapper, ms.getSurfaceMember());
return geom; return geom;
......
...@@ -32,4 +32,6 @@ public interface CityGmlConsumer { ...@@ -32,4 +32,6 @@ public interface CityGmlConsumer {
} }
// public void endOfFile();
} }
...@@ -18,26 +18,43 @@ ...@@ -18,26 +18,43 @@
*/ */
package de.hft.stuttgart.citydoctor2.parser; package de.hft.stuttgart.citydoctor2.parser;
import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel; import java.io.BufferedInputStream;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject; import java.io.ByteArrayInputStream;
import de.hft.stuttgart.citydoctor2.mapper.citygml3.Citygml3FeatureMapper; import java.io.File;
import de.hft.stuttgart.citydoctor2.mapper.citygml3.GMLValidationHandler; import java.io.FileInputStream;
import de.hft.stuttgart.citydoctor2.math.Vector3d; import java.io.IOException;
import de.hft.stuttgart.citydoctor2.utils.Localization; import java.io.InputStream;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry; import java.nio.charset.StandardCharsets;
import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntryFile; import java.nio.file.Path;
import de.hft.stuttgart.quality.QualityADEContext; import java.nio.file.Paths;
import de.hft.stuttgart.quality.QualityADEModule; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import de.hft.stuttgart.citydoctor2.datastructure.ImplicitGeometryHolder;
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.citygml4j.core.ade.ADEException; import org.citygml4j.core.ade.ADEException;
import org.citygml4j.core.ade.ADERegistry; import org.citygml4j.core.ade.ADERegistry;
import org.citygml4j.core.model.CityGMLVersion; import org.citygml4j.core.model.CityGMLVersion;
import org.citygml4j.core.model.ade.ADEProperty;
import org.citygml4j.core.model.core.AbstractCityObject; import org.citygml4j.core.model.core.AbstractCityObject;
import org.citygml4j.core.model.core.AbstractCityObjectProperty; import org.citygml4j.core.model.core.AbstractCityObjectProperty;
import org.citygml4j.core.model.core.AbstractFeature; import org.citygml4j.core.model.core.AbstractFeature;
import org.citygml4j.core.model.core.AbstractFeatureProperty;
import org.citygml4j.core.model.core.CityModel; import org.citygml4j.core.model.core.CityModel;
import org.citygml4j.core.util.CityGMLConstants; import org.citygml4j.core.util.CityGMLConstants;
import org.citygml4j.xml.CityGMLContext; import org.citygml4j.xml.CityGMLContext;
...@@ -68,30 +85,16 @@ import org.xmlobjects.schema.SchemaHandlerException; ...@@ -68,30 +85,16 @@ import org.xmlobjects.schema.SchemaHandlerException;
import org.xmlobjects.stream.XMLReader; import org.xmlobjects.stream.XMLReader;
import org.xmlobjects.stream.XMLReaderFactory; import org.xmlobjects.stream.XMLReaderFactory;
import javax.xml.XMLConstants; import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import javax.xml.namespace.QName; import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import javax.xml.parsers.ParserConfigurationException; import de.hft.stuttgart.citydoctor2.mapper.citygml3.Citygml3FeatureMapper;
import javax.xml.parsers.SAXParser; import de.hft.stuttgart.citydoctor2.mapper.citygml3.GMLValidationHandler;
import javax.xml.parsers.SAXParserFactory; import de.hft.stuttgart.citydoctor2.math.Vector3d;
import javax.xml.transform.Source; import de.hft.stuttgart.citydoctor2.utils.Localization;
import javax.xml.transform.stream.StreamSource; import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
import javax.xml.validation.Schema; import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntryFile;
import javax.xml.validation.SchemaFactory; import de.hft.stuttgart.quality.QualityADEContext;
import javax.xml.validation.Validator; import de.hft.stuttgart.quality.QualityADEModule;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** /**
* Utility class to parse CityGML files. * Utility class to parse CityGML files.
...@@ -430,6 +433,7 @@ public class CityGmlParser { ...@@ -430,6 +433,7 @@ public class CityGmlParser {
writer.writeMember(chunk); writer.writeMember(chunk);
} }
} }
// end of stream // end of stream
logger.debug("End of gml file stream"); logger.debug("End of gml file stream");
} catch (CityGMLReadException e) { } catch (CityGMLReadException e) {
...@@ -447,10 +451,10 @@ public class CityGmlParser { ...@@ -447,10 +451,10 @@ public class CityGmlParser {
} }
} }
private static void writeCityModel(CityGMLChunkWriter writer, CityModel cModel) { private static void writeCityModel(CityGMLChunkWriter writer, CityModel cModel) throws CityGMLWriteException {
if (writer != null) { if (writer != null) {
for (ADEProperty genEle : cModel.getADEProperties()) { for (AbstractFeatureProperty featureProp : cModel.getFeatureMembers()) {
writer.getCityModelInfo().addADEProperty(genEle); writer.writeMember(featureProp.getObject());
} }
} }
} }
...@@ -525,6 +529,8 @@ public class CityGmlParser { ...@@ -525,6 +529,8 @@ public class CityGmlParser {
logger.info(Localization.getText("CityGmlParser.parsedObjects"), logger.info(Localization.getText("CityGmlParser.parsedObjects"),
mapper.getModel().getNumberOfFeatures()); mapper.getModel().getNumberOfFeatures());
} }
// After parsing is complete, try to resolve deferred RelativeGeometries
ImplicitGeometryHolder.resolveDeferredObjects();
mapper.setCityGMLVersion(version); mapper.setCityGMLVersion(version);
return mapper.getModel(); return mapper.getModel();
} }
......
...@@ -26,12 +26,10 @@ import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel; ...@@ -26,12 +26,10 @@ import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject; import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry; import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon; 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.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.MinMaxExtentVisitor;
/** /**
* Utility class for calculating axis aligned bounding boxes for different * Utility class for calculating axis aligned bounding boxes for different
...@@ -99,24 +97,11 @@ public class BoundingBoxCalculator { ...@@ -99,24 +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.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE); // TODO: Rework to Visitor
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 return BoundingBox.of(mima.getMinMaxExtent());
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);
} }
public static BoundingBox calculateBoundingBoxFromPoints(List<? extends Vector3d> points) { public static BoundingBox calculateBoundingBoxFromPoints(List<? extends Vector3d> points) {
...@@ -159,28 +144,21 @@ public class BoundingBoxCalculator { ...@@ -159,28 +144,21 @@ 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());
}
} else if (to instanceof TrafficSpaceObject tso) {
findMinMaxTransport(low, high, tso.getTrafficAreas());
}
}
}
private static void findMinMax(Vector3d low, Vector3d high, CityObject co) { private static void findMinMax(Vector3d low, Vector3d high, CityObject co) {
for (Geometry geom : co.getGeometries()) { CityObjectCollector collector = new CityObjectCollector();
co.accept(collector);
for (CityObject object : collector.getCityObjects()) {
for (Geometry geom : object.getGeometries()) {
if (geom.getVertices() == null) { if (geom.getVertices() == null) {
geom.updateVertices(); geom.updateVertices();
} }
findMinMax(low, high, geom);
}
}
}
private static void findMinMax(Vector3d low, Vector3d high, Geometry geom) {
for (Vertex v : geom.getVertices()) { for (Vertex v : geom.getVertices()) {
if (v.getX() < low.getX()) { if (v.getX() < low.getX()) {
low.setX(v.getX()); low.setX(v.getX());
...@@ -202,6 +180,5 @@ public class BoundingBoxCalculator { ...@@ -202,6 +180,5 @@ public class BoundingBoxCalculator {
} }
} }
} }
}
} }
package de.hft.stuttgart.citydoctor2.utils; package de.hft.stuttgart.citydoctor2.utils;
import java.io.Serial;
/** /**
* This Throwable signals that a requested CheckError was found. * This Throwable signals that a requested CheckError was found.
*/ */
public class CheckErrorFound extends Throwable { public class CheckErrorFound extends Throwable {
@Serial
private static final long serialVersionUID = -2066876428396230230L;
public CheckErrorFound() { public CheckErrorFound() {
super("CheckError was found", null, true, false); super("CheckError was found", null, true, false);
......
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());
}
}
}
}
}
...@@ -11,5 +11,8 @@ ...@@ -11,5 +11,8 @@
<Root level="debug" additivity="false"> <Root level="debug" additivity="false">
<AppenderRef ref="console" /> <AppenderRef ref="console" />
</Root> </Root>
<Logger name="org.apache.fop" level="INFO">
<AppenderRef ref="console" />
</Logger>
</Loggers> </Loggers>
</Configuration> </Configuration>
\ No newline at end of file
...@@ -31,6 +31,7 @@ import org.junit.Test; ...@@ -31,6 +31,7 @@ import org.junit.Test;
import de.hft.stuttgart.citydoctor2.check.error.SchematronError; import de.hft.stuttgart.citydoctor2.check.error.SchematronError;
import de.hft.stuttgart.citydoctor2.datastructure.Building; import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry; 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.GeometryType;
import de.hft.stuttgart.citydoctor2.datastructure.GmlId; import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
import de.hft.stuttgart.citydoctor2.datastructure.Lod; import de.hft.stuttgart.citydoctor2.datastructure.Lod;
...@@ -90,7 +91,7 @@ public class CheckableTest { ...@@ -90,7 +91,7 @@ public class CheckableTest {
@Test @Test
public void testContainsError() { public void testContainsError() {
Building b = new Building(); Building b = new Building();
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD0); Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD0, Orientation.OUTWARD);
b.addGeometry(geom); b.addGeometry(geom);
assertFalse(b.containsError(CheckId.C_GE_P_HOLE_OUTSIDE)); assertFalse(b.containsError(CheckId.C_GE_P_HOLE_OUTSIDE));
assertFalse(b.containsAnyError()); assertFalse(b.containsAnyError());
...@@ -148,7 +149,7 @@ public class CheckableTest { ...@@ -148,7 +149,7 @@ public class CheckableTest {
@Test @Test
public void testCollectAllContainedErrors() { public void testCollectAllContainedErrors() {
Building b = new Building(); Building b = new Building();
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD0); Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD0, Orientation.OUTWARD);
b.addGeometry(geom); b.addGeometry(geom);
b.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR, b.addCheckResult(new CheckResult(CheckId.C_GE_P_HOLE_OUTSIDE, ResultStatus.ERROR,
new SchematronError(null, null, null, null))); new SchematronError(null, null, null, null)));
......
...@@ -30,6 +30,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.Geometry; ...@@ -30,6 +30,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
import de.hft.stuttgart.citydoctor2.datastructure.GmlId; import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
import de.hft.stuttgart.citydoctor2.datastructure.Lod; import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation;
import de.hft.stuttgart.quality.model.properties.AbstractErrorProperty; import de.hft.stuttgart.quality.model.properties.AbstractErrorProperty;
import de.hft.stuttgart.quality.model.types.AbstractError; import de.hft.stuttgart.quality.model.types.AbstractError;
import de.hft.stuttgart.quality.model.types.AllPolygonsOrientedWrongError; import de.hft.stuttgart.quality.model.types.AllPolygonsOrientedWrongError;
...@@ -39,7 +40,7 @@ public class AllPolygonsWrongOrientationErrorTest { ...@@ -39,7 +40,7 @@ public class AllPolygonsWrongOrientationErrorTest {
@Test @Test
public void testAddToValidationResult() { public void testAddToValidationResult() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD2); Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD2, Orientation.OUTWARD);
GmlId gmlId = new GmlId("testId"); GmlId gmlId = new GmlId("testId");
geom.setGmlId(gmlId); geom.setGmlId(gmlId);
AllPolygonsWrongOrientationError err = new AllPolygonsWrongOrientationError(geom); AllPolygonsWrongOrientationError err = new AllPolygonsWrongOrientationError(geom);
......
...@@ -33,6 +33,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.GeometryType; ...@@ -33,6 +33,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
import de.hft.stuttgart.citydoctor2.datastructure.GmlId; import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
import de.hft.stuttgart.citydoctor2.datastructure.Lod; import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon; import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation;
import de.hft.stuttgart.quality.model.properties.AbstractErrorProperty; import de.hft.stuttgart.quality.model.properties.AbstractErrorProperty;
import de.hft.stuttgart.quality.model.properties.PolygonIdListProperty; import de.hft.stuttgart.quality.model.properties.PolygonIdListProperty;
import de.hft.stuttgart.quality.model.types.AbstractError; import de.hft.stuttgart.quality.model.types.AbstractError;
...@@ -44,7 +45,7 @@ public class MultipleConnectedComponentsErrorTest { ...@@ -44,7 +45,7 @@ public class MultipleConnectedComponentsErrorTest {
@Test @Test
public void testConvertToQualityAdeDatastructure() { public void testConvertToQualityAdeDatastructure() {
Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD2); Geometry geom = new Geometry(GeometryType.SOLID, Lod.LOD2, Orientation.OUTWARD);
GmlId geomId = new GmlId("geomId"); GmlId geomId = new GmlId("geomId");
geom.setGmlId(geomId); geom.setGmlId(geomId);
Polygon p1 = new ConcretePolygon(); Polygon p1 = new ConcretePolygon();
......
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