Changeset 1785 in josm


Ignore:
Timestamp:
2009-07-14T10:26:31+02:00 (15 years ago)
Author:
stoecker
Message:

applied #2941 - patch by cjw - improve relation sorting

Location:
trunk/src/org/openstreetmap/josm/gui/dialogs/relation
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java

    r1784 r1785  
    1919import java.util.Arrays;
    2020import java.util.Collection;
     21import java.util.LinkedList;
     22import java.util.Vector;
    2123
    2224import javax.swing.JDialog;
     
    365367
    366368    private void sort() {
    367         java.util.HashMap<Node, java.util.TreeSet<Integer>>   points =
    368             new java.util.HashMap<Node, java.util.TreeSet<Integer>>();
    369         java.util.HashMap<Node, Integer>   nodes =
    370             new java.util.HashMap<Node, Integer>();
    371         int                                i;
    372         boolean                            lastWayStartUsed = true;
    373 
    374         // TODO: sort only selected rows
    375 
    376         for (i = 1; i < getClone().members.size(); ++i)
     369        RelationNodeMap                    map = new RelationNodeMap(getClone());
     370        Vector<LinkedList<Integer>>        segments;
     371        LinkedList<Integer>                segment;
     372        Node                               startSearchNode;
     373        Node                               endSearchNode;
     374        boolean                            something_done;
     375
     376        /*
     377         * sort any 2 or more connected elements together
     378         * may be slow with many unconnected members
     379         * TODO: cleanup again, too much code in 1 method
     380         */
     381
     382        segments = new Vector<LinkedList<Integer>>();
     383        // add first member of relation, not strictly necessary
     384        if (map.remove(0, getClone().members.get(0)))
    377385        {
    378             RelationMember  m = getClone().members.get(i);
    379             if (m.member.incomplete)
    380                 // TODO: emit some message that sorting failed
    381                 return;
    382             try
     386            segment = new LinkedList<Integer>();
     387            segment.add(Integer.valueOf(0));
     388            segments.add(segment);
     389        }
     390        while (!map.isEmpty())
     391        {
     392            segment = segments.lastElement();
     393
     394            do
    383395            {
    384                 Way w = (Way)m.member;
    385                 if (!points.containsKey(w.firstNode()))
     396                something_done = false;
     397                startSearchNode = null;
     398                endSearchNode = null;
     399                if (segment.size() == 1)
    386400                {
    387                     points.put(w.firstNode(), new java.util.TreeSet<Integer>());
    388                 }
    389                 points.get(w.firstNode()).add(Integer.valueOf(i));
    390 
    391                 if (!points.containsKey(w.lastNode()))
    392                 {
    393                     points.put(w.lastNode(), new java.util.TreeSet<Integer>());
    394                 }
    395                 points.get(w.lastNode()).add(Integer.valueOf(i));
    396             }
    397             catch(ClassCastException e1)
    398             {
    399                 try
    400                 {
    401                     Node        n = (Node)m.member;
    402                     nodes.put(n, Integer.valueOf(i));
    403                 }
    404                 catch(ClassCastException e2)
    405                 {
    406                     System.err.println("relation member sort: member " + i + " is not a way or node");
    407                     return;
    408                 }
    409             }
    410         }
    411 
    412         for (i = 0; i < getClone().members.size(); ++i)
    413         {
    414             RelationMember  m = getClone().members.get(i);
    415             Integer         m2 = null;
    416             Node            searchNode = null;
    417             try
    418             {
    419                 Way             w = (Way)m.member;
    420 
    421                 if (lastWayStartUsed || ((i == 0) && !m.role.equals("backward")))
    422                 {
    423                     // try end node
    424                     searchNode = w.lastNode();
    425                 }
    426                 else /* if ((m2 == null) && (!lastWayStartUsed || (i == 0))) */
    427                 {
    428                     searchNode = w.firstNode();
    429                 }
    430             }
    431             catch(ClassCastException e1)
    432             {
    433                 try
    434                 {
    435                     Node n = (Node)m.member;
    436                     searchNode = n;
    437                 }
    438                 catch(ClassCastException e2)
    439                 {
    440                     // impossible
    441                 }
    442             }
    443 
    444             try {
    445                 m2 = nodes.get(searchNode);
    446                 if (m2 == null)
    447                 {
    448                     m2 = points.get(searchNode).first();
    449                     if (m.member == getClone().members.get(m2).member)
     401                    RelationMember  m = getClone().members.get(segment.getFirst());
     402                    try
    450403                    {
    451                         m2 = points.get(searchNode).last();
    452                     }
    453                 }
    454             } catch(NullPointerException f) {}
    455             catch(java.util.NoSuchElementException e) {}
    456 
    457             if ((m2 == null) && ((i+1) < getClone().members.size()))
    458             {
    459                 // TODO: emit some message that sorting failed
    460                 System.err.println("relation member sort: could not find linked way or node for member " + i);
    461                 break;
    462             }
    463 
    464             if (m2 != null)
    465             {
    466                 try
    467                 {
    468                     Way next = (Way)getClone().members.get(m2).member;
    469                     lastWayStartUsed = searchNode.equals(next.firstNode());
    470                 }
    471                 catch(ClassCastException e)
    472                 {
    473                 }
    474 
    475                 if ((m2 < getClone().members.size()) && ((i+1) < getClone().members.size()))
    476                 {
    477                     RelationMember  a = getClone().members.get(i+1);
    478                     RelationMember  b = getClone().members.get(m2);
    479 
    480                     if (m2 != (i+1))
     404                        Way             w = (Way)m.member;
     405                        endSearchNode = w.lastNode();
     406                        startSearchNode = w.firstNode();
     407                    }
     408                    catch(ClassCastException e1)
    481409                    {
    482                         getClone().members.set(i+1, b);
    483                         getClone().members.set(m2, a);
    484 
    485410                        try
    486411                        {
    487                             if (!points.get(((Way)b.member).firstNode()).remove(m2))
    488                             {
    489                                 System.err.println("relation member sort: could not remove start mapping for " + m2);
    490                             }
    491                             if (!points.get(((Way)b.member).lastNode()).remove(m2))
    492                             {
    493                                 System.err.println("relation member sort: could not remove end mapping for " + m2);
    494                             }
    495                         }
    496                         catch(ClassCastException e1)
     412                            Node n = (Node)m.member;
     413                            endSearchNode = n;
     414                        }
     415                        catch(ClassCastException e2)
    497416                        {
    498                             nodes.remove(b.member);
    499                         }
    500 
     417                            // impossible
     418                        }
     419                    }
     420                }
     421                else
     422                {
     423                    // add unused node of first element and unused node of last element
     424                    // start with the first element
     425                    RelationMember element = getClone().members.get(segment.getFirst());
     426                    RelationMember other_element = getClone().members.get(segment.get(1));
     427
     428                    try
     429                    {
     430                        Way w = (Way)element.member;
    501431                        try
    502432                        {
    503                             points.get(((Way)a.member).firstNode()).add(m2);
    504                             points.get(((Way)a.member).lastNode()).add(m2);
    505                         }
    506                         catch(ClassCastException e1)
     433                            Way x = (Way)other_element.member;
     434                            if ((w.firstNode() == x.firstNode()) || (w.firstNode() == x.lastNode()))
     435                            {
     436                                startSearchNode = w.lastNode();
     437                            }
     438                            else
     439                            {
     440                                startSearchNode = w.firstNode();
     441                            }
     442                        }
     443                        catch(ClassCastException e3)
    507444                        {
    508                             nodes.put((Node)a.member, m2);
    509                         }
    510                     }
     445                            try
     446                            {
     447                                Node m = (Node)other_element.member;
     448                                if (w.firstNode() == m)
     449                                {
     450                                    startSearchNode = w.lastNode();
     451                                }
     452                                else
     453                                {
     454                                    startSearchNode = w.firstNode();
     455                                }
     456                            }
     457                            catch(ClassCastException e4)
     458                            {
     459                                // impossible
     460                            }
     461                        }
     462                    }
     463                    catch(ClassCastException e1)
     464                    {
     465                        try
     466                        {
     467                            Node n = (Node)element.member;
     468                            startSearchNode = n;
     469                        }
     470                        catch(ClassCastException e2)
     471                        {
     472                            // impossible
     473                        }
     474                    }
     475                    // now the same for the last element
     476                    element = getClone().members.get(segment.getLast());
     477                    other_element = getClone().members.get(segment.get(segment.size() - 2));
     478
    511479                    try
    512480                    {
    513                         if (!points.get(((Way)a.member).firstNode()).remove(i+1))
     481                        Way w = (Way)element.member;
     482                        try
    514483                        {
    515                             System.err.println("relation member sort: could not remove start mapping for " + (i+1));
    516                         }
    517                         if (!points.get(((Way)a.member).lastNode()).remove(i+1))
     484                            Way x = (Way)other_element.member;
     485                            if ((w.firstNode() == x.firstNode()) || (w.firstNode() == x.lastNode()))
     486                            {
     487                                endSearchNode = w.lastNode();
     488                            }
     489                            else
     490                            {
     491                                endSearchNode = w.firstNode();
     492                            }
     493                        }
     494                        catch(ClassCastException e3)
    518495                        {
    519                             System.err.println("relation member sort: could not remove end mapping for " + (i+1));
     496                            try
     497                            {
     498                                Node m = (Node)other_element.member;
     499                                if (w.firstNode() == m)
     500                                {
     501                                    endSearchNode = w.lastNode();
     502                                }
     503                                else
     504                                {
     505                                    endSearchNode = w.firstNode();
     506                                }
     507                            }
     508                            catch(ClassCastException e4)
     509                            {
     510                                // impossible
     511                            }
    520512                        }
    521513                    }
    522514                    catch(ClassCastException e1)
    523515                    {
    524                         nodes.remove(a.member);
    525                     }
    526                 }
    527             }
    528         }
     516                        try
     517                        {
     518                            Node n = (Node)element.member;
     519                            endSearchNode = n;
     520                        }
     521                        catch(ClassCastException e2)
     522                        {
     523                            // impossible
     524                        }
     525                    }
     526                }
     527
     528                // let's see if we can find connected elements for endSearchNode and startSearchNode
     529                if (startSearchNode != null)
     530                {
     531                    Integer m2 = map.find(startSearchNode, segment.getFirst());
     532                    if (m2 != null)
     533                    {
     534                        segment.add(0, m2);
     535                        map.remove(m2, getClone().members.get(m2));
     536                        something_done = true;
     537                    }
     538                }
     539                if (endSearchNode != null)
     540                {
     541                    Integer m2 = map.find(endSearchNode, segment.getLast());
     542                    if (m2 != null)
     543                    {
     544                        segment.add(segment.size(), m2);
     545                        map.remove(m2, getClone().members.get(m2));
     546                        something_done = true;
     547                    }
     548                }
     549            } while (something_done);
     550
     551            Integer next = map.pop();
     552            if (next == null)
     553            {
     554                break;
     555            }
     556
     557            segment = new LinkedList<Integer>();
     558            segment.add(next);
     559            segments.add(segment);
     560        }
     561        // append map.remaining() to segments list (as a single segment)
     562        segment = new LinkedList<Integer>();
     563        segment.addAll(map.getRemaining());
     564        segments.add(segment);
     565
     566        // now we need to actually re-order the relation members
     567        ArrayList<RelationMember>  newmembers = new ArrayList<RelationMember>();
     568        for (LinkedList<Integer> segment2 : segments)
     569        {
     570            for (Integer p : segment2)
     571            {
     572                newmembers.add(getClone().members.get(p));
     573            }
     574        }
     575        getClone().members.clear();
     576        getClone().members.addAll(newmembers);
     577
    529578        refreshTables();
    530579    }
     
    651700                Node way2first = ((Way)(way2.member)).firstNode();
    652701                Node way2last = ((Way)(way2.member)).lastNode();
     702                /*
    653703                if (way1.role.equals("forward")) {
    654704                    way1first = null;
     
    661711                    way2first = null;
    662712                }
    663 
     713                 */
    664714                if (way1first != null && way2first != null && way1first.equals(way2first)) {
    665715                    link = WayConnectionType.tail_to_tail;
Note: See TracChangeset for help on using the changeset viewer.