Commit 0f3d9a85 authored by Riegel's avatar Riegel
Browse files

Merge branch 'dev' into 'master'

CityDoctor Release Version 3.16.0

See merge request !11
parents b7b8f5fe b2d40f78
Pipeline #10323 passed with stage
in 1 minute and 25 seconds
...@@ -22,7 +22,6 @@ package de.hft.stuttgart.citydoctor2.datastructure; ...@@ -22,7 +22,6 @@ package de.hft.stuttgart.citydoctor2.datastructure;
* The available opening types in CityGML * The available opening types in CityGML
* *
* @author Matthias Betz * @author Matthias Betz
*
*/ */
public enum OpeningType { public enum OpeningType {
......
...@@ -18,17 +18,16 @@ ...@@ -18,17 +18,16 @@
*/ */
package de.hft.stuttgart.citydoctor2.datastructure; package de.hft.stuttgart.citydoctor2.datastructure;
import java.io.Serial;
import java.util.List;
import de.hft.stuttgart.citydoctor2.math.Vector3d; import de.hft.stuttgart.citydoctor2.math.Vector3d;
import de.hft.stuttgart.citydoctor2.tesselation.TesselatedPolygon; import de.hft.stuttgart.citydoctor2.tesselation.TesselatedPolygon;
import java.io.Serial;
import java.util.List;
/** /**
* Interface for concrete and linked polygons. * Interface for concrete and linked polygons.
* *
* @author Matthias Betz * @author Matthias Betz
*
*/ */
public abstract class Polygon extends GmlElement { public abstract class Polygon extends GmlElement {
...@@ -36,6 +35,7 @@ public abstract class Polygon extends GmlElement { ...@@ -36,6 +35,7 @@ public abstract class Polygon extends GmlElement {
private static final long serialVersionUID = -613942946364706513L; private static final long serialVersionUID = -613942946364706513L;
public abstract Vector3d calculateNormalNormalized(); public abstract Vector3d calculateNormalNormalized();
public abstract Vector3d calculateNormal(); public abstract Vector3d calculateNormal();
public abstract TesselatedPolygon tesselate(); public abstract TesselatedPolygon tesselate();
......
package de.hft.stuttgart.citydoctor2.datastructure;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.Serial;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Reference object for handling of implicit geometries with a relative geometry
*
* @author Riegel
*/
public class RelativeGeometry extends Geometry {
private static final Logger logger = LogManager.getLogger(RelativeGeometry.class);
@Serial
private static final long serialVersionUID = -686112245455298977L;
private static Map<Geometry, RelativeGeometry> relativeGeometries = new ConcurrentHashMap<>();
public static RelativeGeometry of(Geometry geom) {
if (relativeGeometries.containsKey(geom)) {
return relativeGeometries.get(geom);
}
RelativeGeometry relGeo = new RelativeGeometry(geom.getType(), geom.getLod());
geom.getPolygons().forEach(relGeo::addPolygon);
relGeo.updateEdgesAndVertices();
relativeGeometries.put(geom, relGeo);
return relGeo;
}
private RelativeGeometry(GeometryType type, Lod lod) {
super(type, lod);
}
}
...@@ -18,19 +18,18 @@ ...@@ -18,19 +18,18 @@
*/ */
package de.hft.stuttgart.citydoctor2.datastructure; package de.hft.stuttgart.citydoctor2.datastructure;
import java.io.Serial;
import java.util.ArrayList;
import java.util.List;
import org.citygml4j.core.model.relief.ReliefFeature;
import org.citygml4j.core.util.geometry.GeometryFactory;
import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.Check;
import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.utils.CopyHandler; import de.hft.stuttgart.citydoctor2.utils.CopyHandler;
import de.hft.stuttgart.citydoctor2.utils.Copyable; import de.hft.stuttgart.citydoctor2.utils.Copyable;
import org.citygml4j.core.model.relief.ReliefFeature;
import org.citygml4j.core.util.geometry.GeometryFactory;
import java.io.Serial;
import java.util.ArrayList;
import java.util.List;
public class ReliefObject extends CityObject { public class ReliefObject extends CityObject {
......
package de.hft.stuttgart.citydoctor2.datastructure;
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.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.utils.CopyHandler;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
import org.citygml4j.core.util.geometry.GeometryFactory;
import java.io.Serial;
import java.util.ArrayList;
import java.util.List;
public class Storey extends AbstractBuildingSubdivision {
@Serial
private static final long serialVersionUID = 5162814691642668089L;
private final List<BuildingUnit> buildingUnits = new ArrayList<>();
@Override
public Copyable createCopyInstance() {
return new Storey();
}
@Override
public void unsetGmlGeometries() {
super.unsetGmlGeometries();
for (BuildingUnit buildingUnit : buildingUnits) {
buildingUnit.unsetGmlGeometries();
}
}
@Override
public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) {
super.reCreateGeometries(factory, config);
for (BuildingUnit buildingUnit : buildingUnits) {
buildingUnit.reCreateGeometries(factory, config);
}
}
@Override
public void accept(Check c) {
super.accept(c);
for (BuildingUnit buildingUnit : buildingUnits) {
buildingUnit.accept(c);
}
}
@Override
public void collectContainedErrors(List<CheckError> errors) {
super.collectContainedErrors(errors);
for (BuildingUnit buildingUnit : buildingUnits) {
buildingUnit.collectContainedErrors(errors);
}
}
@Override
public void clearAllContainedCheckResults() {
super.clearAllContainedCheckResults();
for (BuildingUnit buildingUnit : buildingUnits) {
buildingUnit.clearAllContainedCheckResults();
}
}
@Override
public boolean containsError(CheckId checkIdentifier) {
boolean hasError = super.containsError(checkIdentifier);
if (hasError) {
return true;
}
for (BuildingUnit buildingUnit : buildingUnits) {
if (buildingUnit.containsError(checkIdentifier)) {
return true;
}
}
return false;
}
@Override
public boolean containsAnyError() {
boolean hasError = super.containsAnyError();
if (hasError) {
return true;
}
for (BuildingUnit buildingUnit : buildingUnits) {
if (buildingUnit.containsAnyError()) {
return true;
}
}
return false;
}
@Override
public void prepareForChecking() {
super.prepareForChecking();
for (BuildingUnit buildingUnit : buildingUnits) {
buildingUnit.prepareForChecking();
}
}
@Override
public void clearMetaInformation() {
super.clearMetaInformation();
for (BuildingUnit buildingUnit : buildingUnits) {
buildingUnit.clearMetaInformation();
}
}
@Override
public void collectInstances(CopyHandler handler) {
super.collectInstances(handler);
for (BuildingUnit buildingUnit : buildingUnits) {
buildingUnit.collectInstances(handler);
}
}
@Override
public void fillValues(Copyable original, CopyHandler handler) {
super.fillValues(original, handler);
Storey originalSt = (Storey) original;
for (BuildingUnit buildingUnit : originalSt.buildingUnits) {
buildingUnits.add(handler.getCopyInstance(buildingUnit));
}
this.abs = originalSt.abs;
}
}
...@@ -22,7 +22,6 @@ package de.hft.stuttgart.citydoctor2.datastructure; ...@@ -22,7 +22,6 @@ package de.hft.stuttgart.citydoctor2.datastructure;
* Availabel bridge types in CityGML * Availabel bridge types in CityGML
* *
* @author Matthias Betz * @author Matthias Betz
*
*/ */
public enum SurfaceFeatureType { public enum SurfaceFeatureType {
......
...@@ -18,10 +18,9 @@ ...@@ -18,10 +18,9 @@
*/ */
package de.hft.stuttgart.citydoctor2.datastructure; package de.hft.stuttgart.citydoctor2.datastructure;
import java.io.Serial; import de.hft.stuttgart.citydoctor2.check.Check;
import java.util.ArrayList; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import java.util.List; import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils;
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.model.relief.TINRelief; import org.citygml4j.core.model.relief.TINRelief;
...@@ -31,9 +30,9 @@ import org.xmlobjects.gml.model.geometry.primitives.Triangle; ...@@ -31,9 +30,9 @@ import org.xmlobjects.gml.model.geometry.primitives.Triangle;
import org.xmlobjects.gml.model.geometry.primitives.TriangleArrayProperty; import org.xmlobjects.gml.model.geometry.primitives.TriangleArrayProperty;
import org.xmlobjects.gml.model.geometry.primitives.TriangulatedSurface; import org.xmlobjects.gml.model.geometry.primitives.TriangulatedSurface;
import de.hft.stuttgart.citydoctor2.check.Check; import java.io.Serial;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; import java.util.ArrayList;
import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils; import java.util.List;
public class TinObject extends CityObject { public class TinObject extends CityObject {
......
...@@ -18,10 +18,13 @@ ...@@ -18,10 +18,13 @@
*/ */
package de.hft.stuttgart.citydoctor2.datastructure; package de.hft.stuttgart.citydoctor2.datastructure;
import java.io.Serial; import de.hft.stuttgart.citydoctor2.check.Check;
import java.util.ArrayList; import de.hft.stuttgart.citydoctor2.check.CheckError;
import java.util.List; import de.hft.stuttgart.citydoctor2.check.CheckId;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils;
import de.hft.stuttgart.citydoctor2.utils.CopyHandler;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
import org.citygml4j.core.model.core.AbstractCityObject; import org.citygml4j.core.model.core.AbstractCityObject;
import org.citygml4j.core.model.core.AbstractSpace; import org.citygml4j.core.model.core.AbstractSpace;
import org.citygml4j.core.model.transportation.AbstractTransportationSpace; import org.citygml4j.core.model.transportation.AbstractTransportationSpace;
...@@ -31,19 +34,14 @@ import org.citygml4j.core.util.geometry.GeometryFactory; ...@@ -31,19 +34,14 @@ import org.citygml4j.core.util.geometry.GeometryFactory;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface; import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty; import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
import de.hft.stuttgart.citydoctor2.check.Check; import java.io.Serial;
import de.hft.stuttgart.citydoctor2.check.CheckError; import java.util.ArrayList;
import de.hft.stuttgart.citydoctor2.check.CheckId; import java.util.List;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils;
import de.hft.stuttgart.citydoctor2.utils.CopyHandler;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
/** /**
* Representation of a transportation object. * Representation of a transportation object.
* *
* @author Matthias Betz * @author Matthias Betz
*
*/ */
public class TransportationObject extends CityObject { public class TransportationObject extends CityObject {
...@@ -70,6 +68,9 @@ public class TransportationObject extends CityObject { ...@@ -70,6 +68,9 @@ public class TransportationObject extends CityObject {
@Override @Override
public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) { public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) {
for (Geometry geom : getGeometries()) { for (Geometry geom : getGeometries()) {
if (geom instanceof ImplicitGeometryHolder) {
continue;
}
if (geom.getType() == GeometryType.MULTI_SURFACE) { if (geom.getType() == GeometryType.MULTI_SURFACE) {
MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config); MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config);
switch (type) { switch (type) {
...@@ -236,7 +237,7 @@ public class TransportationObject extends CityObject { ...@@ -236,7 +237,7 @@ public class TransportationObject extends CityObject {
@Override @Override
public void unsetGmlGeometries() { public void unsetGmlGeometries() {
switch (type) { switch (type) {
case ROAD, TRACK, RAILWAY, SQUARE,TRANSPORTATION_COMPLEX: case ROAD, TRACK, RAILWAY, SQUARE, TRANSPORTATION_COMPLEX:
AbstractTransportationSpace tc = (AbstractTransportationSpace) ato; AbstractTransportationSpace tc = (AbstractTransportationSpace) ato;
tc.getDeprecatedProperties().setLod1MultiSurface(null); tc.getDeprecatedProperties().setLod1MultiSurface(null);
tc.setLod2MultiSurface(null); tc.setLod2MultiSurface(null);
......
package de.hft.stuttgart.citydoctor2.datastructure;
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.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.utils.CopyHandler;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
import org.citygml4j.core.model.core.AbstractSpaceBoundaryProperty;
import org.citygml4j.core.model.tunnel.TunnelInstallation;
import org.citygml4j.core.model.tunnel.TunnelInstallationProperty;
import org.citygml4j.core.util.geometry.GeometryFactory;
import java.io.Serial;
import java.util.ArrayList;
import java.util.List;
public class Tunnel extends AbstractTunnel {
@Serial
private static final long serialVersionUID = 5316281216192555555L;
private List<TunnelPart> tunnelParts = new ArrayList<>();
public List<TunnelPart> getTunnelParts() {
return tunnelParts;
}
@Override
public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) {
super.reCreateGeometries(factory, config);
for (TunnelPart tp : tunnelParts) {
tp.reCreateGeometries(factory, config);
}
}
@Override
public void accept(Check c) {
super.accept(c);
if (c.canExecute(this)) {
c.check(this);
}
for (TunnelPart tp : tunnelParts) {
tp.accept(c);
}
}
@Override
public void clearAllContainedCheckResults() {
super.clearAllContainedCheckResults();
for (TunnelPart tp : tunnelParts) {
tp.clearAllContainedCheckResults();
}
}
@Override
public void collectContainedErrors(List<CheckError> errors) {
super.collectContainedErrors(errors);
for (TunnelPart tp : tunnelParts) {
tp.collectContainedErrors(errors);
}
}
@Override
public boolean containsAnyError() {
boolean hasError = super.containsAnyError();
if (hasError) {
return true;
}
for (TunnelPart tp : tunnelParts) {
if (tp.containsAnyError()) {
return true;
}
}
return false;
}
@Override
public boolean containsError(CheckId checkIdentifier) {
boolean hasError = super.containsError(checkIdentifier);
if (hasError) {
return true;
}
for (TunnelPart tp : tunnelParts) {
if (tp.containsError(checkIdentifier)) {
return true;
}
}
return false;
}
public void addTunnelPart(TunnelPart tunnelPart) {
tunnelParts.add(tunnelPart);
}
@Override
public String toString() {
return "Tunnel [id=" + getGmlId() + "]";
}
public void anonymize() {
for (Geometry geom : getGeometries()) {
geom.anonymize();
}
org.citygml4j.core.model.tunnel.Tunnel gmlT = new org.citygml4j.core.model.tunnel.Tunnel();
gmlT.setId(GmlId.generateId().getGmlString());
for (Installation ti : getTunnelInstallations()) {
ti.anonymize();
gmlT.getTunnelInstallations().add(new TunnelInstallationProperty((TunnelInstallation) ti.getGmlObject()));
}
for (BoundarySurface bs : getBoundarySurfaces()) {
bs.anonymize();
gmlT.addBoundary(new AbstractSpaceBoundaryProperty(bs.getGmlObject()));
}
setCityGmlBuilding(gmlT);
}
@Override
public void clearMetaInformation() {
super.clearMetaInformation();
for (TunnelPart tp : tunnelParts) {
tp.clearMetaInformation();
}
}
@Override
public void prepareForChecking() {
super.prepareForChecking();
for (TunnelPart tp : tunnelParts) {
tp.prepareForChecking();
}
}
@Override
public void fillValues(Copyable original, CopyHandler handler) {
super.fillValues(original, handler);
Tunnel originalTunnel = (Tunnel) original;
for (TunnelPart originalTp : originalTunnel.tunnelParts) {
tunnelParts.add(handler.getCopyInstance(originalTp));
}
}
@Override
public void collectInstances(CopyHandler handler) {
super.collectInstances(handler);
for (TunnelPart tp : tunnelParts) {
handler.addInstance(tp);
}
}
@Override
public Copyable createCopyInstance() {
return new Tunnel();
}
}
package de.hft.stuttgart.citydoctor2.datastructure;
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.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils;
import de.hft.stuttgart.citydoctor2.utils.CopyHandler;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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 TunnelConstructiveElement extends CityObject {
private static final Logger logger = LogManager.getLogger(TunnelConstructiveElement.class);
private static final String CANNOT_ADD = "Cannot add ";
@Serial
private static final long serialVersionUID = 7353233899458901155L;
private final org.citygml4j.core.model.tunnel.TunnelConstructiveElement gmlTunnelElement;
private final List<BoundarySurface> boundarySurfaceList = new ArrayList<>();
public TunnelConstructiveElement(org.citygml4j.core.model.tunnel.TunnelConstructiveElement gmlObject) {
this.gmlTunnelElement = gmlObject;
}
@Override
public Copyable createCopyInstance() {
return new TunnelConstructiveElement(gmlTunnelElement);
}
@Override
public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) {
// only handles CityGML2 for now
// unknown which CityGML is handled here
// need context information to decide
for (Geometry geom : getGeometries()) {
if (geom instanceof ImplicitGeometryHolder) {
continue;
}
switch (geom.getType()) {
case SOLID:
Solid solid = CityGmlUtils.createSolid(geom, factory, config);
setSolidAccordingToLod(geom, solid);
break;
case MULTI_SURFACE:
MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config);
setMultiSurfaceAccordingToLod(geom, ms);
break;
}
}
for (BoundarySurface bs : boundarySurfaceList) {
reCreateBoundarySurface(factory, config, bs);
}
}
@Override
public void accept(Check c) {
super.accept(c);
if (c.canExecute(this)) {
c.check(this);
}
for (BoundarySurface bs : boundarySurfaceList) {
bs.accept(c);
}
}
@Override
public void collectContainedErrors(List<CheckError> errors) {
super.collectContainedErrors(errors);
for (BoundarySurface bs : boundarySurfaceList) {
bs.collectContainedErrors(errors);
}
}
@Override
public void clearAllContainedCheckResults() {
super.clearAllContainedCheckResults();
for (BoundarySurface bs : boundarySurfaceList) {
bs.clearAllContainedCheckResults();
}
}
@Override
public boolean containsError(CheckId checkIdentifier) {
boolean hasError = super.containsError(checkIdentifier);
if (hasError) {
return true;
}
for (BoundarySurface bs : boundarySurfaceList) {
if (bs.containsError(checkIdentifier)) {
return true;
}
}
return false;
}
@Override
public boolean containsAnyError() {
boolean hasError = super.containsAnyError();
if (hasError) {
return true;
}
for (BoundarySurface bs : boundarySurfaceList) {
if (bs.containsAnyError()) {
return true;
}
}
return false;
}
private void reCreateBoundarySurface(GeometryFactory factory, ParserConfiguration config, BoundarySurface bs) {
if (bs.getGeometries().isEmpty()) {
for (AbstractSpaceBoundaryProperty bsp : gmlTunnelElement.getBoundaries()) {
if (bsp.getObject() != null && bsp.getObject() == bs.getGmlObject()) {
logger.warn("Found empty boundary surface: {}, removing from TunnelConstructiveElement", bs.getGmlId());
gmlTunnelElement.getBoundaries().remove(bsp);
break;
}
}
return;
}
bs.reCreateGeometries(factory, config);
}
private void setSolidAccordingToLod(Geometry geom, Solid solid) {
switch (geom.getLod()) {
case LOD1:
gmlTunnelElement.setLod1Solid(new SolidProperty(solid));
break;
case LOD2:
gmlTunnelElement.setLod2Solid(new SolidProperty(solid));
break;
case LOD3:
gmlTunnelElement.setLod3Solid(new SolidProperty(solid));
break;
default:
throw new IllegalStateException(CANNOT_ADD + geom.getLod() + " solid to buildings");
}
}
private void setMultiSurfaceAccordingToLod(Geometry geom, MultiSurface ms) {
switch (geom.getLod()) {
case LOD0:
gmlTunnelElement.setLod0MultiSurface(new MultiSurfaceProperty(ms));
break;
case LOD2:
gmlTunnelElement.setLod2MultiSurface(new MultiSurfaceProperty(ms));
break;
case LOD3:
gmlTunnelElement.setLod3MultiSurface(new MultiSurfaceProperty(ms));
break;
default:
throw new IllegalStateException(CANNOT_ADD + geom.getLod() + " multi surface to buildings");
}
}
@Override
public org.citygml4j.core.model.tunnel.TunnelConstructiveElement getGmlObject() {
return gmlTunnelElement;
}
@Override
public void unsetGmlGeometries() {
gmlTunnelElement.setLod0MultiSurface(null);
gmlTunnelElement.setLod2MultiSurface(null);
gmlTunnelElement.setLod3MultiSurface(null);
gmlTunnelElement.setLod1Solid(null);
gmlTunnelElement.setLod2Solid(null);
gmlTunnelElement.setLod3Solid(null);
for (BoundarySurface bs : boundarySurfaceList) {
bs.unsetGmlGeometries();
}
}
@Override
public FeatureType getFeatureType() {
return FeatureType.TUNNEL_CONSTRUCTION_ELEMENT;
}
public void addBoundarySurface(BoundarySurface bs) {
boundarySurfaceList.add(bs);
bs.setParent(this);
}
public List<BoundarySurface> getBoundarySurfaces() {
return boundarySurfaceList;
}
@Override
public void prepareForChecking() {
super.prepareForChecking();
for (BoundarySurface bs : boundarySurfaceList) {
bs.prepareForChecking();
}
}
@Override
public void clearMetaInformation() {
super.clearMetaInformation();
for (BoundarySurface bs : boundarySurfaceList) {
bs.clearMetaInformation();
}
}
@Override
public void collectInstances(CopyHandler handler) {
super.collectInstances(handler);
handler.addInstance(boundarySurfaceList);
}
@Override
public void fillValues(Copyable original, CopyHandler handler) {
super.fillValues(original, handler);
TunnelConstructiveElement originalTce = (TunnelConstructiveElement) original;
for (BoundarySurface originalTs : originalTce.boundarySurfaceList) {
boundarySurfaceList.add(handler.getCopyInstance(originalTs));
}
}
}
package de.hft.stuttgart.citydoctor2.datastructure;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
import java.io.Serial;
public class TunnelFurniture extends AbstractFurniture {
@Serial
private static final long serialVersionUID = -4667219019432204174L;
public void setGmlObject(org.citygml4j.core.model.tunnel.TunnelFurniture gmlObject) {
super.setGmlObject(gmlObject);
}
@Override
public Copyable createCopyInstance() {
return new BuildingRoomFurniture();
}
}
package de.hft.stuttgart.citydoctor2.datastructure;
import de.hft.stuttgart.citydoctor2.utils.CopyHandler;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
import org.citygml4j.core.model.tunnel.TunnelFurnitureProperty;
import java.io.Serial;
import java.util.ArrayList;
import java.util.List;
public class TunnelHollow extends AbstractRoom {
@Serial
private static final long serialVersionUID = -276088332165299253L;
private final List<TunnelFurnitureProperty> furnitureRefs = new ArrayList<>(2);
private CityObject parent;
public void setGmlObject(org.citygml4j.core.model.tunnel.HollowSpace gmlHollowSpace) {
super.cgmlRoom = gmlHollowSpace;
}
public void setParent(CityObject parent) {
this.parent = parent;
}
public void addFurnitureRef(TunnelFurnitureProperty furnitureRef) {
furnitureRefs.add(furnitureRef);
}
public List<TunnelFurnitureProperty> getFurnitureRefs() {
return furnitureRefs;
}
public CityObject getParent() {
return parent;
}
@Override
public void fillValues(Copyable original, CopyHandler handler) {
super.fillValues(original, handler);
TunnelHollow oHollow = (TunnelHollow) original;
parent = handler.getCopyInstance(oHollow.getParent());
}
@Override
public void collectInstances(CopyHandler handler) {
super.collectInstances(handler);
handler.addInstance(parent);
}
@Override
public Copyable createCopyInstance() {
return new TunnelHollow();
}
}
package de.hft.stuttgart.citydoctor2.datastructure;
import de.hft.stuttgart.citydoctor2.utils.CopyHandler;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
import java.io.Serial;
public class TunnelPart extends AbstractTunnel {
@Serial
private static final long serialVersionUID = 8200322261958679163L;
private Tunnel parent;
public TunnelPart(Tunnel parent) {
this.parent = parent;
parent.addTunnelPart(this);
}
public Tunnel getParent() {
return parent;
}
@Override
public FeatureType getFeatureType() {
return FeatureType.TUNNEL_PART;
}
@Override
public String toString() {
return "TunnelPart [id=" + getGmlId() + "]";
}
@Override
public void fillValues(Copyable original, CopyHandler handler) {
super.fillValues(original, handler);
TunnelPart originalPart = (TunnelPart) original;
parent = handler.getCopyInstance(originalPart.parent);
}
@Override
public void collectInstances(CopyHandler handler) {
super.collectInstances(handler);
handler.addInstance(parent);
}
@Override
public Copyable createCopyInstance() {
return new TunnelPart();
}
private TunnelPart() {
}
}
...@@ -18,9 +18,10 @@ ...@@ -18,9 +18,10 @@
*/ */
package de.hft.stuttgart.citydoctor2.datastructure; package de.hft.stuttgart.citydoctor2.datastructure;
import java.io.Serial; import de.hft.stuttgart.citydoctor2.check.Check;
import java.util.Collections; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
import org.citygml4j.core.model.core.AbstractCityObject; import org.citygml4j.core.model.core.AbstractCityObject;
import org.citygml4j.core.model.vegetation.AbstractVegetationObject; import org.citygml4j.core.model.vegetation.AbstractVegetationObject;
import org.citygml4j.core.model.vegetation.PlantCover; import org.citygml4j.core.model.vegetation.PlantCover;
...@@ -33,16 +34,13 @@ import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty; ...@@ -33,16 +34,13 @@ import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
import org.xmlobjects.gml.model.geometry.primitives.Solid; import org.xmlobjects.gml.model.geometry.primitives.Solid;
import org.xmlobjects.gml.model.geometry.primitives.SolidProperty; import org.xmlobjects.gml.model.geometry.primitives.SolidProperty;
import de.hft.stuttgart.citydoctor2.check.Check; import java.io.Serial;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; import java.util.Collections;
import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
/** /**
* Representation of CityGML vegetation objects * Representation of CityGML vegetation objects
* *
* @author Matthias Betz * @author Matthias Betz
*
*/ */
public class Vegetation extends CityObject { public class Vegetation extends CityObject {
...@@ -68,6 +66,9 @@ public class Vegetation extends CityObject { ...@@ -68,6 +66,9 @@ public class Vegetation extends CityObject {
@Override @Override
public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) { public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) {
for (Geometry geom : getGeometries()) { for (Geometry geom : getGeometries()) {
if (geom instanceof ImplicitGeometryHolder) {
continue;
}
if (geom.getType() == GeometryType.MULTI_SURFACE) { if (geom.getType() == GeometryType.MULTI_SURFACE) {
MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config); MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config);
if (type == VegetationType.SOLITARY_VEGETATION_OBJECT) { if (type == VegetationType.SOLITARY_VEGETATION_OBJECT) {
......
...@@ -18,22 +18,21 @@ ...@@ -18,22 +18,21 @@
*/ */
package de.hft.stuttgart.citydoctor2.datastructure; package de.hft.stuttgart.citydoctor2.datastructure;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
import de.hft.stuttgart.citydoctor2.utils.CopyHandler;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
import de.hft.stuttgart.citydoctor2.utils.SerializablePair;
import java.io.Serial; import java.io.Serial;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
import de.hft.stuttgart.citydoctor2.utils.CopyHandler;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
import de.hft.stuttgart.citydoctor2.utils.SerializablePair;
/** /**
* Contains the vertex information of a point in a linear ring * Contains the vertex information of a point in a linear ring
* *
* @author Matthias Betz * @author Matthias Betz
*
*/ */
public class Vertex extends Vector3d implements Copyable { public class Vertex extends Vector3d implements Copyable {
......
...@@ -18,27 +18,25 @@ ...@@ -18,27 +18,25 @@
*/ */
package de.hft.stuttgart.citydoctor2.datastructure; package de.hft.stuttgart.citydoctor2.datastructure;
import java.io.Serial; import de.hft.stuttgart.citydoctor2.check.Check;
import java.util.ArrayList; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import java.util.List; import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils;
import de.hft.stuttgart.citydoctor2.utils.CopyHandler;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
import org.citygml4j.core.model.core.AbstractCityObject; import org.citygml4j.core.model.core.AbstractCityObject;
import org.citygml4j.core.model.waterbody.WaterBody; import org.citygml4j.core.model.waterbody.WaterBody;
import org.citygml4j.core.util.geometry.GeometryFactory; import org.citygml4j.core.util.geometry.GeometryFactory;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface; import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty; import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
import de.hft.stuttgart.citydoctor2.check.Check; import java.io.Serial;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; import java.util.ArrayList;
import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils; import java.util.List;
import de.hft.stuttgart.citydoctor2.utils.CopyHandler;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
/** /**
* Represents cityGML water body objects. * Represents cityGML water body objects.
* *
* @author Matthias Betz * @author Matthias Betz
*
*/ */
public class WaterObject extends CityObject { public class WaterObject extends CityObject {
......
...@@ -18,48 +18,38 @@ ...@@ -18,48 +18,38 @@
*/ */
package de.hft.stuttgart.citydoctor2.mapper.citygml3; package de.hft.stuttgart.citydoctor2.mapper.citygml3;
import java.nio.file.Path; import de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding;
import java.util.ArrayList; import de.hft.stuttgart.citydoctor2.datastructure.AbstractTunnel;
import java.util.HashMap; import de.hft.stuttgart.citydoctor2.datastructure.BridgeConstructiveElement;
import java.util.List; import de.hft.stuttgart.citydoctor2.datastructure.*;
import java.util.Map; import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.BuildingPart;
import de.hft.stuttgart.citydoctor2.datastructure.BuildingRoom;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.BridgeObject.BridgeType;
import de.hft.stuttgart.citydoctor2.datastructure.TunnelConstructiveElement;
import de.hft.stuttgart.citydoctor2.datastructure.TunnelFurniture;
import de.hft.stuttgart.citydoctor2.datastructure.TunnelPart;
import de.hft.stuttgart.citydoctor2.datastructure.TransportationObject.TransportationType;
import de.hft.stuttgart.citydoctor2.datastructure.Vegetation.VegetationType;
import de.hft.stuttgart.citydoctor2.math.graph.KDTree;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.utils.Localization;
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.model.CityGMLVersion; import org.citygml4j.core.model.CityGMLVersion;
import org.citygml4j.core.model.bridge.AbstractBridge; import org.citygml4j.core.model.bridge.*;
import org.citygml4j.core.model.bridge.Bridge; import org.citygml4j.core.model.building.BuildingUnit;
import org.citygml4j.core.model.bridge.BridgeConstructiveElementProperty; import org.citygml4j.core.model.building.Storey;
import org.citygml4j.core.model.bridge.BridgeInstallation; import org.citygml4j.core.model.building.*;
import org.citygml4j.core.model.bridge.BridgeInstallationProperty;
import org.citygml4j.core.model.bridge.BridgePart;
import org.citygml4j.core.model.bridge.BridgePartProperty;
import org.citygml4j.core.model.building.BuildingInstallationProperty;
import org.citygml4j.core.model.building.BuildingPartProperty;
import org.citygml4j.core.model.construction.AbstractConstruction; import org.citygml4j.core.model.construction.AbstractConstruction;
import org.citygml4j.core.model.core.AbstractCityObject; import org.citygml4j.core.model.core.*;
import org.citygml4j.core.model.core.AbstractFeatureWithLifespan;
import org.citygml4j.core.model.core.AbstractOccupiedSpace;
import org.citygml4j.core.model.core.AbstractPhysicalSpace;
import org.citygml4j.core.model.core.AbstractSpace;
import org.citygml4j.core.model.core.AbstractSpaceBoundary;
import org.citygml4j.core.model.core.AbstractSpaceBoundaryProperty;
import org.citygml4j.core.model.core.AbstractThematicSurface;
import org.citygml4j.core.model.core.AbstractUnoccupiedSpace;
import org.citygml4j.core.model.core.CityModel;
import org.citygml4j.core.model.deprecated.transportation.TransportationComplex; import org.citygml4j.core.model.deprecated.transportation.TransportationComplex;
import org.citygml4j.core.model.landuse.LandUse; import org.citygml4j.core.model.landuse.LandUse;
import org.citygml4j.core.model.transportation.AbstractTransportationSpace; import org.citygml4j.core.model.transportation.*;
import org.citygml4j.core.model.transportation.AuxiliaryTrafficArea; import org.citygml4j.core.model.tunnel.Tunnel;
import org.citygml4j.core.model.transportation.AuxiliaryTrafficSpace; import org.citygml4j.core.model.tunnel.*;
import org.citygml4j.core.model.transportation.AuxiliaryTrafficSpaceProperty;
import org.citygml4j.core.model.transportation.Railway;
import org.citygml4j.core.model.transportation.Road;
import org.citygml4j.core.model.transportation.Square;
import org.citygml4j.core.model.transportation.Track;
import org.citygml4j.core.model.transportation.TrafficArea;
import org.citygml4j.core.model.transportation.TrafficSpace;
import org.citygml4j.core.model.transportation.TrafficSpaceProperty;
import org.citygml4j.core.model.vegetation.AbstractVegetationObject; import org.citygml4j.core.model.vegetation.AbstractVegetationObject;
import org.citygml4j.core.model.vegetation.PlantCover; import org.citygml4j.core.model.vegetation.PlantCover;
import org.citygml4j.core.model.vegetation.SolitaryVegetationObject; import org.citygml4j.core.model.vegetation.SolitaryVegetationObject;
...@@ -71,64 +61,42 @@ import org.xmlobjects.gml.model.geometry.AbstractGeometry; ...@@ -71,64 +61,42 @@ import org.xmlobjects.gml.model.geometry.AbstractGeometry;
import org.xmlobjects.gml.model.geometry.GeometryProperty; import org.xmlobjects.gml.model.geometry.GeometryProperty;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface; import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty; import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
import org.xmlobjects.gml.model.geometry.primitives.AbstractSolid; import org.xmlobjects.gml.model.geometry.complexes.CompositeSurface;
import org.xmlobjects.gml.model.geometry.primitives.AbstractSurface; import org.xmlobjects.gml.model.geometry.primitives.*;
import org.xmlobjects.gml.model.geometry.primitives.Shell;
import org.xmlobjects.gml.model.geometry.primitives.ShellProperty;
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 de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding; import java.nio.file.Path;
import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface; import java.util.ArrayList;
import de.hft.stuttgart.citydoctor2.datastructure.BridgeConstructiveElement; import java.util.HashMap;
import de.hft.stuttgart.citydoctor2.datastructure.BridgeObject; import java.util.List;
import de.hft.stuttgart.citydoctor2.datastructure.BridgeObject.BridgeType; import java.util.Map;
import de.hft.stuttgart.citydoctor2.datastructure.Building;
import de.hft.stuttgart.citydoctor2.datastructure.BuildingPart;
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.GeometryType;
import de.hft.stuttgart.citydoctor2.datastructure.GmlElement;
import de.hft.stuttgart.citydoctor2.datastructure.GmlId;
import de.hft.stuttgart.citydoctor2.datastructure.Installation;
import de.hft.stuttgart.citydoctor2.datastructure.LandObject;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.LinkedPolygon;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Opening;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.TransportationObject;
import de.hft.stuttgart.citydoctor2.datastructure.TransportationObject.TransportationType;
import de.hft.stuttgart.citydoctor2.datastructure.Vegetation;
import de.hft.stuttgart.citydoctor2.datastructure.Vegetation.VegetationType;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
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;
public class Citygml3FeatureMapper extends ObjectWalker { public class Citygml3FeatureMapper extends ObjectWalker {
private static final Logger logger = LogManager.getLogger(Citygml3FeatureMapper.class); private static final Logger logger = LogManager.getLogger(Citygml3FeatureMapper.class);
private final CityDoctorModel model; private final CityDoctorModel model;
private final ParserConfiguration config;
private final Path directory;
private final double neighborDistance;
private Map<String, ConcretePolygon> polygonMap = new HashMap<>(); private Map<String, ConcretePolygon> polygonMap = new HashMap<>();
private Map<String, CompositeCollection> compositeMap = new HashMap<>();
private List<ResolvableReference> references = new ArrayList<>(); private List<ResolvableReference> references = new ArrayList<>();
private Map<Vertex, Vertex> vertexMap = new HashMap<>(); private Map<Vertex, Vertex> vertexMap = new HashMap<>();
private final ParserConfiguration config;
private final double neighborDistance;
public Citygml3FeatureMapper(ParserConfiguration config, Path path) { public Citygml3FeatureMapper(ParserConfiguration config, Path path) {
this.config = config; this.config = config;
this.directory = path.getParent();
model = new CityDoctorModel(config, path.toFile()); model = new CityDoctorModel(config, path.toFile());
neighborDistance = 1.8d / Math.pow(10, config.getNumberOfRoundingPlaces()); neighborDistance = 1.8d / Math.pow(10, config.getNumberOfRoundingPlaces());
} }
public static void parseId(AbstractGML gml, GmlElement gmlElement) {
String id = gml.getId();
if (id != null) {
gmlElement.setGmlId(new GmlId(id));
}
}
@Override @Override
public void visit(AbstractSpace space) { public void visit(AbstractSpace space) {
// if we are here, an AbstractSpace thing was read that is not handled in the // if we are here, an AbstractSpace thing was read that is not handled in the
...@@ -136,6 +104,41 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -136,6 +104,41 @@ public class Citygml3FeatureMapper extends ObjectWalker {
} }
@Override
public void visit(org.citygml4j.core.model.cityfurniture.CityFurniture gmlCityFurniture) {
CityFurniture cf = new CityFurniture();
cf.setGmlObject(gmlCityFurniture);
mapAbstractOccupiedSpace(gmlCityFurniture, cf);
resolveAndClearReferences();
cf.unsetGmlGeometries();
updateEdgesAndVertices(cf);
model.addCityFurniture(cf);
}
@Override
public void visit(org.citygml4j.core.model.generics.GenericOccupiedSpace gos) {
GenericCityObject gco = new GenericCityObject();
gco.setGmlObject(gos);
GeometryProperty<?> agLod1 = gos.getDeprecatedProperties().getLod1Geometry();
GeometryProperty<?> agLod4 = gos.getDeprecatedProperties().getLod4Geometry();
if (agLod1 != null && agLod1.getObject() != null &&
agLod1.getObject() instanceof MultiSurface ms) {
gco.addGeometry(parseMultiSurface(ms, Lod.LOD1));
}
if (agLod4 != null && agLod4.getObject() != null) {
if (agLod4.getObject() instanceof MultiSurface ms) {
gco.addGeometry(parseMultiSurface(ms, Lod.LOD4));
} else if (agLod4.getObject() instanceof AbstractSolid solid) {
gco.addGeometry(parseSolid(solid, Lod.LOD4));
}
}
mapAbstractOccupiedSpace(gos, gco);
resolveAndClearReferences();
gco.unsetGmlGeometries();
updateEdgesAndVertices(gco);
model.addGenericCityObject(gco);
}
@Override @Override
public void visit(org.citygml4j.core.model.building.Building gmlBuilding) { public void visit(org.citygml4j.core.model.building.Building gmlBuilding) {
Building cdBuilding = new Building(); Building cdBuilding = new Building();
...@@ -158,7 +161,7 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -158,7 +161,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
parseAndAddMultiSurface(waterBody.getDeprecatedProperties().getLod1MultiSurface(), Lod.LOD1, wo); parseAndAddMultiSurface(waterBody.getDeprecatedProperties().getLod1MultiSurface(), Lod.LOD1, wo);
parseAndAddSolid(waterBody.getDeprecatedProperties().getLod4Solid(), Lod.LOD4, wo); parseAndAddSolid(waterBody.getDeprecatedProperties().getLod4Solid(), Lod.LOD4, wo);
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, vertexMap, config); SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : waterBody.getBoundaries()) { for (AbstractSpaceBoundaryProperty surfaceProp : waterBody.getBoundaries()) {
if (!surfaceProp.isSetObject()) { if (!surfaceProp.isSetObject()) {
continue; continue;
...@@ -223,6 +226,7 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -223,6 +226,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
private void mapAbstractOccupiedSpace(AbstractOccupiedSpace aos, CityObject co) { private void mapAbstractOccupiedSpace(AbstractOccupiedSpace aos, CityObject co) {
mapAbstractPhysicalSpace(aos, co); mapAbstractPhysicalSpace(aos, co);
parseImplicitGeometry(aos, co);
} }
private void mapAbstractPhysicalSpace(AbstractPhysicalSpace aps, CityObject co) { private void mapAbstractPhysicalSpace(AbstractPhysicalSpace aps, CityObject co) {
...@@ -237,11 +241,26 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -237,11 +241,26 @@ public class Citygml3FeatureMapper extends ObjectWalker {
parseAndAddSolid(as.getLod1Solid(), Lod.LOD1, co); parseAndAddSolid(as.getLod1Solid(), Lod.LOD1, co);
parseAndAddSolid(as.getLod2Solid(), Lod.LOD2, co); parseAndAddSolid(as.getLod2Solid(), Lod.LOD2, co);
parseAndAddSolid(as.getLod3Solid(), Lod.LOD3, co); parseAndAddSolid(as.getLod3Solid(), Lod.LOD3, co);
parseAndAddGenericAttributes(as, co);
}
private void parseAndAddGenericAttributes(AbstractSpace as, CityObject co) {
for (AbstractGenericAttributeProperty aga : as.getGenericAttributes()) {
co.addGenericAttribute(new GenericAttribute(aga));
}
} }
@Override @Override
public void visit(Bridge bridge) { public void visit(Bridge bridge) {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, bridge); BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, bridge);
// parse deprecated geometries
parseAndAddMultiSurface(bridge.getDeprecatedProperties().getLod1MultiSurface(), Lod.LOD1, bo);
parseAndAddMultiSurface(bridge.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, bo);
parseAndAddSolid(bridge.getDeprecatedProperties().getLod4Solid(), Lod.LOD4, bo);
mapAbstractBridge(bridge, bo);
for (BridgePartProperty bPartProperty : bridge.getBridgeParts()) { for (BridgePartProperty bPartProperty : bridge.getBridgeParts()) {
if (!bPartProperty.isSetObject()) { if (!bPartProperty.isSetObject()) {
continue; continue;
...@@ -251,7 +270,6 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -251,7 +270,6 @@ public class Citygml3FeatureMapper extends ObjectWalker {
mapAbstractBridge(gmlBridgePart, bPart); mapAbstractBridge(gmlBridgePart, bPart);
bo.addBridgePart(bPart); bo.addBridgePart(bPart);
} }
mapAbstractBridge(bridge, bo);
resolveAndClearReferences(); resolveAndClearReferences();
updateEdgesAndVertices(bo); updateEdgesAndVertices(bo);
for (BridgeObject part : bo.getParts()) { for (BridgeObject part : bo.getParts()) {
...@@ -295,7 +313,7 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -295,7 +313,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
bo.addBridgeInstallation(bi); bo.addBridgeInstallation(bi);
} }
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, vertexMap, config); SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : ab.getBoundaries()) { for (AbstractSpaceBoundaryProperty surfaceProp : ab.getBoundaries()) {
if (!surfaceProp.isSetObject()) { if (!surfaceProp.isSetObject()) {
continue; continue;
...@@ -324,7 +342,7 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -324,7 +342,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
parseAndAddAbstractGeometry(lod4Prop, Lod.LOD4, bi); parseAndAddAbstractGeometry(lod4Prop, Lod.LOD4, bi);
bi.unsetGmlGeometries(); bi.unsetGmlGeometries();
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, vertexMap, config); SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlBi.getBoundaries()) { for (AbstractSpaceBoundaryProperty surfaceProp : gmlBi.getBoundaries()) {
if (!surfaceProp.isSetObject()) { if (!surfaceProp.isSetObject()) {
continue; continue;
...@@ -350,6 +368,228 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -350,6 +368,228 @@ public class Citygml3FeatureMapper extends ObjectWalker {
return bi; return bi;
} }
@Override
public void visit(Tunnel tunnel) {
de.hft.stuttgart.citydoctor2.datastructure.Tunnel tu = new de.hft.stuttgart.citydoctor2.datastructure.Tunnel();
for (TunnelPartProperty tPartProperty : tunnel.getTunnelParts()) {
if (!tPartProperty.isSetObject()) {
continue;
}
org.citygml4j.core.model.tunnel.TunnelPart gmlTunnelPart = tPartProperty.getObject();
TunnelPart tPart = new TunnelPart(tu);
readAbstractTunnel(gmlTunnelPart, tPart);
tu.addTunnelPart(tPart);
}
readAbstractTunnel(tunnel, tu);
resolveAndClearReferences();
updateEdgesAndVertices(tu);
for (TunnelPart part : tu.getTunnelParts()) {
updateEdgesAndVertices(part);
}
model.addTunnel(tu);
}
private void readAbstractTunnel(org.citygml4j.core.model.tunnel.AbstractTunnel gmlTunnel, AbstractTunnel cdTunnel) {
mapAbstractOccupiedSpace(gmlTunnel, cdTunnel);
cdTunnel.setGmlObject(gmlTunnel);
// parse deprecated geometries
parseAndAddMultiSurface(gmlTunnel.getDeprecatedProperties().getLod1MultiSurface(), Lod.LOD1, cdTunnel);
parseAndAddMultiSurface(gmlTunnel.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, cdTunnel);
parseAndAddSolid(gmlTunnel.getDeprecatedProperties().getLod4Solid(), Lod.LOD4, cdTunnel);
for (TunnelInstallationProperty tiProp : gmlTunnel.getTunnelInstallations()) {
var gmlTi = tiProp.getObject();
if (gmlTi == null) {
// ignore empty properties
continue;
}
Installation ti = mapTunnelInstallation(gmlTi);
cdTunnel.addTunnelInstallation(ti);
}
for (HollowSpaceProperty thProp : gmlTunnel.getHollowSpaces()) {
var gmlTh = thProp.getObject();
if (gmlTh == null) {
continue;
}
TunnelHollow br = mapTunnelHollow(gmlTh);
cdTunnel.addTunnelHollow(br);
}
for (Installation ti : cdTunnel.getTunnelInstallations()) {
updateEdgesAndVertices(ti);
for (BoundarySurface bs : ti.getBoundarySurfaces()) {
updateEdgesAndVertices(bs);
for (Opening o : bs.getOpenings()) {
updateEdgesAndVertices(o);
}
}
}
for (TunnelFurnitureProperty tfProp : gmlTunnel.getTunnelFurniture()) {
var gmlTf = tfProp.getObject();
if (gmlTf == null) {
continue;
}
TunnelFurniture tf = mapTunnelFurniture(gmlTf);
cdTunnel.addTunnelFurniture(tf);
}
for (TunnelConstructiveElementProperty teProp : gmlTunnel.getTunnelConstructiveElements()) {
var gmlTc = teProp.getObject();
if (gmlTc == null) {
continue;
}
TunnelConstructiveElement tc = mapTunnelConstructiveElement(gmlTc);
cdTunnel.addTunnelConstructiveElement(tc);
}
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlTunnel.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
updateEdgesAndVertices(bs);
for (Opening o : bs.getOpenings()) {
updateEdgesAndVertices(o);
}
}
cdTunnel.unsetGmlGeometries();
resolveAndClearReferences();
updateEdgesAndVertices(cdTunnel);
}
private Installation mapTunnelInstallation(TunnelInstallation gmlTi) {
Installation ti = new Installation();
ti.setGmlObject(gmlTi);
mapAbstractOccupiedSpace(gmlTi, ti);
GeometryProperty<?> lod2Prop = gmlTi.getDeprecatedProperties().getLod2Geometry();
parseAndAddAbstractGeometry(lod2Prop, Lod.LOD2, ti);
GeometryProperty<?> lod3Prop = gmlTi.getDeprecatedProperties().getLod3Geometry();
parseAndAddAbstractGeometry(lod3Prop, Lod.LOD3, ti);
GeometryProperty<?> lod4Prop = gmlTi.getDeprecatedProperties().getLod4Geometry();
parseAndAddAbstractGeometry(lod4Prop, Lod.LOD4, ti);
ti.unsetGmlGeometries();
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlTi.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
ti.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs);
p.setPartOfInstallation(ti);
}
}
}
for (Geometry geom : ti.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfInstallation(ti);
}
}
return ti;
}
private TunnelHollow mapTunnelHollow(HollowSpace gmlHo) {
TunnelHollow tHollow = new TunnelHollow();
tHollow.setGmlObject(gmlHo);
mapAbstractUnoccupiedSpace(gmlHo, tHollow);
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlHo.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
tHollow.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs);
}
}
}
for (TunnelInstallationProperty tiProp : gmlHo.getTunnelInstallations()) {
var gmlTi = tiProp.getObject();
if (gmlTi == null) {
// ignore empty properties
continue;
}
Installation bi = mapTunnelInstallation(gmlTi);
tHollow.addRoomInstallation(bi);
}
for (TunnelFurnitureProperty tfProp : gmlHo.getTunnelFurniture()) {
var gmlHref = tfProp.getHref();
if (gmlHref == null) {
continue;
}
tHollow.addFurnitureRef(tfProp);
}
return tHollow;
}
private TunnelFurniture mapTunnelFurniture(org.citygml4j.core.model.tunnel.TunnelFurniture gmlTf) {
TunnelFurniture tf = new TunnelFurniture();
tf.setGmlObject(gmlTf);
mapAbstractOccupiedSpace(gmlTf, tf);
tf.unsetGmlGeometries();
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlTf.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
tf.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs);
}
}
}
return tf;
}
private TunnelConstructiveElement mapTunnelConstructiveElement(org.citygml4j.core.model.tunnel.TunnelConstructiveElement gmlTe) {
TunnelConstructiveElement te = new TunnelConstructiveElement(gmlTe);
mapAbstractOccupiedSpace(gmlTe, te);
te.unsetGmlGeometries();
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlTe.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
te.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs);
}
}
}
return te;
}
private void updatePartOfSurface(BridgeObject bo, SurfaceMapper surfaceMapper) { private void updatePartOfSurface(BridgeObject bo, SurfaceMapper surfaceMapper) {
for (BoundarySurface bs : surfaceMapper.getSurfaces()) { for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
bo.addBoundarySurface(bs); bo.addBoundarySurface(bs);
...@@ -364,7 +604,7 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -364,7 +604,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
private void mapConstructiveElement(org.citygml4j.core.model.bridge.BridgeConstructiveElement ele, BridgeConstructiveElement bce) { private void mapConstructiveElement(org.citygml4j.core.model.bridge.BridgeConstructiveElement ele, BridgeConstructiveElement bce) {
mapAbstractConstructiveElement(ele, bce); mapAbstractConstructiveElement(ele, bce);
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, vertexMap, config); SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : ele.getBoundaries()) { for (AbstractSpaceBoundaryProperty surfaceProp : ele.getBoundaries()) {
if (!surfaceProp.isSetObject()) { if (!surfaceProp.isSetObject()) {
continue; continue;
...@@ -498,8 +738,8 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -498,8 +738,8 @@ public class Citygml3FeatureMapper extends ObjectWalker {
mapAbstractUnoccupiedSpace(ts, to); mapAbstractUnoccupiedSpace(ts, to);
} }
private void mapAbstractUnoccupiedSpace(AbstractUnoccupiedSpace aus, TransportationObject to) { private void mapAbstractUnoccupiedSpace(AbstractUnoccupiedSpace aus, CityObject co) {
mapAbstractPhysicalSpace(aus, to); mapAbstractPhysicalSpace(aus, co);
} }
private TransportationObject parseAuxiliaryTrafficSpace(AuxiliaryTrafficSpace ats) { private TransportationObject parseAuxiliaryTrafficSpace(AuxiliaryTrafficSpace ats) {
...@@ -521,6 +761,7 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -521,6 +761,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
parseAndAddSolid(as.getLod1Solid(), Lod.LOD1, co); parseAndAddSolid(as.getLod1Solid(), Lod.LOD1, co);
parseAndAddSolid(as.getLod2Solid(), Lod.LOD2, co); parseAndAddSolid(as.getLod2Solid(), Lod.LOD2, co);
parseAndAddSolid(as.getLod3Solid(), Lod.LOD3, co); parseAndAddSolid(as.getLod3Solid(), Lod.LOD3, co);
} }
private void parseAndAddMultiSurface(MultiSurfaceProperty msp, Lod lod, CityObject co) { private void parseAndAddMultiSurface(MultiSurfaceProperty msp, Lod lod, CityObject co) {
...@@ -541,6 +782,74 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -541,6 +782,74 @@ public class Citygml3FeatureMapper extends ObjectWalker {
} }
} }
private void parseAndAddCompositeSurface(MultiSurfaceProperty ms, Lod lod, CityObject co) {
if (ms == null || ms.getObject() == null) {
return;
}
List<SurfaceProperty> surfaces = ms.getObject().getSurfaceMember();
for (SurfaceProperty surface : surfaces) {
if (surface.getObject() instanceof CompositeSurface cs) {
Geometry geom = parseCompositeSurface(cs, lod);
if (geom != null) {
co.addGeometry(geom);
}
}
}
}
private void parseImplicitGeometry(AbstractOccupiedSpace aos, CityObject co) {
for (int i = 1; i <= 3; i++) {
if (aos.getImplicitRepresentation(i) == null) {
continue;
}
if (aos.getImplicitRepresentation(i).getObject() != null) {
ImplicitGeometry impGeom = aos.getImplicitRepresentation(i).getObject();
ImplicitGeometryHolder igh = resolveImplicitGeometry(impGeom, i);
if (igh != null) {
co.addGeometry(igh);
}
} else if (aos.getImplicitRepresentation(i).getHref() != null) {
// Hrefs of ImplicitGeometries point to its RelativeGeometry.
// Can be ignored for CD since the Href is only used for repeating the RelativeGeometry at different LODs
}
}
}
private ImplicitGeometryHolder resolveImplicitGeometry(ImplicitGeometry ig, int lodInt) {
ImplicitGeometryHolder igh = null;
if (ig.getLibraryObject() != null) {
Path libraryObjectPath = directory.resolve(ig.getLibraryObject());
LibraryObject libObj = LibraryObject.of(libraryObjectPath, 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);
} else if (aGeom instanceof CompositeSurface cs) {
geom = parseCompositeSurface(cs, lod);
}
if (geom != null) {
relGeo = RelativeGeometry.of(geom);
igh = new ImplicitGeometryHolder(ig, relGeo);
}
} else {
logger.error(String.format("Implicit geometry of GML-ID %s has no referenced geometry.", ig.getId()));
}
return igh;
}
private void resolveAndClearReferences() { private void resolveAndClearReferences() {
for (ResolvableReference ref : references) { for (ResolvableReference ref : references) {
String href = ref.href(); String href = ref.href();
...@@ -548,13 +857,16 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -548,13 +857,16 @@ public class Citygml3FeatureMapper extends ObjectWalker {
href = href.substring(1); href = href.substring(1);
} }
Geometry geom = ref.geometry(); Geometry geom = ref.geometry();
CompositeCollection comp = compositeMap.get(href);
if (comp != null) {
comp.getCompositeMembers().forEach(geom::addPolygon);
} else {
ConcretePolygon concPoly = polygonMap.get(href); ConcretePolygon concPoly = polygonMap.get(href);
if (concPoly == null) { if (concPoly == null) {
if (logger.isWarnEnabled()) { if (logger.isWarnEnabled()) {
logger.warn(Localization.getText("FeatureMapper.polygonUnreferenced"), href); logger.warn(Localization.getText("FeatureMapper.polygonUnreferenced"), href);
} }
continue; } else {
}
LinkedPolygon lPoly = new LinkedPolygon(concPoly, geom); LinkedPolygon lPoly = new LinkedPolygon(concPoly, geom);
if (geom.getParent() instanceof BoundarySurface bs) { if (geom.getParent() instanceof BoundarySurface bs) {
lPoly.setPartOfSurface(bs); lPoly.setPartOfSurface(bs);
...@@ -564,6 +876,8 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -564,6 +876,8 @@ public class Citygml3FeatureMapper extends ObjectWalker {
} }
geom.addPolygon(lPoly); geom.addPolygon(lPoly);
} }
}
}
// clear storage for polygons and vertices // clear storage for polygons and vertices
// probably faster than .clear() ? // probably faster than .clear() ?
...@@ -592,7 +906,30 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -592,7 +906,30 @@ public class Citygml3FeatureMapper extends ObjectWalker {
cdBuilding.addBuildingInstallation(bi); cdBuilding.addBuildingInstallation(bi);
} }
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, vertexMap, config); for (BuildingRoomProperty brProp : gmlAb.getBuildingRooms()) {
var gmlBr = brProp.getObject();
if (gmlBr == null) {
continue;
}
BuildingRoom br = mapBuildingRoom(gmlBr);
cdBuilding.addBuildingRoom(br);
}
for (AbstractBuildingSubdivisionProperty abs : gmlAb.getBuildingSubdivisions()) {
var gmlABS = abs.getObject();
if (gmlABS == null) {
continue;
}
if (gmlABS instanceof Storey gmlStorey) {
de.hft.stuttgart.citydoctor2.datastructure.Storey storey = mapBuildingStorey(gmlStorey);
cdBuilding.addStorey(storey);
} else if (gmlABS instanceof BuildingUnit gmlBU) {
de.hft.stuttgart.citydoctor2.datastructure.BuildingUnit bu = mapBuildingUnit(gmlBU);
cdBuilding.addBuildingUnit(bu);
}
}
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlAb.getBoundaries()) { for (AbstractSpaceBoundaryProperty surfaceProp : gmlAb.getBoundaries()) {
if (!surfaceProp.isSetObject()) { if (!surfaceProp.isSetObject()) {
continue; continue;
...@@ -620,23 +957,140 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -620,23 +957,140 @@ public class Citygml3FeatureMapper extends ObjectWalker {
} }
} }
} }
for (BuildingFurnitureProperty bfProp : gmlAb.getBuildingFurniture()) {
var gmlBf = bfProp.getObject();
if (gmlBf == null) {
continue;
}
BuildingRoomFurniture bf = mapBuildingFurniture(gmlBf);
cdBuilding.addBuildingRoomFurniture(bf);
}
} }
private void updatePartOfSurface(AbstractBuilding cdBuilding, SurfaceMapper surfaceMapper) { private BuildingRoom mapBuildingRoom(org.citygml4j.core.model.building.BuildingRoom gmlBr) {
BuildingRoom br = new BuildingRoom();
br.setGmlObject(gmlBr);
mapAbstractUnoccupiedSpace(gmlBr, br);
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlBr.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) { for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
cdBuilding.addBoundarySurface(bs); br.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) { for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) { for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs); p.setPartOfSurface(bs);
} }
} }
} }
for (BuildingInstallationProperty biProp : gmlBr.getBuildingInstallations()) {
var gmlBi = biProp.getObject();
if (gmlBi == null) {
// ignore empty properties
continue;
}
Installation bi = mapBuildingInstallation(gmlBi);
br.addRoomInstallation(bi);
}
for (BuildingFurnitureProperty bfProp : gmlBr.getBuildingFurniture()) {
var gmlHref = bfProp.getHref();
if (gmlHref == null) {
continue;
}
br.addFurnitureRef(bfProp);
} }
public static void parseId(AbstractGML gml, GmlElement gmlElement) {
String id = gml.getId(); return br;
if (id != null) { }
gmlElement.setGmlId(new GmlId(id));
private BuildingRoomFurniture mapBuildingFurniture(BuildingFurniture gmlAF) {
BuildingRoomFurniture bf = new BuildingRoomFurniture();
bf.setGmlObject(gmlAF);
mapAbstractOccupiedSpace(gmlAF, bf);
bf.unsetGmlGeometries();
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlAF.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
bf.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs);
}
}
}
return bf;
}
private de.hft.stuttgart.citydoctor2.datastructure.Storey mapBuildingStorey(Storey gmlStorey) {
de.hft.stuttgart.citydoctor2.datastructure.Storey storey = new de.hft.stuttgart.citydoctor2.datastructure.Storey();
storey.setGmlObject(gmlStorey);
mapAbstractSpace(gmlStorey, storey);
storey.unsetGmlGeometries();
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlStorey.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
storey.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs);
}
}
}
return storey;
}
private de.hft.stuttgart.citydoctor2.datastructure.BuildingUnit mapBuildingUnit(BuildingUnit gmlBU) {
de.hft.stuttgart.citydoctor2.datastructure.BuildingUnit bu = new de.hft.stuttgart.citydoctor2.datastructure.BuildingUnit();
bu.setGmlObject(gmlBU);
mapAbstractSpace(gmlBU, bu);
bu.unsetGmlGeometries();
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlBU.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
bu.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs);
}
}
}
return bu;
}
private void updatePartOfSurface(AbstractBuilding cdBuilding, SurfaceMapper surfaceMapper) {
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
cdBuilding.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs);
}
}
} }
} }
...@@ -652,7 +1106,7 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -652,7 +1106,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
parseAndAddAbstractGeometry(lod4Prop, Lod.LOD4, bi); parseAndAddAbstractGeometry(lod4Prop, Lod.LOD4, bi);
bi.unsetGmlGeometries(); bi.unsetGmlGeometries();
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, vertexMap, config); SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlBi.getBoundaries()) { for (AbstractSpaceBoundaryProperty surfaceProp : gmlBi.getBoundaries()) {
if (!surfaceProp.isSetObject()) { if (!surfaceProp.isSetObject()) {
continue; continue;
...@@ -749,6 +1203,13 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -749,6 +1203,13 @@ public class Citygml3FeatureMapper extends ObjectWalker {
} }
} }
private Geometry parseCompositeSurface(CompositeSurface cs, Lod lod) {
Geometry geom = new Geometry(GeometryType.COMPOSITE_SURFACE, lod);
Citygml3GeometryMapper geometryMapper = new Citygml3GeometryMapper(config, vertexMap);
readSurfaceMember(geom, geometryMapper, cs.getSurfaceMembers());
return geom;
}
private void updateEdgesAndVertices(CityObject co) { private void updateEdgesAndVertices(CityObject co) {
// searching for neighboring vertices, replacing them with one single vertex to // searching for neighboring vertices, replacing them with one single vertex to
// avoid later problems with edges and manifold problems // avoid later problems with edges and manifold problems
......
...@@ -18,35 +18,32 @@ ...@@ -18,35 +18,32 @@
*/ */
package de.hft.stuttgart.citydoctor2.mapper.citygml3; package de.hft.stuttgart.citydoctor2.mapper.citygml3;
import java.math.BigDecimal; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import java.math.RoundingMode; import de.hft.stuttgart.citydoctor2.datastructure.*;
import java.util.ArrayList; import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType;
import java.util.List; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import java.util.Map; import de.hft.stuttgart.citydoctor2.utils.Localization;
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.locationtech.proj4j.BasicCoordinateTransform; import org.locationtech.proj4j.BasicCoordinateTransform;
import org.locationtech.proj4j.ProjCoordinate; import org.locationtech.proj4j.ProjCoordinate;
import org.xmlobjects.gml.model.geometry.primitives.AbstractRing; import org.xmlobjects.gml.model.geometry.complexes.CompositeSurface;
import org.xmlobjects.gml.model.geometry.primitives.AbstractRingProperty;
import org.xmlobjects.gml.model.geometry.primitives.Polygon; import org.xmlobjects.gml.model.geometry.primitives.Polygon;
import org.xmlobjects.gml.model.geometry.primitives.Ring; import org.xmlobjects.gml.model.geometry.primitives.*;
import org.xmlobjects.gml.visitor.GeometryWalker; import org.xmlobjects.gml.visitor.GeometryWalker;
import de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon; import java.math.BigDecimal;
import de.hft.stuttgart.citydoctor2.datastructure.GmlId; import java.math.RoundingMode;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing; import java.util.ArrayList;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType; import java.util.List;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex; import java.util.Map;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.utils.Localization;
public class Citygml3GeometryMapper extends GeometryWalker { public class Citygml3GeometryMapper extends GeometryWalker {
private static final Logger logger = LogManager.getLogger(Citygml3GeometryMapper.class); private static final Logger logger = LogManager.getLogger(Citygml3GeometryMapper.class);
private final List<ConcretePolygon> polygons = new ArrayList<>(); private final List<ConcretePolygon> polygons = new ArrayList<>();
private final List<CompositeCollection> composites = new ArrayList<>();
private LinearRing currentRing = null; private LinearRing currentRing = null;
private final ParserConfiguration config; private final ParserConfiguration config;
private final ProjCoordinate p1 = new ProjCoordinate(); private final ProjCoordinate p1 = new ProjCoordinate();
...@@ -62,7 +59,7 @@ public class Citygml3GeometryMapper extends GeometryWalker { ...@@ -62,7 +59,7 @@ public class Citygml3GeometryMapper extends GeometryWalker {
public void visit(Polygon polygon) { public void visit(Polygon polygon) {
parsePolygon(polygon.getId(), polygon.getExterior(), polygon.getInterior()); parsePolygon(polygon.getId(), polygon.getExterior(), polygon.getInterior());
if (polygon.getExterior() == null) { if (polygon.getExterior() == null) {
logger.warn(String.format("No exterior: %s" ,polygon.getId())); logger.warn(String.format("No exterior: %s", polygon.getId()));
} }
} }
...@@ -95,6 +92,35 @@ public class Citygml3GeometryMapper extends GeometryWalker { ...@@ -95,6 +92,35 @@ public class Citygml3GeometryMapper extends GeometryWalker {
} }
} }
@Override
public void visit(CompositeSurface cs) {
if (cs.getSurfaceMembers() != null && cs.getSurfaceMembers().isEmpty()) {
logger.warn("CompositeSurface %s is empty", cs.getId());
return;
}
List<SurfaceProperty> surfaceMember = cs.getSurfaceMembers();
Citygml3GeometryMapper recursiveMapper = new Citygml3GeometryMapper(config, vertexMap);
CompositeCollection comp = new CompositeCollection();
if (cs.getId() == null) {
comp.setGmlId(GmlId.generateId());
} else {
comp.setGmlId(new GmlId(cs.getId()));
}
for (SurfaceProperty prop : surfaceMember) {
if (prop.getObject() != null) {
AbstractSurface as = prop.getObject();
as.accept(recursiveMapper);
}
}
List<ConcretePolygon> compPolys = recursiveMapper.getPolygons();
compPolys.forEach(comp::addCompositeMember);
comp.addAllChildComposites(recursiveMapper.getComposites());
composites.add(comp);
polygons.addAll(compPolys);
}
@Override @Override
public void visit(org.xmlobjects.gml.model.geometry.primitives.LinearRing gmlRing) { public void visit(org.xmlobjects.gml.model.geometry.primitives.LinearRing gmlRing) {
if (gmlRing.getSrsDimension() != null && gmlRing.getSrsDimension() != 3) { if (gmlRing.getSrsDimension() != null && gmlRing.getSrsDimension() != 3) {
...@@ -177,4 +203,8 @@ public class Citygml3GeometryMapper extends GeometryWalker { ...@@ -177,4 +203,8 @@ public class Citygml3GeometryMapper extends GeometryWalker {
return polygons; return polygons;
} }
public List<CompositeCollection> getComposites() {
return composites;
}
} }
...@@ -18,23 +18,9 @@ ...@@ -18,23 +18,9 @@
*/ */
package de.hft.stuttgart.citydoctor2.mapper.citygml3; package de.hft.stuttgart.citydoctor2.mapper.citygml3;
import java.util.ArrayList; import de.hft.stuttgart.citydoctor2.datastructure.*;
import java.util.List; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import java.util.Map; import org.citygml4j.core.model.construction.*;
import org.citygml4j.core.model.construction.AbstractConstructionSurface;
import org.citygml4j.core.model.construction.AbstractFillingSurface;
import org.citygml4j.core.model.construction.AbstractFillingSurfaceProperty;
import org.citygml4j.core.model.construction.CeilingSurface;
import org.citygml4j.core.model.construction.DoorSurface;
import org.citygml4j.core.model.construction.FloorSurface;
import org.citygml4j.core.model.construction.GroundSurface;
import org.citygml4j.core.model.construction.InteriorWallSurface;
import org.citygml4j.core.model.construction.OuterCeilingSurface;
import org.citygml4j.core.model.construction.OuterFloorSurface;
import org.citygml4j.core.model.construction.RoofSurface;
import org.citygml4j.core.model.construction.WallSurface;
import org.citygml4j.core.model.construction.WindowSurface;
import org.citygml4j.core.model.core.AbstractThematicSurface; import org.citygml4j.core.model.core.AbstractThematicSurface;
import org.citygml4j.core.model.core.ClosureSurface; import org.citygml4j.core.model.core.ClosureSurface;
import org.citygml4j.core.visitor.ObjectWalker; import org.citygml4j.core.visitor.ObjectWalker;
...@@ -43,32 +29,26 @@ import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty; ...@@ -43,32 +29,26 @@ import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
import org.xmlobjects.gml.model.geometry.primitives.AbstractSurface; import org.xmlobjects.gml.model.geometry.primitives.AbstractSurface;
import org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty; import org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty;
import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface; import java.util.ArrayList;
import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurfaceType; import java.util.List;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject; import java.util.Map;
import de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Opening;
import de.hft.stuttgart.citydoctor2.datastructure.OpeningType;
import de.hft.stuttgart.citydoctor2.datastructure.SurfaceFeatureType;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
public class SurfaceMapper extends ObjectWalker { public class SurfaceMapper extends ObjectWalker {
private final List<BoundarySurface> surfaces = new ArrayList<>(); private final List<BoundarySurface> surfaces = new ArrayList<>();
private final Map<String, ConcretePolygon> polygonMap; private final Map<String, ConcretePolygon> polygonMap;
private final Map<String, CompositeCollection> compositeMap;
private final List<ResolvableReference> references; private final List<ResolvableReference> references;
private final Map<Vertex, Vertex> vertexMap; private final Map<Vertex, Vertex> vertexMap;
private final ParserConfiguration config; private final ParserConfiguration config;
public SurfaceMapper(Map<String, ConcretePolygon> polygonMap, List<ResolvableReference> references, public SurfaceMapper(Map<String, ConcretePolygon> polygonMap, List<ResolvableReference> references,
Map<Vertex, Vertex> vertexMap, ParserConfiguration config) { Map<String, CompositeCollection> compositeMap, Map<Vertex, Vertex> vertexMap,
ParserConfiguration config) {
this.polygonMap = polygonMap; this.polygonMap = polygonMap;
this.references = references; this.references = references;
this.vertexMap = vertexMap; this.vertexMap = vertexMap;
this.compositeMap = compositeMap;
this.config = config; this.config = config;
} }
...@@ -95,7 +75,7 @@ public class SurfaceMapper extends ObjectWalker { ...@@ -95,7 +75,7 @@ public class SurfaceMapper extends ObjectWalker {
Opening o; Opening o;
if (afs instanceof DoorSurface ds) { if (afs instanceof DoorSurface ds) {
o = new Opening(OpeningType.DOOR, SurfaceFeatureType.BUILDING, cdSurface, ds); o = new Opening(OpeningType.DOOR, SurfaceFeatureType.BUILDING, cdSurface, ds);
} else if (afs instanceof WindowSurface ws){ } else if (afs instanceof WindowSurface ws) {
o = new Opening(OpeningType.WINDOW, SurfaceFeatureType.BUILDING, cdSurface, ws); o = new Opening(OpeningType.WINDOW, SurfaceFeatureType.BUILDING, cdSurface, ws);
} else { } else {
o = new Opening(OpeningType.UNKNOWN, SurfaceFeatureType.BUILDING, cdSurface, afs); o = new Opening(OpeningType.UNKNOWN, SurfaceFeatureType.BUILDING, cdSurface, afs);
...@@ -133,6 +113,7 @@ public class SurfaceMapper extends ObjectWalker { ...@@ -133,6 +113,7 @@ public class SurfaceMapper extends ObjectWalker {
return geom; return geom;
} }
private void readSurfaceMember(Geometry geom, Citygml3GeometryMapper geometryMapper, private void readSurfaceMember(Geometry geom, Citygml3GeometryMapper geometryMapper,
List<SurfaceProperty> surfaceMember) { List<SurfaceProperty> surfaceMember) {
for (SurfaceProperty prop : surfaceMember) { for (SurfaceProperty prop : surfaceMember) {
...@@ -147,12 +128,18 @@ public class SurfaceMapper extends ObjectWalker { ...@@ -147,12 +128,18 @@ public class SurfaceMapper extends ObjectWalker {
} }
List<ConcretePolygon> polygons = geometryMapper.getPolygons(); List<ConcretePolygon> polygons = geometryMapper.getPolygons();
List<CompositeCollection> composites = geometryMapper.getComposites();
for (CompositeCollection cc : composites) {
references.add(new ResolvableReference(cc.getGmlId().toString(), geom));
compositeMap.put(cc.getGmlId().getGmlString(), cc);
}
for (ConcretePolygon concretePoly : polygons) { for (ConcretePolygon concretePoly : polygons) {
geom.addPolygon(concretePoly); geom.addPolygon(concretePoly);
if (concretePoly.hasExistingGmlId()) { if (concretePoly.hasExistingGmlId()) {
polygonMap.put(concretePoly.getGmlId().getGmlString(), concretePoly); polygonMap.put(concretePoly.getGmlId().getGmlString(), concretePoly);
} }
} }
} }
@Override @Override
......
package de.hft.stuttgart.citydoctor2.math;
import Jama.Matrix;
import de.hft.stuttgart.citydoctor2.datastructure.*;
import de.hft.stuttgart.citydoctor2.utils.Copy;
import org.citygml4j.core.model.core.ImplicitGeometry;
import org.citygml4j.core.model.core.TransformationMatrix4x4;
import org.xmlobjects.gml.model.geometry.primitives.Point;
import org.xmlobjects.gml.model.geometry.primitives.PointProperty;
import org.xmlobjects.util.copy.CopyBuilder;
import java.util.*;
/**
* Adapter class for CityGML-TransformationMatrix4x4
*/
public class TransformationMatrix {
private final TransformationMatrix4x4 originalTM4x4;
private Matrix tMatrix;
/**
* The {@code TransformationMatrix} class is an adapter for applying the {@link TransformationMatrix4x4} of implicitGeometries to geometries
* of CityDoctor's internal model.
* @param transformationMatrix the transformation matrix.
* @param pointProperty the reference point for the translation of the geometry's position.
*/
public TransformationMatrix(TransformationMatrix4x4 transformationMatrix, PointProperty pointProperty) {
originalTM4x4 = transformationMatrix;
setupMatrix();
incorporateRefPoint(pointProperty);
}
/**
* The {@code TransformationMatrix} class is an adapter for applying the {@link TransformationMatrix4x4} of implicitGeometries to geometries
* of CityDoctor's internal model.
* @param implicitGeometry the implicitGeometry containing the TransformationMatrix and ReferencePoint.
*/
public TransformationMatrix(ImplicitGeometry implicitGeometry) {
originalTM4x4 = implicitGeometry.getTransformationMatrix();
setupMatrix();
incorporateRefPoint(implicitGeometry.getReferencePoint());
}
private void setupMatrix() {
double[][] matrix = new double[4][4];
CopyBuilder copyBuilder = new CopyBuilder();
TransformationMatrix4x4 tmMatrix = (TransformationMatrix4x4) originalTM4x4.deepCopy(copyBuilder);
List<Double> tmValues = tmMatrix.toRowMajorList();
for (int i = 0; i < 4 ; i++){
for (int j = 0; j < 4 ; j++){
matrix[i][j] = tmValues.get(i*4+j);
}
}
tMatrix = new Matrix(matrix);
}
private void incorporateRefPoint(PointProperty pointProperty) {
Point refPoint = pointProperty.getObject();
List<Double> refCoord = refPoint.getPos().toCoordinateList3D();
double [][] tArray = tMatrix.getArray();
tArray[0][3] = refCoord.get(0);
tArray[1][3] = refCoord.get(1);
tArray[2][3] = refCoord.get(2);
}
/**
* Transforms a vector with the transformation matrix.
* @param referenceGeom reference geometry to transform.
* @return A transformed copy of {@code referenceGeom}.
*/
public Geometry transformGeometry(Geometry referenceGeom) {
// Create deep copy of reference geom
Geometry geom = Copy.copy(referenceGeom);
Map<Vertex, Boolean> visitedVertices = new IdentityHashMap<>();
Set<Vertex> visitedVerticesSet = Collections.newSetFromMap(visitedVertices);
// Transform all vertices
for (Polygon polygon : geom.getPolygons()){
for (Vertex vertex : polygon.getExteriorRing().getVertices()){
if (!visitedVerticesSet.contains(vertex)){
transformVector3D(vertex);
visitedVerticesSet.add(vertex);
}
}
for (LinearRing ring : polygon.getInnerRings()){
for (Vertex vertex : ring.getVertices()){
if (!visitedVerticesSet.contains(vertex)){
transformVector3D(vertex);
visitedVerticesSet.add(vertex);
}
}
}
}
geom.updateEdgesAndVertices();
return geom;
}
public void transformVector3D(Vector3d vector) {
double[] tfVector = new double[]{vector.getX(), vector.getY(), vector.getZ(), 1d};
Matrix vectorMatrix = new Matrix(tfVector,4);
Matrix res = tMatrix.times(vectorMatrix);
double[] resultVector = res.getRowPackedCopy();
vector.setX(resultVector[0]);
vector.setY(resultVector[1]);
vector.setZ(resultVector[2]);
}
}
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