CityGmlUtils.java 6.53 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*-
 *  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.utils;

import java.util.ArrayList;
import java.util.List;

Matthias Betz's avatar
Matthias Betz committed
24
import org.citygml4j.core.util.geometry.GeometryFactory;
25
26
import org.locationtech.proj4j.BasicCoordinateTransform;
import org.locationtech.proj4j.ProjCoordinate;
Matthias Betz's avatar
Matthias Betz committed
27
28
29
30
31
32
33
import org.xmlobjects.gml.model.geometry.aggregates.MultiSurface;
import org.xmlobjects.gml.model.geometry.complexes.CompositeSurface;
import org.xmlobjects.gml.model.geometry.primitives.AbstractRingProperty;
import org.xmlobjects.gml.model.geometry.primitives.Shell;
import org.xmlobjects.gml.model.geometry.primitives.ShellProperty;
import org.xmlobjects.gml.model.geometry.primitives.Solid;
import org.xmlobjects.gml.model.geometry.primitives.SurfaceProperty;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

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;

/**
 * Utility class dedicated to create CityGML4j datastructures.
 * 
 * @author Matthias Betz
 *
 */
public final class CityGmlUtils {

	private CityGmlUtils() {
		// util class
	}

Matthias Betz's avatar
Matthias Betz committed
54
	public static org.xmlobjects.gml.model.geometry.primitives.Polygon createGmlPolygon(GeometryFactory factory,
55
56
57
58
			Polygon cdPoly, ParserConfiguration config) {
		if (cdPoly.getExteriorRing() == null) {
			return null;
		}
Matthias Betz's avatar
Matthias Betz committed
59
60
61
62
63
		org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = new org.xmlobjects.gml.model.geometry.primitives.Polygon();
		// exterior ring
		LinearRing extLr = cdPoly.getExteriorRing();
		org.xmlobjects.gml.model.geometry.primitives.LinearRing gmlLr = createGmlRing(factory, config, extLr);
		gmlPoly.setExterior(new AbstractRingProperty(gmlLr));
64

Matthias Betz's avatar
Matthias Betz committed
65
66
67
68
		// interior rings
		for (LinearRing lr : cdPoly.getInnerRings()) {
			gmlLr = createGmlRing(factory, config, lr);
			gmlPoly.getInterior().add(new AbstractRingProperty(gmlLr));
69
		}
Matthias Betz's avatar
Matthias Betz committed
70
71
		gmlPoly.setId(cdPoly.getGmlId().getGmlString());
		return gmlPoly;
72
73
	}

74
	public static org.xmlobjects.gml.model.geometry.primitives.LinearRing createGmlRing(GeometryFactory factory,
Matthias Betz's avatar
Matthias Betz committed
75
			ParserConfiguration config, LinearRing lr) {
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
		ProjCoordinate p1 = new ProjCoordinate();
		ProjCoordinate p2 = new ProjCoordinate();
		List<Double> ringValues = new ArrayList<>();
		BasicCoordinateTransform trans = config.getOriginalTransform();
		for (Vertex v : lr.getVertices()) {
			double x = v.getX();
			double y = v.getY();
			double z = v.getZ();
			if (trans != null) {
				p1.x = x;
				p1.y = y;
				trans.transform(p1, p2);
				x = p2.x;
				y = p2.y;
				z = z * config.getFromMetres();
			}
			ringValues.add(x);
			ringValues.add(y);
			ringValues.add(z);
		}
Matthias Betz's avatar
Matthias Betz committed
96
		org.xmlobjects.gml.model.geometry.primitives.LinearRing gmlLr = factory.createLinearRing(ringValues, 3);
97
98
99
100
		gmlLr.setId(lr.getGmlId().getGmlString());
		return gmlLr;
	}

Matthias Betz's avatar
Matthias Betz committed
101
	public static Solid createSolid(Geometry geom, GeometryFactory factory, ParserConfiguration config) {
102
103
104
105
		if (geom.getType() != GeometryType.SOLID) {
			throw new IllegalArgumentException("Only solids are allowed");
		}

Matthias Betz's avatar
Matthias Betz committed
106
107
		CompositeSurface comp = new CompositeSurface();
		List<SurfaceProperty> surfaceMember = comp.getSurfaceMembers();
108
109
		for (Polygon cdPoly : geom.getPolygons()) {
			if (!cdPoly.isLink()) {
Matthias Betz's avatar
Matthias Betz committed
110
				org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config);
111
112
113
114
115
116
117
118
119
120
121
122
123
				if (gmlPoly != null) {
					surfaceMember.add(new SurfaceProperty(gmlPoly));
				}
			} else {
				// add reference to polygon
				surfaceMember.add(new SurfaceProperty("#" + cdPoly.getGmlId().getGmlString()));
			}
		}

