From edf4ab3f7d1db7e5945ff78f37cc27baf8e7da8e Mon Sep 17 00:00:00 2001
From: Jiri Vlasak <jiri.hubacek@gmail.com>
Date: Mon, 14 Nov 2022 21:36:59 +0100
Subject: [PATCH 2/2] Add circularize selected ways code

---
 .../josm/actions/AlignInCircleAction.java     | 43 +++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/src/org/openstreetmap/josm/actions/AlignInCircleAction.java b/src/org/openstreetmap/josm/actions/AlignInCircleAction.java
index f3dec3f3db..c68886f6ab 100644
--- a/src/org/openstreetmap/josm/actions/AlignInCircleAction.java
+++ b/src/org/openstreetmap/josm/actions/AlignInCircleAction.java
@@ -149,6 +149,9 @@ public final class AlignInCircleAction extends JosmAction {
      * <p>
      * Case 3: Only nodes are selected
      * --&gt; Align these nodes, all are fix
+     * <p>
+     * Case 4: Circularize selected ways
+     * --&gt; Circularize each way of the selection.
      * @param ds data set in which the command operates
      * @return the resulting command to execute to perform action, or null if nothing was changed
      * @throws InvalidSelection if selection cannot be used
@@ -226,6 +229,46 @@ public final class AlignInCircleAction extends JosmAction {
             }
             fixNodes.addAll(onWay);
             nodes = collectNodesAnticlockwise(ways);
+        } else if (!ways.isEmpty() && selectedNodes.isEmpty()) {
+            center = null;
+            radius = 0;
+            List<Command> rcmds = new LinkedList<>();
+            for (Way w : ways) {
+                if (!w.isDeleted() && w.isArea()) {
+                    List<Node> wnodes = w.getNodes();
+                    wnodes.remove(wnodes.size() - 1);
+                    if (validateGeometry(wnodes)) {
+                        center = Geometry.getCenter(wnodes);
+                    }
+                    if (center == null) {
+                        continue;
+                    }
+                    boolean skip_this_way = false;
+                    radius = 0;
+                    for (Node n : wnodes) {
+                        if (!n.isLatLonKnown()) {
+                            skip_this_way = true;
+                            break;
+                        } else {
+                            radius += center.distance(n.getEastNorth());
+                        }
+                    }
+                    if (skip_this_way) {
+                        continue;
+                    } else {
+                        radius /= wnodes.size();
+                    }
+                    Command c = moveNodesCommand(
+                            wnodes, new HashSet<Node>(), center, radius);
+                    if (c != null) {
+                        rcmds.add(c);
+                    }
+                }
+            }
+            if (rcmds.isEmpty()) {
+                return null;
+            }
+            return new SequenceCommand(tr("Align each Way in Circle"), rcmds);
         } else {
             throw new InvalidSelection();
         }
-- 
2.30.2

