Commit 6aa2677f authored by Riegel's avatar Riegel
Browse files

Fix: Parsing of RelativeGeometry

parent 6e94b4c8
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 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 +21,11 @@ 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;
private ImplicitGeometry cgmlImplicitGeometry = null;
private static ConcurrentHashMap<ImplicitGeometryHolder, ImplicitGeometry> deferredRelGeomObjects = new ConcurrentHashMap<>();
private final PrototypeGeometryType type;
private final Geometry prototypeGeometry;
......@@ -38,7 +45,40 @@ 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() {
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
* transformed geometry into this object.
......
......@@ -14,19 +14,23 @@ public class RelativeGeometry extends Geometry {
@Serial
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) {
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);
}
......
......@@ -1035,19 +1035,33 @@ public class Citygml3FeatureMapper extends ObjectWalker {
}
} 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 {
......
......@@ -44,6 +44,7 @@ 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.LogManager;
import org.apache.logging.log4j.Logger;
......@@ -528,6 +529,8 @@ public class CityGmlParser {
logger.info(Localization.getText("CityGmlParser.parsedObjects"),
mapper.getModel().getNumberOfFeatures());
}
// After parsing is complete, try to resolve deferred RelativeGeometries
ImplicitGeometryHolder.resolveDeferredObjects();
mapper.setCityGMLVersion(version);
return mapper.getModel();
}
......
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