Ignore:
Timestamp:
2009-07-08T20:23:47+02:00 (15 years ago)
Author:
stoecker
Message:

applied relation sort - fix #27789 - patch by cjw

File:
1 edited

Legend:

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

    r1706 r1748  
    5050import org.xml.sax.SAXException;
    5151
     52enum WayConnectionType
     53{
     54    none,
     55    head_to_head,
     56    tail_to_tail,
     57    head_to_tail,
     58    tail_to_head;
     59    @Override
     60    public String toString()
     61    {
     62        String  result = "";
     63        switch(this)
     64        {
     65        case head_to_head:
     66            result = "-><-";
     67            break;
     68        case head_to_tail:
     69            result = "->->";
     70            break;
     71        case tail_to_head:
     72            result = "<-<-";
     73            break;
     74        case tail_to_tail:
     75            result = "<-->";
     76            break;
     77        }
     78
     79        return result;
     80    }
     81}
     82
    5283/**
    5384 * This dialog is for editing relations.
     
    236267     */
    237268    private JPanel setupBasicButtons() {
    238         JPanel buttonPanel = new JPanel(new GridLayout(2, 3));
     269        JPanel buttonPanel = new JPanel(new GridLayout(2, 4));
    239270
    240271        buttonPanel.add(createButton(marktr("Move Up"), "moveup", tr("Move the currently selected members up"), KeyEvent.VK_N, new ActionListener() {
     
    255286            public void actionPerformed(ActionEvent e) {
    256287                deleteSelected();
     288            }
     289        }));
     290
     291        buttonPanel.add(createButton(marktr("Sort"), "sort",
     292                tr("Sort the selected relation members or the whole list"), KeyEvent.VK_O, new ActionListener() {
     293            public void actionPerformed(ActionEvent e) {
     294                sort();
    257295            }
    258296        }));
     
    288326        return buttonPanel;
    289327    }
     328
     329    private class NodeCompare implements java.util.Comparator<Node>
     330    {
     331        public int compare(Node a, Node b)
     332        {
     333            int result = 0;
     334
     335            if ((a.id == 0) && (b.id == 0))
     336            {
     337                if (a.getCoor().lat() == b.getCoor().lat())
     338                {
     339                    result = Double.compare(a.getCoor().lon(), b.getCoor().lon());
     340                }
     341                else
     342                {
     343                    result = Double.compare(a.getCoor().lat(), b.getCoor().lat());
     344                }
     345            }
     346            else
     347            {
     348                result = a.compareTo(b);
     349            }
     350
     351            return result;
     352        }
     353    }
     354
     355    private void sort() {
     356        java.util.TreeMap<Node, java.util.TreeSet<Integer>>   points =
     357            new java.util.TreeMap<Node, java.util.TreeSet<Integer>>(new NodeCompare());
     358        java.util.TreeMap<Node, Integer>   nodes =
     359            new java.util.TreeMap<Node, Integer>(new NodeCompare());
     360        int                                i;
     361        boolean                            lastWayStartUsed = true;
     362
     363        // TODO: sort only selected rows
     364
     365        for (i = 1; i < clone.members.size(); ++i)
     366        {
     367            RelationMember  m = clone.members.get(i);
     368            if (m.member.incomplete)
     369            {
     370                // TODO: emit some message that sorting failed
     371                return;
     372            }
     373            try
     374            {
     375                Way w = (Way)m.member;
     376                if (!points.containsKey(w.firstNode()))
     377                {
     378                    points.put(w.firstNode(), new java.util.TreeSet<Integer>());
     379                }
     380                points.get(w.firstNode()).add(Integer.valueOf(i));
     381
     382                if (!points.containsKey(w.lastNode()))
     383                {
     384                    points.put(w.lastNode(), new java.util.TreeSet<Integer>());
     385                }
     386                points.get(w.lastNode()).add(Integer.valueOf(i));
     387            }
     388            catch(ClassCastException e1)
     389            {
     390                try
     391                {
     392                    Node        n = (Node)m.member;
     393                    nodes.put(n, Integer.valueOf(i));
     394                }
     395                catch(ClassCastException e2)
     396                {
     397                    System.err.println("relation member sort: member " + i + " is not a way or node");
     398                    return;
     399                }
     400            }
     401        }
     402
     403        for (i = 0; i < clone.members.size(); ++i)
     404        {
     405            RelationMember  m = clone.members.get(i);
     406            Integer         m2 = null;
     407            Node            searchNode = null;
     408            try
     409            {
     410                Way             w = (Way)m.member;
     411
     412                if (lastWayStartUsed || ((i == 0) && !m.role.equals("backward")))
     413                {
     414                    // try end node
     415                    searchNode = w.lastNode();
     416                }
     417                else /* if ((m2 == null) && (!lastWayStartUsed || (i == 0))) */
     418                {
     419                    searchNode = w.firstNode();
     420                }
     421            }
     422            catch(ClassCastException e1)
     423            {
     424                try
     425                {
     426                    Node n = (Node)m.member;
     427                    searchNode = n;
     428                }
     429                catch(ClassCastException e2)
     430                {
     431                    // impossible
     432                }
     433            }
     434
     435            try {
     436                m2 = nodes.get(searchNode);
     437                if (m2 == null)
     438                {
     439                    m2 = points.get(searchNode).first();
     440                    if (m.member == clone.members.get(m2).member)
     441                    {
     442                        m2 = points.get(searchNode).last();
     443                    }
     444                }
     445            } catch(NullPointerException f) {}
     446            catch(java.util.NoSuchElementException e) {}
     447
     448            if (m2 == null)
     449            {
     450                // TODO: emit some message that sorting failed
     451                System.err.println("relation member sort: could not find linked way or node for member " + i);
     452                System.err.println("last way start used = " + lastWayStartUsed);
     453                break;
     454            }
     455
     456            if (m2 != null)
     457            {
     458                try
     459                {
     460                    Way next = (Way)clone.members.get(m2).member;
     461                    lastWayStartUsed = searchNode.equals(next.firstNode());
     462                }
     463                catch(ClassCastException e)
     464                {
     465                }
     466            }
     467
     468            if ((m2 < clone.members.size()) && ((i+1) < clone.members.size()))
     469            {
     470                RelationMember  a = clone.members.get(i+1);
     471                RelationMember  b = clone.members.get(m2);
     472
     473                if (m2 != (i+1))
     474                {
     475                    System.err.println("swapping " + (i+1) + " and " + m2);
     476                    clone.members.set(i+1, b);
     477                    clone.members.set(m2, a);
     478
     479                    try
     480                    {
     481                        if (!points.get(((Way)b.member).firstNode()).remove(m2))
     482                        {
     483                            System.err.println("relation member sort: could not remove start mapping for " + m2);
     484                        }
     485                        if (!points.get(((Way)b.member).lastNode()).remove(m2))
     486                        {
     487                            System.err.println("relation member sort: could not remove end mapping for " + m2);
     488                        }
     489                    }
     490                    catch(ClassCastException e1)
     491                    {
     492                        nodes.remove(b.member);
     493                    }
     494
     495                    try
     496                    {
     497                        points.get(((Way)a.member).firstNode()).add(m2);
     498                        points.get(((Way)a.member).lastNode()).add(m2);
     499                    }
     500                    catch(ClassCastException e1)
     501                    {
     502                        nodes.put((Node)a.member, m2);
     503                    }
     504                }
     505                try
     506                {
     507                    if (!points.get(((Way)a.member).firstNode()).remove(i+1))
     508                    {
     509                        System.err.println("relation member sort: could not remove start mapping for " + (i+1));
     510                    }
     511                    if (!points.get(((Way)a.member).lastNode()).remove(i+1))
     512                    {
     513                        System.err.println("relation member sort: could not remove end mapping for " + (i+1));
     514                    }
     515                }
     516                catch(ClassCastException e1)
     517                {
     518                    nodes.remove(a.member);
     519                }
     520            }
     521        }
     522
     523        refreshTables();
     524    }
     525
    290526
    291527    /**
     
    324560    private void refreshTables() {
    325561        // re-load property data
     562        int numLinked = 0;
    326563
    327564        propertyData.setRowCount(0);
     
    340577            // (if both are ways) these ways are connected. It should
    341578            // really produce a much more beautiful output (with a linkage
    342             // symbol somehow places betweeen the two member lines!), and
     579            // symbol somehow places between the two member lines!), and
    343580            // it should cache results, so... FIXME ;-)
    344581
    345582            RelationMember em = clone.members.get(i);
    346             boolean linked = false;
     583            WayConnectionType link = WayConnectionType.none;
    347584            RelationMember m = em;
    348585            RelationMember way1 = null;
     
    365602            }
    366603            if (way1 != null) {
    367                 int next = i+1;
    368                 while (next <= clone.members.size()) {
    369                     m = clone.members.get(next == clone.members.size() ? 0 : next);
    370                     next++;
     604                int next = (i+1) % clone.members.size();
     605                while (next != i) {
     606                    m = clone.members.get(next);
     607                    next = (next + 1) % clone.members.size();
    371608                    depth = 0;
    372609                    while (m != null && depth < 10) {
     
    406643
    407644                if (way1first != null && way2first != null && way1first.equals(way2first)) {
    408                     linked = true;
     645                    link = WayConnectionType.tail_to_tail;
    409646                } else if (way1first != null && way2last != null && way1first.equals(way2last)) {
    410                     linked = true;
     647                    link = WayConnectionType.tail_to_head;
    411648                } else if (way1last != null && way2first != null && way1last.equals(way2first)) {
    412                     linked = true;
     649                    link = WayConnectionType.head_to_tail;
    413650                } else if (way1last != null && way2last != null && way1last.equals(way2last)) {
    414                     linked = true;
     651                    link = WayConnectionType.head_to_head;
    415652                }
    416653
    417654                // end of section to determine linkedness.
    418 
    419                 memberData.addRow(new Object[]{em.role, em.member, linked ? tr("yes") : tr("no")});
    420             } else {
    421                 memberData.addRow(new Object[]{em.role, em.member, ""});
    422             }
    423         }
    424         status.setText(tr("Members: {0}", clone.members.size()));
     655                if (link != WayConnectionType.none)
     656                {
     657                    ++numLinked;
     658                }
     659
     660            }
     661            memberData.addRow(new Object[]{em.role, em.member, link});
     662        }
     663        status.setText(tr("Members: {0} (linked: {1})", clone.members.size(), numLinked));
    425664    }
    426665
Note: See TracChangeset for help on using the changeset viewer.