		if (surfaceMember.isEmpty()) {
			return null;
		}
		Solid solid = new Solid();
Matthias Betz's avatar
Matthias Betz committed
124
125
		Shell shell = new Shell(surfaceMember);
		solid.setExterior(new ShellProperty(shell));
126
127
128
129
		solid.setId(geom.getGmlId().getGmlString());
		return solid;
	}

Matthias Betz's avatar
Matthias Betz committed
130
	public static MultiSurface createMultiSurface(Geometry geom, GeometryFactory factory,
131
132
133
134
			ParserConfiguration config) {
		if (geom.getType() != GeometryType.MULTI_SURFACE) {
			throw new IllegalArgumentException("This can only handle MultiSurfaces");
		}
Matthias Betz's avatar
Matthias Betz committed
135
		List<SurfaceProperty> surfaces = new ArrayList<>();
136
137
138
		for (Polygon cdPoly : geom.getPolygons()) {
			if (!cdPoly.isLink()) {
				// is not part of a boundary surface
Matthias Betz's avatar
Matthias Betz committed
139
				org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config);
140
				if (gmlPoly != null) {
Matthias Betz's avatar
Matthias Betz committed
141
					surfaces.add(new SurfaceProperty(gmlPoly));
142
143
144
				}
			} else {
				// add reference to polygon
Matthias Betz's avatar
Matthias Betz committed
145
				surfaces.add(new SurfaceProperty("#" + cdPoly.getGmlId().getGmlString()));
146
147
148
149
150
151
152
153
154
155
			}
		}
		if (surfaces.isEmpty()) {
			return null;
		}
		MultiSurface ms = new MultiSurface(surfaces);
		ms.setId(geom.getGmlId().getGmlString());
		return ms;
	}

Matthias Betz's avatar
Matthias Betz committed
156
	public static MultiSurface createMultiSurface(List<Polygon> polygons, GeometryFactory factory,
157
			ParserConfiguration config) {
Matthias Betz's avatar
Matthias Betz committed
158
		List<SurfaceProperty> surfaces = new ArrayList<>();
159
		for (Polygon cdPoly : polygons) {
Matthias Betz's avatar
Matthias Betz committed
160
			org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config);
161
			if (gmlPoly != null) {
Matthias Betz's avatar
Matthias Betz committed
162
				surfaces.add(new SurfaceProperty(gmlPoly));
163
164
165
166
167
168
169
170
			}
		}
		if (surfaces.isEmpty()) {
			return null;
		}
		return new MultiSurface(surfaces);
	}

Matthias Betz's avatar
Matthias Betz committed
171
	public static CompositeSurface createCompositeSurface(Geometry geom, GeometryFactory factory,
Matthias Betz's avatar
Matthias Betz committed
172
			ParserConfiguration config) {
Matthias Betz's avatar
Matthias Betz committed
173
		List<SurfaceProperty> surfaces = new ArrayList<>();
Matthias Betz's avatar
Matthias Betz committed
174
		for (Polygon cdPoly : geom.getPolygons()) {
Matthias Betz's avatar
Matthias Betz committed
175
			org.xmlobjects.gml.model.geometry.primitives.Polygon gmlPoly = createGmlPolygon(factory, cdPoly, config);
Matthias Betz's avatar
Matthias Betz committed
176
			if (gmlPoly != null) {
Matthias Betz's avatar
Matthias Betz committed
177
				surfaces.add(new SurfaceProperty(gmlPoly));
Matthias Betz's avatar
Matthias Betz committed
178
179
180
181
182
183
184
185
			}
		}
		if (surfaces.isEmpty()) {
			return null;
		}
		return new CompositeSurface(surfaces);
	}

186
}