Commit 5d40c7b6 authored by Matthias Betz's avatar Matthias Betz
Browse files

CityDoctor2 validation open source release

parents
/*-
* 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 <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.Edge;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
/**
* If a point of a linear ring touches an edge of the same ring it is considered
* self intersecting and this error object is created.
*
* @author Matthias Betz
*
*/
public class PointTouchesEdgeError extends CheckError {
private static final long serialVersionUID = 3277456707271748954L;
private LinearRing lr;
private Edge e;
private Vertex v;
public PointTouchesEdgeError(LinearRing lr, Edge e, Vertex v) {
super(ErrorId.GE_R_SELF_INTERSECTION, ErrorType.ERROR, lr);
this.lr = lr;
this.e = e;
this.v = v;
}
public LinearRing getRing() {
return lr;
}
public Edge getEdge() {
return e;
}
public Vertex getVertex() {
return v;
}
@Override
public void report(ErrorReport report) {
report.add("type", "point touches edge");
report.add(lr);
report.add(v);
report.add(e);
}
@Override
public void accept(ErrorVisitor errorVisitor) {
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
}
@Override
public String toString() {
return "PointTouchesEdgeError [lr=" + lr + ", e=" + e + ", v=" + v + "]";
}
}
/*-
* 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 <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.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.utils.SerializablePair;
/**
* If the exterior ring and interior rings are intersecting each other, it
* results in a polygon self intersection and this error is created.
*
* @author Matthias Betz
*
*/
public class PolygonSelfIntError extends CheckError {
private static final long serialVersionUID = -7043521697085991901L;
private Polygon p;
private SerializablePair<LinearRing, LinearRing> intersectingRings;
public PolygonSelfIntError(Polygon p, SerializablePair<LinearRing, LinearRing> intersectingRings) {
super(ErrorId.GE_P_INTERSECTING_RINGS, ErrorType.ERROR, p);
this.p = p;
this.intersectingRings = intersectingRings;
}
public Polygon getPolygon() {
return p;
}
public SerializablePair<LinearRing, LinearRing> getIntersectingRings() {
return intersectingRings;
}
@Override
public void report(ErrorReport report) {
report.add(p);
report.add(intersectingRings.getValue0());
report.add(intersectingRings.getValue1());
}
@Override
public void accept(ErrorVisitor errorVisitor) {
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
}
@Override
public String toString() {
return "PolygonSelfIntError [p=" + p + ", intersectingRings=" + intersectingRings + "]";
}
}
/*-
* 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 <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check.error;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
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.Edge;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
/**
* If a polygon is wrongly oriented it results in edges being traversed in the
* same direction. This error stores all edges that have been traversed in the
* same direction twice.
*
* @author Matthias Betz
*
*/
public class PolygonWrongOrientationError extends CheckError {
private static final long serialVersionUID = -3006643655816847097L;
private List<Edge> edges;
private Geometry g;
public PolygonWrongOrientationError(Geometry g, List<Edge> edges) {
super(ErrorId.GE_S_POLYGON_WRONG_ORIENTATION, ErrorType.ERROR, g);
this.edges = edges;
this.g = g;
}
public List<Edge> getEdges() {
return edges;
}
public Geometry getGeometry() {
return g;
}
@Override
public void report(ErrorReport report) {
report.add(g);
Set<Polygon> possiblePolygons = new HashSet<>();
for (Edge e : edges) {
possiblePolygons.addAll(e.getAdjacentPolygons());
}
report.addPolygons("possible polygons", possiblePolygons);
}
@Override
public void accept(ErrorVisitor errorVisitor) {
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
}
@Override
public String toString() {
return "PolygonWrongOrientationError [edges=" + edges + ", g=" + g + "]";
}
}
/*-
* 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 <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.LinearRing;
/**
* If the first and last point of a linear ring are not the same, this error is
* created.
*
* @author Matthias Betz
*
*/
public class RingNotClosedError extends CheckError {
private static final long serialVersionUID = 2554099996830579201L;
private LinearRing ring;
public RingNotClosedError(LinearRing ring) {
super(ErrorId.GE_R_NOT_CLOSED, ErrorType.ERROR, ring);
this.ring = ring;
}
public LinearRing getRing() {
return ring;
}
@Override
public void report(ErrorReport report) {
report.add(ring);
}
@Override
public void accept(ErrorVisitor errorVisitor) {
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
}
@Override
public String toString() {
return "RingNotClosedError [ring=" + ring + "]";
}
}
/*-
* 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 <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check.error;
import java.util.Set;
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.Edge;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
/**
* If two edges of the same linear ring are intersecting with each other, this
* error is created.
*
* @author Matthias Betz
*
*/
public class RingSelfIntError extends CheckError {
private static final long serialVersionUID = 8007952264635395514L;
private LinearRing lr;
private Set<Edge> edges;
public RingSelfIntError(LinearRing lr, Set<Edge> intersectingEdges) {
super(ErrorId.GE_R_SELF_INTERSECTION, ErrorType.ERROR, lr);
this.lr = lr;
edges = intersectingEdges;
}
public LinearRing getRing() {
return lr;
}
public Set<Edge> getEdges() {
return edges;
}
@Override
public void report(ErrorReport report) {
report.add(lr);
}
@Override
public void accept(ErrorVisitor errorVisitor) {
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
}
@Override
public String toString() {
return "RingSelfIntError [lr=" + lr + ", edges=" + edges + "]";
}
}
/*-
* 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 <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.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
/**
* If the interior rings have the same orientation as the exterior ring, this
* error is created.
*
* @author Matthias Betz
*
*/
public class SameOrientationError extends CheckError {
private static final long serialVersionUID = -6192337889977667459L;
private Polygon p;
private LinearRing innerRing;
public SameOrientationError(Polygon p, LinearRing inner) {
super(ErrorId.GE_P_ORIENTATION_RINGS_SAME, ErrorType.ERROR, p);
this.p = p;
this.innerRing = inner;
}
public Polygon getPolygon() {
return p;
}
public LinearRing getInnerRing() {
return innerRing;
}
@Override
public void report(ErrorReport report) {
report.add(p);
report.add(innerRing);
}
@Override
public void accept(ErrorVisitor errorVisitor) {
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
}
@Override
public String toString() {
return "SameOrientationError [p=" + p + ", innerRing=" + innerRing + "]";
}
}
/*-
* 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 <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;
public class SchematronError extends CheckError {
private static final long serialVersionUID = -2964084500589868928L;
private String text;
public SchematronError(String text) {
super(ErrorId.SEM_SCHEMATRON_ERROR, ErrorType.ERROR, null);
this.text = text;
}
@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("Description", text);
}
@Override
public String toString() {
return "SchematronError [text=" + text + "]";
}
public String getText() {
return text;
}
}
/*-
* 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 <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check.error;
import java.util.List;
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.Edge;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
/**
* If a geometry has holes in it, it results in edges being traversed only once.
* This error list all those edges.
*
* @author Matthias Betz
*
*/
public class SolidNotClosedError extends CheckError {
private static final long serialVersionUID = 8256385219885788891L;
private List<Edge> errorEdges;
private Geometry g;
public SolidNotClosedError(Geometry g, List<Edge> errorEdges) {
super(ErrorId.GE_S_NOT_CLOSED, ErrorType.ERROR, g);
this.errorEdges = errorEdges;
this.g = g;
}
public Geometry getGeometry() {
return g;
}
public List<Edge> getErrorEdges() {
return errorEdges;
}
@Override
public void report(ErrorReport report) {
report.add(g);
report.addEdges("open edges", errorEdges);
}
@Override
public void accept(ErrorVisitor errorVisitor) {
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
}
@Override
public String toString() {
return "SolidNotClosedError [errorEdges=" + errorEdges + ", g=" + g + "]";
}
}
/*-
* 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 <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check.error;
import java.util.List;
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.Geometry;
import de.hft.stuttgart.citydoctor2.utils.PolygonIntersection;
/**
* When two polygons of the same geometry are intersecting each other.
*
* @author Matthias Betz
*
*/
public class SolidSelfIntError extends CheckError {
private static final long serialVersionUID = -4479936555545861422L;
private Geometry g;
private List<PolygonIntersection> intersections;
public SolidSelfIntError(Geometry g, List<PolygonIntersection> intersections) {
super(ErrorId.GE_S_SELF_INTERSECTION, ErrorType.ERROR, g);
this.g = g;
this.intersections = intersections;
}
public Geometry getGeometry() {
return g;
}
@Override
public void report(ErrorReport report) {
report.add(g);
}
public List<PolygonIntersection> getIntersections() {
return intersections;
}
@Override
public void accept(ErrorVisitor errorVisitor) {
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
}
@Override
public String toString() {
return "SolidSelfIntError [g=" + g + ", intersection=" + intersections + "]";
}
}
/*-
* 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 <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.BoundarySurface;
/**
* Container object for an unfragmented error
*
* @author Matthias Betz
*
*/
public class SurfaceUnfragmentedError extends CheckError {
private static final long serialVersionUID = 3146243879393474196L;
private BoundarySurface bs;
private double angleDeviation;
public SurfaceUnfragmentedError(BoundarySurface bs, double angleDerivation) {
super(ErrorId.SEM_BS_UNFRAGMENTED, ErrorType.ERROR, bs);
this.bs = bs;
this.angleDeviation = angleDerivation;
}
@Override
public void accept(ErrorVisitor errorVisitor) {
errorVisitor.visit(this);
}
public double getAngleDeviation() {
return angleDeviation;
}
public BoundarySurface getBoundarySurface() {
return bs;
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
}
@Override
public void report(ErrorReport report) {
report.add(bs);
report.add("angleDerivation", angleDeviation);
}
}
/*-
* 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 <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.Polygon;
public class TinyEdgeError extends CheckError {
/**
*
*/
private static final long serialVersionUID = 865493182529055651L;
public TinyEdgeError(Polygon p) {
super(ErrorId.GE_P_TINY_EDGE, ErrorType.ERROR, p);
}
public Polygon getPolygon() {
return (Polygon) getFeature();
}
@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(getPolygon());
}
}
/*-
* 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 <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.LinearRing;
/**
* If a linear ring has less than 4 distinct points, it is has too few points.
*
* @author Matthias Betz
*
*/
public class TooFewPointsError extends CheckError {
private static final long serialVersionUID = 7207518573842743261L;
private LinearRing lr;
public TooFewPointsError(LinearRing lr) {
super(ErrorId.GE_R_TOO_FEW_POINTS, ErrorType.ERROR, lr);
this.lr = lr;
}
public LinearRing getRing() {
return lr;
}
@Override
public void report(ErrorReport report) {
report.add(lr);
}
@Override
public void accept(ErrorVisitor errorVisitor) {
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
}
@Override
public String toString() {
return "TooFewPointsError [lr=" + lr + "]";
}
}
/*-
* 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 <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.Geometry;
/**
* When a geometry has less than 4 polygons, it cannot form a valid solid.
*
* @author Matthias Betz
*
*/
public class TooFewPolygonsError extends CheckError {
private static final long serialVersionUID = 5800732409355221678L;
private Geometry g;
public TooFewPolygonsError(Geometry g) {
super(ErrorId.GE_S_TOO_FEW_POLYGONS, ErrorType.ERROR, g);
this.g = g;
}
public Geometry getGeometry() {
return g;
}
@Override
public void report(ErrorReport report) {
report.add(g);
report.add("number of polygons", g.getPolygons().size());
}
@Override
public void accept(ErrorVisitor errorVisitor) {
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
}
@Override
public String toString() {
return "TooFewPolygonsError [g=" + g + "]";
}
}
/*-
* 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 <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.check.error;
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.check.Checkable;
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;
/**
* This error is created when an unexpected exception is thrown by the code.
*
* @author Matthias Betz
*
*/
public class UnknownCheckError extends CheckError {
private static final long serialVersionUID = -6554097632341055596L;
private Checkable c;
private Exception e;
private CheckId checkId;
public UnknownCheckError(Checkable c, Exception e, Check check) {
super(ErrorId.UNKNOWN_ERROR, ErrorType.ERROR, null);
this.c = c;
this.e = e;
checkId = check.getCheckId();
}
public CheckId getCheck() {
return checkId;
}
public Checkable getCheckable() {
return c;
}
public Exception getException() {
return e;
}
@Override
public void report(ErrorReport report) {
report.add("check", checkId.toString());
report.add("exception", e.getClass().getSimpleName());
report.add("object", c.getGmlId().getGmlString());
}
@Override
public void accept(ErrorVisitor errorVisitor) {
errorVisitor.visit(this);
}
@Override
public boolean accept(HealingMethod method, ModificationListener l) {
return method.visit(this, l);
}
@Override
public String toString() {
return "UnknownCheckError [c=" + c + ", e=" + e + "]";
}
}
/*-
* 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 <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.datastructure;
import java.util.ArrayList;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.citygml4j.factory.GMLGeometryFactory;
import org.citygml4j.model.citygml.building.BoundarySurfaceProperty;
import org.citygml4j.model.gml.geometry.aggregates.MultiSurface;
import org.citygml4j.model.gml.geometry.aggregates.MultiSurfaceProperty;
import org.citygml4j.model.gml.geometry.primitives.Solid;
import org.citygml4j.model.gml.geometry.primitives.SolidProperty;
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;
/**
* Container for attributes of an abstract building. It can be a Building or
* BuildingPart.
*
* @author Matthias Betz
*
*/
public abstract class AbstractBuilding extends CityObject {
private static final long serialVersionUID = -2196414503088741206L;
private static final Logger logger = LogManager.getLogger(AbstractBuilding.class);
private List<BuildingInstallation> buildingInstallations = new ArrayList<>(2);
private List<BoundarySurface> boundarySurfaceList = new ArrayList<>();
private org.citygml4j.model.citygml.building.AbstractBuilding ab;
/**
* Getter for all boundary surfaces contained in this building.
*
* @return the boundary surfaces
*/
public List<BoundarySurface> getBoundarySurfaces() {
return boundarySurfaceList;
}
@Override
public org.citygml4j.model.citygml.building.AbstractBuilding getGmlObject() {
return ab;
}
@Override
public FeatureType getFeatureType() {
return FeatureType.BUILDING;
}
@Override
public void unsetGmlGeometries() {
ab.unsetLod1MultiSurface();
ab.unsetLod2MultiSurface();
ab.unsetLod3MultiSurface();
ab.unsetLod4MultiSurface();
ab.unsetLod1Solid();
ab.unsetLod2Solid();
ab.unsetLod3Solid();
ab.unsetLod4Solid();
for (BoundarySurface bs : boundarySurfaceList) {
bs.unsetGmlGeometries();
}
for (BuildingInstallation bi : buildingInstallations) {
bi.unsetGmlGeometries();
}
}
@Override
public void reCreateGeometries(GMLGeometryFactory factory, ParserConfiguration config) {
for (Geometry geom : getGeometries()) {
if (geom.getType() == GeometryType.MULTI_SURFACE) {
MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config);
setMultiSurfaceAccordingToLod(geom, ms);
} else {
Solid solid = CityGmlUtils.createSolid(geom, factory, config);
setSolidAccordingToLod(geom, solid);
}
}
for (BoundarySurface bs : boundarySurfaceList) {
reCreateBoundarySurface(factory, config, bs);
}
for (BuildingInstallation bi : buildingInstallations) {
bi.reCreateGeometries(factory, config);
}
}
private void reCreateBoundarySurface(GMLGeometryFactory factory, ParserConfiguration config, BoundarySurface bs) {
if (bs.getGeometries().isEmpty()) {
for (BoundarySurfaceProperty bsp : ab.getBoundedBySurface()) {
if (bsp.getBoundarySurface() != null && bsp.getBoundarySurface() == bs.getGmlObject()) {
logger.warn("Found empty boundary surface: {}, removing from building", bs.getGmlId());
ab.getBoundedBySurface().remove(bsp);
break;
}
}
return;
}
bs.reCreateGeometries(factory, config);
}
private void setMultiSurfaceAccordingToLod(Geometry geom, MultiSurface ms) {
switch (geom.getLod()) {
case LOD1:
ab.setLod1MultiSurface(new MultiSurfaceProperty(ms));
break;
case LOD2:
ab.setLod2MultiSurface(new MultiSurfaceProperty(ms));
break;
case LOD3:
ab.setLod3MultiSurface(new MultiSurfaceProperty(ms));
break;
case LOD4:
ab.setLod4MultiSurface(new MultiSurfaceProperty(ms));
break;
default:
throw new IllegalStateException("Cannot add " + geom.getLod() + " multi surface to buildings");
}
}
private void setSolidAccordingToLod(Geometry geom, Solid solid) {
switch (geom.getLod()) {
case LOD1:
ab.setLod1Solid(new SolidProperty(solid));
break;
case LOD2:
ab.setLod2Solid(new SolidProperty(solid));
break;
case LOD3:
ab.setLod3Solid(new SolidProperty(solid));
break;
case LOD4:
ab.setLod4Solid(new SolidProperty(solid));
break;
default:
throw new IllegalStateException("Cannot add " + geom.getLod() + " solid to buildings");
}
}
@Override
public void accept(Check c) {
super.accept(c);
if (c.canExecute(this)) {
c.check(this);
}
for (BuildingInstallation bi : buildingInstallations) {
bi.accept(c);
}
for (BoundarySurface bs : boundarySurfaceList) {
bs.accept(c);
}
}
@Override
public void collectContainedErrors(List<CheckError> errors) {
super.collectContainedErrors(errors);
for (BuildingInstallation bi : buildingInstallations) {
bi.collectContainedErrors(errors);
}
for (BoundarySurface bs : boundarySurfaceList) {
bs.collectContainedErrors(errors);
}
}
@Override
public void clearAllContainedCheckResults() {
super.clearAllContainedCheckResults();
for (BuildingInstallation bi : buildingInstallations) {
bi.clearAllContainedCheckResults();
}
for (BoundarySurface bs : boundarySurfaceList) {
bs.clearAllContainedCheckResults();
}
}
@Override
public boolean containsError(CheckId checkIdentifier) {
boolean hasError = super.containsError(checkIdentifier);
if (hasError) {
return true;
}
for (BuildingInstallation bi : buildingInstallations) {
if (bi.containsError(checkIdentifier)) {
return true;
}
}
for (BoundarySurface bs : boundarySurfaceList) {
if (bs.containsError(checkIdentifier)) {
return true;
}
}
return false;
}
@Override
public boolean containsAnyError() {
boolean hasError = super.containsAnyError();
if (hasError) {
return true;
}
for (BuildingInstallation bi : buildingInstallations) {
if (bi.containsAnyError()) {
return true;
}
}
for (BoundarySurface bs : boundarySurfaceList) {
if (bs.containsAnyError()) {
return true;
}
}
return false;
}
void setCityGmlBuilding(org.citygml4j.model.citygml.building.AbstractBuilding ab) {
this.ab = ab;
}
public void addBoundarySurface(BoundarySurface bs) {
boundarySurfaceList.add(bs);
bs.setParent(this);
}
public void addBuildingInstallation(BuildingInstallation coBi) {
buildingInstallations.add(coBi);
coBi.setParent(this);
}
public void setGmlObject(org.citygml4j.model.citygml.building.AbstractBuilding ab) {
this.ab = ab;
}
public List<BuildingInstallation> getBuildingInstallations() {
return buildingInstallations;
}
}
/*-
* 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 <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.datastructure;
import java.util.ArrayList;
import java.util.List;
import org.citygml4j.factory.GMLGeometryFactory;
import org.citygml4j.model.citygml.core.AbstractCityObject;
import org.citygml4j.model.gml.geometry.aggregates.MultiSurface;
import org.citygml4j.model.gml.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;
/**
* 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<Opening> openings;
private CityObject parent;
private AbstractCityObject gmlObject;
public BoundarySurface(AbstractCityObject aco) {
this(SurfaceFeatureType.BUILDING, BoundarySurfaceType.UNDEFINED, aco);
}
@Override
public CityObject copy() {
throw new UnsupportedOperationException("Cannot copy BoundarySurface");
}
public BoundarySurface(SurfaceFeatureType featureType, BoundarySurfaceType type, AbstractCityObject aco) {
this.featureType = featureType;
this.type = type;
gmlObject = aco;
openings = new ArrayList<>(2);
}
public void setFeatureType(SurfaceFeatureType featureType) {
this.featureType = featureType;
}
public void setType(BoundarySurfaceType type) {
this.type = type;
}
public void setGmlObject(AbstractCityObject gmlObject) {
this.gmlObject = gmlObject;
}
public SurfaceFeatureType getSurfaceFeatureType() {
return featureType;
}
public BoundarySurfaceType getType() {
return type;
}
public List<Opening> getOpenings() {
return openings;
}
@Override
public void reCreateGeometries(GMLGeometryFactory factory, ParserConfiguration config) {
if (!gmlObject.isSetId()) {
gmlObject.setId(getGmlId().getGmlString());
}
for (Geometry geom : getGeometries()) {
if (geom.getType() == GeometryType.MULTI_SURFACE) {
MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config);
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 LOD2:
setLod2Ms(ms);
break;
case LOD3:
setLod3Ms(ms);
break;
case LOD4:
setLod4Ms(ms);
break;
default:
throw new IllegalStateException("Found geometry with LOD other than LOD2,"
+ " LOD3, LOD4, which is illegal for BoundarySurfaces: " + lod);
}
}
private void setLod2Ms(MultiSurfaceProperty ms) {
switch (featureType) {
case BRIDGE:
org.citygml4j.model.citygml.bridge.AbstractBoundarySurface bridgeAbs = (org.citygml4j.model.citygml.bridge.AbstractBoundarySurface) gmlObject;
bridgeAbs.setLod2MultiSurface(ms);
break;
case BUILDING:
org.citygml4j.model.citygml.building.AbstractBoundarySurface buildAbs = (org.citygml4j.model.citygml.building.AbstractBoundarySurface) gmlObject;
buildAbs.setLod2MultiSurface(ms);
break;
case TUNNEL:
org.citygml4j.model.citygml.tunnel.AbstractBoundarySurface tunAbs = (org.citygml4j.model.citygml.tunnel.AbstractBoundarySurface) gmlObject;
tunAbs.setLod2MultiSurface(ms);
}
}
private void setLod3Ms(MultiSurfaceProperty ms) {
switch (featureType) {
case BRIDGE:
org.citygml4j.model.citygml.bridge.AbstractBoundarySurface bridgeAbs = (org.citygml4j.model.citygml.bridge.AbstractBoundarySurface) gmlObject;
bridgeAbs.setLod3MultiSurface(ms);
break;
case BUILDING:
org.citygml4j.model.citygml.building.AbstractBoundarySurface buildAbs = (org.citygml4j.model.citygml.building.AbstractBoundarySurface) gmlObject;
buildAbs.setLod3MultiSurface(ms);
break;
case TUNNEL:
org.citygml4j.model.citygml.tunnel.AbstractBoundarySurface tunAbs = (org.citygml4j.model.citygml.tunnel.AbstractBoundarySurface) gmlObject;
tunAbs.setLod3MultiSurface(ms);
}
}
private void setLod4Ms(MultiSurfaceProperty ms) {
switch (featureType) {
case BRIDGE:
org.citygml4j.model.citygml.bridge.AbstractBoundarySurface bridgeAbs = (org.citygml4j.model.citygml.bridge.AbstractBoundarySurface) gmlObject;
bridgeAbs.setLod4MultiSurface(ms);
break;
case BUILDING:
org.citygml4j.model.citygml.building.AbstractBoundarySurface buildAbs = (org.citygml4j.model.citygml.building.AbstractBoundarySurface) gmlObject;
buildAbs.setLod4MultiSurface(ms);
break;
case TUNNEL:
org.citygml4j.model.citygml.tunnel.AbstractBoundarySurface tunAbs = (org.citygml4j.model.citygml.tunnel.AbstractBoundarySurface) gmlObject;
tunAbs.setLod4MultiSurface(ms);
}
}
@Override
public void clearAllContainedCheckResults() {
super.clearAllContainedCheckResults();
for (Opening o : openings) {
o.clearAllContainedCheckResults();
}
}
@Override
public void collectContainedErrors(List<CheckError> 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;
}
public void unsetGmlGeometries() {
switch (featureType) {
case BRIDGE:
org.citygml4j.model.citygml.bridge.AbstractBoundarySurface bridgeAbs = (org.citygml4j.model.citygml.bridge.AbstractBoundarySurface) gmlObject;
bridgeAbs.unsetLod2MultiSurface();
bridgeAbs.unsetLod3MultiSurface();
bridgeAbs.unsetLod4MultiSurface();
break;
case BUILDING:
org.citygml4j.model.citygml.building.AbstractBoundarySurface buildAbs = (org.citygml4j.model.citygml.building.AbstractBoundarySurface) gmlObject;
buildAbs.unsetLod2MultiSurface();
buildAbs.unsetLod3MultiSurface();
buildAbs.unsetLod4MultiSurface();
break;
case TUNNEL:
org.citygml4j.model.citygml.tunnel.AbstractBoundarySurface tunAbs = (org.citygml4j.model.citygml.tunnel.AbstractBoundarySurface) gmlObject;
tunAbs.unsetLod2MultiSurface();
tunAbs.unsetLod3MultiSurface();
tunAbs.unsetLod4MultiSurface();
}
for (Opening o : openings) {
o.unsetGmlGeometries();
}
}
@Override
public String toString() {
return "BoundarySurface [type=" + type + ", id=" + getGmlId() + "]";
}
void anonymize() {
gmlObject.unsetAppearance();
gmlObject.unsetBoundedBy();
gmlObject.unsetCreationDate();
gmlObject.unsetDescription();
gmlObject.unsetExternalReference();
gmlObject.unsetGeneralizesTo();
gmlObject.unsetGenericADEElement();
gmlObject.unsetGenericApplicationPropertyOfCityObject();
gmlObject.unsetGenericAttribute();
setGmlId(GmlId.generateId());
gmlObject.setId(getGmlId().getGmlString());
}
@Override
public AbstractCityObject getGmlObject() {
return gmlObject;
}
@Override
public FeatureType getFeatureType() {
return FeatureType.BOUNDARY_SURFACE;
}
public void addOpening(Opening opening) {
openings.add(opening);
opening.setPartOfSurface(this);
}
}
/*-
* 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 <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.datastructure;
/**
* Types of boundary surfaces used in city doctor
*
* @author Matthias Betz
*
*/
public enum BoundarySurfaceType {
UNDEFINED, ROOF, WALL, GROUND, CLOSURE, OUTER_FLOOR, OUTER_CEILING, CEILING, INTERIOR_WALL, FLOOR
}
/*-
* 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 <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.datastructure;
import java.util.List;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
import de.hft.stuttgart.citydoctor2.utils.BoundingBoxCalculator;
/**
* An axis aligned bounding box represented by its two corners
*
* @author Matthias Betz
*
*/
public class BoundingBox {
private Vector3d[] bbox;
/**
* Creates an axis aligned bounding box containing all points of all polygons
*
* @param polygons containing the points from which the box will be created
* @return the bounding box around all points
*/
public static BoundingBox of(List<Polygon> polygons) {
return BoundingBoxCalculator.calculateBoundingBox(polygons);
}
/**
* Creates an axis aligned bounding box of the whole model.
*
* @param model the model containing the features with geometries used for the
* bounding box
* @return the bounding box around all features
*/
public static BoundingBox of(CityDoctorModel model) {
return BoundingBoxCalculator.calculateBoundingBox(model);
}
/**
* Creates a new bounding box with two vectors as corner points.
*
* @param box the array of length 2 containing both corners
* @return the new bounding box
*/
public static BoundingBox of(Vector3d[] box) {
return new BoundingBox(box);
}
private BoundingBox(Vector3d[] bbox) {
if (bbox == null || bbox.length != 2) {
throw new IllegalArgumentException("BoundingBox must be an array of the length 2");
}
this.bbox = bbox;
}
/**
* Calculates the volume of the box
*
* @return the volume of the box
*/
public double getVolume() {
double length = getDepth();
double width = getWidth();
double height = getHeight();
return height * width * length;
}
/**
* Calculates the center of the bounding box
*
* @return the center of the bounding box
*/
public Vector3d getCenter() {
return bbox[0].plus(bbox[1].minus(bbox[0]).mult(0.5));
}
/**
* Getter for the corner array
*
* @return the array containing the corner points
*/
public Vector3d[] getBox() {
return bbox;
}
/**
* Calculates the width of the bounding box
*
* @return the width of the bounding box
*/
public double getWidth() {
return bbox[1].getY() - bbox[0].getY();
}
/**
* Calculates the height of the bounding box
*
* @return the height of the bounding box
*/
public double getHeight() {
return bbox[1].getZ() - bbox[0].getZ();
}
/**
* Calculates the depth of the bounding box
*
* @return the depth of the bounding box
*/
public double getDepth() {
return bbox[1].getX() - bbox[0].getX();
}
/**
* Returns the length of the longest side of the bounding box, ignoring the
* height. Only X and Y axis are considered
*
* @return the length of the longest side in X or Y direction
*/
public double getLongestSide() {
double width = getWidth();
double depth = getDepth();
if (width > depth) {
return width;
} else {
return depth;
}
}
/**
* Calculates the direction vector from the lower corner to the upper corner
*
* @return the direction vector from the lower corner to the upper corner
*/
public Vector3d getDiagonal() {
return bbox[1].minus(bbox[0]);
}
/**
* Calculates the distance between the corner points
*
* @return the distance between the corner points
*/
public double getDiagonalLength() {
return bbox[1].getDistance(bbox[0]);
}
}
/*-
* 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 <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.datastructure;
import java.util.LinkedList;
import java.util.List;
import org.citygml4j.factory.GMLGeometryFactory;
import org.citygml4j.model.citygml.bridge.AbstractBridge;
import org.citygml4j.model.gml.geometry.aggregates.MultiSurface;
import org.citygml4j.model.gml.geometry.aggregates.MultiSurfaceProperty;
import org.citygml4j.model.gml.geometry.primitives.Solid;
import org.citygml4j.model.gml.geometry.primitives.SolidProperty;
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;
/**
* Bridge representation object of CityGML bridge objects
*
* @author Matthias Betz
*
*/
public class BridgeObject extends CityObject {
private static final long serialVersionUID = 6301112640328373842L;
public enum BridgeType {
BRIDGE, BRIDGE_PART
}
private AbstractBridge ab;
private BridgeType type;
private List<BoundarySurface> boundarySurfaces = new LinkedList<>();
public BridgeObject(BridgeType type, AbstractBridge ab) {
this.ab = ab;
this.type = type;
}
@Override
public FeatureType getFeatureType() {
return FeatureType.BRIDGE;
}
@Override
public void reCreateGeometries(GMLGeometryFactory factory, ParserConfiguration config) {
for (Geometry geom : getGeometries()) {
if (geom.getType() == GeometryType.MULTI_SURFACE) {
MultiSurface ms = CityGmlUtils.createMultiSurface(geom, factory, config);
setMultiSurfaceAccordingToLod(geom, ms);
} else {
Solid solid = CityGmlUtils.createSolid(geom, factory, config);
setSolidAccordingToLod(geom, solid);
}
}
}
private void setMultiSurfaceAccordingToLod(Geometry geom, MultiSurface ms) {
switch (geom.getLod()) {
case LOD1:
ab.setLod1MultiSurface(new MultiSurfaceProperty(ms));
break;
case LOD2:
ab.setLod2MultiSurface(new MultiSurfaceProperty(ms));
break;
case LOD3:
ab.setLod3MultiSurface(new MultiSurfaceProperty(ms));
break;
case LOD4:
ab.setLod4MultiSurface(new MultiSurfaceProperty(ms));
break;
default:
throw new IllegalStateException("Cannot add " + geom.getLod() + " multi surface to bridges");
}
}
private void setSolidAccordingToLod(Geometry geom, Solid solid) {
switch (geom.getLod()) {
case LOD1:
ab.setLod1Solid(new SolidProperty(solid));
break;
case LOD2:
ab.setLod2Solid(new SolidProperty(solid));
break;
case LOD3:
ab.setLod3Solid(new SolidProperty(solid));
break;
case LOD4:
ab.setLod4Solid(new SolidProperty(solid));
break;
default:
throw new IllegalStateException("Cannot add " + geom.getLod() + " solid to bridges");
}
}
@Override
public void clearAllContainedCheckResults() {
super.clearAllContainedCheckResults();
for (BoundarySurface bs : boundarySurfaces) {
bs.clearAllContainedCheckResults();
}
}
@Override
public void collectContainedErrors(List<CheckError> errors) {
super.collectContainedErrors(errors);
for (BoundarySurface bs : boundarySurfaces) {
bs.collectContainedErrors(errors);
}
}
@Override
public boolean containsAnyError() {
boolean hasError = super.containsAnyError();
if (hasError) {
return true;
}
for (BoundarySurface bs : boundarySurfaces) {
if (bs.containsAnyError()) {
return true;
}
}
return false;
}
@Override
public boolean containsError(CheckId checkIdentifier) {
boolean hasError = super.containsError(checkIdentifier);
if (hasError) {
return true;
}
for (BoundarySurface bs : boundarySurfaces) {
if (bs.containsError(checkIdentifier)) {
return true;
}
}
return false;
}
@Override
public void accept(Check c) {
super.accept(c);
if (c.canExecute(this)) {
c.check(this);
}
}
/**
* Getter method for type
*
* @return the type
*/
public BridgeType getType() {
return type;
}
/**
* Setter Method for type
*
* @param type the type to set
*/
public void setType(BridgeType type) {
this.type = type;
}
public void addBoundarySurface(BoundarySurface bs) {
boundarySurfaces.add(bs);
bs.setParent(this);
}
@Override
public AbstractBridge getGmlObject() {
return ab;
}
@Override
public void unsetGmlGeometries() {
ab.unsetLod1MultiSurface();
ab.unsetLod2MultiSurface();
ab.unsetLod3MultiSurface();
ab.unsetLod4MultiSurface();
ab.unsetLod1Solid();
ab.unsetLod2Solid();
ab.unsetLod3Solid();
ab.unsetLod4Solid();
}
public void setGmlObject(AbstractBridge aBridge) {
ab = aBridge;
}
@Override
public String toString() {
return "BridgeObject [type=" + type + ", id=" + getGmlId() + "]";
}
}
/*-
* 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 <https://www.gnu.org/licenses/>.
*/
package de.hft.stuttgart.citydoctor2.datastructure;
import java.util.ArrayList;
import java.util.List;
import org.citygml4j.factory.GMLGeometryFactory;
import org.citygml4j.model.citygml.building.AbstractBoundarySurface;
import org.citygml4j.model.citygml.building.BoundarySurfaceProperty;
import org.citygml4j.model.citygml.building.BuildingInstallationProperty;
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;
public class Building extends AbstractBuilding {
private static final long serialVersionUID = 588480113268630052L;
private List<BuildingPart> buildingParts = new ArrayList<>(2);
public List<BuildingPart> getBuildingParts() {
return buildingParts;
}
@Override
public Building copy() {
return (Building) super.copy();
}
@Override
public void reCreateGeometries(GMLGeometryFactory factory, ParserConfiguration config) {
super.reCreateGeometries(factory, config);
for (BuildingPart bp : buildingParts) {
bp.reCreateGeometries(factory, config);
}
}
@Override
public void accept(Check c) {
super.accept(c);
if (c.canExecute(this)) {
c.check(this);
}
for (BuildingPart bp : buildingParts) {
bp.accept(c);
}
}
@Override
public void clearAllContainedCheckResults() {
super.clearAllContainedCheckResults();
for (BuildingPart bp : buildingParts) {
bp.clearAllContainedCheckResults();
}
}
@Override
public void collectContainedErrors(List<CheckError> errors) {
super.collectContainedErrors(errors);
for (BuildingPart bp : buildingParts) {
bp.collectContainedErrors(errors);
}
}
@Override
public boolean containsAnyError() {
boolean hasError = super.containsAnyError();
if (hasError) {
return true;
}
for (BuildingPart bp : buildingParts) {
if (bp.containsAnyError()) {
return true;
}
}
return false;
}
@Override
public boolean containsError(CheckId checkIdentifier) {
boolean hasError = super.containsError(checkIdentifier);
if (hasError) {
return true;
}
for (BuildingPart bp : buildingParts) {
if (bp.containsError(checkIdentifier)) {
return true;
}
}
return false;
}
public void addBuildingPart(BuildingPart buildingPart) {
buildingParts.add(buildingPart);
}
@Override
public String toString() {
return "Building [id=" + getGmlId() + "]";
}
public void anonymize() {
for (Geometry geom : getGeometries()) {
geom.anonymize();
}
org.citygml4j.model.citygml.building.Building gmlB = new org.citygml4j.model.citygml.building.Building();
gmlB.setId(GmlId.generateId().getGmlString());
for (BuildingInstallation bi : getBuildingInstallations()) {
bi.anonymize();
gmlB.addOuterBuildingInstallation(new BuildingInstallationProperty(bi.getGmlObject()));
}
for (BoundarySurface bs : getBoundarySurfaces()) {
bs.anonymize();
gmlB.addBoundedBySurface(new BoundarySurfaceProperty((AbstractBoundarySurface) bs.getGmlObject()));
}
setCityGmlBuilding(gmlB);
}
}
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