Commit b75c2602 authored by Riegel's avatar Riegel
Browse files

Merge branch 'refs/heads/dev' into dev_zip_files

# Conflicts:
#	CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/LibraryObject.java
#	CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/mapper/citygml3/Citygml3FeatureMapper.java
#	CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java
#	CityDoctorParent/Extensions/CityDoctorGUI/pom.xml
#	CityDoctorParent/Extensions/CityDoctorGUI/src/main/resources/de/hft/stuttgart/citydoctor2/gui/MainToolBar.fxml
#	CityDoctorParent/Extensions/CityDoctorHealer/pom.xml
#	CityDoctorParent/pom.xml
2 merge requests!28Version 3.17.0 Release,!26Add ZIP-archive support
Pipeline #10991 passed with stage
in 1 minute and 24 seconds
Showing with 1274 additions and 1226 deletions
+1274 -1226
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.hft.stuttgart</groupId>
......
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.hft.stuttgart</groupId>
......
......@@ -29,7 +29,6 @@ public class Vector2d {
this.y = y;
}
@SuppressWarnings("SuspiciousNameCombination")
public Vector2d getPerpendicularVector() {
return new Vector2d(y, -x);
}
......
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.hft.stuttgart</groupId>
......@@ -102,7 +104,8 @@
<prefix>git</prefix>
<verbose>false</verbose>
<generateGitPropertiesFile>true</generateGitPropertiesFile>
<generateGitPropertiesFilename>${project.build.outputDirectory}/git.properties</generateGitPropertiesFilename>
<generateGitPropertiesFilename>
${project.build.outputDirectory}/git.properties</generateGitPropertiesFilename>
<gitDescribe>
<skip>false</skip>
<always>false</always>
......
......@@ -60,10 +60,8 @@ import de.hft.stuttgart.citydoctor2.check.error.UnknownCheckError;
* @author Matthias Betz
*
*/
@SuppressWarnings("unused")
public interface HealingMethod {
public HealingID getID();
default boolean visit(CheckError e, ModificationListener l) {
......
......@@ -129,7 +129,10 @@ public abstract class AbstractFurniture extends CityObject {
public void setParent(CityObject co) {
parent = co;
}
public CityObject getParent() {
return parent;
}
@Override
public void unsetGmlGeometries() {
......
package de.hft.stuttgart.citydoctor2.datastructure;
import java.io.Serial;
import java.util.List;
import org.citygml4j.core.model.core.ImplicitGeometry;
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.math.TransformationMatrix;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.citygml4j.core.model.core.ImplicitGeometry;
import java.io.Serial;
import java.util.List;
/**
* Datastructure for representation and resolving of implicit geometries
......@@ -18,7 +17,6 @@ import java.util.List;
*/
public class ImplicitGeometryHolder extends Geometry {
private static final Logger logger = LogManager.getLogger(ImplicitGeometryHolder.class);
@Serial
private static final long serialVersionUID = -8938931081577196349L;
......
......@@ -16,16 +16,18 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Reference object for handling of implicit geometries with a library object contained in an external file
* Reference object for handling of implicit geometries with a library object
* contained in an external file
*
* @author Riegel
*/
public class LibraryObject extends Geometry {
private static final Logger logger = LogManager.getLogger(LibraryObject.class);
@Serial
private static final long serialVersionUID = -50293435187454911L;
private static Map<String, LibraryObject> libraryObjects = new ConcurrentHashMap<>();
private static final Logger logger = LogManager.getLogger(LibraryObject.class);
@Serial
private static final long serialVersionUID = -50293435187454911L;
private static Map<String, LibraryObject> libraryObjects = new ConcurrentHashMap<>();
public static LibraryObject of(Path path, ParserConfiguration config) {
if (libraryObjects.containsKey(path.toString())) {
......
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;
......@@ -15,27 +11,23 @@ import java.util.concurrent.ConcurrentHashMap;
*/
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);
}
@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);
}
}
......@@ -68,6 +68,8 @@ public class TunnelConstructiveElement extends CityObject {
MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config);
setMultiSurfaceAccordingToLod(geom, ms);
break;
case COMPOSITE_SURFACE:
throw new IllegalStateException("Tunnel constructive element cannot have a composite surface geometry");
}
}
for (BoundarySurface bs : boundarySurfaceList) {
......
......@@ -72,17 +72,17 @@ import java.util.Map;
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 ParserConfiguration config;
private final Path directory;
private final CityGmlZipEntry zipEntry;
private final CityDoctorModel model;
private final ParserConfiguration config;
private final Path directory;
private final CityGmlZipEntry zipEntry;
private final double neighborDistance;
private Map<String, ConcretePolygon> polygonMap = new HashMap<>();
private Map<String, CompositeCollection> compositeMap = new HashMap<>();
private List<ResolvableReference> references = new ArrayList<>();
private Map<Vertex, Vertex> vertexMap = new HashMap<>();
private Map<String, ConcretePolygon> polygonMap = new HashMap<>();
private Map<String, CompositeCollection> compositeMap = new HashMap<>();
private List<ResolvableReference> references = new ArrayList<>();
private Map<Vertex, Vertex> vertexMap = new HashMap<>();
public Citygml3FeatureMapper(ParserConfiguration config, Path path) {
this.config = config;
......@@ -100,687 +100,709 @@ public class Citygml3FeatureMapper extends ObjectWalker {
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
public void visit(AbstractSpace space) {
// if we are here, an AbstractSpace thing was read that is not handled in the
// other methods
}
@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
public void visit(org.citygml4j.core.model.building.Building gmlBuilding) {
Building cdBuilding = new Building();
readAbstractBuilding(gmlBuilding, cdBuilding);
for (BuildingPartProperty bpProp : gmlBuilding.getBuildingParts()) {
if (!bpProp.isSetObject()) {
continue;
}
BuildingPart part = new BuildingPart(cdBuilding);
readAbstractBuilding(bpProp.getObject(), part);
}
model.addBuilding(cdBuilding);
}
@Override
public void visit(WaterBody waterBody) {
WaterObject wo = new WaterObject();
wo.setGmlObject(waterBody);
mapAbstractOccupiedSpace(waterBody, wo);
parseAndAddMultiSurface(waterBody.getDeprecatedProperties().getLod1MultiSurface(), Lod.LOD1, wo);
parseAndAddSolid(waterBody.getDeprecatedProperties().getLod4Solid(), Lod.LOD4, wo);
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : waterBody.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
wo.addBoundarySurface(bs);
}
resolveAndClearReferences();
wo.unsetGmlGeometries();
updateEdgesAndVertices(wo);
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
updateEdgesAndVertices(bs);
}
model.addWater(wo);
}
@Override
public void visit(LandUse landUse) {
LandObject lo = new LandObject(landUse);
mapAbstractThematicSurface(landUse, lo);
finishCityObjectConstruction(lo);
model.addLand(lo);
}
@Override
public void visit(PlantCover plantCover) {
Vegetation veg = new Vegetation(VegetationType.PLANT_COVER);
veg.setGmlObject(plantCover);
mapAbstractVegetationObject(plantCover, veg);
parseAndAddMultiSurface(plantCover.getDeprecatedProperties().getLod1MultiSurface(), Lod.LOD1, veg);
parseAndAddMultiSurface(plantCover.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, veg);
finishCityObjectConstruction(veg);
model.addVegetation(veg);
}
@Override
public void visit(SolitaryVegetationObject solitaryVegetationObject) {
Vegetation veg = new Vegetation(VegetationType.SOLITARY_VEGETATION_OBJECT);
veg.setGmlObject(solitaryVegetationObject);
mapAbstractVegetationObject(solitaryVegetationObject, veg);
parseAndAddAbstractGeometry(solitaryVegetationObject.getDeprecatedProperties().getLod1Geometry(), Lod.LOD1, veg);
parseAndAddAbstractGeometry(solitaryVegetationObject.getDeprecatedProperties().getLod2Geometry(), Lod.LOD2, veg);
parseAndAddAbstractGeometry(solitaryVegetationObject.getDeprecatedProperties().getLod3Geometry(), Lod.LOD3, veg);
parseAndAddAbstractGeometry(solitaryVegetationObject.getDeprecatedProperties().getLod4Geometry(), Lod.LOD4, veg);
finishCityObjectConstruction(veg);
model.addVegetation(veg);
}
private void mapAbstractVegetationObject(AbstractVegetationObject avo, Vegetation veg) {
mapAbstractOccupiedSpace(avo, veg);
}
private void mapAbstractOccupiedSpace(AbstractOccupiedSpace aos, CityObject co) {
mapAbstractPhysicalSpace(aos, co);
parseImplicitGeometry(aos, co);
}
private void mapAbstractPhysicalSpace(AbstractPhysicalSpace aps, CityObject co) {
mapAbstractSpace(aps, co);
}
private void mapAbstractSpace(AbstractSpace as, CityObject co) {
mapAbstractFeature(as, co);
parseAndAddMultiSurface(as.getLod0MultiSurface(), Lod.LOD0, co);
parseAndAddMultiSurface(as.getLod2MultiSurface(), Lod.LOD2, co);
parseAndAddMultiSurface(as.getLod3MultiSurface(), Lod.LOD3, co);
parseAndAddSolid(as.getLod1Solid(), Lod.LOD1, co);
parseAndAddSolid(as.getLod2Solid(), Lod.LOD2, 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
public void visit(Bridge bridge) {
BridgeObject bo = new BridgeObject(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()) {
if (!bPartProperty.isSetObject()) {
continue;
}
BridgePart gmlBridgePart = bPartProperty.getObject();
BridgeObject bPart = new BridgeObject(gmlBridgePart, bo);
mapAbstractBridge(gmlBridgePart, bPart);
bo.addBridgePart(bPart);
}
resolveAndClearReferences();
updateEdgesAndVertices(bo);
for (BridgeObject part : bo.getParts()) {
updateEdgesAndVertices(part);
}
for (BridgeConstructiveElement ele : bo.getConstructiveElements()) {
updateEdgesAndVertices(ele);
for (BoundarySurface bs : ele.getBoundarySurfaces()) {
updateEdgesAndVertices(bs);
}
}
for (Installation bi : bo.getBridgeInstallations()) {
updateEdgesAndVertices(bi);
for (BoundarySurface bs : bi.getBoundarySurfaces()) {
updateEdgesAndVertices(bs);
}
}
model.addBridge(bo);
}
private void mapAbstractBridge(AbstractBridge ab, BridgeObject bo) {
mapAbstractConstruction(ab, bo);
for (BridgeConstructiveElementProperty eleProp : ab.getBridgeConstructiveElements()) {
if (!eleProp.isSetObject()) {
continue;
}
org.citygml4j.core.model.bridge.BridgeConstructiveElement constructiveElement = eleProp.getObject();
BridgeConstructiveElement cdEle = new BridgeConstructiveElement(constructiveElement);
mapConstructiveElement(constructiveElement, cdEle);
bo.addConstructiveElement(cdEle);
}
List<BridgeInstallationProperty> bridgeInstallations = ab.getBridgeInstallations();
for (BridgeInstallationProperty installationProp : bridgeInstallations) {
var gmlBi = installationProp.getObject();
if (gmlBi == null) {
// ignore empty properties
continue;
}
Installation bi = mapBridgeInstallation(gmlBi);
bo.addBridgeInstallation(bi);
}
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : ab.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
updatePartOfSurface(bo, surfaceMapper);
for (BoundarySurface bs : bo.getBoundarySurfaces()) {
updateEdgesAndVertices(bs);
}
bo.unsetGmlGeometries();
}
private Installation mapBridgeInstallation(BridgeInstallation gmlBi) {
Installation bi = new Installation();
bi.setGmlObject(gmlBi);
mapAbstractOccupiedSpace(gmlBi, bi);
GeometryProperty<?> lod2Prop = gmlBi.getDeprecatedProperties().getLod2Geometry();
parseAndAddAbstractGeometry(lod2Prop, Lod.LOD2, bi);
GeometryProperty<?> lod3Prop = gmlBi.getDeprecatedProperties().getLod3Geometry();
parseAndAddAbstractGeometry(lod3Prop, Lod.LOD3, bi);
GeometryProperty<?> lod4Prop = gmlBi.getDeprecatedProperties().getLod4Geometry();
parseAndAddAbstractGeometry(lod4Prop, Lod.LOD4, bi);
bi.unsetGmlGeometries();
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlBi.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
bi.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs);
p.setPartOfInstallation(bi);
}
}
}
for (Geometry geom : bi.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfInstallation(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) {
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
bo.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs);
}
}
}
}
private void mapConstructiveElement(org.citygml4j.core.model.bridge.BridgeConstructiveElement ele, BridgeConstructiveElement bce) {
mapAbstractConstructiveElement(ele, bce);
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : ele.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
bce.addBoundarySurface(bs);
}
}
private void mapAbstractConstructiveElement(org.citygml4j.core.model.bridge.BridgeConstructiveElement ele, BridgeConstructiveElement bce) {
mapAbstractOccupiedSpace(ele, bce);
}
private void mapAbstractConstruction(AbstractConstruction ac, BridgeObject bo) {
mapAbstractOccupiedSpace(ac, bo);
}
@Override
public void visit(AuxiliaryTrafficArea ata) {
TransportationObject to = new TransportationObject(TransportationType.AUXILLIARY_TRAFFIC_AREA);
mapAbstractThematicSurface(ata, to);
finishTransportationMapping(to);
}
@Override
public void visit(TrafficArea ta) {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA);
mapAbstractThematicSurface(ta, to);
finishTransportationMapping(to);
}
@Override
public void visit(Road road) {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
mapAbstractTransportationSpace(road, to);
finishTransportationMapping(to);
}
private void mapAbstractThematicSurface(AbstractThematicSurface ats, CityObject co) {
mapAbstractSpaceBoundary(ats, co);
parseAndAddMultiSurface(ats.getLod0MultiSurface(), Lod.LOD0, co);
parseAndAddMultiSurface(ats.getLod1MultiSurface(), Lod.LOD1, co);
parseAndAddMultiSurface(ats.getLod2MultiSurface(), Lod.LOD2, co);
parseAndAddMultiSurface(ats.getLod3MultiSurface(), Lod.LOD3, co);
parseAndAddMultiSurface(ats.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, co);
}
private void mapAbstractSpaceBoundary(AbstractSpaceBoundary asb, CityObject co) {
mapAbstractCityObject(asb, co);
}
private void mapAbstractCityObject(AbstractCityObject aco, CityObject to) {
mapAbstractFeatureWithLifespan(aco, to);
}
private void mapAbstractFeatureWithLifespan(AbstractFeatureWithLifespan afwl, CityObject to) {
mapAbstractFeature(afwl, to);
}
private void mapAbstractFeature(AbstractFeature af, CityObject to) {
mapAbstractGML(af, to);
}
private void mapAbstractGML(AbstractGML ag, CityObject to) {
parseId(ag, to);
}
@Override
public void visit(Railway railway) {
TransportationObject to = new TransportationObject(TransportationType.RAILWAY);
mapAbstractTransportationSpace(railway, to);
finishTransportationMapping(to);
}
@Override
public void visit(Square square) {
TransportationObject to = new TransportationObject(TransportationType.SQUARE);
mapAbstractTransportationSpace(square, to);
finishTransportationMapping(to);
}
@Override
public void visit(Track track) {
TransportationObject to = new TransportationObject(TransportationType.TRACK);
mapAbstractTransportationSpace(track, to);
finishTransportationMapping(to);
}
@Override
public void visit(TransportationComplex transportationComplex) {
TransportationObject to = new TransportationObject(TransportationType.TRANSPORTATION_COMPLEX);
mapAbstractTransportationSpace(transportationComplex, to);
finishTransportationMapping(to);
}
private void finishTransportationMapping(TransportationObject to) {
finishCityObjectConstruction(to);
model.addTransportation(to);
}
private void finishCityObjectConstruction(CityObject co) {
co.unsetGmlGeometries();
resolveAndClearReferences();
updateEdgesAndVertices(co);
}
private void mapAbstractTransportationSpace(AbstractTransportationSpace ats, TransportationObject to) {
to.setGmlObject(ats);
parseAbstractTransportationSpaceGeometries(ats, to);
for (TrafficSpaceProperty tsp : ats.getTrafficSpaces()) {
if (tsp.isSetObject()) {
TransportationObject trafficSpace = new TransportationObject(TransportationType.TRAFFIC_SPACE);
mapTrafficSpace(tsp.getObject(), trafficSpace);
finishTransportationMapping(trafficSpace);
to.getChildren().add(trafficSpace);
}
}
for (AuxiliaryTrafficSpaceProperty auxTrafficProp : ats.getAuxiliaryTrafficSpaces()) {
if (auxTrafficProp.isSetObject()) {
TransportationObject trafficSpace = parseAuxiliaryTrafficSpace(auxTrafficProp.getObject());
finishTransportationMapping(trafficSpace);
to.addChild(trafficSpace);
}
}
}
private void mapTrafficSpace(TrafficSpace ts, TransportationObject to) {
mapAbstractUnoccupiedSpace(ts, to);
}
private void mapAbstractUnoccupiedSpace(AbstractUnoccupiedSpace aus, CityObject co) {
mapAbstractPhysicalSpace(aus, co);
}
private TransportationObject parseAuxiliaryTrafficSpace(AuxiliaryTrafficSpace ats) {
TransportationObject to = new TransportationObject(TransportationType.AUXILLIARY_TRAFFIC_SPACE);
parseAbstractSpaceGeometries(ats, to);
finishCityObjectConstruction(to);
return to;
}
private void parseAbstractTransportationSpaceGeometries(AbstractTransportationSpace space, CityObject co) {
parseAndAddMultiSurface(space.getDeprecatedProperties().getLod1MultiSurface(), Lod.LOD1, co);
parseAndAddMultiSurface(space.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, co);
}
private void parseAbstractSpaceGeometries(AbstractSpace as, CityObject co) {
parseAndAddMultiSurface(as.getLod0MultiSurface(), Lod.LOD0, co);
parseAndAddMultiSurface(as.getLod2MultiSurface(), Lod.LOD2, co);
parseAndAddMultiSurface(as.getLod3MultiSurface(), Lod.LOD3, co);
parseAndAddSolid(as.getLod1Solid(), Lod.LOD1, co);
parseAndAddSolid(as.getLod2Solid(), Lod.LOD2, co);
parseAndAddSolid(as.getLod3Solid(), Lod.LOD3, co);
}
private void parseAndAddMultiSurface(MultiSurfaceProperty msp, Lod lod, CityObject co) {
if (msp == null || msp.getObject() == null) {
return;
}
Geometry geom = parseMultiSurface(msp.getObject(), lod);
co.addGeometry(geom);
}
public static void parseId(AbstractGML gml, GmlElement gmlElement) {
String id = gml.getId();
if (id != null) {
gmlElement.setGmlId(new GmlId(id));
}
}
@Override
public void visit(AbstractSpace space) {
// if we are here, an AbstractSpace thing was read that is not handled in the
// other methods
}
@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
public void visit(org.citygml4j.core.model.building.Building gmlBuilding) {
Building cdBuilding = new Building();
readAbstractBuilding(gmlBuilding, cdBuilding);
for (BuildingPartProperty bpProp : gmlBuilding.getBuildingParts()) {
if (!bpProp.isSetObject()) {
continue;
}
BuildingPart part = new BuildingPart(cdBuilding);
readAbstractBuilding(bpProp.getObject(), part);
}
model.addBuilding(cdBuilding);
}
@Override
public void visit(WaterBody waterBody) {
WaterObject wo = new WaterObject();
wo.setGmlObject(waterBody);
mapAbstractOccupiedSpace(waterBody, wo);
parseAndAddMultiSurface(waterBody.getDeprecatedProperties().getLod1MultiSurface(), Lod.LOD1, wo);
parseAndAddSolid(waterBody.getDeprecatedProperties().getLod4Solid(), Lod.LOD4, wo);
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : waterBody.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
wo.addBoundarySurface(bs);
}
resolveAndClearReferences();
wo.unsetGmlGeometries();
updateEdgesAndVertices(wo);
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
updateEdgesAndVertices(bs);
}
model.addWater(wo);
}
@Override
public void visit(LandUse landUse) {
LandObject lo = new LandObject(landUse);
mapAbstractThematicSurface(landUse, lo);
finishCityObjectConstruction(lo);
model.addLand(lo);
}
@Override
public void visit(PlantCover plantCover) {
Vegetation veg = new Vegetation(VegetationType.PLANT_COVER);
veg.setGmlObject(plantCover);
mapAbstractVegetationObject(plantCover, veg);
parseAndAddMultiSurface(plantCover.getDeprecatedProperties().getLod1MultiSurface(), Lod.LOD1, veg);
parseAndAddMultiSurface(plantCover.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, veg);
finishCityObjectConstruction(veg);
model.addVegetation(veg);
}
@Override
public void visit(SolitaryVegetationObject solitaryVegetationObject) {
Vegetation veg = new Vegetation(VegetationType.SOLITARY_VEGETATION_OBJECT);
veg.setGmlObject(solitaryVegetationObject);
mapAbstractVegetationObject(solitaryVegetationObject, veg);
parseAndAddAbstractGeometry(solitaryVegetationObject.getDeprecatedProperties().getLod1Geometry(), Lod.LOD1,
veg);
parseAndAddAbstractGeometry(solitaryVegetationObject.getDeprecatedProperties().getLod2Geometry(), Lod.LOD2,
veg);
parseAndAddAbstractGeometry(solitaryVegetationObject.getDeprecatedProperties().getLod3Geometry(), Lod.LOD3,
veg);
parseAndAddAbstractGeometry(solitaryVegetationObject.getDeprecatedProperties().getLod4Geometry(), Lod.LOD4,
veg);
finishCityObjectConstruction(veg);
model.addVegetation(veg);
}
private void mapAbstractVegetationObject(AbstractVegetationObject avo, Vegetation veg) {
mapAbstractOccupiedSpace(avo, veg);
}
private void mapAbstractOccupiedSpace(AbstractOccupiedSpace aos, CityObject co) {
mapAbstractPhysicalSpace(aos, co);
parseImplicitGeometry(aos, co);
}
private void mapAbstractPhysicalSpace(AbstractPhysicalSpace aps, CityObject co) {
mapAbstractSpace(aps, co);
}
private void mapAbstractSpace(AbstractSpace as, CityObject co) {
mapAbstractFeature(as, co);
parseAndAddMultiSurface(as.getLod0MultiSurface(), Lod.LOD0, co);
parseAndAddMultiSurface(as.getLod2MultiSurface(), Lod.LOD2, co);
parseAndAddMultiSurface(as.getLod3MultiSurface(), Lod.LOD3, co);
parseAndAddSolid(as.getLod1Solid(), Lod.LOD1, co);
parseAndAddSolid(as.getLod2Solid(), Lod.LOD2, 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
public void visit(Bridge bridge) {
BridgeObject bo = new BridgeObject(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()) {
if (!bPartProperty.isSetObject()) {
continue;
}
BridgePart gmlBridgePart = bPartProperty.getObject();
BridgeObject bPart = new BridgeObject(gmlBridgePart, bo);
mapAbstractBridge(gmlBridgePart, bPart);
bo.addBridgePart(bPart);
}
resolveAndClearReferences();
updateEdgesAndVertices(bo);
for (BridgeObject part : bo.getParts()) {
updateEdgesAndVertices(part);
}
for (BridgeConstructiveElement ele : bo.getConstructiveElements()) {
updateEdgesAndVertices(ele);
for (BoundarySurface bs : ele.getBoundarySurfaces()) {
updateEdgesAndVertices(bs);
}
}
for (Installation bi : bo.getBridgeInstallations()) {
updateEdgesAndVertices(bi);
for (BoundarySurface bs : bi.getBoundarySurfaces()) {
updateEdgesAndVertices(bs);
}
}
model.addBridge(bo);
}
private void mapAbstractBridge(AbstractBridge ab, BridgeObject bo) {
mapAbstractConstruction(ab, bo);
for (BridgeConstructiveElementProperty eleProp : ab.getBridgeConstructiveElements()) {
if (!eleProp.isSetObject()) {
continue;
}
org.citygml4j.core.model.bridge.BridgeConstructiveElement constructiveElement = eleProp.getObject();
BridgeConstructiveElement cdEle = new BridgeConstructiveElement(constructiveElement);
mapConstructiveElement(constructiveElement, cdEle);
bo.addConstructiveElement(cdEle);
}
List<BridgeInstallationProperty> bridgeInstallations = ab.getBridgeInstallations();
for (BridgeInstallationProperty installationProp : bridgeInstallations) {
var gmlBi = installationProp.getObject();
if (gmlBi == null) {
// ignore empty properties
continue;
}
Installation bi = mapBridgeInstallation(gmlBi);
bo.addBridgeInstallation(bi);
}
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : ab.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
updatePartOfSurface(bo, surfaceMapper);
for (BoundarySurface bs : bo.getBoundarySurfaces()) {
updateEdgesAndVertices(bs);
}
bo.unsetGmlGeometries();
}
private Installation mapBridgeInstallation(BridgeInstallation gmlBi) {
Installation bi = new Installation();
bi.setGmlObject(gmlBi);
mapAbstractOccupiedSpace(gmlBi, bi);
GeometryProperty<?> lod2Prop = gmlBi.getDeprecatedProperties().getLod2Geometry();
parseAndAddAbstractGeometry(lod2Prop, Lod.LOD2, bi);
GeometryProperty<?> lod3Prop = gmlBi.getDeprecatedProperties().getLod3Geometry();
parseAndAddAbstractGeometry(lod3Prop, Lod.LOD3, bi);
GeometryProperty<?> lod4Prop = gmlBi.getDeprecatedProperties().getLod4Geometry();
parseAndAddAbstractGeometry(lod4Prop, Lod.LOD4, bi);
bi.unsetGmlGeometries();
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlBi.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
bi.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs);
p.setPartOfInstallation(bi);
}
}
}
for (Geometry geom : bi.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfInstallation(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);
parseTunnelInstallations(gmlTunnel, cdTunnel);
parseHollowSpaces(gmlTunnel, cdTunnel);
parseTunnelFurniture(gmlTunnel, cdTunnel);
parseTunnelConstructiveElements(gmlTunnel, cdTunnel);
parseTunnelBoundarySurfaces(gmlTunnel);
for (Installation ti : cdTunnel.getTunnelInstallations()) {
updateEdgesAndVertices(ti);
for (BoundarySurface bs : ti.getBoundarySurfaces()) {
updateEdgesAndVertices(bs);
for (Opening o : bs.getOpenings()) {
updateEdgesAndVertices(o);
}
}
}
cdTunnel.unsetGmlGeometries();
resolveAndClearReferences();
updateEdgesAndVertices(cdTunnel);
}
private void parseTunnelBoundarySurfaces(org.citygml4j.core.model.tunnel.AbstractTunnel gmlTunnel) {
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);
}
}
}
private void parseTunnelConstructiveElements(org.citygml4j.core.model.tunnel.AbstractTunnel gmlTunnel, AbstractTunnel cdTunnel) {
for (TunnelConstructiveElementProperty teProp : gmlTunnel.getTunnelConstructiveElements()) {
var gmlTc = teProp.getObject();
if (gmlTc == null) {
continue;
}
TunnelConstructiveElement tc = mapTunnelConstructiveElement(gmlTc);
cdTunnel.addTunnelConstructiveElement(tc);
}
}
private void parseTunnelFurniture(org.citygml4j.core.model.tunnel.AbstractTunnel gmlTunnel, AbstractTunnel cdTunnel) {
for (TunnelFurnitureProperty tfProp : gmlTunnel.getTunnelFurniture()) {
var gmlTf = tfProp.getObject();
if (gmlTf == null) {
continue;
}
TunnelFurniture tf = mapTunnelFurniture(gmlTf);
cdTunnel.addTunnelFurniture(tf);
}
}
private void parseHollowSpaces(org.citygml4j.core.model.tunnel.AbstractTunnel gmlTunnel, AbstractTunnel cdTunnel) {
for (HollowSpaceProperty thProp : gmlTunnel.getHollowSpaces()) {
var gmlTh = thProp.getObject();
if (gmlTh == null) {
continue;
}
TunnelHollow br = mapTunnelHollow(gmlTh);
cdTunnel.addTunnelHollow(br);
}
}
private void parseTunnelInstallations(org.citygml4j.core.model.tunnel.AbstractTunnel gmlTunnel, AbstractTunnel cdTunnel) {
for (TunnelInstallationProperty tiProp : gmlTunnel.getTunnelInstallations()) {
var gmlTi = tiProp.getObject();
if (gmlTi == null) {
// ignore empty properties
continue;
}
Installation ti = mapTunnelInstallation(gmlTi);
cdTunnel.addTunnelInstallation(ti);
}
}
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) {
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
bo.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs);
}
}
}
}
private void mapConstructiveElement(org.citygml4j.core.model.bridge.BridgeConstructiveElement ele,
BridgeConstructiveElement bce) {
mapAbstractConstructiveElement(ele, bce);
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : ele.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
bce.addBoundarySurface(bs);
}
}
private void mapAbstractConstructiveElement(org.citygml4j.core.model.bridge.BridgeConstructiveElement ele,
BridgeConstructiveElement bce) {
mapAbstractOccupiedSpace(ele, bce);
}
private void mapAbstractConstruction(AbstractConstruction ac, BridgeObject bo) {
mapAbstractOccupiedSpace(ac, bo);
}
@Override
public void visit(AuxiliaryTrafficArea ata) {
TransportationObject to = new TransportationObject(TransportationType.AUXILLIARY_TRAFFIC_AREA);
mapAbstractThematicSurface(ata, to);
finishTransportationMapping(to);
}
@Override
public void visit(TrafficArea ta) {
TransportationObject to = new TransportationObject(TransportationType.TRAFFIC_AREA);
mapAbstractThematicSurface(ta, to);
finishTransportationMapping(to);
}
@Override
public void visit(Road road) {
TransportationObject to = new TransportationObject(TransportationType.ROAD);
mapAbstractTransportationSpace(road, to);
finishTransportationMapping(to);
}
private void mapAbstractThematicSurface(AbstractThematicSurface ats, CityObject co) {
mapAbstractSpaceBoundary(ats, co);
parseAndAddMultiSurface(ats.getLod0MultiSurface(), Lod.LOD0, co);
parseAndAddMultiSurface(ats.getLod1MultiSurface(), Lod.LOD1, co);
parseAndAddMultiSurface(ats.getLod2MultiSurface(), Lod.LOD2, co);
parseAndAddMultiSurface(ats.getLod3MultiSurface(), Lod.LOD3, co);
parseAndAddMultiSurface(ats.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, co);
}
private void mapAbstractSpaceBoundary(AbstractSpaceBoundary asb, CityObject co) {
mapAbstractCityObject(asb, co);
}
private void mapAbstractCityObject(AbstractCityObject aco, CityObject to) {
mapAbstractFeatureWithLifespan(aco, to);
}
private void mapAbstractFeatureWithLifespan(AbstractFeatureWithLifespan afwl, CityObject to) {
mapAbstractFeature(afwl, to);
}
private void mapAbstractFeature(AbstractFeature af, CityObject to) {
mapAbstractGML(af, to);
}
private void mapAbstractGML(AbstractGML ag, CityObject to) {
parseId(ag, to);
}
@Override
public void visit(Railway railway) {
TransportationObject to = new TransportationObject(TransportationType.RAILWAY);
mapAbstractTransportationSpace(railway, to);
finishTransportationMapping(to);
}
@Override
public void visit(Square square) {
TransportationObject to = new TransportationObject(TransportationType.SQUARE);
mapAbstractTransportationSpace(square, to);
finishTransportationMapping(to);
}
@Override
public void visit(Track track) {
TransportationObject to = new TransportationObject(TransportationType.TRACK);
mapAbstractTransportationSpace(track, to);
finishTransportationMapping(to);
}
@Override
public void visit(TransportationComplex transportationComplex) {
TransportationObject to = new TransportationObject(TransportationType.TRANSPORTATION_COMPLEX);
mapAbstractTransportationSpace(transportationComplex, to);
finishTransportationMapping(to);
}
private void finishTransportationMapping(TransportationObject to) {
finishCityObjectConstruction(to);
model.addTransportation(to);
}
private void finishCityObjectConstruction(CityObject co) {
co.unsetGmlGeometries();
resolveAndClearReferences();
updateEdgesAndVertices(co);
}
private void mapAbstractTransportationSpace(AbstractTransportationSpace ats, TransportationObject to) {
to.setGmlObject(ats);
parseAbstractTransportationSpaceGeometries(ats, to);
for (TrafficSpaceProperty tsp : ats.getTrafficSpaces()) {
if (tsp.isSetObject()) {
TransportationObject trafficSpace = new TransportationObject(TransportationType.TRAFFIC_SPACE);
mapTrafficSpace(tsp.getObject(), trafficSpace);
finishTransportationMapping(trafficSpace);
to.getChildren().add(trafficSpace);
}
}
for (AuxiliaryTrafficSpaceProperty auxTrafficProp : ats.getAuxiliaryTrafficSpaces()) {
if (auxTrafficProp.isSetObject()) {
TransportationObject trafficSpace = parseAuxiliaryTrafficSpace(auxTrafficProp.getObject());
finishTransportationMapping(trafficSpace);
to.addChild(trafficSpace);
}
}
}
private void mapTrafficSpace(TrafficSpace ts, TransportationObject to) {
mapAbstractUnoccupiedSpace(ts, to);
}
private void mapAbstractUnoccupiedSpace(AbstractUnoccupiedSpace aus, CityObject co) {
mapAbstractPhysicalSpace(aus, co);
}
private TransportationObject parseAuxiliaryTrafficSpace(AuxiliaryTrafficSpace ats) {
TransportationObject to = new TransportationObject(TransportationType.AUXILLIARY_TRAFFIC_SPACE);
parseAbstractSpaceGeometries(ats, to);
finishCityObjectConstruction(to);
return to;
}
private void parseAbstractTransportationSpaceGeometries(AbstractTransportationSpace space, CityObject co) {
parseAndAddMultiSurface(space.getDeprecatedProperties().getLod1MultiSurface(), Lod.LOD1, co);
parseAndAddMultiSurface(space.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, co);
}
private void parseAbstractSpaceGeometries(AbstractSpace as, CityObject co) {
parseAndAddMultiSurface(as.getLod0MultiSurface(), Lod.LOD0, co);
parseAndAddMultiSurface(as.getLod2MultiSurface(), Lod.LOD2, co);
parseAndAddMultiSurface(as.getLod3MultiSurface(), Lod.LOD3, co);
parseAndAddSolid(as.getLod1Solid(), Lod.LOD1, co);
parseAndAddSolid(as.getLod2Solid(), Lod.LOD2, co);
parseAndAddSolid(as.getLod3Solid(), Lod.LOD3, co);
}
private void parseAndAddMultiSurface(MultiSurfaceProperty msp, Lod lod, CityObject co) {
if (msp == null || msp.getObject() == null) {
return;
}
Geometry geom = parseMultiSurface(msp.getObject(), lod);
co.addGeometry(geom);
}
private void parseAndAddSolid(SolidProperty sp, Lod lod, CityObject co) {
if (sp == null || sp.getObject() == null) {
......@@ -792,32 +814,31 @@ public class Citygml3FeatureMapper extends ObjectWalker {
}
}
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) {
LibraryObject libObj = null;
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) {
LibraryObject libObj = null;
if (directory != null){
Path libraryObjectPath = directory.resolve(ig.getLibraryObject());
libObj = LibraryObject.of(libraryObjectPath, config);
......@@ -827,435 +848,455 @@ public class Citygml3FeatureMapper extends ObjectWalker {
CityGmlZipEntry libEntry = zipEntry.getArchive().getEntry(loPath.toString());
libObj = LibraryObject.of(libEntry, 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("Implicit geometry of GML-ID {} has no referenced geometry.", ig.getId());
}
return igh;
}
private void resolveAndClearReferences() {
for (ResolvableReference ref : references) {
String href = ref.href();
if (href.startsWith("#")) {
href = href.substring(1);
}
Geometry geom = ref.geometry();
CompositeCollection comp = compositeMap.get(href);
if (comp != null) {
comp.getCompositeMembers().forEach(geom::addPolygon);
} else {
ConcretePolygon concPoly = polygonMap.get(href);
if (concPoly == null) {
if (logger.isWarnEnabled()) {
logger.warn(Localization.getText("FeatureMapper.polygonUnreferenced"), href);
}
} else {
LinkedPolygon lPoly = new LinkedPolygon(concPoly, geom);
if (geom.getParent() instanceof BoundarySurface bs) {
lPoly.setPartOfSurface(bs);
if (bs.getParent() instanceof Installation bi) {
lPoly.setPartOfInstallation(bi);
}
}
geom.addPolygon(lPoly);
}
}
}
// clear storage for polygons and vertices
// probably faster than .clear() ?
references = new ArrayList<>();
vertexMap = new HashMap<>();
polygonMap = new HashMap<>();
}
private void readAbstractBuilding(org.citygml4j.core.model.building.AbstractBuilding gmlAb,
AbstractBuilding cdBuilding) {
mapAbstractOccupiedSpace(gmlAb, cdBuilding);
cdBuilding.setGmlObject(gmlAb);
// parse deprecated geometries
parseAndAddMultiSurface(gmlAb.getDeprecatedProperties().getLod1MultiSurface(), Lod.LOD1, cdBuilding);
parseAndAddMultiSurface(gmlAb.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, cdBuilding);
parseAndAddSolid(gmlAb.getDeprecatedProperties().getLod4Solid(), Lod.LOD4, cdBuilding);
for (BuildingInstallationProperty biProp : gmlAb.getBuildingInstallations()) {
var gmlBi = biProp.getObject();
if (gmlBi == null) {
// ignore empty properties
continue;
}
Installation bi = mapBuildingInstallation(gmlBi);
cdBuilding.addBuildingInstallation(bi);
}
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()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
updatePartOfSurface(cdBuilding, surfaceMapper);
cdBuilding.unsetGmlGeometries();
resolveAndClearReferences();
updateEdgesAndVertices(cdBuilding);
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
updateEdgesAndVertices(bs);
for (Opening o : bs.getOpenings()) {
updateEdgesAndVertices(o);
}
}
for (Installation bi : cdBuilding.getBuildingInstallations()) {
updateEdgesAndVertices(bi);
for (BoundarySurface bs : bi.getBoundarySurfaces()) {
updateEdgesAndVertices(bs);
for (Opening o : bs.getOpenings()) {
updateEdgesAndVertices(o);
}
}
}
for (BuildingFurnitureProperty bfProp : gmlAb.getBuildingFurniture()) {
var gmlBf = bfProp.getObject();
if (gmlBf == null) {
continue;
}
BuildingRoomFurniture bf = mapBuildingFurniture(gmlBf);
cdBuilding.addBuildingRoomFurniture(bf);
}
}
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()) {
br.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
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);
}
return br;
}
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);
}
}
}
}
private Installation mapBuildingInstallation(org.citygml4j.core.model.building.BuildingInstallation gmlBi) {
Installation bi = new Installation();
bi.setGmlObject(gmlBi);
mapAbstractOccupiedSpace(gmlBi, bi);
GeometryProperty<?> lod2Prop = gmlBi.getDeprecatedProperties().getLod2Geometry();
parseAndAddAbstractGeometry(lod2Prop, Lod.LOD2, bi);
GeometryProperty<?> lod3Prop = gmlBi.getDeprecatedProperties().getLod3Geometry();
parseAndAddAbstractGeometry(lod3Prop, Lod.LOD3, bi);
GeometryProperty<?> lod4Prop = gmlBi.getDeprecatedProperties().getLod4Geometry();
parseAndAddAbstractGeometry(lod4Prop, Lod.LOD4, bi);
bi.unsetGmlGeometries();
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlBi.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
bi.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs);
p.setPartOfInstallation(bi);
}
}
}
for (Geometry geom : bi.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfInstallation(bi);
}
}
return bi;
}
private void parseAndAddAbstractGeometry(GeometryProperty<?> geomProp, Lod lod, CityObject co) {
if (geomProp == null || geomProp.getObject() == null) {
return;
}
AbstractGeometry abstractGeometry = geomProp.getObject();
if (abstractGeometry instanceof MultiSurface ms) {
Geometry geom = parseMultiSurface(ms, lod);
co.addGeometry(geom);
} else if (abstractGeometry instanceof Solid solid) {
Geometry geom = parseSolid(solid, lod);
if (geom != null) {
co.addGeometry(geom);
}
} else {
logger.warn("Cannot handle geometry type {}, ignoring", abstractGeometry.getClass().getSimpleName());
}
}
private Geometry parseSolid(AbstractSolid abstractSolid, Lod lod) {
if (abstractSolid instanceof Solid s) {
return handleSolidGeometry(s, lod);
} else {
logger.warn("Cannot handle solid class {}, can only process pure solids",
abstractSolid.getClass().getSimpleName());
return null;
}
}
private Geometry handleSolidGeometry(Solid solid, Lod lod) {
ShellProperty exteriorProperty = solid.getExterior();
if (exteriorProperty == null || exteriorProperty.getObject() == null) {
logger.warn("Found solid {} without exterior hull, ignoring", solid.getId());
return null;
}
Geometry geom = new Geometry(GeometryType.SOLID, lod);
Shell exterior = solid.getExterior().getObject();
Citygml3GeometryMapper geometryMapper = new Citygml3GeometryMapper(config, vertexMap);
readSurfaceMember(geom, geometryMapper, exterior.getSurfaceMembers());
return geom;
}
private Geometry parseMultiSurface(MultiSurface ms, Lod lod) {
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, lod);
Citygml3GeometryMapper geometryMapper = new Citygml3GeometryMapper(config, vertexMap);
readSurfaceMember(geom, geometryMapper, ms.getSurfaceMember());
return geom;
}
private void readSurfaceMember(Geometry geom, Citygml3GeometryMapper geometryMapper,
List<SurfaceProperty> surfaceMember) {
for (SurfaceProperty prop : surfaceMember) {
if (prop.getHref() != null) {
references.add(new ResolvableReference(prop.getHref(), geom));
continue;
}
if (prop.getObject() != null) {
AbstractSurface as = prop.getObject();
as.accept(geometryMapper);
}
}
List<ConcretePolygon> polygons = geometryMapper.getPolygons();
for (ConcretePolygon concretePoly : polygons) {
geom.addPolygon(concretePoly);
if (concretePoly.hasExistingGmlId()) {
polygonMap.put(concretePoly.getGmlId().getGmlString(), concretePoly);
}
}
}
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) {
// searching for neighboring vertices, replacing them with one single vertex to
// avoid later problems with edges and manifold problems
for (Geometry geom : co.getGeometries()) {
KDTree tree = new KDTree();
for (Polygon poly : geom.getPolygons()) {
LinearRing lr = poly.getExteriorRing();
updateRing(tree, lr);
for (LinearRing innerRing : poly.getInnerRings()) {
updateRing(tree, innerRing);
}
}
if (!config.useLowMemoryConsumption()) {
// no low memory consumption mode meaning create all meta information in
// geometry
geom.updateEdgesAndVertices();
}
}
}
private void updateRing(KDTree tree, LinearRing lr) {
for (int i = 0; i < lr.getVertices().size(); i++) {
Vertex v = lr.getVertices().get(i);
List<Vertex> nodesInRange = tree.getNodesInRange(v, neighborDistance);
if (nodesInRange.isEmpty()) {
tree.add(v);
} else {
// replace other vertex with any neighboring one
Vertex original = nodesInRange.get(0);
lr.setVertex(i, original);
}
}
}
public void setCityModel(CityModel cModel) {
model.setCityModel(cModel);
}
public CityDoctorModel getModel() {
return model;
}
public void setCityGMLVersion(CityGMLVersion cityGMLVersion) {
model.setParsedCityGMLVersion(cityGMLVersion);
}
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("Implicit geometry of GML-ID {} has no referenced geometry.", ig.getId());
}
return igh;
}
private void resolveAndClearReferences() {
for (ResolvableReference ref : references) {
String href = ref.href();
if (href.startsWith("#")) {
href = href.substring(1);
}
Geometry geom = ref.geometry();
CompositeCollection comp = compositeMap.get(href);
if (comp != null) {
// composite collection, add each containing polygon to the geometry
comp.getCompositeMembers().forEach(geom::addPolygon);
} else {
handlePolygonReference(href, geom);
}
}
// clear storage for polygons and vertices
references = new ArrayList<>();
vertexMap = new HashMap<>();
polygonMap = new HashMap<>();
}
private void handlePolygonReference(String href, Geometry geom) {
ConcretePolygon concPoly = polygonMap.get(href);
if (concPoly == null) {
if (logger.isWarnEnabled()) {
logger.warn(Localization.getText("FeatureMapper.polygonUnreferenced"), href);
}
} else {
LinkedPolygon lPoly = new LinkedPolygon(concPoly, geom);
if (geom.getParent() instanceof BoundarySurface bs) {
lPoly.setPartOfSurface(bs);
if (bs.getParent() instanceof Installation bi) {
lPoly.setPartOfInstallation(bi);
}
}
geom.addPolygon(lPoly);
}
}
private void readAbstractBuilding(org.citygml4j.core.model.building.AbstractBuilding gmlAb,
AbstractBuilding cdBuilding) {
mapAbstractOccupiedSpace(gmlAb, cdBuilding);
cdBuilding.setGmlObject(gmlAb);
// parse deprecated geometries
parseAndAddMultiSurface(gmlAb.getDeprecatedProperties().getLod1MultiSurface(), Lod.LOD1, cdBuilding);
parseAndAddMultiSurface(gmlAb.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, cdBuilding);
parseAndAddSolid(gmlAb.getDeprecatedProperties().getLod4Solid(), Lod.LOD4, cdBuilding);
parseBuildingInstallations(gmlAb, cdBuilding);
parseBuildingRooms(gmlAb, cdBuilding);
parseBuildingSubdivisions(gmlAb, cdBuilding);
parseBoundarySurfaces(gmlAb, cdBuilding);
parseBuildingFurniture(gmlAb, cdBuilding);
}
private void parseBuildingFurniture(org.citygml4j.core.model.building.AbstractBuilding gmlAb, AbstractBuilding cdBuilding) {
for (BuildingFurnitureProperty bfProp : gmlAb.getBuildingFurniture()) {
var gmlBf = bfProp.getObject();
if (gmlBf == null) {
continue;
}
BuildingRoomFurniture bf = mapBuildingFurniture(gmlBf);
cdBuilding.addBuildingRoomFurniture(bf);
}
}
private void parseBoundarySurfaces(org.citygml4j.core.model.building.AbstractBuilding gmlAb, AbstractBuilding cdBuilding) {
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlAb.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
updatePartOfSurface(cdBuilding, surfaceMapper);
cdBuilding.unsetGmlGeometries();
resolveAndClearReferences();
updateEdgesAndVertices(cdBuilding);
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
updateEdgesAndVertices(bs);
for (Opening o : bs.getOpenings()) {
updateEdgesAndVertices(o);
}
}
}
private void parseBuildingSubdivisions(org.citygml4j.core.model.building.AbstractBuilding gmlAb, AbstractBuilding cdBuilding) {
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);
}
}
}
private void parseBuildingRooms(org.citygml4j.core.model.building.AbstractBuilding gmlAb, AbstractBuilding cdBuilding) {
for (BuildingRoomProperty brProp : gmlAb.getBuildingRooms()) {
var gmlBr = brProp.getObject();
if (gmlBr == null) {
continue;
}
BuildingRoom br = mapBuildingRoom(gmlBr);
cdBuilding.addBuildingRoom(br);
}
}
private void parseBuildingInstallations(org.citygml4j.core.model.building.AbstractBuilding gmlAb, AbstractBuilding cdBuilding) {
for (BuildingInstallationProperty biProp : gmlAb.getBuildingInstallations()) {
var gmlBi = biProp.getObject();
if (gmlBi == null) {
// ignore empty properties
continue;
}
Installation bi = mapBuildingInstallation(gmlBi);
cdBuilding.addBuildingInstallation(bi);
}
for (Installation bi : cdBuilding.getBuildingInstallations()) {
updateEdgesAndVertices(bi);
for (BoundarySurface bs : bi.getBoundarySurfaces()) {
updateEdgesAndVertices(bs);
for (Opening o : bs.getOpenings()) {
updateEdgesAndVertices(o);
}
}
}
}
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()) {
br.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
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);
}
return br;
}
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);
}
}
}
}
private Installation mapBuildingInstallation(org.citygml4j.core.model.building.BuildingInstallation gmlBi) {
Installation bi = new Installation();
bi.setGmlObject(gmlBi);
mapAbstractOccupiedSpace(gmlBi, bi);
GeometryProperty<?> lod2Prop = gmlBi.getDeprecatedProperties().getLod2Geometry();
parseAndAddAbstractGeometry(lod2Prop, Lod.LOD2, bi);
GeometryProperty<?> lod3Prop = gmlBi.getDeprecatedProperties().getLod3Geometry();
parseAndAddAbstractGeometry(lod3Prop, Lod.LOD3, bi);
GeometryProperty<?> lod4Prop = gmlBi.getDeprecatedProperties().getLod4Geometry();
parseAndAddAbstractGeometry(lod4Prop, Lod.LOD4, bi);
bi.unsetGmlGeometries();
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, compositeMap, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : gmlBi.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
continue;
}
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
bi.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs);
p.setPartOfInstallation(bi);
}
}
}
for (Geometry geom : bi.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfInstallation(bi);
}
}
return bi;
}
private void parseAndAddAbstractGeometry(GeometryProperty<?> geomProp, Lod lod, CityObject co) {
if (geomProp == null || geomProp.getObject() == null) {
return;
}
AbstractGeometry abstractGeometry = geomProp.getObject();
if (abstractGeometry instanceof MultiSurface ms) {
Geometry geom = parseMultiSurface(ms, lod);
co.addGeometry(geom);
} else if (abstractGeometry instanceof Solid solid) {
Geometry geom = parseSolid(solid, lod);
if (geom != null) {
co.addGeometry(geom);
}
} else {
logger.warn("Cannot handle geometry type {}, ignoring", abstractGeometry.getClass().getSimpleName());
}
}
private Geometry parseSolid(AbstractSolid abstractSolid, Lod lod) {
if (abstractSolid instanceof Solid s) {
return handleSolidGeometry(s, lod);
} else {
logger.warn("Cannot handle solid class {}, can only process pure solids",
abstractSolid.getClass().getSimpleName());
return null;
}
}
private Geometry handleSolidGeometry(Solid solid, Lod lod) {
ShellProperty exteriorProperty = solid.getExterior();
if (exteriorProperty == null || exteriorProperty.getObject() == null) {
logger.warn("Found solid {} without exterior hull, ignoring", solid.getId());
return null;
}
Geometry geom = new Geometry(GeometryType.SOLID, lod);
Shell exterior = solid.getExterior().getObject();
Citygml3GeometryMapper geometryMapper = new Citygml3GeometryMapper(config, vertexMap);
readSurfaceMember(geom, geometryMapper, exterior.getSurfaceMembers());
return geom;
}
private Geometry parseMultiSurface(MultiSurface ms, Lod lod) {
Geometry geom = new Geometry(GeometryType.MULTI_SURFACE, lod);
Citygml3GeometryMapper geometryMapper = new Citygml3GeometryMapper(config, vertexMap);
readSurfaceMember(geom, geometryMapper, ms.getSurfaceMember());
return geom;
}
private void readSurfaceMember(Geometry geom, Citygml3GeometryMapper geometryMapper,
List<SurfaceProperty> surfaceMember) {
for (SurfaceProperty prop : surfaceMember) {
if (prop.getHref() != null) {
references.add(new ResolvableReference(prop.getHref(), geom));
continue;
}
if (prop.getObject() != null) {
AbstractSurface as = prop.getObject();
as.accept(geometryMapper);
}
}
List<ConcretePolygon> polygons = geometryMapper.getPolygons();
for (ConcretePolygon concretePoly : polygons) {
geom.addPolygon(concretePoly);
if (concretePoly.hasExistingGmlId()) {
polygonMap.put(concretePoly.getGmlId().getGmlString(), concretePoly);
}
}
}
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) {
// searching for neighboring vertices, replacing them with one single vertex to
// avoid later problems with edges and manifold problems
for (Geometry geom : co.getGeometries()) {
KDTree tree = new KDTree();
for (Polygon poly : geom.getPolygons()) {
LinearRing lr = poly.getExteriorRing();
updateRing(tree, lr);
for (LinearRing innerRing : poly.getInnerRings()) {
updateRing(tree, innerRing);
}
}
if (!config.useLowMemoryConsumption()) {
// no low memory consumption mode meaning create all meta information in
// geometry
geom.updateEdgesAndVertices();
}
}
}
private void updateRing(KDTree tree, LinearRing lr) {
for (int i = 0; i < lr.getVertices().size(); i++) {
Vertex v = lr.getVertices().get(i);
List<Vertex> nodesInRange = tree.getNodesInRange(v, neighborDistance);
if (nodesInRange.isEmpty()) {
tree.add(v);
} else {
// replace other vertex with any neighboring one
Vertex original = nodesInRange.get(0);
lr.setVertex(i, original);
}
}
}
public void setCityModel(CityModel cModel) {
model.setCityModel(cModel);
}
public CityDoctorModel getModel() {
return model;
}
public void setCityGMLVersion(CityGMLVersion cityGMLVersion) {
model.setParsedCityGMLVersion(cityGMLVersion);
}
}
......@@ -59,7 +59,7 @@ public class Citygml3GeometryMapper extends GeometryWalker {
public void visit(Polygon polygon) {
parsePolygon(polygon.getId(), polygon.getExterior(), polygon.getInterior());
if (polygon.getExterior() == null) {
logger.warn(String.format("No exterior: %s", polygon.getId()));
logger.warn("No exterior: {}", polygon.getId());
}
}
......
......@@ -34,7 +34,7 @@ import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
*
*/
public class ProjectionAxis {
private static final String DIVISOR_IS_0 = "Divisor is 0";
private final int[] axis;
......@@ -87,20 +87,36 @@ public class ProjectionAxis {
this.axis = axis;
}
/**
* This will write the two coordinates determined in this projection axis into a
* given array at the startIndex location. The array has to have at least a
* length of startIndex + 1.
*
* @param v the vector from which the coordinates are taken.
* @param array the array that is written to.
* @param startIndex the start location in the array.
*/
public void writeCoordinatesOfVectorInArray(Vector3d v, double[] array, int startIndex) {
array[startIndex] = v.getCoordinate(axis[0]);
array[startIndex + 1] = v.getCoordinate(axis[1]);
}
public Vector2d project(Vector3d v) {
return new Vector2d(v.getCoordinate(axis[0]), v.getCoordinate(axis[1]));
}
/**
* calculates the missing coordinate for 3d vector from the plane and this axis.
*
* @return the projected 3d point.
*/
public Vector3d projectToPlane(Plane plane, Vector2d v) {
return projectToPlane(plane, v.getX(), v.getY());
}
/**
* calculates the missing coordinate for 3d vector from the plane and this axis.
*
* @return the projected 3d point.
*/
public Vector3d projectToPlane(Plane plane, double vectorX, double vectorY) {
......
......@@ -6,10 +6,8 @@ import java.util.List;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.math.Polygon2d;
import de.hft.stuttgart.citydoctor2.math.Ring2d;
import de.hft.stuttgart.citydoctor2.math.ProjectionAxis;
import de.hft.stuttgart.citydoctor2.math.Triangle3d;
import de.hft.stuttgart.citydoctor2.math.Vector2d;
import earcut4j.Earcut;
/**
......@@ -35,8 +33,8 @@ public class EarcutTesselator {
}
}
// collect vertices
// project polygon to 2D space as library is buggy for more than 2 dimensions
Polygon2d projectedPolygon = Polygon2d.withProjection(p);
// find most dominant projection axis for 2d projection
ProjectionAxis axis = ProjectionAxis.of(p);
double[] vertices = new double[nrOfVertices * 2];
List<Vertex> vertexObjects = new ArrayList<>();
......@@ -45,9 +43,10 @@ public class EarcutTesselator {
addVerticesToList(innerRing, vertexObjects);
}
int start = addRingToArray(projectedPolygon.getExterior(), vertices, 0);
for (Ring2d innerRing : projectedPolygon.getInteriorRings()) {
start = addRingToArray(innerRing, vertices, start);
// write the vector data according to the projection axis into the array
int start = addRingToArray(p.getExteriorRing(), vertices, 0, axis);
for (LinearRing innerRing : p.getInnerRings()) {
start = addRingToArray(innerRing, vertices, start, axis);
}
// triangulation
......@@ -73,12 +72,12 @@ public class EarcutTesselator {
}
}
private static int addRingToArray(Ring2d ring, double[] vertices, int start) {
List<Vector2d> ringVertices = ring.getVertices();
private static int addRingToArray(LinearRing ring, double[] vertices, int start, ProjectionAxis axis) {
List<Vertex> ringVertices = ring.getVertices();
for (int i = 0; i < ringVertices.size() - 1; i++) {
Vector2d v = ringVertices.get(i);
vertices[start++] = v.getX();
vertices[start++] = v.getY();
Vertex v = ringVertices.get(i);
axis.writeCoordinatesOfVectorInArray(v, vertices, start);
start = start + 2;
}
return start;
}
......
......@@ -31,7 +31,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.citygml4j.core.model.CityGMLVersion;
import org.citygml4j.core.model.core.AbstractCityObjectProperty;
import org.citygml4j.core.model.core.AbstractFeatureProperty;
import org.citygml4j.core.model.core.CityModel;
......
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.hft.stuttgart</groupId>
......@@ -65,11 +65,11 @@
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
</dependencies>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
......
......@@ -426,6 +426,7 @@ public class Checker {
}
}
@SuppressWarnings("resource")
public static SvrlContentHandler executeSchematronValidationIfAvailable(ValidationConfiguration config,
InputStream in) {
if (config.getSchematronFilePath() != null && !config.getSchematronFilePath().isEmpty()) {
......
......@@ -65,23 +65,19 @@ public class SvrlContentHandler implements ContentHandler {
public void setDocumentLocator(Locator locator) {
// not needed
}
@SuppressWarnings("RedundantThrows")
@Override
public void startDocument() throws SAXException {
// not needed
}
@SuppressWarnings("RedundantThrows")
@Override
public void endDocument() throws SAXException {
// not needed
}
@SuppressWarnings("RedundantThrows")
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
// not needed
}
@SuppressWarnings("RedundantThrows")
@Override
public void endPrefixMapping(String prefix) throws SAXException {
// not needed
......@@ -133,17 +129,14 @@ public class SvrlContentHandler implements ContentHandler {
buffer.append(ch, start, length);
}
}
@SuppressWarnings("RedundantThrows")
@Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
// not needed
}
@SuppressWarnings("RedundantThrows")
@Override
public void processingInstruction(String target, String data) throws SAXException {
// not needed
}
@SuppressWarnings("RedundantThrows")
@Override
public void skippedEntity(String name) throws SAXException {
// not needed
......
......@@ -76,7 +76,6 @@ public class SolidSelfIntCheck extends Check {
}
CheckResult cr;
List<PolygonIntersection> intersections = SelfIntersectionUtil.calculateSolidSelfIntersection(g);
// List<PolygonIntersection> intersections = SelfIntersectionUtil.doesSolidSelfIntersect2(g);
if (intersections.isEmpty()) {
cr = new CheckResult(this, ResultStatus.OK, null);
} else {
......
......@@ -36,7 +36,6 @@ public class SolidSelfIntCheckFalsePositiveBigMeshTest {
Checker c = new Checker(config, m);
c.runChecks();
Building building = m.getBuildings().get(0);
System.out.println(building.containsAnyError());
/*
* The examples have no actual self-intersections, but can contain other actual model defects.
* If an error is detected, it is thus required to check if the
......
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