Commit d240ea97 authored by Matthias Betz's avatar Matthias Betz
Browse files

add workaround for unserializable Attributes and TextContent

parent 664abca9
Pipeline #12280 passed with stage
in 2 minutes and 11 seconds
......@@ -18,13 +18,10 @@
*/
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 org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.citygml4j.core.model.core.AbstractSpaceBoundaryProperty;
import java.io.Serial;
import java.util.ArrayList;
import java.util.List;
import org.citygml4j.core.model.deprecated.bridge.DeprecatedPropertiesOfBridgeConstructiveElement;
import org.citygml4j.core.util.geometry.GeometryFactory;
import org.xmlobjects.gml.model.geometry.GeometryProperty;
......@@ -34,14 +31,13 @@ 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 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 BridgeConstructiveElement extends CityObject {
private static final Logger logger = LogManager.getLogger(BridgeConstructiveElement.class);
private static final String CANNOT_ADD = "Cannot add ";
@Serial
......@@ -105,20 +101,6 @@ public class BridgeConstructiveElement extends CityObject {
}
}
private void reCreateBoundarySurface(GeometryFactory factory, ParserConfiguration config, BoundarySurface bs) {
if (bs.getGeometries().isEmpty()) {
for (AbstractSpaceBoundaryProperty bsp : gmlBridgeElement.getBoundaries()) {
if (bsp.getObject() != null && bsp.getObject() == bs.getGmlObject()) {
logger.warn("Found empty boundary surface: {}, removing from BridgeConstructiveElement", bs.getGmlId());
gmlBridgeElement.getBoundaries().remove(bsp);
break;
}
}
return;
}
bs.reCreateGeometries(factory, config);
}
private void setCompositeSurfaceAccordingToLod(Geometry geom, CompositeSurface cs) {
switch (geom.getLod()) {
case LOD1:
......
......@@ -41,175 +41,174 @@ import java.util.Set;
*/
public final class CityGmlUtils {
private CityGmlUtils() {
// util class
}
public static org.xmlobjects.gml.model.geometry.primitives.Polygon createGmlPolygon(GeometryFactory factory,
Polygon cdPoly, ParserConfiguration config) {
if (cdPoly.getExteriorRing() == null) {
return null;
}
org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = new org.xmlobjects.gml.model.geometry.primitives.Polygon();
// exterior ring
LinearRing extLr = cdPoly.getExteriorRing();
if (extLr.getVertices().size() < 3) {
// this ring does not have enough points in it
// this leads to errors when exporting therefore ignore it
return null;
}
org.xmlobjects.gml.model.geometry.primitives.LinearRing gmlLr = createGmlRing(factory, config, extLr);
gmlPoly.setExterior(new AbstractRingProperty(gmlLr));
// interior rings
for (LinearRing lr : cdPoly.getInnerRings()) {
gmlLr = createGmlRing(factory, config, lr);
if (lr.getVertices().size() < 3) {
// this ring does not have enough points in it
// this leads to errors when exporting therefore ignore it
return null;
}
gmlPoly.getInterior().add(new AbstractRingProperty(gmlLr));
}
gmlPoly.setId(cdPoly.getGmlId().getGmlString());
return gmlPoly;
}
public static CompositeSurface createGmlComposite(GeometryFactory factory, CompositeCollection comp,
ParserConfiguration config) {
List<SurfaceProperty> surfaces = new ArrayList<>();
for (ConcretePolygon cd : comp.getNonRecursiveCompositeMembers()) {
surfaces.add(new SurfaceProperty(createGmlPolygon(factory, cd, config)));
}
for (CompositeCollection cc : comp.getChildComposites()) {
surfaces.add(new SurfaceProperty(createGmlComposite(factory, cc, config)));
}
if (surfaces.isEmpty()) {
return null;
}
return new CompositeSurface(surfaces);
}
public static org.xmlobjects.gml.model.geometry.primitives.LinearRing createGmlRing(GeometryFactory factory,
ParserConfiguration config, LinearRing lr) {
ProjCoordinate p1 = new ProjCoordinate();
ProjCoordinate p2 = new ProjCoordinate();
List<Double> ringValues = new ArrayList<>();
BasicCoordinateTransform trans = config.getOriginalTransform();
for (Vertex v : lr.getVertices()) {
double x = v.getX();
double y = v.getY();
double z = v.getZ();
if (trans != null) {
p1.x = x;
p1.y = y;
trans.transform(p1, p2);
x = p2.x;
y = p2.y;
z = z * config.getFromMeters();
}
ringValues.add(x);
ringValues.add(y);
ringValues.add(z);
}
org.xmlobjects.gml.model.geometry.primitives.LinearRing gmlLr = factory.createLinearRing(ringValues, 3);
gmlLr.setId(lr.getGmlId().getGmlString());
return gmlLr;
}
public static Solid createSolid(Geometry geom, GeometryFactory factory, ParserConfiguration config) {
if (geom.getType() != GeometryType.SOLID) {
throw new IllegalArgumentException("Only solids are allowed");
}
CompositeSurface comp = new CompositeSurface();
List<SurfaceProperty> surfaceMember = comp.getSurfaceMembers();
for (Polygon cdPoly : geom.getPolygons()) {
if (!cdPoly.isLink()) {
org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config);
if (gmlPoly != null) {
surfaceMember.add(new SurfaceProperty(gmlPoly));
}
} else {
// add reference to polygon
surfaceMember.add(new SurfaceProperty("#" + cdPoly.getGmlId().getGmlString()));
}
}
if (surfaceMember.isEmpty()) {
return null;
}
Solid solid = new Solid();
Shell shell = new Shell(surfaceMember);
solid.setExterior(new ShellProperty(shell));
solid.setId(geom.getGmlId().getGmlString());
return solid;
}
public static MultiSurface createMultiSurface(Geometry geom, GeometryFactory factory,
ParserConfiguration config) {
if (geom.getType() != GeometryType.MULTI_SURFACE && geom.getType() != GeometryType.COMPOSITE_SURFACE) {
throw new IllegalArgumentException("This can only handle MultiSurfaces");
}
List<SurfaceProperty> surfaces = new ArrayList<>();
Set<CompositeCollection> compositeCollections = new HashSet<>();
for (Polygon cdPoly : geom.getPolygons()) {
if (cdPoly instanceof ConcretePolygon conc && conc.isCompositeMember()) {
compositeCollections.add(conc.getPartOfComposite());
} else if (!cdPoly.isLink()) {
// is not part of a boundary surface
org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config);
if (gmlPoly != null) {
surfaces.add(new SurfaceProperty(gmlPoly));
}
} else {
// add reference to polygon
surfaces.add(new SurfaceProperty("#" + cdPoly.getGmlId().getGmlString()));
}
}
for (CompositeCollection cdPoly : compositeCollections) {
surfaces.add(new SurfaceProperty(createGmlComposite(factory, cdPoly, config)));
}
if (surfaces.isEmpty()) {
return null;
}
MultiSurface ms = new MultiSurface(surfaces);
ms.setId(geom.getGmlId().getGmlString());
return ms;
}
public static MultiSurface createMultiSurface(List<Polygon> polygons, GeometryFactory factory,
ParserConfiguration config) {
List<SurfaceProperty> surfaces = new ArrayList<>();
for (Polygon cdPoly : polygons) {
org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config);
if (gmlPoly != null) {
surfaces.add(new SurfaceProperty(gmlPoly));
}
}
if (surfaces.isEmpty()) {
return null;
}
return new MultiSurface(surfaces);
}
public static CompositeSurface createCompositeSurface(Geometry geom, GeometryFactory factory,
ParserConfiguration config) {
List<SurfaceProperty> surfaces = new ArrayList<>();
for (Polygon cdPoly : geom.getPolygons()) {
org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config);
if (gmlPoly != null) {
surfaces.add(new SurfaceProperty(gmlPoly));
}
}
if (surfaces.isEmpty()) {
return null;
}
return new CompositeSurface(surfaces);
}
private CityGmlUtils() {
// util class
}
public static org.xmlobjects.gml.model.geometry.primitives.Polygon createGmlPolygon(GeometryFactory factory,
Polygon cdPoly, ParserConfiguration config) {
if (cdPoly.getExteriorRing() == null) {
return null;
}
org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = new org.xmlobjects.gml.model.geometry.primitives.Polygon();
// exterior ring
LinearRing extLr = cdPoly.getExteriorRing();
if (extLr.getVertices().size() < 3) {
// this ring does not have enough points in it
// this leads to errors when exporting therefore ignore it
return null;
}
org.xmlobjects.gml.model.geometry.primitives.LinearRing gmlLr = createGmlRing(factory, config, extLr);
gmlPoly.setExterior(new AbstractRingProperty(gmlLr));
// interior rings
for (LinearRing lr : cdPoly.getInnerRings()) {
gmlLr = createGmlRing(factory, config, lr);
if (lr.getVertices().size() < 3) {
// this ring does not have enough points in it
// this leads to errors when exporting therefore ignore it
return null;
}
gmlPoly.getInterior().add(new AbstractRingProperty(gmlLr));
}
gmlPoly.setId(cdPoly.getGmlId().getGmlString());
return gmlPoly;
}
public static CompositeSurface createGmlComposite(GeometryFactory factory, CompositeCollection comp,
ParserConfiguration config) {
List<SurfaceProperty> surfaces = new ArrayList<>();
for (ConcretePolygon cd : comp.getNonRecursiveCompositeMembers()) {
surfaces.add(new SurfaceProperty(createGmlPolygon(factory, cd, config)));
}
for (CompositeCollection cc : comp.getChildComposites()) {
surfaces.add(new SurfaceProperty(createGmlComposite(factory, cc, config)));
}
if (surfaces.isEmpty()) {
return null;
}
return new CompositeSurface(surfaces);
}
public static org.xmlobjects.gml.model.geometry.primitives.LinearRing createGmlRing(GeometryFactory factory,
ParserConfiguration config, LinearRing lr) {
ProjCoordinate p1 = new ProjCoordinate();
ProjCoordinate p2 = new ProjCoordinate();
List<Double> ringValues = new ArrayList<>();
BasicCoordinateTransform trans = config.getOriginalTransform();
for (Vertex v : lr.getVertices()) {
double x = v.getX();
double y = v.getY();
double z = v.getZ();
if (trans != null) {
p1.x = x;
p1.y = y;
trans.transform(p1, p2);
x = p2.x;
y = p2.y;
z = z * config.getFromMeters();
}
ringValues.add(x);
ringValues.add(y);
ringValues.add(z);
}
org.xmlobjects.gml.model.geometry.primitives.LinearRing gmlLr = factory.createLinearRing(ringValues, 3);
gmlLr.setId(lr.getGmlId().getGmlString());
return gmlLr;
}
public static Solid createSolid(Geometry geom, GeometryFactory factory, ParserConfiguration config) {
if (geom.getType() != GeometryType.SOLID) {
throw new IllegalArgumentException("Only solids are allowed");
}
CompositeSurface comp = new CompositeSurface();
List<SurfaceProperty> surfaceMember = comp.getSurfaceMembers();
for (Polygon cdPoly : geom.getPolygons()) {
if (!cdPoly.isLink()) {
org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly,
config);
if (gmlPoly != null) {
surfaceMember.add(new SurfaceProperty(gmlPoly));
}
} else {
// add reference to polygon
surfaceMember.add(new SurfaceProperty("#" + cdPoly.getGmlId().getGmlString()));
}
}
if (surfaceMember.isEmpty()) {
return null;
}
Solid solid = new Solid();
Shell shell = new Shell(surfaceMember);
solid.setExterior(new ShellProperty(shell));
solid.setId(geom.getGmlId().getGmlString());
return solid;
}
public static MultiSurface createMultiSurface(Geometry geom, GeometryFactory factory, ParserConfiguration config) {
if (geom.getType() != GeometryType.MULTI_SURFACE && geom.getType() != GeometryType.COMPOSITE_SURFACE) {
throw new IllegalArgumentException("This can only handle MultiSurfaces");
}
List<SurfaceProperty> surfaces = new ArrayList<>();
Set<CompositeCollection> compositeCollections = new HashSet<>();
for (Polygon cdPoly : geom.getPolygons()) {
if (cdPoly instanceof ConcretePolygon conc && conc.isCompositeMember()) {
compositeCollections.add(conc.getPartOfComposite());
} else if (!cdPoly.isLink()) {
// is not part of a boundary surface
org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly,
config);
if (gmlPoly != null) {
surfaces.add(new SurfaceProperty(gmlPoly));
}
} else {
// add reference to polygon
surfaces.add(new SurfaceProperty("#" + cdPoly.getGmlId().getGmlString()));
}
}
for (CompositeCollection cdPoly : compositeCollections) {
surfaces.add(new SurfaceProperty(createGmlComposite(factory, cdPoly, config)));
}
if (surfaces.isEmpty()) {
return null;
}
MultiSurface ms = new MultiSurface(surfaces);
ms.setId(geom.getGmlId().getGmlString());
return ms;
}
public static MultiSurface createMultiSurface(List<Polygon> polygons, GeometryFactory factory,
ParserConfiguration config) {
List<SurfaceProperty> surfaces = new ArrayList<>();
for (Polygon cdPoly : polygons) {
org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config);
if (gmlPoly != null) {
surfaces.add(new SurfaceProperty(gmlPoly));
}
}
if (surfaces.isEmpty()) {
return null;
}
return new MultiSurface(surfaces);
}
public static CompositeSurface createCompositeSurface(Geometry geom, GeometryFactory factory,
ParserConfiguration config) {
List<SurfaceProperty> surfaces = new ArrayList<>();
for (Polygon cdPoly : geom.getPolygons()) {
org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config);
if (gmlPoly != null) {
surfaces.add(new SurfaceProperty(gmlPoly));
}
}
if (surfaces.isEmpty()) {
return null;
}
return new CompositeSurface(surfaces);
}
}
package org.xmlobjects.xml;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
public class Attributes implements Serializable {
private static final long serialVersionUID = 8942583366234714632L;
private final Map<String, Map<String, TextContent>> attributes = new HashMap<>();
public boolean isEmpty() {
return attributes.isEmpty();
}
public void add(String namespaceURI, String localName, TextContent value) {
attributes.computeIfAbsent(namespaceURI, v -> new HashMap<>()).put(localName, value);
}
public void add(String namespaceURI, String localName, String value) {
add(namespaceURI, localName, TextContent.of(value));
}
public void add(String localName, TextContent value) {
add(XMLConstants.NULL_NS_URI, localName, value);
}
public void add(String localName, String value) {
add(localName, TextContent.of(value));
}
public void add(QName name, TextContent value) {
add(name.getNamespaceURI(), name.getLocalPart(), value);
}
public void add(QName name, String value) {
add(name, TextContent.of(value));
}
public void addAll(String namespaceURI, Map<String, TextContent> attributes) {
this.attributes.computeIfAbsent(namespaceURI, v -> new HashMap<>()).putAll(attributes);
}
public Map<String, Map<String, TextContent>> get() {
return attributes;
}
public Map<String, TextContent> get(String namespaceURI) {
return attributes.getOrDefault(namespaceURI, Collections.emptyMap());
}
public TextContent getValue(String localName) {
return getValue(XMLConstants.NULL_NS_URI, localName);
}
public TextContent getValue(String namespaceURI, String localName) {
return get(namespaceURI).getOrDefault(localName, TextContent.empty());
}
public TextContent getValue(QName name) {
return getValue(name.getNamespaceURI(), name.getLocalPart());
}
public Attributes copy() {
Attributes copy = new Attributes();
copy.attributes.putAll(attributes);
return copy;
}
}
package de.hft.stuttgart.citydoctor2.datastructure;
import static org.junit.jupiter.api.Assertions.*;
import org.citygml4j.core.model.construction.WallSurface;
import org.citygml4j.core.util.geometry.GeometryFactory;
import org.junit.jupiter.api.Test;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
class BridgeConstructiveElementTest {
@Test
void testBoundarySurfaceGeometryRecreation() {
WallSurface wallSurface = new WallSurface();
BoundarySurface surface = new BoundarySurface(wallSurface);
surface.addGeometry(GeometryTestUtils.createDummyGeometry(GeometryType.MULTI_SURFACE, Lod.LOD2));
var gmlBce = new org.citygml4j.core.model.bridge.BridgeConstructiveElement();
BridgeConstructiveElement bce = new BridgeConstructiveElement(gmlBce);
bce.addBoundarySurface(surface);
assertNull(wallSurface.getLod2MultiSurface());
GeometryFactory factory = GeometryFactory.newInstance();
ParserConfiguration config = new ParserConfiguration(8, false);
bce.reCreateGeometries(factory, config);
assertNotNull(wallSurface.getLod2MultiSurface());
}
}
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