/*- * 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 * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * CityDoctor2 is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with CityDoctor2. If not, see . */ package de.hft.stuttgart.citydoctor2.datastructure; import java.util.ArrayList; import java.util.List; import org.citygml4j.core.model.core.AbstractThematicSurface; import org.citygml4j.core.util.geometry.GeometryFactory; import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface; import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty; import de.hft.stuttgart.citydoctor2.check.Check; import de.hft.stuttgart.citydoctor2.check.CheckError; import de.hft.stuttgart.citydoctor2.check.CheckId; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils; import de.hft.stuttgart.citydoctor2.utils.CopyHandler; import de.hft.stuttgart.citydoctor2.utils.Copyable; /** * Representing a boundary surface in CityGML * * @author Matthias Betz * */ public class BoundarySurface extends CityObject { private static final long serialVersionUID = 8793865135393496408L; private SurfaceFeatureType featureType; private BoundarySurfaceType type; private List openings = new ArrayList<>(2); private CityObject parent; private AbstractThematicSurface gmlObject; public BoundarySurface(AbstractThematicSurface aco) { this(SurfaceFeatureType.BUILDING, BoundarySurfaceType.UNDEFINED, aco); } public BoundarySurface(SurfaceFeatureType featureType, BoundarySurfaceType type, AbstractThematicSurface aco) { this.featureType = featureType; this.type = type; gmlObject = aco; } public void setFeatureType(SurfaceFeatureType featureType) { this.featureType = featureType; } public void setType(BoundarySurfaceType type) { this.type = type; } public void setGmlObject(AbstractThematicSurface gmlObject) { this.gmlObject = gmlObject; } public SurfaceFeatureType getSurfaceFeatureType() { return featureType; } public BoundarySurfaceType getType() { return type; } public List getOpenings() { return openings; } @Override public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) { if (gmlObject.getId() == null) { gmlObject.setId(getGmlId().getGmlString()); } for (Geometry geom : getGeometries()) { if (geom.getType() == GeometryType.MULTI_SURFACE) { MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config); if (ms != null) { setGeometryAccordingToLod(geom.getLod(), new MultiSurfaceProperty(ms)); } } else { throw new IllegalStateException("BoundarySurfaces can only have MultiSurface geometries"); } } for (Opening o : openings) { o.reCreateGeometries(factory, config); } } private void setGeometryAccordingToLod(Lod lod, MultiSurfaceProperty ms) { switch (lod) { case LOD0: gmlObject.setLod0MultiSurface(ms); break; case LOD1: gmlObject.setLod1MultiSurface(ms); break; case LOD2: gmlObject.setLod2MultiSurface(ms); break; case LOD3: gmlObject.setLod3MultiSurface(ms); break; case LOD4: gmlObject.getDeprecatedProperties().setLod4MultiSurface(ms); break; default: throw new IllegalStateException("Found geometry with LOD other than LOD1-4, which is illegal for BoundarySurfaces: " + lod); } } @Override public void clearAllContainedCheckResults() { super.clearAllContainedCheckResults(); for (Opening o : openings) { o.clearAllContainedCheckResults(); } } @Override public void collectContainedErrors(List errors) { super.collectContainedErrors(errors); for (Opening o : openings) { o.collectContainedErrors(errors); } } @Override public boolean containsAnyError() { boolean hasError = super.containsAnyError(); if (hasError) { return true; } for (Opening o : openings) { if (o.containsAnyError()) { return true; } } return false; } @Override public boolean containsError(CheckId checkIdentifier) { boolean hasError = super.containsError(checkIdentifier); if (hasError) { return true; } for (Opening o : openings) { if (o.containsError(checkIdentifier)) { return true; } } return false; } @Override public void accept(Check c) { super.accept(c); if (c.canExecute(this)) { c.check(this); } for (Opening o : openings) { o.accept(c); } } public void setParent(CityObject parent) { this.parent = parent; } public CityObject getParent() { return parent; } @Override public void unsetGmlGeometries() { gmlObject.setLod0MultiSurface(null); gmlObject.setLod1MultiSurface(null); gmlObject.setLod2MultiSurface(null); gmlObject.setLod3MultiSurface(null); gmlObject.getDeprecatedProperties().setLod4MultiSurface(null); for (Opening o : openings) { o.unsetGmlGeometries(); } } @Override public String toString() { return "BoundarySurface [type=" + type + ", id=" + getGmlId() + "]"; } void anonymize() { gmlObject.setAppearances(null); gmlObject.setBoundedBy(null); gmlObject.setCreationDate(null); gmlObject.setDescription(null); gmlObject.setExternalReferences(null); gmlObject.setGeneralizesTo(null); gmlObject.setADEProperties(null); gmlObject.setGenericAttributes(null); setGmlId(GmlId.generateId()); gmlObject.setId(getGmlId().getGmlString()); } @Override public AbstractThematicSurface getGmlObject() { return gmlObject; } @Override public FeatureType getFeatureType() { return FeatureType.BOUNDARY_SURFACE; } public void addOpening(Opening opening) { openings.add(opening); opening.setPartOfSurface(this); } @Override public void prepareForChecking() { super.prepareForChecking(); for (Opening o : openings) { o.prepareForChecking(); } } @Override public void clearMetaInformation() { super.clearMetaInformation(); for (Opening o : openings) { o.clearMetaInformation(); } } @Override public Copyable createCopyInstance() { return new BoundarySurface(gmlObject); } @Override public void collectInstances(CopyHandler handler) { super.collectInstances(handler); for (Opening o : openings) { handler.addInstance(o); } handler.addInstance(parent); } @Override public void fillValues(Copyable original, CopyHandler handler) { super.fillValues(original, handler); BoundarySurface originalBs = (BoundarySurface) original; featureType = originalBs.featureType; type = originalBs.type; for (Opening originalOpening : originalBs.openings) { openings.add(handler.getCopyInstance(originalOpening)); } parent = handler.getCopyInstance(originalBs.parent); gmlObject = originalBs.gmlObject; } }