Commit a3786746 authored by Riegel's avatar Riegel
Browse files

Add mapping of ImplicitGeometry

parent fdfd472b
This commit is part of merge request !11. Comments created here will be created in the context of that merge request.
/*- /*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart * Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
* *
* This file is part of CityDoctor2. * This file is part of CityDoctor2.
* *
* CityDoctor2 is free software: you can redistribute it and/or modify * CityDoctor2 is free software: you can redistribute it and/or modify
...@@ -44,16 +44,7 @@ import org.citygml4j.core.model.building.BuildingFurniture; ...@@ -44,16 +44,7 @@ import org.citygml4j.core.model.building.BuildingFurniture;
import org.citygml4j.core.model.building.BuildingUnit; import org.citygml4j.core.model.building.BuildingUnit;
import org.citygml4j.core.model.building.Storey; import org.citygml4j.core.model.building.Storey;
import org.citygml4j.core.model.construction.AbstractConstruction; import org.citygml4j.core.model.construction.AbstractConstruction;
import org.citygml4j.core.model.core.AbstractCityObject; import org.citygml4j.core.model.core.*;
import org.citygml4j.core.model.core.AbstractFeatureWithLifespan;
import org.citygml4j.core.model.core.AbstractOccupiedSpace;
import org.citygml4j.core.model.core.AbstractPhysicalSpace;
import org.citygml4j.core.model.core.AbstractSpace;
import org.citygml4j.core.model.core.AbstractSpaceBoundary;
import org.citygml4j.core.model.core.AbstractSpaceBoundaryProperty;
import org.citygml4j.core.model.core.AbstractThematicSurface;
import org.citygml4j.core.model.core.AbstractUnoccupiedSpace;
import org.citygml4j.core.model.core.CityModel;
import org.citygml4j.core.model.deprecated.transportation.TransportationComplex; import org.citygml4j.core.model.deprecated.transportation.TransportationComplex;
import org.citygml4j.core.model.landuse.LandUse; import org.citygml4j.core.model.landuse.LandUse;
import org.citygml4j.core.model.transportation.AbstractTransportationSpace; import org.citygml4j.core.model.transportation.AbstractTransportationSpace;
...@@ -103,11 +94,12 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -103,11 +94,12 @@ public class Citygml3FeatureMapper extends ObjectWalker {
private List<ResolvableReference> references = new ArrayList<>(); private List<ResolvableReference> references = new ArrayList<>();
private Map<Vertex, Vertex> vertexMap = new HashMap<>(); private Map<Vertex, Vertex> vertexMap = new HashMap<>();
private final ParserConfiguration config; private final ParserConfiguration config;
private final Path directory;
private final double neighborDistance; private final double neighborDistance;
public Citygml3FeatureMapper(ParserConfiguration config, Path path) { public Citygml3FeatureMapper(ParserConfiguration config, Path path) {
this.config = config; this.config = config;
this.directory = path.getParent();
model = new CityDoctorModel(config, path.toFile()); model = new CityDoctorModel(config, path.toFile());
neighborDistance = 1.8d / Math.pow(10, config.getNumberOfRoundingPlaces()); neighborDistance = 1.8d / Math.pow(10, config.getNumberOfRoundingPlaces());
} }
...@@ -207,13 +199,13 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -207,13 +199,13 @@ public class Citygml3FeatureMapper extends ObjectWalker {
finishCityObjectConstruction(veg); finishCityObjectConstruction(veg);
model.addVegetation(veg); model.addVegetation(veg);
} }
@Override @Override
public void visit(SolitaryVegetationObject solitaryVegetationObject) { public void visit(SolitaryVegetationObject solitaryVegetationObject) {
Vegetation veg = new Vegetation(VegetationType.SOLITARY_VEGETATION_OBJECT); Vegetation veg = new Vegetation(VegetationType.SOLITARY_VEGETATION_OBJECT);
veg.setGmlObject(solitaryVegetationObject); veg.setGmlObject(solitaryVegetationObject);
mapAbstractVegetationObject(solitaryVegetationObject, veg); mapAbstractVegetationObject(solitaryVegetationObject, veg);
parseAndAddAbstractGeometry(solitaryVegetationObject.getDeprecatedProperties().getLod1Geometry(), Lod.LOD1, veg); parseAndAddAbstractGeometry(solitaryVegetationObject.getDeprecatedProperties().getLod1Geometry(), Lod.LOD1, veg);
parseAndAddAbstractGeometry(solitaryVegetationObject.getDeprecatedProperties().getLod2Geometry(), Lod.LOD2, veg); parseAndAddAbstractGeometry(solitaryVegetationObject.getDeprecatedProperties().getLod2Geometry(), Lod.LOD2, veg);
parseAndAddAbstractGeometry(solitaryVegetationObject.getDeprecatedProperties().getLod3Geometry(), Lod.LOD3, veg); parseAndAddAbstractGeometry(solitaryVegetationObject.getDeprecatedProperties().getLod3Geometry(), Lod.LOD3, veg);
...@@ -222,13 +214,14 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -222,13 +214,14 @@ public class Citygml3FeatureMapper extends ObjectWalker {
finishCityObjectConstruction(veg); finishCityObjectConstruction(veg);
model.addVegetation(veg); model.addVegetation(veg);
} }
private void mapAbstractVegetationObject(AbstractVegetationObject avo, Vegetation veg) { private void mapAbstractVegetationObject(AbstractVegetationObject avo, Vegetation veg) {
mapAbstractOccupiedSpace(avo, veg); mapAbstractOccupiedSpace(avo, veg);
} }
private void mapAbstractOccupiedSpace(AbstractOccupiedSpace aos, CityObject co) { private void mapAbstractOccupiedSpace(AbstractOccupiedSpace aos, CityObject co) {
mapAbstractPhysicalSpace(aos, co); mapAbstractPhysicalSpace(aos, co);
parseImplicitGeometry(aos, co);
} }
private void mapAbstractPhysicalSpace(AbstractPhysicalSpace aps, CityObject co) { private void mapAbstractPhysicalSpace(AbstractPhysicalSpace aps, CityObject co) {
...@@ -245,6 +238,8 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -245,6 +238,8 @@ public class Citygml3FeatureMapper extends ObjectWalker {
parseAndAddSolid(as.getLod3Solid(), Lod.LOD3, co); parseAndAddSolid(as.getLod3Solid(), Lod.LOD3, co);
} }
@Override @Override
public void visit(Bridge bridge) { public void visit(Bridge bridge) {
BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, bridge); BridgeObject bo = new BridgeObject(BridgeType.BRIDGE, bridge);
...@@ -289,7 +284,7 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -289,7 +284,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
mapConstructiveElement(constructiveElement, cdEle); mapConstructiveElement(constructiveElement, cdEle);
bo.addConstructiveElement(cdEle); bo.addConstructiveElement(cdEle);
} }
List<BridgeInstallationProperty> bridgeInstallations = ab.getBridgeInstallations(); List<BridgeInstallationProperty> bridgeInstallations = ab.getBridgeInstallations();
for (BridgeInstallationProperty installationProp : bridgeInstallations) { for (BridgeInstallationProperty installationProp : bridgeInstallations) {
var gmlBi = installationProp.getObject(); var gmlBi = installationProp.getObject();
...@@ -300,7 +295,7 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -300,7 +295,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
Installation bi = mapBridgeInstallation(gmlBi); Installation bi = mapBridgeInstallation(gmlBi);
bo.addBridgeInstallation(bi); bo.addBridgeInstallation(bi);
} }
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, vertexMap, config); SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : ab.getBoundaries()) { for (AbstractSpaceBoundaryProperty surfaceProp : ab.getBoundaries()) {
if (!surfaceProp.isSetObject()) { if (!surfaceProp.isSetObject()) {
...@@ -310,11 +305,11 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -310,11 +305,11 @@ public class Citygml3FeatureMapper extends ObjectWalker {
surface.accept(surfaceMapper); surface.accept(surfaceMapper);
} }
updatePartOfSurface(bo, surfaceMapper); updatePartOfSurface(bo, surfaceMapper);
for (BoundarySurface bs : bo.getBoundarySurfaces()) { for (BoundarySurface bs : bo.getBoundarySurfaces()) {
updateEdgesAndVertices(bs); updateEdgesAndVertices(bs);
} }
bo.unsetGmlGeometries(); bo.unsetGmlGeometries();
} }
...@@ -369,7 +364,7 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -369,7 +364,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
private void mapConstructiveElement(org.citygml4j.core.model.bridge.BridgeConstructiveElement ele, BridgeConstructiveElement bce) { private void mapConstructiveElement(org.citygml4j.core.model.bridge.BridgeConstructiveElement ele, BridgeConstructiveElement bce) {
mapAbstractConstructiveElement(ele, bce); mapAbstractConstructiveElement(ele, bce);
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, vertexMap, config); SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, vertexMap, config);
for (AbstractSpaceBoundaryProperty surfaceProp : ele.getBoundaries()) { for (AbstractSpaceBoundaryProperty surfaceProp : ele.getBoundaries()) {
if (!surfaceProp.isSetObject()) { if (!surfaceProp.isSetObject()) {
...@@ -547,6 +542,55 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -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() { private void resolveAndClearReferences() {
for (ResolvableReference ref : references) { for (ResolvableReference ref : references) {
String href = ref.href(); String href = ref.href();
......
...@@ -122,6 +122,9 @@ public class CityGmlParser { ...@@ -122,6 +122,9 @@ public class CityGmlParser {
private static CityGMLContext context; private static CityGMLContext context;
private static List<QName> chunkProperties = new ArrayList<>(); private static List<QName> chunkProperties = new ArrayList<>();
// Toggle to suppress logger output for parsing of libraryObjects
private static boolean gagged = false;
static { static {
System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"); System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
FACTORY = SAXParserFactory.newInstance(); FACTORY = SAXParserFactory.newInstance();
...@@ -326,6 +329,14 @@ public class CityGmlParser { ...@@ -326,6 +329,14 @@ public class CityGmlParser {
return writer; 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, private static CityDoctorModel readAndKeepFeatures(ParserConfiguration config, Path file,
CityGMLInputFactory inputFactory, ObservedInputStream ois) throws CityGMLReadException { CityGMLInputFactory inputFactory, ObservedInputStream ois) throws CityGMLReadException {
try (CityGMLReader reader = inputFactory.createCityGMLReader(ois)) { try (CityGMLReader reader = inputFactory.createCityGMLReader(ois)) {
...@@ -362,9 +373,12 @@ public class CityGmlParser { ...@@ -362,9 +373,12 @@ public class CityGmlParser {
for (AbstractCityObject aco : acos) { for (AbstractCityObject aco : acos) {
cModel.getCityObjectMembers().add(new AbstractCityObjectProperty(aco)); cModel.getCityObjectMembers().add(new AbstractCityObjectProperty(aco));
} }
if (logger.isInfoEnabled()) { if (logger.isInfoEnabled() && !gagged) {
logger.info(Localization.getText("CityGmlParser.parsedObjects"), logger.info(Localization.getText("CityGmlParser.parsedObjects"),
mapper.getModel().getNumberOfFeatures()); mapper.getModel().getNumberOfFeatures());
} else if (gagged){
// Remove gag
gagged = false;
} }
return mapper.getModel(); 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