Ticket #6251: multiDownload.patch
| File multiDownload.patch, 18.0 KB (added by , 15 years ago) |
|---|
-
src/org/openstreetmap/josm/actions/DownloadPrimitiveAction.java
8 8 import java.awt.GridBagLayout; 9 9 import java.awt.event.ActionEvent; 10 10 import java.awt.event.KeyEvent; 11 import java.util.List; 12 import javax.swing.ComboBoxModel; 11 13 12 14 import javax.swing.JCheckBox; 13 15 import javax.swing.JLabel; … … 19 21 import org.openstreetmap.josm.actions.downloadtasks.DownloadPrimitiveTask; 20 22 import org.openstreetmap.josm.actions.downloadtasks.DownloadReferrersTask; 21 23 import org.openstreetmap.josm.data.osm.DataSet; 24 import org.openstreetmap.josm.data.osm.Node; 22 25 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 23 26 import org.openstreetmap.josm.data.osm.SimplePrimitiveId; 24 27 import org.openstreetmap.josm.gui.ExtendedDialog; 28 import org.openstreetmap.josm.gui.io.DownloadPrimitivesTask; 25 29 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 30 import org.openstreetmap.josm.gui.widgets.HtmlPanel; 26 31 import org.openstreetmap.josm.gui.widgets.OsmIdTextField; 27 32 import org.openstreetmap.josm.gui.widgets.OsmPrimitiveTypesComboBox; 33 import org.openstreetmap.josm.io.MultiFetchServerObjectReader; 28 34 import org.openstreetmap.josm.tools.Shortcut; 29 35 30 36 /** … … 51 57 GridBagConstraints gc = new GridBagConstraints(); 52 58 gc.fill = GridBagConstraints.HORIZONTAL; 53 59 gc.anchor = GridBagConstraints.FIRST_LINE_START; 54 gc.gridy = 0; 55 gc.weightx = 0; 56 all.add(new JLabel(tr("Object type:")), gc); 60 gc.gridy = 0; gc.gridwidth=0; gc.weightx = 0; 61 all.add(new HtmlPanel(tr("Please choose defalt primitive type and enter primitives numbers<br/>" 62 + " Examples: <b><ul><li>1 2 5</li><li>1, 2, 5</li><li>123,v2 123,v1</li></ul><br/></b>" 63 + " It is also possible to specify primitive types in the list: <b>w123, n110, w12, r15</b><br/>" 64 + " v-words are ignored for copy-paste from openstreetmap.org<br/><br/>")), gc); 65 gc.gridwidth=1; gc.weightx = 0; gc.gridy = 1; gc.gridx = 0; 66 all.add(new JLabel(tr("Object type:")),gc); 57 67 OsmPrimitiveTypesComboBox cbType = new OsmPrimitiveTypesComboBox(); 68 cbType.addItem(new SimpleListItem("auto", tr("Auto"))); 58 69 cbType.setToolTipText(tr("Choose the OSM object type")); 59 gc.weightx = 1; 70 gc.weightx = 1; gc.gridx = 1; 60 71 all.add(cbType, gc); 61 gc.gridy = 1; 62 gc.weightx = 0; 72 gc.gridy = 2; gc.gridx = 0; gc.weightx = 0; 63 73 all.add(new JLabel(tr("Object ID:")), gc); 64 74 OsmIdTextField tfId = new OsmIdTextField(); 65 75 tfId.setToolTipText(tr("Enter the ID of the object that should be downloaded")); 66 76 // forward the enter key stroke to the download button 67 77 tfId.getKeymap().removeKeyStrokeBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false)); 68 gc. weightx = 1;78 gc.gridx = 1; gc.weightx = 1; 69 79 all.add(tfId, gc); 70 gc.gridy = 2;80 gc.gridy = 3; gc.gridx = 0; 71 81 gc.fill = GridBagConstraints.BOTH; 72 gc.weighty = 1.0; 73 gc.weightx = 0; 82 gc.weighty = 1.0; gc.weightx = 0; 74 83 all.add(referrers, gc); 75 gc.gridy = 3;84 gc.gridy = 4; 76 85 all.add(layer, gc); 77 86 ExtendedDialog dialog = new ExtendedDialog(Main.parent, 78 87 tr("Download object"), … … 92 101 Main.pref.putInteger("downloadprimitive.lasttype", cbType.getSelectedIndex()); 93 102 Main.pref.put("downloadprimitive.referrers", referrers.isSelected()); 94 103 Main.pref.put("download.newlayer", layer.isSelected()); 95 int id = tfId.getOsmId(); 96 if(id <= 0) 104 105 tfId.setType(cbType.getType()); 106 if(tfId.readOsmIds()==false) { 97 107 JOptionPane.showMessageDialog( 98 108 Main.parent, 99 tr("Invalid ID specified. Cannot download object."), 109 tr("Invalid ID list specified\n" 110 + " Cannot download object."), 100 111 tr("Information"), 101 112 JOptionPane.INFORMATION_MESSAGE 102 113 ); 103 else 104 download(layer.isSelected(), cbType.getType(), id, referrers.isSelected()); 114 return; 115 } 116 117 processItems(layer.isSelected(), cbType.getType(),tfId.getNodeIds(), 118 tfId.getWayIds(), tfId.getRelIds(), referrers.isSelected()); 105 119 } 106 107 /** 108 * Download the given primitive. 109 */ 110 public void download(boolean newLayer, OsmPrimitiveType type, int id, boolean downloadReferrers) { 120 121 void processItems(boolean newLayer, OsmPrimitiveType type, 122 List<Long> nodeIds,List<Long> wayIds,List<Long> relIds, 123 boolean downloadReferrers) { 124 System.out.println(nodeIds); 125 System.out.println(wayIds); 126 System.out.println(relIds); 111 127 OsmDataLayer layer = getEditLayer(); 112 if ((layer == null) || newLayer) { 113 layer = new OsmDataLayer(new DataSet(), OsmDataLayer.createNewName(), null); 114 Main.main.addLayer(layer); 115 } 116 Main.worker.submit(new DownloadPrimitiveTask(new SimplePrimitiveId(id, type), layer)); 117 if (downloadReferrers) { 118 Main.worker.submit(new DownloadReferrersTask(layer, id, type)); 119 } 128 if ((layer == null) || newLayer) { 129 layer = new OsmDataLayer(new DataSet(), OsmDataLayer.createNewName(), null); 130 Main.main.addLayer(layer); 131 } 132 Main.worker.submit(new DownloadPrimitivesTask(layer, nodeIds, wayIds, relIds,downloadReferrers)); 120 133 } 134 135 private void processMixedItems(boolean selected, OsmPrimitiveType osmPrimitiveType, int[] type, boolean osmIds) { 136 throw new UnsupportedOperationException("Not yet implemented"); 137 } 138 139 private static class SimpleListItem { 140 final String data; 141 final String text; 142 public SimpleListItem(String data, String text) { this.data = data; this.text = text; } 143 @Override public String toString() { return text; } 144 } 121 145 } -
src/org/openstreetmap/josm/gui/widgets/OsmIdTextField.java
1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.gui.widgets; 3 3 4 import java.util.ArrayList; 5 import java.util.Arrays; 6 import java.util.List; 7 import java.util.StringTokenizer; 4 8 import static org.openstreetmap.josm.tools.I18n.tr; 5 9 6 10 import javax.swing.JTextField; 7 11 import javax.swing.text.JTextComponent; 12 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 8 13 9 14 /** 10 15 * @author Matthias Julius … … 17 22 validator = OsmIdValidator.decorate(this); 18 23 } 19 24 20 public int getOsmId() { 25 public void setType(OsmPrimitiveType type) { 26 validator.type = type; 27 } 28 29 public long getOsmId() { 21 30 return validator.getOsmId(); 22 31 } 23 32 24 33 /** 34 * Get entered ID list - supports "1,2,3" "1 2 ,3" or even "1 2 3 v2 6 v8" 35 * @return array of id's 36 */ 37 public List<Long> getNodeIds() { 38 return validator.nodeIds; 39 } 40 41 public List<Long> getWayIds() { 42 return validator.wayIds; 43 } 44 45 public List<Long> getRelIds() { 46 return validator.relIds; 47 } 48 49 public boolean readOsmIds() { 50 return validator.readOsmIds(); 51 } 52 53 54 /** 25 55 * Validator for a changeset ID entered in a {@see JTextComponent}. 26 56 * 27 57 */ … … 31 61 return new OsmIdValidator(tc); 32 62 } 33 63 64 private List<Long> nodeIds=new ArrayList<Long>(); 65 private List<Long> wayIds=new ArrayList<Long>(); 66 private List<Long> relIds=new ArrayList<Long>(); 67 private OsmPrimitiveType type; 68 34 69 public OsmIdValidator(JTextComponent tc) { 35 70 super(tc, false); 36 71 } 37 72 38 73 @Override 39 74 public boolean isValid() { 40 return getOsmId() > 0 ;75 return getOsmId() > 0 || readOsmIds()!=false; 41 76 } 42 77 43 78 @Override … … 49 84 } 50 85 } 51 86 52 public intgetOsmId() {87 public long getOsmId() { 53 88 String value = getComponent().getText(); 54 89 if (value == null || value.trim().length() == 0) return 0; 55 90 try { 56 int osmId = Integer.parseInt(value.trim());91 long osmId = Long.parseLong(value.trim()); 57 92 if (osmId > 0) return osmId; 58 93 return 0; 59 94 } catch(NumberFormatException e) { 60 95 return 0; 61 96 } 62 97 } 98 public boolean readOsmIds() { 99 String value = getComponent().getText(); 100 char c; 101 if (value == null || value.trim().length() == 0) return false; 102 try { 103 nodeIds.clear(); wayIds.clear(); relIds.clear(); 104 //String[] parts = value.split("[,\\.\\s\\t\\n]+"); 105 StringTokenizer st = new StringTokenizer(value,",.+/ \t\n"); 106 String s; 107 while (st.hasMoreTokens()) { 108 s = st.nextToken(); 109 // convert tokens to int skipping v-words (version v2 etc) 110 c = s.charAt(0); 111 if (c=='v') continue; 112 if (c=='n') nodeIds.add(Long.parseLong(s.substring(1))); else 113 if (c=='w') wayIds.add(Long.parseLong(s.substring(1))); else 114 if (c=='r') relIds.add(Long.parseLong(s.substring(1))); else 115 if (type==OsmPrimitiveType.NODE) nodeIds.add(Long.parseLong(s)); else 116 if (type==OsmPrimitiveType.WAY) wayIds.add(Long.parseLong(s)); else 117 if (type==OsmPrimitiveType.RELATION) relIds.add(Long.parseLong(s)); 118 } 119 return true; 120 } catch(NumberFormatException e) { 121 return false; 122 } 123 } 63 124 } 64 125 } -
src/org/openstreetmap/josm/gui/widgets/OsmPrimitiveTypesComboBox.java
18 18 } 19 19 20 20 public OsmPrimitiveType getType() { 21 return (OsmPrimitiveType)this.getSelectedItem(); 21 try { 22 return (OsmPrimitiveType)this.getSelectedItem(); 23 } catch (Exception e) { 24 return null; 25 } 22 26 } 23 27 } -
src/org/openstreetmap/josm/gui/io/DownloadPrimitivesTask.java
1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.gui.io; 3 4 import static org.openstreetmap.josm.tools.CheckParameterUtil.ensureParameterNotNull; 5 import static org.openstreetmap.josm.tools.I18n.tr; 6 7 import java.io.IOException; 8 import java.lang.reflect.InvocationTargetException; 9 import java.util.Collection; 10 import java.util.Collections; 11 import java.util.List; 12 import java.util.logging.Logger; 13 14 import javax.swing.SwingUtilities; 15 16 import org.openstreetmap.josm.data.osm.DataSet; 17 import org.openstreetmap.josm.data.osm.DataSetMerger; 18 import org.openstreetmap.josm.data.osm.Node; 19 import org.openstreetmap.josm.data.osm.OsmPrimitive; 20 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 21 import org.openstreetmap.josm.data.osm.Relation; 22 import org.openstreetmap.josm.data.osm.Way; 23 import org.openstreetmap.josm.gui.ExceptionDialogUtil; 24 import org.openstreetmap.josm.gui.PleaseWaitRunnable; 25 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 26 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 27 import org.openstreetmap.josm.io.MultiFetchServerObjectReader; 28 import org.openstreetmap.josm.io.OsmServerObjectReader; 29 import org.openstreetmap.josm.io.OsmTransferException; 30 import org.xml.sax.SAXException; 31 32 /** 33 * The asynchronous task for updating a collection of objects using multi fetch. 34 * 35 */ 36 public class DownloadPrimitivesTask extends PleaseWaitRunnable { 37 @SuppressWarnings("unused") 38 static private final Logger logger = Logger.getLogger(UpdatePrimitivesTask.class.getName()); 39 40 private DataSet ds; 41 private boolean canceled; 42 private Exception lastException; 43 private List<Long> nodeIds; 44 private List<Long> wayIds; 45 private List<Long> relIds; 46 47 private OsmDataLayer layer; 48 private MultiFetchServerObjectReader multiObjectReader; 49 private OsmServerObjectReader objectReader; 50 private final boolean downloadReferrers; 51 52 /** 53 * Creates the task 54 * 55 * @param layer the layer in which primitives are updated. Must not be null. 56 * @param toUpdate a collection of primitives to update from the server. Set to 57 * the empty collection if null. 58 * @throws IllegalArgumentException thrown if layer is null. 59 */ 60 public DownloadPrimitivesTask(OsmDataLayer layer, List<Long> nodeIds, 61 List<Long> wayIds,List<Long> relIds, boolean downloadReferrers) throws IllegalArgumentException{ 62 super(tr("Download objects"), false /* don't ignore exception */); 63 ensureParameterNotNull(layer, "layer"); 64 this.nodeIds = nodeIds; this.wayIds = wayIds; this.relIds = relIds; 65 this.layer = layer; 66 this.downloadReferrers = downloadReferrers; 67 } 68 69 @Override 70 protected void cancel() { 71 canceled = true; 72 synchronized(this) { 73 if (multiObjectReader != null) { 74 multiObjectReader.cancel(); 75 } 76 if (objectReader != null) { 77 objectReader.cancel(); 78 } 79 } 80 } 81 82 @Override 83 protected void finish() { 84 if (canceled) 85 return; 86 if (lastException != null) { 87 ExceptionDialogUtil.explainException(lastException); 88 return; 89 } 90 Runnable r = new Runnable() { 91 public void run() { 92 layer.mergeFrom(ds); 93 layer.onPostDownloadFromServer(); 94 } 95 }; 96 97 if (SwingUtilities.isEventDispatchThread()) { 98 r.run(); 99 } else { 100 try { 101 SwingUtilities.invokeAndWait(r); 102 } catch(InterruptedException e) { 103 e.printStackTrace(); 104 } catch(InvocationTargetException e) { 105 e.printStackTrace(); 106 } 107 } 108 } 109 110 protected void initMultiFetchReaderWithNodes(MultiFetchServerObjectReader reader) { 111 getProgressMonitor().indeterminateSubTask(tr("Initializing nodes to download ...")); 112 for (Long id : nodeIds) { 113 Node n=(Node) layer.data.getPrimitiveById(id, OsmPrimitiveType.NODE); 114 if (n == null) n=new Node(id); 115 reader.append(n); 116 } 117 } 118 119 protected void initMultiFetchReaderWithWays(MultiFetchServerObjectReader reader) { 120 getProgressMonitor().indeterminateSubTask(tr("Initializing ways to download ...")); 121 for (Long id : wayIds) { 122 Way w=(Way) layer.data.getPrimitiveById(id, OsmPrimitiveType.WAY); 123 if (w == null) w=new Way(id); 124 reader.append(w); 125 } 126 } 127 128 protected void initMultiFetchReaderWithRelations(MultiFetchServerObjectReader reader) { 129 getProgressMonitor().indeterminateSubTask(tr("Initializing relations to download ...")); 130 for (Long id : relIds) { 131 Relation r=(Relation) layer.data.getPrimitiveById(id, OsmPrimitiveType.RELATION); 132 if (r == null) r=new Relation(id); 133 reader.append(r); 134 } 135 } 136 137 @Override 138 protected void realRun() throws SAXException, IOException, OsmTransferException { 139 this.ds = new DataSet(); 140 DataSet theirDataSet; 141 try { 142 synchronized(this) { 143 if (canceled) return; 144 multiObjectReader = new MultiFetchServerObjectReader(); 145 } 146 initMultiFetchReaderWithNodes(multiObjectReader); 147 initMultiFetchReaderWithWays(multiObjectReader); 148 initMultiFetchReaderWithRelations(multiObjectReader); 149 theirDataSet = multiObjectReader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); 150 synchronized(this) { 151 multiObjectReader = null; 152 } 153 DataSetMerger merger = new DataSetMerger(ds, theirDataSet); 154 merger.merge(); 155 // a way loaded with MultiFetch may have incomplete nodes because at least one of its 156 // nodes isn't present in the local data set. We therefore fully load all 157 // ways with incomplete nodes. 158 // 159 for (Way w : ds.getWays()) { 160 if (canceled) return; 161 if (w.hasIncompleteNodes()) { 162 synchronized(this) { 163 if (canceled) return; 164 objectReader = new OsmServerObjectReader(w.getId(), OsmPrimitiveType.WAY, true /* full */); 165 } 166 theirDataSet = objectReader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); 167 synchronized (this) { 168 objectReader = null; 169 } 170 merger = new DataSetMerger(ds, theirDataSet); 171 merger.merge(); 172 } 173 } 174 } catch(Exception e) { 175 if (canceled) 176 return; 177 lastException = e; 178 } 179 } 180 }
