Commit a3786746 authored by Riegel's avatar Riegel
Browse files

Add mapping of ImplicitGeometry

Showing with 79 additions and 21 deletions
+79 -21
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
......@@ -44,16 +44,7 @@ import org.citygml4j.core.model.building.BuildingFurniture;
import org.citygml4j.core.model.building.BuildingUnit;
import org.citygml4j.core.model.building.Storey;
import org.citygml4j.core.model.construction.AbstractConstruction;
import org.citygml4j.core.model.core.AbstractCityObject;
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.core.*;
import org.citygml4j.core.model.deprecated.transportation.TransportationComplex;
import org.citygml4j.core.model.landuse.LandUse;
import org.citygml4j.core.model.transportation.AbstractTransportationSpace;
......@@ -103,11 +94,12 @@ public class Citygml3FeatureMapper extends ObjectWalker {
private List<ResolvableReference> references = new ArrayList<>();
private Map<Vertex, Vertex> vertexMap = new HashMap<>();
private final ParserConfiguration config;
private final Path directory;
private final double neighborDistance;
public Citygml3FeatureMapper(ParserConfiguration config, Path path) {
this.config = config;
this.directory = path.getParent();
model = new CityDoctorModel(config, path.toFile());
neighborDistance = 1.8d / Math.pow(10, config.getNumberOfRoundingPlaces());
}
......@@ -207,13 +199,13 @@ public class Citygml3FeatureMapper extends ObjectWalker {
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);
......@@ -222,13 +214,14 @@ public class Citygml3FeatureMapper extends ObjectWalker {
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) {
......@@ -245,6 +238,8 @@ public class Citygml3FeatureMapper extends ObjectWalker {
parseAndAddSolid(as.getLod3Solid(), Lod.LOD3, co);
}
@Override
public void visit(Bridge bridge) {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, bridge);
......@@ -289,7 +284,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
mapConstructiveElement(constructiveElement, cdEle);
bo.addConstructiveElement(cdEle);
}
List<BridgeInstallationProperty> bridgeInstallations = ab.getBridgeInstallations();
for (BridgeInstallationProperty installationProp : bridgeInstallations) {
var gmlBi = installationProp.getObject();
......@@ -300,7 +295,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
Installation bi = mapBridgeInstallation(gmlBi);
bo.addBridgeInstallation(bi);
}
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : ab.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
......@@ -310,11 +305,11 @@ public class Citygml3FeatureMapper extends ObjectWalker {
surface.accept(surfaceMapper);
}
updatePartOfSurface(bo, surfaceMapper);
for (BoundarySurface bs : bo.getBoundarySurfaces()) {
updateEdgesAndVertices(bs);
}
bo.unsetGmlGeometries();
}
......@@ -369,7 +364,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
private void mapConstructiveElement(org.citygml4j.core.model.bridge.BridgeConstructiveElement ele, BridgeConstructiveElement bce) {
mapAbstractConstructiveElement(ele, bce);
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : ele.getBoundaries()) {
if (!surfaceProp.isSetObject()) {
......@@ -547,6 +542,55 @@ 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){
// TODO: HREF handling of implicit geometries
}
}
}
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);
}
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() {
for (ResolvableReference ref : references) {
String href = ref.href();
......
......@@ -122,6 +122,9 @@ public class CityGmlParser {
private static CityGMLContext context;
private static List<QName> chunkProperties = new ArrayList<>();
// Toggle to suppress logger output for parsing of libraryObjects
private static boolean gagged = false;
static {
System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
FACTORY = SAXParserFactory.newInstance();
......@@ -326,6 +329,14 @@ public class CityGmlParser {
return writer;
}
/**
* Suppresses logger output of {@link #readAndKeepFeatures} for the next parse.
* Used to prevent logging spam while resolving implicit geometries.
*/
public static void gagLogger(boolean value){
gagged = value;
}
private static CityDoctorModel readAndKeepFeatures(ParserConfiguration config, Path file,
CityGMLInputFactory inputFactory, ObservedInputStream ois) throws CityGMLReadException {
try (CityGMLReader reader = inputFactory.createCityGMLReader(ois)) {
......@@ -362,9 +373,12 @@ public class CityGmlParser {
for (AbstractCityObject aco : acos) {
cModel.getCityObjectMembers().add(new AbstractCityObjectProperty(aco));
}
if (logger.isInfoEnabled()) {
if (logger.isInfoEnabled() && !gagged) {
logger.info(Localization.getText("CityGmlParser.parsedObjects"),
mapper.getModel().getNumberOfFeatures());
} else if (gagged){
// Remove gag
gagged = false;
}
return mapper.getModel();
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment