| 200 | | BigDecimal east = BigDecimal.ZERO; |
| 201 | | BigDecimal north = BigDecimal.ZERO; |
| 202 | | |
| 203 | | for (Node n : nodes) { |
| 204 | | BigDecimal x = new BigDecimal(n.getEastNorth().east()); |
| 205 | | BigDecimal y = new BigDecimal(n.getEastNorth().north()); |
| 206 | | east = east.add(x, MathContext.DECIMAL128); |
| 207 | | north = north.add(y, MathContext.DECIMAL128); |
| 208 | | } |
| 209 | | BigDecimal nodesSize = new BigDecimal(nodes.size()); |
| 210 | | east = east.divide(nodesSize, MathContext.DECIMAL128); |
| 211 | | north = north.divide(nodesSize, MathContext.DECIMAL128); |
| 212 | | |
| 213 | | EastNorth average = new EastNorth(east.doubleValue(), north.doubleValue()); |
| | 188 | if (!isPolygon) { |
| | 189 | // Then reorder them based on heading from the center point |
| 254 | | PolarCoor pc; |
| 255 | | |
| 256 | | if (regular) { // Make a regular polygon |
| 257 | | double angle = Math.PI * 2 / nodes.size(); |
| 258 | | pc = new PolarCoor(nodes.get(0).getEastNorth(), center, 0); |
| 259 | | |
| 260 | | if (pc.angle > (new PolarCoor(nodes.get(1).getEastNorth(), center, 0).angle)) { |
| 261 | | angle *= -1; |
| 262 | | } |
| 263 | | |
| 264 | | pc.radius = radius; |
| 265 | | for (Node n : nodes) { |
| 266 | | EastNorth no = pc.toEastNorth(); |
| 267 | | cmds.add(new MoveCommand(n, no.east() - n.getEastNorth().east(), no.north() - n.getEastNorth().north())); |
| 268 | | pc.angle += angle; |
| 269 | | } |
| 270 | | } else { // Move each node to that distance from the center. |
| 271 | | int nodeCount = nodes.size(); |
| 272 | | // Search first fixed node |
| 273 | | int startPosition = 0; |
| 274 | | for(startPosition = 0; startPosition < nodeCount; startPosition++) |
| 275 | | if(isFixNode(nodes.get(startPosition % nodeCount), sel)) break; |
| 276 | | int i = startPosition; // Start position for current arc |
| 277 | | int j; // End position for current arc |
| 278 | | while(i < startPosition + nodeCount) { |
| 279 | | for(j = i + 1; j < startPosition + nodeCount; j++) |
| 280 | | if(isFixNode(nodes.get(j % nodeCount), sel)) break; |
| 281 | | Node first = nodes.get(i % nodeCount); |
| 282 | | PolarCoor pcFirst = new PolarCoor(first.getEastNorth(), center, 0); |
| 283 | | pcFirst.radius = radius; |
| 284 | | cmds.add(pcFirst.createMoveCommand(first)); |
| 285 | | if(j > i + 1) { |
| 286 | | double delta; |
| 287 | | if(j == i + nodeCount) { |
| 288 | | delta = 2 * Math.PI / nodeCount; |
| 289 | | } else { |
| 290 | | PolarCoor pcLast = new PolarCoor(nodes.get(j % nodeCount).getEastNorth(), center, 0); |
| 291 | | delta = pcLast.angle - pcFirst.angle; |
| 292 | | if(delta < 0) // Assume each PolarCoor.angle is in range ]-pi; pi] |
| 293 | | delta += 2*Math.PI; |
| 294 | | delta /= j - i; |
| 295 | | } |
| 296 | | for(int k = i+1; k < j; k++) { |
| 297 | | PolarCoor p = new PolarCoor(radius, pcFirst.angle + (k-i)*delta, center, 0); |
| 298 | | cmds.add(p.createMoveCommand(nodes.get(k % nodeCount))); |
| 299 | | } |
| | 221 | // Move each node to that distance from the center. |
| | 222 | // Nodes that are not "fix" will be adjust making regular arcs. |
| | 223 | int nodeCount = nodes.size(); |
| | 224 | // Search first fixed node |
| | 225 | int startPosition = 0; |
| | 226 | for(startPosition = 0; startPosition < nodeCount; startPosition++) |
| | 227 | if(isFixNode(nodes.get(startPosition % nodeCount), sel)) break; |
| | 228 | int i = startPosition; // Start position for current arc |
| | 229 | int j; // End position for current arc |
| | 230 | while(i < startPosition + nodeCount) { |
| | 231 | for(j = i + 1; j < startPosition + nodeCount; j++) |
| | 232 | if(isFixNode(nodes.get(j % nodeCount), sel)) break; |
| | 233 | Node first = nodes.get(i % nodeCount); |
| | 234 | PolarCoor pcFirst = new PolarCoor(first.getEastNorth(), center, 0); |
| | 235 | pcFirst.radius = radius; |
| | 236 | cmds.add(pcFirst.createMoveCommand(first)); |
| | 237 | if(j > i + 1) { |
| | 238 | double delta; |
| | 239 | if(j == i + nodeCount) { |
| | 240 | delta = 2 * Math.PI / nodeCount; |
| | 241 | } else { |
| | 242 | PolarCoor pcLast = new PolarCoor(nodes.get(j % nodeCount).getEastNorth(), center, 0); |
| | 243 | delta = pcLast.angle - pcFirst.angle; |
| | 244 | if(delta < 0) // Assume each PolarCoor.angle is in range ]-pi; pi] |
| | 245 | delta += 2*Math.PI; |
| | 246 | delta /= j - i; |
| | 261 | * Assuming all ways can be joined into polygon, create an ordered list of node. |
| | 262 | * @param ways List of ways to be joined |
| | 263 | * @return Nodes anticlockwise ordered |
| | 264 | */ |
| | 265 | private List<Node> collectNodesAnticlockwise(List<Way> ways) { |
| | 266 | ArrayList<Node> nodes = new ArrayList<Node>(); |
| | 267 | Node firstNode = ways.get(0).firstNode(); |
| | 268 | Node lastNode = null; |
| | 269 | Way lastWay = null; |
| | 270 | while(firstNode != lastNode) { |
| | 271 | if(lastNode == null) lastNode = firstNode; |
| | 272 | for(Way way: ways) { |
| | 273 | if(way == lastWay) continue; |
| | 274 | if(way.firstNode() == lastNode) { |
| | 275 | List<Node> wayNodes = way.getNodes(); |
| | 276 | for(int i = 0; i < wayNodes.size() - 1; i++) |
| | 277 | nodes.add(wayNodes.get(i)); |
| | 278 | lastNode = way.lastNode(); |
| | 279 | lastWay = way; |
| | 280 | break; |
| | 281 | } |
| | 282 | if(way.lastNode() == lastNode) { |
| | 283 | List<Node> wayNodes = way.getNodes(); |
| | 284 | for(int i = wayNodes.size() - 1; i > 0; i--) |
| | 285 | nodes.add(wayNodes.get(i)); |
| | 286 | lastNode = way.firstNode(); |
| | 287 | lastWay = way; |
| | 288 | break; |
| | 289 | } |
| | 290 | } |
| | 291 | } |
| | 292 | // Check if nodes are in anticlockwise order |
| | 293 | int nc = nodes.size(); |
| | 294 | double area = 0; |
| | 295 | for(int i = 0; i < nc; i++) { |
| | 296 | EastNorth p1 = nodes.get(i).getEastNorth(); |
| | 297 | EastNorth p2 = nodes.get((i+1) % nc).getEastNorth(); |
| | 298 | area += p1.east()*p2.north() - p2.east()*p1.north(); |
| | 299 | } |
| | 300 | if(area < 0) |
| | 301 | Collections.reverse(nodes); |
| | 302 | return nodes; |
| | 303 | } |
| | 304 | |
| | 305 | /** |