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/utilsplugin2/src/utilsplugin2/dumbutils
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • 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.