/*-
* 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 .
*/
package de.hft.stuttgart.citydoctor2.edge;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
public class CDPolygonNs extends PolygonNs {
private List> innerHalfEdges = new ArrayList<>();
public static CDPolygonNs of(Polygon p, Map pointMap) {
List> loopCoordinates = new ArrayList<>();
List edgeExtRing = createCoordinatesFromRing(pointMap, p.getExteriorRing().getVertices());
loopCoordinates.add(edgeExtRing);
for (LinearRing innerRing : p.getInnerRings()) {
List edgeInnerRing = createCoordinatesFromRing(pointMap, innerRing.getVertices());
loopCoordinates.add(edgeInnerRing);
}
List> halfEdges = new ArrayList<>();
for (List ringCoordinates : loopCoordinates) {
List currHeList = createHalfEdgesFromCoordinates(ringCoordinates);
halfEdges.add(currHeList);
}
return new CDPolygonNs(halfEdges, p);
}
private static List createHalfEdgesFromCoordinates(List ringCoordinates) {
List currHeList = new ArrayList<>();
HalfEdge prevHalfEdge = null;
for (int currCoordIndex = 1; currCoordIndex < ringCoordinates.size(); currCoordIndex++) {
int prevCoordIndex = currCoordIndex - 1;
Coordinate3d currCoord = ringCoordinates.get(currCoordIndex);
Coordinate3d prevCoord = ringCoordinates.get(prevCoordIndex);
HalfEdge e = new HalfEdge(prevCoord, currCoord);
if (prevHalfEdge != null) {
prevHalfEdge.setNext(e);
}
currHeList.add(e);
prevHalfEdge = e;
}
if (prevHalfEdge == null) {
throw new IllegalStateException("No half edges were created");
}
Coordinate3d start = ringCoordinates.get(0);
Coordinate3d end = ringCoordinates.get(ringCoordinates.size() - 1);
HalfEdge e = new HalfEdge(end, start);
prevHalfEdge.setNext(e);
e.setNext(currHeList.get(0));
currHeList.add(e);
return currHeList;
}
private static List createCoordinatesFromRing(Map pointMap,
List vertices) {
List edgeRing = new ArrayList<>();
for (int i = 0; i < vertices.size() - 1; i++) {
Vertex v = vertices.get(i);
Coordinate3d c = pointMap.computeIfAbsent(v, key -> new Coordinate3d(key.getX(), key.getY(), key.getZ()));
edgeRing.add(c);
}
return edgeRing;
}
public CDPolygonNs(List> halfEdges, Polygon original) {
super(halfEdges.get(0), original);
for (int i = 1; i < halfEdges.size(); i++) {
List loopEdges = halfEdges.get(i);
for (HalfEdge e : loopEdges) {
addChild(e);
}
innerHalfEdges.add(loopEdges);
}
}
public List> getInnerHalfEdges() {
return innerHalfEdges;
}
}