Changeset 18613 in osm for applications/editors/josm/plugins/waydownloader/src
- Timestamp:
- 2009-11-15T11:51:34+01:00 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/waydownloader/src/org/openstreetmap/josm/plugins/waydownloader/WayDownloaderPlugin.java
r18417 r18613 7 7 import java.util.ArrayList; 8 8 import java.util.Collection; 9 import java.util.Collections; 9 10 import java.util.LinkedList; 11 import java.util.List; 10 12 import java.util.concurrent.Future; 11 13 … … 16 18 import org.openstreetmap.josm.actions.MergeNodesAction; 17 19 import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask; 20 import org.openstreetmap.josm.command.Command; 18 21 import org.openstreetmap.josm.data.Bounds; 22 import org.openstreetmap.josm.data.osm.BBox; 23 import org.openstreetmap.josm.data.osm.DataSet; 19 24 import org.openstreetmap.josm.data.osm.DataSource; 20 25 import org.openstreetmap.josm.data.osm.Node; 21 26 import org.openstreetmap.josm.data.osm.OsmPrimitive; 22 27 import org.openstreetmap.josm.data.osm.Way; 28 import org.openstreetmap.josm.gui.DefaultNameFormatter; 23 29 import org.openstreetmap.josm.gui.MainMenu; 24 30 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor; … … 47 53 /** Set up the action (text appearing on the menu, keyboard shortcut etc */ 48 54 public WayDownloadAction() { 49 50 super( "Way Download" , 55 super( tr("Way Download") , 51 56 "way-download", 52 "Download map data on the end of selected way",57 tr("Download map data on the end of selected way"), 53 58 Shortcut.registerShortcut("waydownloader:waydownload", "Way Download", KeyEvent.VK_W, Shortcut.GROUP_MENU, Shortcut.SHIFT_DEFAULT), 54 59 true); 55 60 } 56 61 62 protected void showWarningMessage(String msg) { 63 if(msg == null) return; 64 JOptionPane.showMessageDialog( 65 Main.parent, 66 msg, 67 tr("Warning"), 68 JOptionPane.WARNING_MESSAGE 69 ); 70 } 71 72 protected void showErrorMessage(String msg) { 73 if(msg == null) return; 74 JOptionPane.showMessageDialog( 75 Main.parent, 76 msg, 77 tr("Error"), 78 JOptionPane.ERROR_MESSAGE 79 ); 80 } 81 82 protected void showInfoMessage(String msg) { 83 if(msg == null) return; 84 JOptionPane.showMessageDialog( 85 Main.parent, 86 msg, 87 tr("Information"), 88 JOptionPane.INFORMATION_MESSAGE 89 ); 90 } 91 57 92 /** Called when the WayDownloadAction action is triggered (e.g. user clicked the menu option) */ 58 93 public void actionPerformed(ActionEvent e) { 59 60 System.out.println("Way Download");61 62 String errMsg = null;63 64 94 selectedNode = null; 65 95 Collection<OsmPrimitive> selection = Main.main.getCurrentDataSet().getSelectedNodes(); 66 67 96 if (selection.size()==0) { 68 97 selection = Main.main.getCurrentDataSet().getSelectedWays(); 69 98 if (!workFromWaySelection(selection)) { 70 errMsg = tr("Select a starting node on the end of a way"); 99 showWarningMessage(tr("<html>Neither a node nor a way with an endpoint outside of the<br>current download areas is selected.<br>Select a node on the start or end of a way or an entire way first.</html>")); 100 return; 71 101 } 72 102 selection = Main.main.getCurrentDataSet().getSelectedNodes(); 73 103 } 74 104 75 if ( selection.size()==0 || selection.size()>1 ) { 76 errMsg = tr("Select a starting node on the end of a way"); 77 } else { 78 OsmPrimitive p = selection.iterator().next(); 79 80 81 82 if (!(p instanceof Node)) { 83 errMsg = tr("Select a starting node on the end of a way"); 84 } else { 85 selectedNode = (Node) p; 86 87 88 Main.map.mapView.zoomTo(selectedNode.getEastNorth()); 89 90 //Before downloading. Figure a few things out. 91 //Find connected way 92 ArrayList<Way> connectedWays = findConnectedWays(); 93 94 if (connectedWays.size()==0) { 95 errMsg = tr("Select a starting node on the end of a way"); 96 } else { 97 priorConnectedWay =connectedWays.get(0); 98 99 //Download a little rectangle around the selected node 100 double latbuffer=0.0003; //TODO make this an option 101 double lonbuffer=0.0005; 102 DownloadOsmTask downloadTask = new DownloadOsmTask(); 103 final PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(); 104 final Future<?> future = downloadTask.download( 105 false /* no new layer */, 106 new Bounds( 107 selectedNode.getCoor().lat()- latbuffer, 108 selectedNode.getCoor().lon()- lonbuffer, 109 selectedNode.getCoor().lat()+ latbuffer, 110 selectedNode.getCoor().lon()+ lonbuffer 111 ), 112 monitor 113 ); 114 // schedule closing of the progress monitor after the download 115 // job has finished 116 Main.worker.submit( 117 new Runnable() { 118 public void run() { 119 try { 120 future.get(); 121 } catch(Exception e) { 122 e.printStackTrace(); 123 return; 124 } 125 monitor.close(); 126 } 127 } 128 ); 129 //The download is scheduled to be executed. 130 //Now schedule the run() method (below) to be executed once that's completed. 131 Main.worker.execute(this); 105 if ( selection.size()==0 || selection.size()>1 || ! (selection.iterator().next() instanceof Node)) { 106 showWarningMessage(tr("<html>Could not find a unique node to start downloading from.</html>")); 107 return; 108 } 109 110 selectedNode = (Node) selection.iterator().next(); 111 Main.map.mapView.zoomTo(selectedNode.getEastNorth()); 112 113 //Before downloading. Figure a few things out. 114 //Find connected way 115 List<Way> connectedWays = findConnectedWays(selectedNode); 116 if (connectedWays.size()==0) { 117 showWarningMessage( 118 tr("<html>There are no ways connected to node ''{0}''. Aborting.</html>", 119 selectedNode.getDisplayName(DefaultNameFormatter.getInstance())) 120 ); 121 return; 122 } 123 priorConnectedWay =connectedWays.get(0); 124 125 //Download a little rectangle around the selected node 126 double latbuffer=0.0003; //TODO make this an option 127 double lonbuffer=0.0005; 128 DownloadOsmTask downloadTask = new DownloadOsmTask(); 129 final PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(); 130 final Future<?> future = downloadTask.download( 131 false /* no new layer */, 132 new Bounds( 133 selectedNode.getCoor().lat()- latbuffer, 134 selectedNode.getCoor().lon()- lonbuffer, 135 selectedNode.getCoor().lat()+ latbuffer, 136 selectedNode.getCoor().lon()+ lonbuffer 137 ), 138 monitor 139 ); 140 // schedule closing of the progress monitor after the download 141 // job has finished 142 Main.worker.submit( 143 new Runnable() { 144 public void run() { 145 try { 146 future.get(); 147 } catch(Exception e) { 148 e.printStackTrace(); 149 return; 150 } 151 monitor.close(); 152 } 132 153 } 133 } 134 } 135 136 if(errMsg != null) 137 JOptionPane.showMessageDialog(Main.parent, errMsg); 154 ); 155 //The download is scheduled to be executed. 156 //Now schedule the run() method (below) to be executed once that's completed. 157 Main.worker.execute(this); 138 158 } 139 159 … … 143 163 public void run() { 144 164 //Find ways connected to the node after the download 145 ArrayList<Way> connectedWays = findConnectedWays(); 146 147 String errMsg = null; 165 List<Way> connectedWays = findConnectedWays(selectedNode); 166 148 167 if (connectedWays.size()==0) { 149 throw new RuntimeException("Way downloader data inconsistency. priorConnectedWay (" + 150 priorConnectedWay.toString() + ") wasn't discovered after download"); 151 152 } else if (connectedWays.size()==1) { 153 //Just one way connecting the node still. Presumably the one which was there before 154 168 String msg = tr("Way downloader data inconsistency. Prior connected way ''{0}'' wasn''t discovered after download", 169 priorConnectedWay.getDisplayName(DefaultNameFormatter.getInstance()) 170 ); 171 System.err.println(msg); 172 showErrorMessage(msg); 173 return; 174 } 175 176 if (connectedWays.size()==1) { 177 //Just one way connecting still to the node . Presumably the one which was there before 155 178 //Check if it's just a duplicate node 156 Node dupeNode = duplicateNode(); 179 180 Node dupeNode = findDuplicateNode(selectedNode); 157 181 if (dupeNode!=null) { 158 159 if (JOptionPane.showConfirmDialog(null, "Merge duplicate node?")==JOptionPane.YES_OPTION) { 160 LinkedList<Node> dupeNodes = new LinkedList<Node>(); 161 dupeNodes.add(dupeNode); 162 MergeNodesAction.mergeNodes(Main.main.getEditLayer(), 163 dupeNodes, selectedNode); 164 165 connectedWays = findConnectedWays(); //Carry on 182 String msg = tr("<html>There aren''t further connected ways to download.<br>" 183 + "A potential duplicate node of the currently selected node was found, though.<br><br>" 184 + "The currently selected node is ''{0}''<br>" 185 + "The potential duplicate node is ''{1}''<br>" 186 + "Merge the duplicate node onto the currently selected node and continue way downloading?" 187 + "</html>", 188 selectedNode.getDisplayName(DefaultNameFormatter.getInstance()), 189 dupeNode.getDisplayName(DefaultNameFormatter.getInstance()) 190 ); 191 192 int ret = JOptionPane.showConfirmDialog( 193 Main.parent, 194 msg, 195 tr("Merge duplicate node?"), 196 JOptionPane.YES_NO_OPTION, 197 JOptionPane.QUESTION_MESSAGE 198 ); 199 if (ret != JOptionPane.YES_OPTION) 200 return; 201 Command cmd = MergeNodesAction.mergeNodes( 202 Main.main.getEditLayer(), 203 Collections.singletonList(dupeNode), 204 selectedNode 205 ); 206 if (cmd != null) { 207 Main.main.undoRedo.add(cmd); 208 Main.main.getEditLayer().data.setSelected(selectedNode); 166 209 } 167 168 210 connectedWays = findConnectedWays(selectedNode); 169 211 } else { 170 errMsg = tr("Reached the end of the line"); 171 } 172 173 } 174 212 showInfoMessage(tr("<html>No more connected ways to download.</html>")); 213 return; 214 } 215 return; 216 } 217 175 218 if (connectedWays.size()>2) { 176 219 //Three or more ways meeting at this node. Means we have a junction. 177 errMsg = tr("Reached a junction"); 178 179 } else if (connectedWays.size()==2) { 220 String msg = tr( 221 "Node ''{0}'' is a junction with more than 2 connected ways.", 222 selectedNode.getDisplayName(DefaultNameFormatter.getInstance()) 223 ); 224 showWarningMessage(msg); 225 return; 226 } 227 228 if (connectedWays.size()==2) { 180 229 //Two connected ways (The "normal" way downloading case) 181 230 //Figure out which of the two is new. 182 System.out.println("connectedWays.toString()=" + connectedWays.toString());183 231 Way wayA = connectedWays.get(0); 184 232 Way wayB = connectedWays.get(1); … … 190 238 //Select the next node 191 239 Main.main.getCurrentDataSet().setSelected(nextNode); 192 193 240 Main.map.mapView.zoomTo(nextNode.getEastNorth()); 194 241 } 195 if(errMsg != null) 196 JOptionPane.showMessageDialog(Main.parent, errMsg); 197 } 198 } 199 200 /** See if there's another node at the same coordinates. If so return it. Otherwise null */ 201 private Node duplicateNode() { 202 for (Node onNode:Main.main.getCurrentDataSet().getNodes()) { 203 if (!onNode.equals(this.selectedNode) 204 && !onNode.incomplete 205 && onNode.getCoor().lat()==selectedNode.getCoor().lat() 206 && onNode.getCoor().lon()==selectedNode.getCoor().lon()) { 207 return onNode; 208 } 242 } 243 244 @Override 245 protected void updateEnabledState() { 246 setEnabled(getEditLayer() != null); 247 } 248 249 @Override 250 protected void updateEnabledState( 251 Collection<? extends OsmPrimitive> selection) { 252 // do nothing 253 } 254 } 255 256 /** 257 * Check whether there is a potentially duplicate node for <code>referenceNode</code>. 258 * 259 * @param referenceNode the reference node 260 * @return the potential duplicate node. null, if no duplicate found. 261 */ 262 private Node findDuplicateNode(Node referenceNode) { 263 DataSet ds = Main.main.getCurrentDataSet(); 264 List<Node> candidates = ds.searchNodes(new BBox(new Bounds(referenceNode.getCoor(), 0.0003, 0.0005))); 265 for (Node candidate: candidates) { 266 if (!candidate.equals(referenceNode) 267 && !candidate.incomplete 268 && candidate.getCoor().equals(referenceNode.getCoor())) 269 return candidate; 209 270 } 210 271 return null; … … 218 279 } 219 280 220 /** find set of ways which have an end on the selectedNode */ 221 private ArrayList<Way> findConnectedWays() { 222 ArrayList<Way> connectedWays = new ArrayList<Way>(); 223 224 //loop through every way 225 for (Way onWay:Main.main.getCurrentDataSet().getWays()) { 226 if (onWay.getNodesCount() >= 2) { 227 if (onWay.isFirstLastNode(selectedNode)) { 228 //Found it 229 connectedWays.add(onWay); 230 } 281 /** 282 * Replies the list of ways <code>referenceNode</code> is either the first or the 283 * last node in. 284 * 285 * @param referenceNode the reference node 286 * @return the list of ways. May be empty, but null. 287 */ 288 private List<Way> findConnectedWays(Node referenceNode) { 289 List<Way> referers = OsmPrimitive.getFilteredList(referenceNode.getReferrers(), Way.class); 290 ArrayList<Way> connectedWays = new ArrayList<Way>(referers.size()); 291 292 //loop through referers 293 for (Way way: referers) { 294 if (way.getNodesCount() >= 2 && way.isFirstLastNode(referenceNode)) { 295 connectedWays.add(way); 231 296 } 232 297 } … … 239 304 */ 240 305 private boolean workFromWaySelection(Collection<OsmPrimitive> selection) { 241 242 306 if (selection.size() != 1) 243 307 return false; … … 257 321 for (DataSource datasource:Main.main.getCurrentDataSet().dataSources) { 258 322 Bounds bounds = datasource.bounds; 259 260 if (node.getCoor().lat()>bounds.getMin().lat() && 261 node.getCoor().lat()<bounds.getMax().lat() && 262 node.getCoor().lon()>bounds.getMin().lon() && 263 node.getCoor().lon()<bounds.getMax().lon()) { 264 return true; 265 } 323 if (bounds != null && bounds.contains(node.getCoor())) return true; 266 324 } 267 325 return false;
Note:
See TracChangeset
for help on using the changeset viewer.