Commit 2d9f08ee authored by Riegel's avatar Riegel
Browse files

Add CompositePolygon

2 merge requests!11CityDoctor Release Version 3.16.0,!10CityGML 3.0. Support
Pipeline #10265 passed with stage
in 2 minutes and 39 seconds
Showing with 326 additions and 14 deletions
+326 -14
package de.hft.stuttgart.citydoctor2.datastructure;
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.math.Triangle3d;
import de.hft.stuttgart.citydoctor2.math.Vector3d;
import de.hft.stuttgart.citydoctor2.tesselation.TesselatedPolygon;
import de.hft.stuttgart.citydoctor2.utils.CopyHandler;
import de.hft.stuttgart.citydoctor2.utils.Copyable;
import java.io.Serial;
import java.util.*;
/**
*
*/
public class CompositePolygon extends ConcretePolygon{
@Serial
private static final long serialVersionUID = -1867197873443341287L;
private Geometry parent;
private BoundarySurface partOfSurface;
private Installation partOfInstallation;
private List<Polygon> compositeMembers = new ArrayList<>();
private LinearRing exterior = null;
@Override
public Vector3d calculateNormalNormalized() {
return this.calculateNormal().normalize();
}
@Override
public void accept(Check c){
for (Polygon p : compositeMembers){
p.accept(c);
}
setValidated(true);
}
@Override
public Class<? extends Checkable> getCheckClass() {
return Polygon.class;
}
@Override
public boolean containsAnyError(){
if (super.containsAnyError()){
return true;
}
for (Polygon p : compositeMembers){
if (p.containsAnyError()){
return true;
}
}
return false;
}
@Override
public void collectContainedErrors(List<CheckError> errors) {
super.collectContainedErrors(errors);
for (Polygon p : compositeMembers){
p.collectContainedErrors(errors);
}
}
@Override
public void clearAllContainedCheckResults() {
super.clearCheckResults();
for (Polygon p : compositeMembers){
p.clearAllContainedCheckResults();
}
}
public void addCompositeMember(Polygon p){
compositeMembers.add(p);
}
public List<Polygon> getCompositeMembers(){
return compositeMembers;
}
@Override
public boolean containsError(CheckId checkIdentifier) {
boolean hasError = super.containsError(checkIdentifier);
if (hasError) {
return true;
}
for (Polygon p : compositeMembers){
if (p.containsError(checkIdentifier)) {
return true;
}
}
return false;
}
@Override
public Vector3d calculateNormal() {
return this.getExteriorRing().calculateNormal();
}
@Override
public TesselatedPolygon tesselate() {
List<Triangle3d> tessPolys = new ArrayList<>();
for (Polygon p : compositeMembers){
TesselatedPolygon t = p.tesselate();
tessPolys.addAll(t.getTriangles());
}
return new TesselatedPolygon(tessPolys,this );
}
@Override
public LinearRing getExteriorRing() {
if( exterior != null ){
return exterior;
}
Map<Vertex, Integer> outerVertices = new HashMap<>();
for (Polygon p : compositeMembers){
for (Vertex v: p.getExteriorRing().getVertices()){
outerVertices.merge(v, 1, Integer::sum);
}
}
List<Vertex> vertices = new ArrayList<>();
for (Vertex v : outerVertices.keySet()){
if (outerVertices.get(v) <= 3){
vertices.add(v);
}
}
LinearRing ext = new LinearRing(LinearRing.LinearRingType.EXTERIOR);
ext.setParent(this);
ext.addAllVertices(vertices);
exterior = ext;
return ext;
}
@Override
public List<LinearRing> getInnerRings() {
List<LinearRing> innerRings = new ArrayList<>();
for (Polygon p : compositeMembers){
innerRings.addAll(p.getInnerRings());
}
return innerRings;
}
@Override
public boolean isPointInsideExteriorRing(Vector3d v) {
for (Polygon p : compositeMembers) {
if (p.isPointInsideExteriorRing(v)) {
return true;
}
}
return false;
}
@Override
public Geometry getParent() {
return parent;
}
@Override
public void setParent(Geometry geometry) {
this.parent = geometry;
}
@Override
public void setExteriorRing(LinearRing extRing) {
// ConcretePolygons' exterior ring is not settable
}
@Override
public boolean isPolygonConnectedViaPoint(Polygon other) {
for (Polygon p : compositeMembers) {
if (p.isPolygonConnectedViaPoint(other)) {
return true;
}
}
return false;
}
@Override
public void addInteriorRing(LinearRing inter) {
// ConcretePolygons have no interior ring themselves
}
@Override
public BoundarySurface getPartOfSurface() {
return partOfSurface;
}
@Override
public void setPartOfSurface(BoundarySurface bs) {
this.partOfSurface = bs;
}
@Override
public void removeInnerRing(LinearRing ring) {
for (Polygon p : compositeMembers) {
p.removeInnerRing(ring);
}
}
@Override
public void setPartOfInstallation(Installation bi) {
this.partOfInstallation = bi;
}
@Override
public Installation getPartOfInstallation() {
return partOfInstallation;
}
@Override
public boolean hasPointAsCorner(Vertex v) {
for (Polygon p : compositeMembers){
if (p.hasPointAsCorner(v)) {
return true;
}
}
return false;
}
@Override
public void removeRings() {
}
@Override
public boolean isLinkedTo() {
return false;
}
@Override
public boolean isLink() {
return false;
}
@Override
public LinkedPolygon getLinkedFromPolygon() {
return null;
}
@Override
void anonymize() {
}
@Override
public double getArea() {
return 0;
}
@Override
public void prepareForChecking() {
}
@Override
public void clearMetaInformation() {
}
@Override
public void collectInstances(CopyHandler handler) {
}
@Override
public Copyable createCopyInstance() {
return null;
}
}
...@@ -553,7 +553,7 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -553,7 +553,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
} }
private void parseAndAddCompositeSurface(MultiSurfaceProperty ms, Lod lod, CityObject co){ private void parseAndAddCompositeSurface(MultiSurfaceProperty ms, Lod lod, CityObject co){
if (ms == null || ms.getObject() == null || ms.getObject().getSurfaceMember().isEmpty()) { if (ms == null || ms.getObject() == null) {
return; return;
} }
List<SurfaceProperty> surfaces = ms.getObject().getSurfaceMember(); List<SurfaceProperty> surfaces = ms.getObject().getSurfaceMember();
...@@ -633,6 +633,10 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -633,6 +633,10 @@ public class Citygml3FeatureMapper extends ObjectWalker {
} }
continue; continue;
} }
// TODO: Insert handling of compPoly dummy objects
if (concPoly instanceof CompositePolygon comp) {}
//
LinkedPolygon lPoly = new LinkedPolygon(concPoly, geom); LinkedPolygon lPoly = new LinkedPolygon(concPoly, geom);
if (geom.getParent() instanceof BoundarySurface bs) { if (geom.getParent() instanceof BoundarySurface bs) {
lPoly.setPartOfSurface(bs); lPoly.setPartOfSurface(bs);
...@@ -976,7 +980,7 @@ public class Citygml3FeatureMapper extends ObjectWalker { ...@@ -976,7 +980,7 @@ public class Citygml3FeatureMapper extends ObjectWalker {
} }
} }
public Geometry parseCompositeSurface(CompositeSurface cs, Lod lod) { private Geometry parseCompositeSurface(CompositeSurface cs, Lod lod) {
Geometry geom = new Geometry(GeometryType.COMPOSITE_SURFACE, lod); Geometry geom = new Geometry(GeometryType.COMPOSITE_SURFACE, lod);
Citygml3GeometryMapper geometryMapper = new Citygml3GeometryMapper(config, vertexMap); Citygml3GeometryMapper geometryMapper = new Citygml3GeometryMapper(config, vertexMap);
readSurfaceMember(geom, geometryMapper, cs.getSurfaceMembers()); readSurfaceMember(geom, geometryMapper, cs.getSurfaceMembers());
......
...@@ -22,6 +22,7 @@ import java.util.ArrayList; ...@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import de.hft.stuttgart.citydoctor2.datastructure.*;
import org.citygml4j.core.model.construction.AbstractConstructionSurface; import org.citygml4j.core.model.construction.AbstractConstructionSurface;
import org.citygml4j.core.model.construction.AbstractFillingSurface; import org.citygml4j.core.model.construction.AbstractFillingSurface;
import org.citygml4j.core.model.construction.AbstractFillingSurfaceProperty; import org.citygml4j.core.model.construction.AbstractFillingSurfaceProperty;
...@@ -40,20 +41,10 @@ import org.citygml4j.core.model.core.ClosureSurface; ...@@ -40,20 +41,10 @@ import org.citygml4j.core.model.core.ClosureSurface;
import org.citygml4j.core.visitor.ObjectWalker; import org.citygml4j.core.visitor.ObjectWalker;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface; import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface;
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty; import org.xmlobjects.gml.model.geometry.aggregates.MultiSurfaceProperty;
import org.xmlobjects.gml.model.geometry.complexes.CompositeSurface;
import org.xmlobjects.gml.model.geometry.primitives.AbstractSurface; import org.xmlobjects.gml.model.geometry.primitives.AbstractSurface;
import org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty; import org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty;
import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface;
import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurfaceType;
import de.hft.stuttgart.citydoctor2.datastructure.CityObject;
import de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
import de.hft.stuttgart.citydoctor2.datastructure.Lod;
import de.hft.stuttgart.citydoctor2.datastructure.Opening;
import de.hft.stuttgart.citydoctor2.datastructure.OpeningType;
import de.hft.stuttgart.citydoctor2.datastructure.SurfaceFeatureType;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration; import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
public class SurfaceMapper extends ObjectWalker { public class SurfaceMapper extends ObjectWalker {
...@@ -106,6 +97,11 @@ public class SurfaceMapper extends ObjectWalker { ...@@ -106,6 +97,11 @@ public class SurfaceMapper extends ObjectWalker {
parseAndAddMultiSurface(afs.getLod2MultiSurface(), Lod.LOD2, o); parseAndAddMultiSurface(afs.getLod2MultiSurface(), Lod.LOD2, o);
parseAndAddMultiSurface(afs.getLod3MultiSurface(), Lod.LOD3, o); parseAndAddMultiSurface(afs.getLod3MultiSurface(), Lod.LOD3, o);
parseAndAddMultiSurface(afs.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, o); parseAndAddMultiSurface(afs.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, o);
parseAndAddCompositeSurface(afs.getLod0MultiSurface(), Lod.LOD0, o);
parseAndAddCompositeSurface(afs.getLod1MultiSurface(), Lod.LOD1, o);
parseAndAddCompositeSurface(afs.getLod2MultiSurface(), Lod.LOD2, o);
parseAndAddCompositeSurface(afs.getLod3MultiSurface(), Lod.LOD3, o);
parseAndAddCompositeSurface(afs.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, o);
o.unsetGmlGeometries(); o.unsetGmlGeometries();
} }
...@@ -116,6 +112,11 @@ public class SurfaceMapper extends ObjectWalker { ...@@ -116,6 +112,11 @@ public class SurfaceMapper extends ObjectWalker {
parseAndAddMultiSurface(gmlSurface.getLod2MultiSurface(), Lod.LOD2, cdSurface); parseAndAddMultiSurface(gmlSurface.getLod2MultiSurface(), Lod.LOD2, cdSurface);
parseAndAddMultiSurface(gmlSurface.getLod3MultiSurface(), Lod.LOD3, cdSurface); parseAndAddMultiSurface(gmlSurface.getLod3MultiSurface(), Lod.LOD3, cdSurface);
parseAndAddMultiSurface(gmlSurface.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, cdSurface); parseAndAddMultiSurface(gmlSurface.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, cdSurface);
parseAndAddCompositeSurface(gmlSurface.getLod0MultiSurface(), Lod.LOD0, cdSurface);
parseAndAddCompositeSurface(gmlSurface.getLod1MultiSurface(), Lod.LOD1, cdSurface);
parseAndAddCompositeSurface(gmlSurface.getLod2MultiSurface(), Lod.LOD2, cdSurface);
parseAndAddCompositeSurface(gmlSurface.getLod3MultiSurface(), Lod.LOD3, cdSurface);
parseAndAddCompositeSurface(gmlSurface.getDeprecatedProperties().getLod4MultiSurface(), Lod.LOD4, cdSurface);
} }
private void parseAndAddMultiSurface(MultiSurfaceProperty msp, Lod lod, CityObject cdSurface) { private void parseAndAddMultiSurface(MultiSurfaceProperty msp, Lod lod, CityObject cdSurface) {
...@@ -132,7 +133,36 @@ public class SurfaceMapper extends ObjectWalker { ...@@ -132,7 +133,36 @@ public class SurfaceMapper extends ObjectWalker {
readSurfaceMember(geom, geometryMapper, ms.getSurfaceMember()); readSurfaceMember(geom, geometryMapper, ms.getSurfaceMember());
return geom; return geom;
} }
private void parseAndAddCompositeSurface(MultiSurfaceProperty ms, Lod lod, CityObject cdSurface){
if (ms == null || ms.getObject() == null) {
return;
}
List<SurfaceProperty> surfaceMember = ms.getObject().getSurfaceMember();
for (SurfaceProperty surface : surfaceMember) {
if (surface.getObject() instanceof CompositeSurface cs) {
Geometry geom = parseCompositeSurface(cs, lod);
cdSurface.addGeometry(geom);
}
}
}
private Geometry parseCompositeSurface(CompositeSurface cs, Lod lod) {
Geometry geom = new Geometry(GeometryType.COMPOSITE_SURFACE, lod);
Citygml3GeometryMapper geometryMapper = new Citygml3GeometryMapper(config, vertexMap);
readSurfaceMember(geom, geometryMapper, cs.getSurfaceMembers());
if (cs.getId() != null){
CompositePolygon compPoly = new CompositePolygon();
polygonMap.put(cs.getId(), compPoly);
geom.getPolygons().forEach(compPoly::addCompositeMember);
compPoly.setParent(geom);
}
return geom;
}
private void readSurfaceMember(Geometry geom, Citygml3GeometryMapper geometryMapper, private void readSurfaceMember(Geometry geom, Citygml3GeometryMapper geometryMapper,
List<SurfaceProperty> surfaceMember) { List<SurfaceProperty> surfaceMember) {
for (SurfaceProperty prop : surfaceMember) { for (SurfaceProperty prop : surfaceMember) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment