Changeset 16290 in osm for applications/editors/josm/plugins/waydownloader/src
- Timestamp:
- 2009-07-03T12:34:14+02:00 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/waydownloader/src/WayDownloaderPlugin.java
r15412 r16290 25 25 /** 26 26 * Plugin class for the Way Downloader plugin 27 * 27 * 28 28 * @author Harry Wood 29 29 */ 30 30 public class WayDownloaderPlugin extends Plugin { 31 31 32 private Way priorConnectedWay = null; 33 private Node selectedNode = null; 34 35 36 /** Plugin constructor called at JOSM startup */ 37 public WayDownloaderPlugin() { 38 //add WayDownloadAction to tools menu 39 MainMenu.add(Main.main.menu.toolsMenu, new WayDownloadAction()); 40 } 41 42 private class WayDownloadAction extends JosmAction implements Runnable { 43 44 /** Set up the action (text appearing on the menu, keyboard shortcut etc */ 45 public WayDownloadAction() { 46 47 super( "Way Download" , 48 "way-download", 49 "Download map data on the end of selected way", 50 Shortcut.registerShortcut("waydownloader:waydownload", "Way Download", KeyEvent.VK_W, Shortcut.GROUP_MENU, Shortcut.SHIFT_DEFAULT), 51 true); 52 } 53 54 /** Called when the WayDownloadAction action is triggered (e.g. user clicked the menu option) */ 55 public void actionPerformed(ActionEvent e) { 56 57 System.out.println("Way Download"); 58 59 String errMsg = null; 60 61 selectedNode = null; 62 Collection<OsmPrimitive> selection = Main.ds.getSelectedNodes(); 63 64 if (selection.size()==0) { 65 selection = Main.ds.getSelectedWays(); 66 if (!workFromWaySelection(selection)) { 67 errMsg = tr("Select a starting node on the end of a way"); 68 } 69 selection = Main.ds.getSelectedNodes(); 70 } 71 72 if ( selection.size()==0 || selection.size()>1 ) { 73 errMsg = tr("Select a starting node on the end of a way"); 74 } else { 75 OsmPrimitive p = selection.iterator().next(); 76 77 78 79 if (!(p instanceof Node)) { 80 errMsg = tr("Select a starting node on the end of a way"); 81 } else { 82 selectedNode = (Node) p; 83 84 85 Main.map.mapView.zoomTo(selectedNode.eastNorth , Main.map.mapView.getScale()); 86 87 //Before downloading. Figure a few things out. 88 //Find connected way 89 ArrayList<Way> connectedWays = findConnectedWays(); 90 91 if (connectedWays.size()==0) { 92 errMsg = tr("Select a starting node on the end of a way"); 93 } else { 94 priorConnectedWay =(Way) connectedWays.get(0); 95 96 //Download a little rectangle around the selected node 97 double latbuffer=0.0003; //TODO make this an option 98 double lonbuffer=0.0005; 99 DownloadOsmTask downloadTask = new DownloadOsmTask(); 100 downloadTask.download( null, 101 selectedNode.coor.lat()-latbuffer, 102 selectedNode.coor.lon()-lonbuffer, 103 selectedNode.coor.lat()+latbuffer, 104 selectedNode.coor.lon()+lonbuffer); 105 106 //The download is scheduled to be executed. 107 //Now schedule the run() method (below) to be executed once that's completed. 108 Main.worker.execute(this); 109 110 } 111 } 112 } 113 114 if(errMsg != null) 115 JOptionPane.showMessageDialog(Main.parent, errMsg); 116 117 118 } 119 120 /** 121 * Logic to excute after the download has happened 122 */ 123 public void run() { 124 //Find ways connected to the node after the download 125 ArrayList<Way> connectedWays = findConnectedWays(); 126 127 String errMsg = null; 128 if (connectedWays.size()==0) { 129 throw new RuntimeException("Way downloader data inconsistency. priorConnectedWay (" + 130 priorConnectedWay.toString() + ") wasn't discovered after download"); 131 132 } else if (connectedWays.size()==1) { 133 //Just one way connecting the node still. Presumably the one which was there before 134 135 //Check if it's just a duplicate node 136 Node dupeNode = duplicateNode(); 137 if (dupeNode!=null) { 138 139 if (JOptionPane.showConfirmDialog(null, "Merge duplicate node?")==JOptionPane.YES_OPTION) { 140 LinkedList<Node> dupeNodes = new LinkedList<Node>(); 141 dupeNodes.add(dupeNode); 142 MergeNodesAction.mergeNodes(dupeNodes, selectedNode); 143 144 connectedWays = findConnectedWays(); //Carry on 145 } 146 147 148 } else { 149 errMsg = tr("Reached the end of the line"); 150 } 151 152 } 153 154 if (connectedWays.size()>2) { 155 //Three or more ways meeting at this node. Means we have a junction. 156 errMsg = tr("Reached a junction"); 157 158 } else if (connectedWays.size()==2) { 159 //Two connected ways (The "normal" way downloading case) 160 //Figure out which of the two is new. 161 System.out.println("connectedWays.toString()=" + connectedWays.toString()); 162 Way wayA = (Way) connectedWays.get(0); 163 Way wayB = (Way) connectedWays.get(1); 164 Way nextWay = wayA; 165 if (priorConnectedWay.equals(wayA)) nextWay = wayB; 166 167 Node nextNode = findOtherEnd(nextWay, selectedNode); 168 169 //Select the next node 170 Main.ds.setSelected(nextNode); 171 172 Main.map.mapView.zoomTo(nextNode.eastNorth , Main.map.mapView.getScale()); 173 174 } 175 if(errMsg != null) 176 JOptionPane.showMessageDialog(Main.parent, errMsg); 177 } 178 } 179 180 /** See if there's another node at the same coordinates. If so return it. Otherwise null */ 181 private Node duplicateNode() { 182 Iterator nodesIter = Main.ds.nodes.iterator(); 183 while (nodesIter.hasNext()) { 184 Node onNode = (Node) nodesIter.next(); 185 if (!onNode.equals(this.selectedNode) 186 && onNode.coor.lat()==selectedNode.coor.lat() 187 && onNode.coor.lon()==selectedNode.coor.lon()) { 188 return onNode; 189 } 190 } 191 return null; 192 } 193 194 /** Given the the node on one end of the way, return the node on the other end */ 195 private Node findOtherEnd(Way way, Node firstEnd) { 196 Node otherEnd = way.nodes.get(0); 197 if (otherEnd.equals(firstEnd)) otherEnd = way.nodes.get(way.nodes.size()-1); 198 return otherEnd; 199 } 200 201 /** find set of ways which have an end on the selectedNode */ 202 private ArrayList<Way> findConnectedWays() { 203 ArrayList<Way> connectedWays = new ArrayList<Way>(); 204 205 //loop through every way 206 Iterator waysIter = Main.ds.ways.iterator(); 207 while (waysIter.hasNext()) { 208 Way onWay = (Way) waysIter.next(); 209 210 211 Object[] nodes = onWay.nodes.toArray(); 212 if (nodes.length<2) { 213 //Should never happen should it? TODO: investigate. For the moment ignore these 214 System.err.println("WayDownloader plugin encountered a way with " + nodes.length + " nodes :" + onWay.toString()); 215 } else { 216 Node firstNode = (Node) nodes[0]; 217 Node lastNode = (Node) nodes[nodes.length-1]; 218 219 if (firstNode.equals(selectedNode) || lastNode.equals(selectedNode)) { 220 //Found it 221 connectedWays.add(onWay); 222 } 223 } 224 } 225 return connectedWays; 226 } 227 228 /** 229 * given a selected way, select a node on the end of the way which is not in a downloaded area 230 * return true if this worked 231 */ 232 private boolean workFromWaySelection(Collection<OsmPrimitive> selection) { 233 234 if (selection.size()>1) { 235 //more than one way selected 236 return false; 237 } else { 238 Way selectedWay = (Way) selection.toArray()[0]; 239 selectedNode = (Node) selectedWay.nodes.get(0); 32 private Way priorConnectedWay = null; 33 private Node selectedNode = null; 34 35 36 /** Plugin constructor called at JOSM startup */ 37 public WayDownloaderPlugin() { 38 //add WayDownloadAction to tools menu 39 MainMenu.add(Main.main.menu.toolsMenu, new WayDownloadAction()); 40 } 41 42 private class WayDownloadAction extends JosmAction implements Runnable { 43 44 /** Set up the action (text appearing on the menu, keyboard shortcut etc */ 45 public WayDownloadAction() { 46 47 super( "Way Download" , 48 "way-download", 49 "Download map data on the end of selected way", 50 Shortcut.registerShortcut("waydownloader:waydownload", "Way Download", KeyEvent.VK_W, Shortcut.GROUP_MENU, Shortcut.SHIFT_DEFAULT), 51 true); 52 } 53 54 /** Called when the WayDownloadAction action is triggered (e.g. user clicked the menu option) */ 55 public void actionPerformed(ActionEvent e) { 56 57 System.out.println("Way Download"); 58 59 String errMsg = null; 60 61 selectedNode = null; 62 Collection<OsmPrimitive> selection = Main.ds.getSelectedNodes(); 63 64 if (selection.size()==0) { 65 selection = Main.ds.getSelectedWays(); 66 if (!workFromWaySelection(selection)) { 67 errMsg = tr("Select a starting node on the end of a way"); 68 } 69 selection = Main.ds.getSelectedNodes(); 70 } 71 72 if ( selection.size()==0 || selection.size()>1 ) { 73 errMsg = tr("Select a starting node on the end of a way"); 74 } else { 75 OsmPrimitive p = selection.iterator().next(); 76 77 78 79 if (!(p instanceof Node)) { 80 errMsg = tr("Select a starting node on the end of a way"); 81 } else { 82 selectedNode = (Node) p; 83 84 85 Main.map.mapView.zoomTo(selectedNode.getEastNorth()); 86 87 //Before downloading. Figure a few things out. 88 //Find connected way 89 ArrayList<Way> connectedWays = findConnectedWays(); 90 91 if (connectedWays.size()==0) { 92 errMsg = tr("Select a starting node on the end of a way"); 93 } else { 94 priorConnectedWay =(Way) connectedWays.get(0); 95 96 //Download a little rectangle around the selected node 97 double latbuffer=0.0003; //TODO make this an option 98 double lonbuffer=0.0005; 99 DownloadOsmTask downloadTask = new DownloadOsmTask(); 100 downloadTask.download( null, 101 selectedNode.getCoor().lat()-latbuffer, 102 selectedNode.getCoor().lon()-lonbuffer, 103 selectedNode.getCoor().lat()+latbuffer, 104 selectedNode.getCoor().lon()+lonbuffer); 105 106 //The download is scheduled to be executed. 107 //Now schedule the run() method (below) to be executed once that's completed. 108 Main.worker.execute(this); 109 } 110 } 111 } 112 113 if(errMsg != null) 114 JOptionPane.showMessageDialog(Main.parent, errMsg); 115 } 116 117 /** 118 * Logic to excute after the download has happened 119 */ 120 public void run() { 121 //Find ways connected to the node after the download 122 ArrayList<Way> connectedWays = findConnectedWays(); 123 124 String errMsg = null; 125 if (connectedWays.size()==0) { 126 throw new RuntimeException("Way downloader data inconsistency. priorConnectedWay (" + 127 priorConnectedWay.toString() + ") wasn't discovered after download"); 128 129 } else if (connectedWays.size()==1) { 130 //Just one way connecting the node still. Presumably the one which was there before 131 132 //Check if it's just a duplicate node 133 Node dupeNode = duplicateNode(); 134 if (dupeNode!=null) { 135 136 if (JOptionPane.showConfirmDialog(null, "Merge duplicate node?")==JOptionPane.YES_OPTION) { 137 LinkedList<Node> dupeNodes = new LinkedList<Node>(); 138 dupeNodes.add(dupeNode); 139 MergeNodesAction.mergeNodes(dupeNodes, selectedNode); 140 141 connectedWays = findConnectedWays(); //Carry on 142 } 143 144 145 } else { 146 errMsg = tr("Reached the end of the line"); 147 } 148 149 } 150 151 if (connectedWays.size()>2) { 152 //Three or more ways meeting at this node. Means we have a junction. 153 errMsg = tr("Reached a junction"); 154 155 } else if (connectedWays.size()==2) { 156 //Two connected ways (The "normal" way downloading case) 157 //Figure out which of the two is new. 158 System.out.println("connectedWays.toString()=" + connectedWays.toString()); 159 Way wayA = (Way) connectedWays.get(0); 160 Way wayB = (Way) connectedWays.get(1); 161 Way nextWay = wayA; 162 if (priorConnectedWay.equals(wayA)) nextWay = wayB; 163 164 Node nextNode = findOtherEnd(nextWay, selectedNode); 165 166 //Select the next node 167 Main.ds.setSelected(nextNode); 168 169 Main.map.mapView.zoomTo(nextNode.getEastNorth()); 170 } 171 if(errMsg != null) 172 JOptionPane.showMessageDialog(Main.parent, errMsg); 173 } 174 } 175 176 /** See if there's another node at the same coordinates. If so return it. Otherwise null */ 177 private Node duplicateNode() { 178 Iterator nodesIter = Main.ds.nodes.iterator(); 179 while (nodesIter.hasNext()) { 180 Node onNode = (Node) nodesIter.next(); 181 if (!onNode.equals(this.selectedNode) 182 && onNode.getCoor().lat()==selectedNode.getCoor().lat() 183 && onNode.getCoor().lon()==selectedNode.getCoor().lon()) { 184 return onNode; 185 } 186 } 187 return null; 188 } 189 190 /** Given the the node on one end of the way, return the node on the other end */ 191 private Node findOtherEnd(Way way, Node firstEnd) { 192 Node otherEnd = way.nodes.get(0); 193 if (otherEnd.equals(firstEnd)) otherEnd = way.nodes.get(way.nodes.size()-1); 194 return otherEnd; 195 } 196 197 /** find set of ways which have an end on the selectedNode */ 198 private ArrayList<Way> findConnectedWays() { 199 ArrayList<Way> connectedWays = new ArrayList<Way>(); 200 201 //loop through every way 202 Iterator waysIter = Main.ds.ways.iterator(); 203 while (waysIter.hasNext()) { 204 Way onWay = (Way) waysIter.next(); 205 206 207 Object[] nodes = onWay.nodes.toArray(); 208 if (nodes.length<2) { 209 //Should never happen should it? TODO: investigate. For the moment ignore these 210 System.err.println("WayDownloader plugin encountered a way with " + nodes.length + " nodes :" + onWay.toString()); 211 } else { 212 Node firstNode = (Node) nodes[0]; 213 Node lastNode = (Node) nodes[nodes.length-1]; 214 215 if (firstNode.equals(selectedNode) || lastNode.equals(selectedNode)) { 216 //Found it 217 connectedWays.add(onWay); 218 } 219 } 220 } 221 return connectedWays; 222 } 223 224 /** 225 * given a selected way, select a node on the end of the way which is not in a downloaded area 226 * return true if this worked 227 */ 228 private boolean workFromWaySelection(Collection<OsmPrimitive> selection) { 229 230 if (selection.size()>1) { 231 //more than one way selected 232 return false; 233 } else { 234 Way selectedWay = (Way) selection.toArray()[0]; 235 selectedNode = (Node) selectedWay.nodes.get(0); 240 236 241 237 if (isDownloaded(selectedNode)) { 242 243 238 selectedNode = findOtherEnd(selectedWay, selectedNode); 239 244 240 if (isDownloaded(selectedNode)) return false; 245 246 247 248 249 250 251 252 253 254 255 256 257 coor.lat()>bounds.min.lat() &&258 node.coor.lat()<bounds.max.lat() &&259 node.coor.lon()>bounds.min.lon() &&260 node.coor.lon()<bounds.max.lon()) {261 262 263 264 265 241 } 242 } 243 Main.ds.setSelected(selectedNode); 244 return true; 245 } 246 247 private boolean isDownloaded(Node node) { 248 Iterator downloadedAreasIter = Main.ds.dataSources.iterator(); 249 while (downloadedAreasIter.hasNext()) { 250 DataSource datasource = (DataSource) downloadedAreasIter.next(); 251 Bounds bounds = datasource.bounds; 252 253 if (node.getCoor().lat()>bounds.min.lat() && 254 node.getCoor().lat()<bounds.max.lat() && 255 node.getCoor().lon()>bounds.min.lon() && 256 node.getCoor().lon()<bounds.max.lon()) { 257 return true; 258 } 259 } 260 return false; 261 } 266 262 }
Note:
See TracChangeset
for help on using the changeset viewer.