Ignore:
Timestamp:
2011-10-08T09:33:46+02:00 (13 years ago)
Author:
zverik
Message:

finished SelectHighway

File:
1 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/SelectHighwayAction.java

    r26795 r26799  
    6363    private Set<Way> selectHighwayBetween( Way firstWay, Way lastWay ) {
    6464        int minRank = Math.min(getHighwayRank(firstWay), getHighwayRank(lastWay));
    65         Set<Way> newWays = new HashSet<Way>();
    66         // todo: make two trees and expand them until they touch.
    67         // do not lower highway rank!
    68         JOptionPane.showMessageDialog(Main.parent, "Sorry, two ways are not supported yet", "Select Highway", JOptionPane.ERROR_MESSAGE);
    69         newWays.add(lastWay);
    70         newWays.add(firstWay);
    71         return newWays;
     65        HighwayTree firstTree = new HighwayTree(firstWay, minRank);
     66        HighwayTree secondTree = new HighwayTree(lastWay, minRank);
     67        Way intersection = firstTree.getIntersection(secondTree);
     68        while( intersection == null && (firstTree.canMoveOn() || secondTree.canMoveOn()) ) {
     69            firstTree.processNextLevel();
     70            secondTree.processNextLevel();
     71            intersection = firstTree.getIntersection(secondTree);
     72        }
     73        Set<Way> newWays = new HashSet<Way>();
     74        newWays.addAll(firstTree.getPath(intersection));
     75        newWays.addAll(secondTree.getPath(intersection));
     76        return newWays;
    7277    }
    7378   
    74     private int getHighwayRank( OsmPrimitive way ) {
     79    private static int getHighwayRank( OsmPrimitive way ) {
    7580        if( !way.hasKey("highway") )
    7681            return 0;
     
    116121        setEnabled(count == 1 || (count == 2 && rank > 0));
    117122    }
     123   
     124    private static class HighwayTree {
     125        private List<Way> tree;
     126        private List<Integer> refs;
     127        private List<Node> nodesToCheck;
     128        private List<Integer> nodeRefs;
     129        private int minHighwayRank;
     130
     131        public HighwayTree( Way from, int minHighwayRank ) {
     132            tree = new ArrayList<Way>(1);
     133            refs = new ArrayList<Integer>(1);
     134            tree.add(from);
     135            refs.add(Integer.valueOf(-1));
     136            this.minHighwayRank = minHighwayRank;
     137            nodesToCheck = new ArrayList<Node>(2);
     138            nodeRefs = new ArrayList<Integer>(2);
     139            nodesToCheck.add(from.firstNode());
     140            nodesToCheck.add(from.lastNode());
     141            nodeRefs.add(Integer.valueOf(0));
     142            nodeRefs.add(Integer.valueOf(0));
     143        }
     144       
     145        public void processNextLevel() {
     146            List<Node> newNodes = new ArrayList<Node>();
     147            List<Integer> newIdx = new ArrayList<Integer>();
     148            for( int i = 0; i < nodesToCheck.size(); i++ ) {
     149                Node node = nodesToCheck.get(i);
     150                Integer nodeRef = nodeRefs.get(i);
     151                for( Way way : OsmPrimitive.getFilteredList(node.getReferrers(), Way.class) ) {
     152                    if( (way.firstNode().equals(node) || way.lastNode().equals(node)) &&
     153                        !tree.contains(way) && suits(way) ) {
     154                        tree.add(way);
     155                        refs.add(nodeRef);
     156                        Node newNode = way.firstNode().equals(node) ? way.lastNode() : way.firstNode();
     157                        newNodes.add(newNode);
     158                        newIdx.add(Integer.valueOf(tree.size() - 1));
     159                    }
     160                }
     161            }
     162            nodesToCheck = newNodes;
     163            nodeRefs = newIdx;
     164        }
     165       
     166        private boolean suits( Way w ) {
     167            return getHighwayRank(w) >= minHighwayRank;
     168        }
     169       
     170        public boolean canMoveOn() {
     171            return !nodesToCheck.isEmpty() && tree.size() < 10000;
     172        }
     173       
     174        public Way getIntersection( HighwayTree other ) {
     175            for( Way w : other.tree )
     176                if( tree.contains(w) )
     177                    return w;
     178            return null;
     179        }
     180       
     181        public List<Way> getPath( Way to ) {
     182            if( to == null )
     183                return Collections.singletonList(tree.get(0));
     184            int pos = tree.indexOf(to);
     185            if( pos < 0 )
     186                throw new ArrayIndexOutOfBoundsException("Way " + to + " is not in the tree.");
     187            List<Way> result = new ArrayList<Way>(1);
     188            while( pos >= 0 ) {
     189                result.add(tree.get(pos));
     190                pos = refs.get(pos);
     191            }
     192            return result;
     193        }
     194    }
    118195}
Note: See TracChangeset for help on using the changeset viewer.