Changeset 4385 in josm


Ignore:
Timestamp:
2011-08-31T15:29:36+02:00 (8 years ago)
Author:
bastiK
Message:

fixed #6190 - orthogonalize produces strange shapes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/OrthogonalizeAction.java

    r4139 r4385  
    1414import java.util.HashMap;
    1515import java.util.HashSet;
     16import java.util.Iterator;
    1617import java.util.LinkedList;
     18import java.util.List;
     19import java.util.Set;
    1720
    1821import javax.swing.JOptionPane;
     
    161164                    }
    162165                    else if (nodeList.isEmpty()) {
    163                         // collect groups of ways with common nodes and orthogonalize each group separately.
    164                         ArrayList<ArrayList<WayData>> groups = new ArrayList<ArrayList<WayData>>();
    165                         for (WayData w: wayDataList) {
    166                             boolean add = false;
    167                             for (ArrayList<WayData> g: groups) {
    168                                 for (WayData groupedWay: g) {
    169                                     if (!Collections.disjoint(w.way.getNodes(), groupedWay.way.getNodes())) {
    170                                         add = true;
    171                                         break;
    172                                     }
    173                                 }
    174                                 if (add) {
    175                                     g.add(w);
    176                                 }
    177                             }
    178                             if (!add) {
    179                                 ArrayList<WayData> newGroup = new ArrayList<WayData>();
    180                                 newGroup.add(w);
    181                                 groups.add(newGroup);
    182                             }
    183                         }
     166                        List<ArrayList<WayData>> groups = buildGroups(wayDataList);
    184167                        for (ArrayList<WayData> g: groups) {
    185168                            commands.addAll(orthogonalize(g, nodeList));
     
    208191                        tr("Selected Elements cannot be orthogonalized"),
    209192                        JOptionPane.INFORMATION_MESSAGE);
     193            }
     194        }
     195    }
     196   
     197    /**
     198     * Collect groups of ways with common nodes in order to orthogonalize each group separately.
     199     */
     200    private static List<ArrayList<WayData>> buildGroups(ArrayList<WayData> wayDataList) {
     201        List<ArrayList<WayData>> groups = new ArrayList<ArrayList<WayData>>();
     202        Set<WayData> remaining = new HashSet<WayData>(wayDataList);
     203        while (!remaining.isEmpty()) {
     204            ArrayList<WayData> group = new ArrayList<WayData>();
     205            groups.add(group);
     206            Iterator<WayData> it = remaining.iterator();
     207            WayData next = it.next();
     208            it.remove();
     209            extendGroupRec(group, next, new ArrayList<WayData>(remaining));
     210            remaining.removeAll(group);
     211        }
     212        return groups;
     213    }
     214   
     215    private static void extendGroupRec(List<WayData> group, WayData newGroupMember, List<WayData> remaining) {
     216        group.add(newGroupMember);
     217        for (int i = 0; i < remaining.size(); ++i) {
     218            WayData candidate = remaining.get(i);
     219            if (candidate == null) continue;
     220            if (!Collections.disjoint(candidate.way.getNodes(), newGroupMember.way.getNodes())) {
     221                remaining.set(i, null);
     222                extendGroupRec(group, candidate, remaining);
    210223            }
    211224        }
     
    302315            final HashSet<Node> s = new HashSet<Node>(allNodes);
    303316            int s_size = s.size();
    304             for (int dummy = 0; dummy < s_size; ++ dummy) {
     317            for (int dummy = 0; dummy < s_size; ++dummy) {
    305318                if (s.isEmpty()) {
    306319                    break;
     
    522535    /**
    523536     * Recognize angle to be approximately 0, 90, 180 or 270 degrees.
    524      * returns a integral value, corresponding to a counter clockwise turn:
     537     * returns an integral value, corresponding to a counter clockwise turn:
    525538     */
    526539    private static int angleToDirectionChange(double a, double deltaMax) throws RejectedAngleException {
Note: See TracChangeset for help on using the changeset viewer.