Collection<OsmPrimitive> sel = getCurrentDataSet().getSelected();
List<Node> nodes = new LinkedList<>();
// fixNodes: All nodes for which the angle relative to center should not be modified
HashSet<Node> fixNodes = new HashSet<>();
List<Way> ways = new LinkedList<>();
EastNorth center = null;
double radius = 0;
for (OsmPrimitive osm : sel) {
if (osm instanceof Node) {
nodes.add((Node) osm);
} else if (osm instanceof Way) {
ways.add((Way) osm);
}
}
if (ways.size() == 1 && ways.get(0).firstNode() != ways.get(0).lastNode()) {
// Case 1
Way w = ways.get(0);
fixNodes.add(w.firstNode());
fixNodes.add(w.lastNode());
fixNodes.addAll(nodes);
fixNodes.addAll(collectNodesWithExternReferers(ways));
// Temporary closed way used to reorder nodes
Way closedWay = new Way(w);
closedWay.addNode(w.firstNode());
ArrayList<Way> usedWays = new ArrayList<>(1);
usedWays.add(closedWay);
nodes = collectNodesAnticlockwise(usedWays);
} else if (!ways.isEmpty() && checkWaysArePolygon(ways)) {
// Case 2
ArrayList<Node> inside = new ArrayList<>();
ArrayList<Node> outside = new ArrayList<>();
for(Node n: nodes) {
boolean isInside = false;
for(Way w: ways) {
if(w.getNodes().contains(n)) {
isInside = true;
break;
}
}
if(isInside)
inside.add(n);
else
outside.add(n);
}
if(outside.size() == 1 && inside.isEmpty()) {
center = outside.get(0).getEastNorth();
} else if(outside.size() == 1 && inside.size() == 1) {
center = outside.get(0).getEastNorth();
radius = distance(center, inside.get(0).getEastNorth());
} else if(inside.size() == 2 && outside.isEmpty()) {
// 2 nodes inside, define diameter
EastNorth en0 = inside.get(0).getEastNorth();
EastNorth en1 = inside.get(1).getEastNorth();
center = new EastNorth((en0.east() + en1.east()) / 2, (en0.north() + en1.north()) / 2);
radius = distance(en0, en1) / 2;
}
fixNodes.addAll(inside);
fixNodes.addAll(collectNodesWithExternReferers(ways));