Commit 7ebb95c1 authored by Matthias Betz's avatar Matthias Betz
Browse files

Merge branch 'dev'

parents 84d3169f 75c0e581
Pipeline #7499 passed with stage
in 1 minute and 13 seconds
......@@ -272,3 +272,34 @@ $RECYCLE.BIN/
*.lnk
# End of https://www.gitignore.io/api/java,maven,macos,linux,eclipse,windows,netbeans,intellij
/.gradle/
### Gradle ###
.gradle
**/build/
!src/**/build/
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
# Avoid ignore Gradle wrappper properties
!gradle-wrapper.properties
# Cache of project
.gradletasknamecache
# Eclipse Gradle plugin generated files
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath
### Gradle Patch ###
# Java heap dump
*.hprof
# End of https://www.toptal.com/developers/gitignore/api/gradle
......@@ -5,7 +5,7 @@
<parent>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorParent</artifactId>
<version>3.12.0</version>
<version>3.13.0</version>
</parent>
<artifactId>CityDoctorCheckResult</artifactId>
......
......@@ -5,7 +5,7 @@
<parent>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorParent</artifactId>
<version>3.12.0</version>
<version>3.13.0</version>
</parent>
<artifactId>CityDoctorEdge</artifactId>
......
......@@ -3,7 +3,7 @@
<parent>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorParent</artifactId>
<version>3.12.0</version>
<version>3.13.0</version>
</parent>
<properties>
......
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
* Copyright 2023 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
......@@ -19,6 +19,7 @@
package de.hft.stuttgart.citydoctor2.check;
import de.hft.stuttgart.citydoctor2.check.error.AllPolygonsWrongOrientationError;
import de.hft.stuttgart.citydoctor2.check.error.AttributeInvalidError;
import de.hft.stuttgart.citydoctor2.check.error.AttributeMissingError;
import de.hft.stuttgart.citydoctor2.check.error.AttributeValueWrongError;
import de.hft.stuttgart.citydoctor2.check.error.ConsecutivePointSameError;
......@@ -129,4 +130,6 @@ public interface ErrorVisitor {
public void visit(AttributeValueWrongError err);
public void visit(AttributeInvalidError cdErr);
}
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
* Copyright 2023 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
......@@ -24,6 +24,7 @@ import org.xmlobjects.gml.model.measures.Angle;
import org.xmlobjects.gml.model.measures.Length;
import de.hft.stuttgart.citydoctor2.check.error.AllPolygonsWrongOrientationError;
import de.hft.stuttgart.citydoctor2.check.error.AttributeInvalidError;
import de.hft.stuttgart.citydoctor2.check.error.AttributeMissingError;
import de.hft.stuttgart.citydoctor2.check.error.AttributeValueWrongError;
import de.hft.stuttgart.citydoctor2.check.error.ConsecutivePointSameError;
......@@ -80,6 +81,7 @@ import de.hft.stuttgart.quality.model.types.PlanarDistancePlaneError;
import de.hft.stuttgart.quality.model.types.PlanarNormalsDeviationError;
import de.hft.stuttgart.quality.model.types.PolygonIdList;
import de.hft.stuttgart.quality.model.types.RingSelfIntersectionError;
import de.hft.stuttgart.quality.model.types.SemanticAttributeInvalidError;
import de.hft.stuttgart.quality.model.types.SemanticAttributeMissingError;
import de.hft.stuttgart.quality.model.types.SemanticAttributeWrongValueError;
import de.hft.stuttgart.quality.model.types.SolidSelfIntersectionError;
......@@ -377,7 +379,6 @@ public class QualityAdeErrorVisitor implements ErrorVisitor {
var err = new SemanticAttributeMissingError();
err.setChildId(cdErr.getChildId());
err.setAttributeName(cdErr.getNameOfAttribute());
err.setGeneric(cdErr.isGeneric());
res.getErrors().add(new AbstractErrorProperty(err));
}
......@@ -386,7 +387,14 @@ public class QualityAdeErrorVisitor implements ErrorVisitor {
SemanticAttributeWrongValueError err = new SemanticAttributeWrongValueError();
err.setChildId(cdErr.getChildId());
err.setAttributeName(cdErr.getNameOfAttribute());
err.setGeneric(cdErr.isGeneric());
res.getErrors().add(new AbstractErrorProperty(err));
}
@Override
public void visit(AttributeInvalidError cdErr) {
SemanticAttributeInvalidError err = new SemanticAttributeInvalidError();
err.setChildId(cdErr.getChildId());
err.setAttributeName(cdErr.getNameOfAttribute());
res.getErrors().add(new AbstractErrorProperty(err));
}
......
/*-
* Copyright 2022 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 <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check.error;
import de.hft.stuttgart.citydoctor2.check.CheckError;
import de.hft.stuttgart.citydoctor2.check.ErrorId;
import de.hft.stuttgart.citydoctor2.check.ErrorReport;
import de.hft.stuttgart.citydoctor2.check.ErrorType;
import de.hft.stuttgart.citydoctor2.check.ErrorVisitor;
import de.hft.stuttgart.citydoctor2.check.HealingMethod;
import de.hft.stuttgart.citydoctor2.check.ModificationListener;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.GmlElement;
public class AttributeInvalidError implements CheckError {
private static final long serialVersionUID = 346311592089394220L;
public static final ErrorId ID = new ErrorId("SE_ATTRIBUTE_INVALID");
private CityObject co;
private String childId;
private String nameOfAttribute;
public AttributeInvalidError(CityObject co, String childId, String nameOfAttribute) {
this.co = co;
this.childId = childId;
this.nameOfAttribute = nameOfAttribute;
}
@Override
public ErrorType getType() {
return ErrorType.ERROR;
}
@Override
public ErrorId getErrorId() {
return ID;
}
public String getChildId() {
return childId;
}
public String getNameOfAttribute() {
return nameOfAttribute;
}
@Override
public GmlElement getFeature() {
return co;
}
@Override
public void accept(ErrorVisitor errorVisitor) {
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
}
@Override
public void report(ErrorReport report) {
report.add("childId", childId);
report.add("name", nameOfAttribute);
}
}
......@@ -35,15 +35,13 @@ public class AttributeMissingError implements CheckError {
public static final ErrorId ID = new ErrorId("SE_ATTRIBUTE_MISSING");
private CityObject co;
private boolean generic;
private String childId;
private String nameOfAttribute;
public AttributeMissingError(CityObject co, String childId, String nameOfAttribute, boolean generic) {
public AttributeMissingError(CityObject co, String childId, String nameOfAttribute) {
this.co = co;
this.childId = childId;
this.nameOfAttribute = nameOfAttribute;
this.generic = generic;
}
@Override
......@@ -60,10 +58,6 @@ public class AttributeMissingError implements CheckError {
return childId;
}
public boolean isGeneric() {
return generic;
}
public String getNameOfAttribute() {
return nameOfAttribute;
}
......@@ -87,7 +81,6 @@ public class AttributeMissingError implements CheckError {
public void report(ErrorReport report) {
report.add("childId", childId);
report.add("name", nameOfAttribute);
report.add("generic", "" + generic);
}
}
......@@ -35,15 +35,13 @@ public class AttributeValueWrongError implements CheckError {
public static final ErrorId ID = new ErrorId("SE_ATTRIBUTE_WRONG_VALUE");
private CityObject co;
private boolean generic;
private String childId;
private String nameOfAttribute;
public AttributeValueWrongError(CityObject co, String childId, String nameOfAttribute, boolean generic) {
public AttributeValueWrongError(CityObject co, String childId, String nameOfAttribute) {
this.co = co;
this.childId = childId;
this.nameOfAttribute = nameOfAttribute;
this.generic = generic;
}
@Override
......@@ -65,10 +63,6 @@ public class AttributeValueWrongError implements CheckError {
return childId;
}
public boolean isGeneric() {
return generic;
}
public String getNameOfAttribute() {
return nameOfAttribute;
}
......@@ -87,6 +81,5 @@ public class AttributeValueWrongError implements CheckError {
public void report(ErrorReport report) {
report.add("childId", childId);
report.add("name", nameOfAttribute);
report.add("generic", "" + generic);
}
}
......@@ -28,22 +28,19 @@ import de.hft.stuttgart.citydoctor2.check.ModificationListener;
import de.hft.stuttgart.citydoctor2.datastructure.GmlElement;
public class SchematronError implements CheckError {
private static final long serialVersionUID = -2964084500589868928L;
private String errorId;
private String gmlId;
private String childId;
private String nameOfAttribute;
private boolean generic;
public SchematronError(String errorId, String gmlId, String childId, String nameOfAttribute, boolean generic) {
public SchematronError(String errorId, String gmlId, String childId, String nameOfAttribute) {
this.errorId = errorId;
this.gmlId = gmlId;
this.childId = childId;
this.nameOfAttribute = nameOfAttribute;
this.generic = generic;
}
@Override
......@@ -64,29 +61,25 @@ public class SchematronError implements CheckError {
@Override
public String toString() {
return "SchematronError [errorId=" + errorId + ", gmlId=" + gmlId + ", childId=" + childId
+ ", nameOfAttribute=" + nameOfAttribute + ", generic=" + generic + "]";
+ ", nameOfAttribute=" + nameOfAttribute + "]";
}
public String getChildId() {
return childId;
}
public String getGmlId() {
return gmlId;
}
public String getNameOfAttribute() {
return nameOfAttribute;
}
public String getErrorIdString() {
return errorId;
}
public boolean isGeneric() {
return generic;
}
@Override
public ErrorType getType() {
return ErrorType.ERROR;
......
/*-
* Copyright 2022 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 <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.datastructure;
import org.citygml4j.core.model.deprecated.bridge.DeprecatedPropertiesOfBridgeConstructiveElement;
import org.citygml4j.core.util.geometry.GeometryFactory;
import org.xmlobjects.gml.model.geometry.GeometryProperty;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
import org.xmlobjects.gml.model.geometry.complexes.CompositeSurface;
import org.xmlobjects.gml.model.geometry.primitives.Solid;
import org.xmlobjects.gml.model.geometry.primitives.SolidProperty;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
import de.hft.stuttgart.citydoctor2.utils.CityGmlUtils;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
public class BridgeConstructiveElement extends CityObject {
private static final String CANNOT_ADD = "Cannot add ";
private static final long serialVersionUID = 7353233899458901155L;
private org.citygml4j.core.model.bridge.BridgeConstructiveElement gmlBridgeElement;
public BridgeConstructiveElement(org.citygml4j.core.model.bridge.BridgeConstructiveElement gmlObject) {
this.gmlBridgeElement = gmlObject;
}
@Override
public Copyable createCopyInstance() {
return new BridgeConstructiveElement(gmlBridgeElement);
}
@Override
public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) {
// only handles CityGML2 for now
// unknown which CityGML is handled here
// need context information to decide
for (Geometry geom : getGeometries()) {
switch (geom.getType()) {
case SOLID:
Solid solid = CityGmlUtils.createSolid(geom, factory, config);
setSolidAccordingToLod(geom, solid);
break;
case MULTI_SURFACE:
MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config);
setMultiSurfaceAccordingToLod(geom, ms);
break;
case COMPOSITE_SURFACE:
CompositeSurface cs = CityGmlUtils.createCompositeSurface(geom, factory, config);
setCompositeSurfaceAccordingToLod(geom, cs);
break;
}
}
}
private void setCompositeSurfaceAccordingToLod(Geometry geom, CompositeSurface cs) {
switch (geom.getLod()) {
case LOD1:
gmlBridgeElement.getDeprecatedProperties().setLod1Geometry(new GeometryProperty<>(cs));
break;
case LOD2:
gmlBridgeElement.getDeprecatedProperties().setLod2Geometry(new GeometryProperty<>(cs));
break;
case LOD3:
gmlBridgeElement.getDeprecatedProperties().setLod3Geometry(new GeometryProperty<>(cs));
break;
case LOD4:
gmlBridgeElement.getDeprecatedProperties().setLod4Geometry(new GeometryProperty<>(cs));
break;
default:
throw new IllegalStateException(CANNOT_ADD + geom.getLod() + " composite surface to buildings");
}
}
private void setSolidAccordingToLod(Geometry geom, Solid solid) {
switch (geom.getLod()) {
case LOD1:
gmlBridgeElement.getDeprecatedProperties().setLod1Geometry(new SolidProperty(solid));
break;
case LOD2:
gmlBridgeElement.getDeprecatedProperties().setLod2Geometry(new SolidProperty(solid));
break;
case LOD3:
gmlBridgeElement.getDeprecatedProperties().setLod3Geometry(new SolidProperty(solid));
break;
case LOD4:
gmlBridgeElement.getDeprecatedProperties().setLod4Geometry(new SolidProperty(solid));
break;
default:
throw new IllegalStateException(CANNOT_ADD + geom.getLod() + " solid to buildings");
}
}
private void setMultiSurfaceAccordingToLod(Geometry geom, MultiSurface ms) {
switch (geom.getLod()) {
case LOD0:
gmlBridgeElement.getDeprecatedProperties().setLod1Geometry(new MultiSurfaceProperty(ms));
break;
case LOD1:
gmlBridgeElement.getDeprecatedProperties().setLod1Geometry(new MultiSurfaceProperty(ms));
break;
case LOD2:
gmlBridgeElement.getDeprecatedProperties().setLod1Geometry(new MultiSurfaceProperty(ms));
break;
case LOD3:
gmlBridgeElement.getDeprecatedProperties().setLod1Geometry(new MultiSurfaceProperty(ms));
break;
case LOD4:
gmlBridgeElement.getDeprecatedProperties().setLod1Geometry(new MultiSurfaceProperty(ms));
break;
default:
throw new IllegalStateException(CANNOT_ADD + geom.getLod() + " multi surface to buildings");
}
}
@Override
public org.citygml4j.core.model.bridge.BridgeConstructiveElement getGmlObject() {
return gmlBridgeElement;
}
@Override
public void unsetGmlGeometries() {
gmlBridgeElement.setLod0MultiSurface(null);
gmlBridgeElement.setLod2MultiSurface(null);
gmlBridgeElement.setLod3MultiSurface(null);
DeprecatedPropertiesOfBridgeConstructiveElement depProps = gmlBridgeElement.getDeprecatedProperties();
depProps.setLod1Geometry(null);
depProps.setLod2Geometry(null);
depProps.setLod3Geometry(null);
depProps.setLod4Geometry(null);
gmlBridgeElement.setLod1Solid(null);
gmlBridgeElement.setLod2Solid(null);
gmlBridgeElement.setLod3Solid(null);
}
@Override
public FeatureType getFeatureType() {
return FeatureType.BRIDGE_CONSTRUCTION_ELEMENT;
}
}
......@@ -54,8 +54,9 @@ public class BridgeObject extends CityObject {
private BridgeType type;
private List<BridgeObject> parts = null;
private List<BridgeConstructiveElement> elements = null;
private List<BoundarySurface> boundarySurfaces = new ArrayList<>();
private List<BoundarySurface> boundarySurfaces = new ArrayList<>(2);
public BridgeObject(BridgeType type, AbstractBridge ab) {
this.ab = ab;
......@@ -66,6 +67,13 @@ public class BridgeObject extends CityObject {
public FeatureType getFeatureType() {
return FeatureType.BRIDGE;
}
public List<BridgeConstructiveElement> getConstructiveElements() {
if (elements == null) {
elements = new ArrayList<>(2);
}
return elements;
}
@Override
public void reCreateGeometries(GeometryFactory factory, ParserConfiguration config) {
......@@ -81,6 +89,16 @@ public class BridgeObject extends CityObject {
for (BoundarySurface bs : boundarySurfaces) {
bs.reCreateGeometries(factory, config);
}
if (parts != null) {
for (BridgeObject part : parts) {
part.reCreateGeometries(factory, config);
}
}
if (elements != null) {
for (BridgeConstructiveElement ele : elements) {
ele.reCreateGeometries(factory, config);
}
}
}
private void setMultiSurfaceAccordingToLod(Geometry geom, MultiSurface ms) {
......@@ -127,6 +145,16 @@ public class BridgeObject extends CityObject {
for (BoundarySurface bs : boundarySurfaces) {
bs.clearAllContainedCheckResults();
}
if (parts != null) {
for (BridgeObject part : parts) {
part.clearAllContainedCheckResults();
}
}
if (elements != null) {
for (BridgeConstructiveElement ele : elements) {
ele.clearAllContainedCheckResults();
}
}
}
@Override
......@@ -135,6 +163,16 @@ public class BridgeObject extends CityObject {
for (BoundarySurface bs : boundarySurfaces) {
bs.collectContainedErrors(errors);
}
if (parts != null) {
for (BridgeObject part : parts) {
part.collectContainedErrors(errors);
}
}
if (elements != null) {
for (BridgeConstructiveElement ele : elements) {
ele.collectContainedErrors(errors);
}
}
}
@Override
......@@ -148,6 +186,27 @@ public class BridgeObject extends CityObject {
return true;
}
}
if (doPartsContainAnyError()) {
return true;
}
if (elements != null) {
for (BridgeConstructiveElement ele : elements) {
if (ele.containsAnyError()) {
return true;
}
}
}
return false;
}
private boolean doPartsContainAnyError() {
if (parts != null) {
for (BridgeObject part : parts) {
if (part.containsAnyError()) {
return true;
}
}
}
return false;
}
......@@ -162,6 +221,27 @@ public class BridgeObject extends CityObject {
return true;
}
}
if (doPartsContainError(checkIdentifier)) {
return true;
}
if (elements != null) {
for (BridgeConstructiveElement ele : elements) {
if (ele.containsError(checkIdentifier)) {
return true;
}
}
}
return false;
}
private boolean doPartsContainError(CheckId checkIdentifier) {
if (parts != null) {
for (BridgeObject part : parts) {
if (part.containsError(checkIdentifier)) {
return true;
}
}
}
return false;
}
......@@ -174,6 +254,16 @@ public class BridgeObject extends CityObject {
for (BoundarySurface bs : boundarySurfaces) {
bs.accept(c);
}
if (parts != null) {
for (BridgeObject part : parts) {
part.accept(c);
}
}
if (elements != null) {
for (BridgeConstructiveElement ele : elements) {
ele.accept(c);
}
}
}
/**
......@@ -217,6 +307,16 @@ public class BridgeObject extends CityObject {
for (BoundarySurface bs : boundarySurfaces) {
bs.unsetGmlGeometries();
}
if (parts != null) {
for (BridgeObject part : parts) {
part.unsetGmlGeometries();
}
}
if (elements != null) {
for (BridgeConstructiveElement ele : elements) {
ele.unsetGmlGeometries();
}
}
}
public void setGmlObject(AbstractBridge aBridge) {
......@@ -242,6 +342,16 @@ public class BridgeObject extends CityObject {
for (BoundarySurface bs : boundarySurfaces) {
bs.clearMetaInformation();
}
if (parts != null) {
for (BridgeObject part : parts) {
part.clearMetaInformation();
}
}
if (elements != null) {
for (BridgeConstructiveElement ele : elements) {
ele.clearMetaInformation();
}
}
}
@Override
......@@ -250,6 +360,16 @@ public class BridgeObject extends CityObject {
for (BoundarySurface bs : boundarySurfaces) {
handler.addInstance(bs);
}
if (parts != null) {
for (BridgeObject part : parts) {
handler.addInstance(part);
}
}
if (elements != null) {
for (BridgeConstructiveElement ele : elements) {
handler.addInstance(ele);
}
}
}
@Override
......@@ -259,6 +379,24 @@ public class BridgeObject extends CityObject {
for (BoundarySurface originalBs : originalBo.boundarySurfaces) {
boundarySurfaces.add(handler.getCopyInstance(originalBs));
}
if (parts != null) {
for (BridgeObject part : parts) {
handler.addInstance(part);
}
}
if (elements != null) {
for (BridgeConstructiveElement ele : elements) {
handler.addInstance(ele);
}
}
}
public List<BoundarySurface> getBoundarySurfaces() {
return boundarySurfaces;
}
public void addConstructiveElement(BridgeConstructiveElement element) {
getConstructiveElements().add(element);
}
@Override
......@@ -274,10 +412,7 @@ public class BridgeObject extends CityObject {
}
public void addBridgePart(BridgeObject bPart) {
if (parts == null) {
parts = new ArrayList<>(2);
}
parts.add(bPart);
getParts().add(bPart);
}
}
......@@ -89,6 +89,11 @@ public class CityDoctorModel {
}
public void setValidated(ValidationPlan plan) {
if (plan == null) {
this.plan = null;
this.isValidated = false;
return;
}
this.plan = plan;
this.isValidated = true;
}
......@@ -118,11 +123,18 @@ public class CityDoctorModel {
water.stream()).flatMap(co -> co);
}
public void saveAs(String file) throws CityDoctorWriteException {
public void saveAs(String file, boolean saveQualityAde) throws CityDoctorWriteException {
if (file.endsWith(".off")) {
exportAsOff(file);
} else {
ValidationPlan tempPlan = plan;
if (!saveQualityAde) {
setValidated(null);
}
exportAsGML(file);
if (!saveQualityAde) {
setValidated(tempPlan);
}
}
}
......
......@@ -503,6 +503,21 @@ public class ConcretePolygon extends Polygon {
public void remove() {
parent.removePolygon(this);
}
@Override
public double getArea() {
if (exterior == null) {
return 0;
}
double area = exterior.getArea();
if (innerRings == null || innerRings.isEmpty()) {
return area;
}
for (LinearRing innerRing : innerRings) {
area -= innerRing.getArea();
}
return area;
}
......
......@@ -27,6 +27,6 @@ package de.hft.stuttgart.citydoctor2.datastructure;
public enum FeatureType {
BUILDING, TRANSPORTATION, VEGETATION, BRIDGE, LAND, WATER, BOUNDARY_SURFACE, BUILDING_INSTALLATION, OPENING,
BUILDING_PART;
BUILDING_PART, BRIDGE_CONSTRUCTION_ELEMENT;
}
......@@ -119,7 +119,7 @@ public class LinearRing extends GmlElement {
public UnitVector3d calculateNormalNormalized() {
return calculateNormal().normalize();
}
/**
* Calculates the normal vector of the ring. Method by Newell. If the Newell
* method would return a (0, 0, 0) vector a cross product is formed from the
......@@ -152,6 +152,77 @@ public class LinearRing extends GmlElement {
return new Vector3d(coords);
}
public double getArea() {
int n = vertices.size();
if (n < 3)
return 0.0; // a degenerated polygon
// prepare an vertex array with n+2 vertices:
// V[0] ... V[n-1] - the n different vertices
// V[n]=V[0]
// V[n+1]=V[1]
Vertex[] vertexArray = new Vertex[n + 2];
for (int i = 0; i < n; i++) {
vertexArray[i] = vertices.get(i);
}
vertexArray[n] = vertices.get(0);
vertexArray[n + 1] = vertices.get(1);
double area = 0;
// make sure the normal has been calculated
Vector3d normal = calculateNormal();
// select largest abs coordinate to ignore for projection
double ax = Math.abs(normal.getX()); // abs x-coord
double ay = Math.abs(normal.getY()); // abs y-coord
double az = Math.abs(normal.getZ()); // abs z-coord
// coord to ignore: 1=x, 2=y, 3=z
int coord = 3; // ignore z-coord
if (ax > ay) {
if (ax > az) {
coord = 1; // ignore x-coord
}
} else if (ay > az) {
coord = 2; // ignore y-coord
}
// compute area of the 2D projection
for (int i = 1, j = 2, k = 0; i <= vertexArray.length - 2; i++, j++, k++) {
switch (coord) {
case 1:
area += (vertexArray[i].getY() * (vertexArray[j].getZ() - vertexArray[k].getZ()));
break;
case 2:
area += (vertexArray[i].getX() * (vertexArray[j].getZ() - vertexArray[k].getZ()));
break;
case 3:
area += (vertexArray[i].getX() * (vertexArray[j].getY() - vertexArray[k].getY()));
break;
default:
throw new IllegalStateException();
}
}
// scale to get area before projection
double an = Math.sqrt(ax * ax + ay * ay + az * az); // length of normal vector
switch (coord) {
case 1:
area *= (an / (2 * ax));
break;
case 2:
area *= (an / (2 * ay));
break;
case 3:
area *= (an / (2 * az));
break;
default:
throw new IllegalStateException();
}
return Math.abs(area);
}
private UnitVector3d calculateNormalWithCross(Vertex v1, Vertex v2, Vertex v3) {
Vector3d dir1 = v2.minus(v1);
Vector3d dir2 = v3.minus(v1);
......@@ -206,7 +277,7 @@ public class LinearRing extends GmlElement {
}
v.addAdjacentRing(this, parent.getParent());
}
public void setVertex(int i, Vertex v) {
vertices.set(i, v);
if (parent.isLinkedTo()) {
......@@ -244,17 +315,17 @@ public class LinearRing extends GmlElement {
public void addAllVertices(List<Vertex> extRing) {
vertices.addAll(extRing);
}
@Override
public void prepareForChecking() {
parent.getParent().prepareForChecking();
}
@Override
public void clearMetaInformation() {
parent.getParent().clearMetaInformation();
}
@Override
public void fillValues(Copyable original, CopyHandler handler) {
super.fillValues(original, handler);
......
......@@ -295,4 +295,9 @@ public class LinkedPolygon extends Polygon {
poly.remove();
}
@Override
public double getArea() {
return poly.getArea();
}
}
......@@ -79,5 +79,7 @@ public abstract class Polygon extends GmlElement {
public abstract ConcretePolygon getOriginal();
public abstract void remove();
public abstract double getArea();
}
\ No newline at end of file
......@@ -29,6 +29,7 @@ import org.apache.logging.log4j.Logger;
import org.citygml4j.core.model.CityGMLVersion;
import org.citygml4j.core.model.bridge.AbstractBridge;
import org.citygml4j.core.model.bridge.Bridge;
import org.citygml4j.core.model.bridge.BridgeConstructiveElementProperty;
import org.citygml4j.core.model.bridge.BridgePart;
import org.citygml4j.core.model.bridge.BridgePartProperty;
import org.citygml4j.core.model.building.BuildingInstallationProperty;
......@@ -59,6 +60,7 @@ import org.citygml4j.core.model.transportation.TrafficSpace;
import org.citygml4j.core.model.transportation.TrafficSpaceProperty;
import org.citygml4j.core.model.vegetation.AbstractVegetationObject;
import org.citygml4j.core.model.vegetation.PlantCover;
import org.citygml4j.core.model.vegetation.SolitaryVegetationObject;
import org.citygml4j.core.model.waterbody.WaterBody;
import org.citygml4j.core.visitor.ObjectWalker;
import org.xmlobjects.gml.model.base.AbstractGML;
......@@ -77,6 +79,7 @@ import org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty;
import de.hft.stuttgart.citydoctor2.datastructure.AbstractBuilding;
import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface;
import de.hft.stuttgart.citydoctor2.datastructure.BridgeConstructiveElement;
import de.hft.stuttgart.citydoctor2.datastructure.BridgeObject;
import de.hft.stuttgart.citydoctor2.datastructure.BridgeObject.BridgeType;
import de.hft.stuttgart.citydoctor2.datastructure.Building;
......@@ -140,7 +143,6 @@ public class Citygml3FeatureMapper extends ObjectWalker {
}
BuildingPart part = new BuildingPart(cdBuilding);
readAbstractBuilding(bpProp.getObject(), part);
cdBuilding.addBuildingPart(part);
}
model.addBuilding(cdBuilding);
}
......@@ -196,7 +198,22 @@ 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);
parseAndAddAbstractGeometry(solitaryVegetationObject.getDeprecatedProperties().getLod4Geometry(), Lod.LOD4, veg);
finishCityObjectConstruction(veg);
model.addVegetation(veg);
}
private void mapAbstractVegetationObject(AbstractVegetationObject avo, Vegetation veg) {
mapAbstractOccupiedSpace(avo, veg);
}
......@@ -237,14 +254,61 @@ public class Citygml3FeatureMapper extends ObjectWalker {
for (BridgeObject part : bo.getParts()) {
updateEdgesAndVertices(part);
}
for (BridgeConstructiveElement ele : bo.getConstructiveElements()) {
updateEdgesAndVertices(ele);
}
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);
}
SurfaceMapper surfaceMapper = new SurfaceMapper(polygonMap, references, 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 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);
}
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);
}
......@@ -464,14 +528,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
AbstractSpaceBoundary surface = surfaceProp.getObject();
surface.accept(surfaceMapper);
}
for (BoundarySurface bs : surfaceMapper.getSurfaces()) {
cdBuilding.addBoundarySurface(bs);
for (Geometry geom : bs.getGeometries()) {
for (Polygon p : geom.getPolygons()) {
p.setPartOfSurface(bs);
}
}
}
updatePartOfSurface(cdBuilding, surfaceMapper);
cdBuilding.unsetGmlGeometries();
resolveAndClearReferences();
......@@ -487,6 +544,17 @@ public class Citygml3FeatureMapper extends ObjectWalker {
}
}
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);
}
}
}
}
public static void parseId(AbstractGML gml, GmlElement gmlElement) {
String id = gml.getId();
if (id != null) {
......
......@@ -47,6 +47,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.citygml4j.core.ade.ADEException;
import org.citygml4j.core.ade.ADERegistry;
import org.citygml4j.core.model.CityGMLVersion;
import org.citygml4j.core.model.ade.ADEProperty;
import org.citygml4j.core.model.core.AbstractCityObject;
import org.citygml4j.core.model.core.AbstractCityObjectProperty;
......@@ -55,7 +56,6 @@ import org.citygml4j.core.model.core.CityModel;
import org.citygml4j.core.util.CityGMLConstants;
import org.citygml4j.xml.CityGMLContext;
import org.citygml4j.xml.CityGMLContextException;
import org.citygml4j.xml.module.citygml.CityGMLModule;
import org.citygml4j.xml.module.citygml.CityGMLModules;
import org.citygml4j.xml.reader.ChunkOptions;
import org.citygml4j.xml.reader.CityGMLInputFactory;
......@@ -121,6 +121,7 @@ public class CityGmlParser {
private static List<QName> chunkProperties = new ArrayList<>();
static {
System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
FACTORY = SAXParserFactory.newInstance();
try {
FACTORY.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
......@@ -311,8 +312,8 @@ public class CityGmlParser {
return null;
}
CityGMLContext gmlContext = CityGmlParser.getContext();
CityGMLModule module = CityGMLModules.getCityGMLModule(reader.getName().getNamespaceURI());
CityGMLOutputFactory factory = gmlContext.createCityGMLOutputFactory(module.getCityGMLVersion());
CityGMLVersion version = CityGMLModules.getCityGMLVersion(reader.getName().getNamespaceURI());
CityGMLOutputFactory factory = gmlContext.createCityGMLOutputFactory(version);
CityGMLChunkWriter writer = factory.createCityGMLChunkWriter(new File(outputFile),
StandardCharsets.UTF_8.name());
writer.withPrefix("qual", QualityADEModule.NAMESPACE_URI);
......@@ -336,8 +337,8 @@ public class CityGmlParser {
if (chunk instanceof CityModel cModel) {
cModel.setCityObjectMembers(null);
mapper.setCityModel(cModel);
CityGMLModule module = CityGMLModules.getCityGMLModule(reader.getName().getNamespaceURI());
mapper.setCityGMLVersion(module.getCityGMLVersion());
CityGMLVersion version = CityGMLModules.getCityGMLVersion(reader.getName().getNamespaceURI());
mapper.setCityGMLVersion(version);
} else if (chunk instanceof AbstractCityObject aco) {
acos.add(aco);
aco.accept(mapper);
......
Markdown is supported
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