Ignore:
Timestamp:
31.08.2011 15:29:36 (9 months 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.