Changeset 28027 in osm


Ignore:
Timestamp:
2012-03-10T06:18:26+01:00 (13 years ago)
Author:
joshdoe
Message:

utilsplugin2, conflation: better assignment of nodes with Replace Geometry

Move Hungarian code from conflation to utilsplugin2, since the former depends on the latter already.

Location:
applications/editors/josm/plugins
Files:
3 edited
1 moved

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationCandidateList.java

    r27971 r28027  
    1 /*
    2  * To change this template, choose Tools | Templates
    3  * and open the template in the editor.
    4  */
    51package org.openstreetmap.josm.plugins.conflation;
    62
  • applications/editors/josm/plugins/conflation/src/org/openstreetmap/josm/plugins/conflation/ConflationToggleDialog.java

    r27997 r28027  
    11package org.openstreetmap.josm.plugins.conflation;
    22
     3import utilsplugin2.dumbutils.HungarianAlgorithm;
    34import java.awt.BorderLayout;
    45import java.awt.Component;
     
    206207        @Override
    207208        public void actionPerformed(ActionEvent e) {
     209            //FIXME: should layer listen for selection change?
    208210            ConflationCandidate c = conflationLayer.getSelectedCandidate();
     211            if (c.getReferenceLayer() != c.getSubjectLayer()) {
     212                JOptionPane.showMessageDialog(Main.parent, tr("Conflation between layers isn't supported yet."),
     213                        tr("Cannot conflate between layes"), JOptionPane.ERROR_MESSAGE);
     214                return;
     215            }
    209216            if (ReplaceGeometryUtils.replace(c.getReferenceObject(), c.getSubjectObject())) {
    210217                candidates.remove(c);
     
    331338            int n = subjectSelection.size();
    332339            int m = referenceSelection.size();
    333             int maxLen = Math.max(n, m);
    334             double cost[][] = new double[maxLen][maxLen];
     340            double cost[][] = new double[n][m];
    335341
    336342            // calculate cost matrix
     
    345351            OsmPrimitive subObject, refObject;
    346352            candidates.clear();
    347             for (int i = 0; i < maxLen; i++) {
     353            for (int i = 0; i < n; i++) {
    348354                int subIdx = assignment[i][0];
    349355                int refIdx = assignment[i][1];
  • applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/HungarianAlgorithm.java

    r28026 r28027  
    3737 */
    3838
    39 package org.openstreetmap.josm.plugins.conflation;
     39package utilsplugin2.dumbutils;
    4040
    4141import static java.lang.Math.*;
  • applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/ReplaceGeometryUtils.java

    r27997 r28027  
    256256       
    257257        // Prepare a list of nodes that are not used anywhere except in the way
    258         Collection<Node> nodePool = getUnimportantNodes(subjectWay);
     258        List<Node> nodePool = getUnimportantNodes(subjectWay);
    259259
    260260        // And the same for geometry, list nodes that can be freely deleted
    261         Set<Node> geometryPool = new HashSet<Node>();
     261        List<Node> geometryPool = new LinkedList<Node>();
    262262        for( Node node : referenceWay.getNodes() ) {
    263263            List<OsmPrimitive> referrers = node.getReferrers();
    264264            if( node.isNew() && !node.isDeleted() && referrers.size() == 1
    265265                    && referrers.get(0).equals(referenceWay) && !subjectWay.containsNode(node)
    266                     && !hasInterestingKey(node))
     266                    && !hasInterestingKey(node) && !geometryPool.contains(node))
    267267                geometryPool.add(node);
    268268        }
    269269
    270270        // Find new nodes that are closest to the old ones, remove matching old ones from the pool
     271        // Assign node moves with least overall distance moved
    271272        Map<Node, Node> nodeAssoc = new HashMap<Node, Node>();
    272         for( Node n : geometryPool ) {
    273             Node nearest = findNearestNode(n, nodePool);
    274             if( nearest != null ) {
    275                 nodeAssoc.put(n, nearest);
    276                 nodePool.remove(nearest);
    277             }
     273        if (geometryPool.size() > 0 && nodePool.size() > 0) {
     274            int gLen = geometryPool.size();
     275            int nLen = nodePool.size();
     276            double cost[][] = new double[nLen][gLen];
     277
     278            double maxDistance = Double.parseDouble(Main.pref.get("utilsplugin2.replace-geometry.max-distance", "1"));
     279            for (int i = 0; i < nLen; i++) {
     280                for (int j = 0; j < gLen; j++) {
     281                    double d = nodePool.get(i).getCoor().distance(geometryPool.get(j).getCoor());
     282                    if (d > maxDistance)
     283                        cost[i][j] = Double.MAX_VALUE;
     284                    else
     285                        cost[i][j] = d;
     286                }
     287            }
     288            int[][] assignment = HungarianAlgorithm.hgAlgorithm(cost, "min");
     289            for (int i = 0; i < nLen; i++) {
     290                int nIdx = assignment[i][0];
     291                int gIdx = assignment[i][1];
     292                if (cost[nIdx][gIdx] != Double.MAX_VALUE) {
     293                    nodeAssoc.put(geometryPool.get(gIdx), nodePool.get(nIdx));
     294                }
     295            }
     296        }
     297       
     298        // node will be moved, remove from pool
     299        for (Node n : nodeAssoc.values()) {
     300            nodePool.remove(n);
    278301        }
    279302
     
    319342     * @return
    320343     */
    321     protected static Collection<Node> getUnimportantNodes(Way way) {
    322         Set<Node> nodePool = new HashSet<Node>();
     344    protected static List<Node> getUnimportantNodes(Way way) {
     345        List<Node> nodePool = new LinkedList<Node>();
    323346        for (Node n : way.getNodes()) {
    324347            List<OsmPrimitive> referrers = n.getReferrers();
    325348            if (!n.isDeleted() && referrers.size() == 1 && referrers.get(0).equals(way)
    326                     && !hasInterestingKey(n)) {
     349                    && !hasInterestingKey(n) && !nodePool.contains(n)) {
    327350                nodePool.add(n);
    328351            }
Note: See TracChangeset for help on using the changeset viewer.