From ad3589e8fe4d8e9f07b51f5be626cceb7e8d3653 Mon Sep 17 00:00:00 2001
From: Riegel <alexander.riegel@hft-stuttgart.de>
Date: Tue, 29 Oct 2024 15:47:54 +0100
Subject: [PATCH] Add export of CompositeSurfaces

---
 .../datastructure/CompositePolygon.java       |  1 +
 .../datastructure/ConcretePolygon.java        | 13 ++++++
 .../citydoctor2/utils/CityGmlUtils.java       | 40 ++++++++++++++++---
 3 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/CompositePolygon.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/CompositePolygon.java
index 20614c4..5607485 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/CompositePolygon.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/CompositePolygon.java
@@ -54,6 +54,7 @@ public final class CompositePolygon extends ConcretePolygon{
 
     public void addCompositeMember(ConcretePolygon p){
         compositeMembers.add(p);
+        p.setPartOfComposite(this);
     }
 
     public List<ConcretePolygon> getCompositeMembers(){
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/ConcretePolygon.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/ConcretePolygon.java
index c57113e..eca5454 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/ConcretePolygon.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/datastructure/ConcretePolygon.java
@@ -49,6 +49,7 @@ public class ConcretePolygon extends Polygon {
 	private List<LinearRing> innerRings;
 	private BoundarySurface partOfSurface;
 	private Installation partfOfInstallation;
+	private CompositePolygon partOfComposite = null;
 	private Geometry parent;
 	private LinkedPolygon linkedFromPolygon;
 	
@@ -138,6 +139,18 @@ public class ConcretePolygon extends Polygon {
 		parent = geometry;
 	}
 
+	protected void setPartOfComposite(CompositePolygon comp) {
+		this.partOfComposite = comp;
+	}
+
+	public CompositePolygon getPartOfComposite() {
+		return partOfComposite;
+	}
+
+	public boolean isCompositeMember() {
+		return (partOfComposite != null);
+	}
+
 	/*
 	 * (non-Javadoc)
 	 * 
diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/CityGmlUtils.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/CityGmlUtils.java
index 0ecc8fa..34f6f71 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/CityGmlUtils.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/CityGmlUtils.java
@@ -19,8 +19,11 @@
 package de.hft.stuttgart.citydoctor2.utils;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
+import de.hft.stuttgart.citydoctor2.datastructure.*;
 import org.citygml4j.core.util.geometry.GeometryFactory;
 import org.locationtech.proj4j.BasicCoordinateTransform;
 import org.locationtech.proj4j.ProjCoordinate;
@@ -32,11 +35,6 @@ import org.xmlobjects.gml.model.geometry.primitives.ShellProperty;
 import org.xmlobjects.gml.model.geometry.primitives.Solid;
 import org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty;
 
-import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
-import de.hft.stuttgart.citydoctor2.datastructure.GeometryType;
-import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
-import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
-import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
 import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
 
 /**
@@ -81,6 +79,28 @@ public final class CityGmlUtils {
 		return gmlPoly;
 	}
 
+	public static CompositeSurface createGmlComposite(GeometryFactory factory, CompositePolygon cdPoly,
+													  ParserConfiguration config) {
+		List<ConcretePolygon> cdMembers = cdPoly.getCompositeMembers();
+		List<SurfaceProperty> surfaces = new ArrayList<>();
+		for (ConcretePolygon cd : cdMembers) {
+			surfaces.add(resolveCompositeMember(factory, cd, config));
+		}
+		if (surfaces.isEmpty()){
+			return null;
+		}
+		return new CompositeSurface(surfaces);
+	}
+
+	private static SurfaceProperty resolveCompositeMember(GeometryFactory factory, ConcretePolygon cdPoly,
+														  ParserConfiguration config){
+		if (cdPoly instanceof CompositePolygon comp) {
+			return new SurfaceProperty(createGmlComposite(factory, comp, config));
+		} else {
+			return new SurfaceProperty(createGmlPolygon(factory, cdPoly, config));
+		}
+	}
+
 	public static org.xmlobjects.gml.model.geometry.primitives.LinearRing createGmlRing(GeometryFactory factory,
 			ParserConfiguration config, LinearRing lr) {
 
@@ -145,8 +165,13 @@ public final class CityGmlUtils {
 			throw new IllegalArgumentException("This can only handle MultiSurfaces");
 		}
 		List<SurfaceProperty> surfaces = new ArrayList<>();
+		Set<CompositePolygon> compositePolygons = new HashSet<>();
 		for (Polygon cdPoly : geom.getPolygons()) {
-			if (!cdPoly.isLink()) {
+			if (cdPoly instanceof ConcretePolygon conc && conc.isCompositeMember()) {
+				compositePolygons.add(conc.getPartOfComposite());
+			}else if (cdPoly instanceof CompositePolygon composite) {
+				compositePolygons.add(composite);
+			} else if (!cdPoly.isLink()) {
 				// is not part of a boundary surface
 				org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config);
 				if (gmlPoly != null) {
@@ -157,6 +182,9 @@ public final class CityGmlUtils {
 				surfaces.add(new SurfaceProperty("#" + cdPoly.getGmlId().getGmlString()));
 			}
 		}
+		for (CompositePolygon cdPoly : compositePolygons) {
+			surfaces.add(new SurfaceProperty(createGmlComposite(factory, cdPoly, config)));
+		}
 		if (surfaces.isEmpty()) {
 			return null;
 		}
-- 
GitLab