Changeset 2070 in josm for trunk/src/org/openstreetmap
- Timestamp:
- 2009-09-06T23:07:33+02:00 (15 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 12 added
- 76 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/Main.java
r2047 r2070 58 58 import org.openstreetmap.josm.gui.preferences.TaggingPresetPreference; 59 59 import org.openstreetmap.josm.gui.preferences.ToolbarPreferences; 60 import org.openstreetmap.josm.io.IllegalDataException; 60 61 import org.openstreetmap.josm.plugins.PluginHandler; 61 62 import org.openstreetmap.josm.tools.ImageProvider; … … 503 504 OpenFileAction.openFile(f); 504 505 } 506 } catch(IllegalDataException e) { 507 e.printStackTrace(); 508 JOptionPane.showMessageDialog( 509 Main.parent, 510 tr("<html>Could not read file ''{0}\''.<br> Error is: <br>{1}</html>", f.getName(), e.getMessage()), 511 tr("Error"), 512 JOptionPane.ERROR_MESSAGE 513 ); 505 514 }catch(IOException e) { 506 515 e.printStackTrace(); … … 527 536 try { 528 537 OpenFileAction.openFile(f); 538 }catch(IllegalDataException e) { 539 e.printStackTrace(); 540 JOptionPane.showMessageDialog( 541 Main.parent, 542 tr("<html>Could not read file ''{0}\''.<br> Error is: <br>{1}</html>", f.getName(), e.getMessage()), 543 tr("Error"), 544 JOptionPane.ERROR_MESSAGE 545 ); 529 546 }catch(IOException e) { 530 547 e.printStackTrace(); -
trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java
r2032 r2070 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.awt.GridBagLayout;7 6 import java.awt.event.ActionEvent; 8 7 import java.awt.event.KeyEvent; … … 13 12 import java.util.LinkedList; 14 13 import java.util.List; 15 import java.util.ListIterator;16 14 import java.util.Map; 17 15 import java.util.Set; 18 import java.util.TreeMap; 19 import java.util.TreeSet; 20 import java.util.Map.Entry; 21 22 import javax.swing.Box; 23 import javax.swing.JComboBox; 24 import javax.swing.JLabel; 16 import java.util.Stack; 17 25 18 import javax.swing.JOptionPane; 26 import javax.swing. JPanel;19 import javax.swing.SwingUtilities; 27 20 28 21 import org.openstreetmap.josm.Main; … … 31 24 import org.openstreetmap.josm.command.DeleteCommand; 32 25 import org.openstreetmap.josm.command.SequenceCommand; 26 import org.openstreetmap.josm.data.osm.DataSet; 33 27 import org.openstreetmap.josm.data.osm.Node; 34 28 import org.openstreetmap.josm.data.osm.OsmPrimitive; 35 29 import org.openstreetmap.josm.data.osm.Relation; 36 30 import org.openstreetmap.josm.data.osm.RelationMember; 37 import org.openstreetmap.josm.data.osm.TigerUtils; 31 import org.openstreetmap.josm.data.osm.Tag; 32 import org.openstreetmap.josm.data.osm.TagCollection; 38 33 import org.openstreetmap.josm.data.osm.Way; 39 34 import org.openstreetmap.josm.gui.ExtendedDialog; 40 import org.openstreetmap.josm. tools.GBC;35 import org.openstreetmap.josm.gui.conflict.tags.CombineWaysConflictResolverDialog; 41 36 import org.openstreetmap.josm.tools.Pair; 42 37 import org.openstreetmap.josm.tools.Shortcut; … … 45 40 * Combines multiple ways into one. 46 41 * 47 * @author Imi48 42 */ 49 43 public class CombineWayAction extends JosmAction { … … 54 48 } 55 49 56 @SuppressWarnings("unchecked") 50 protected Set<OsmPrimitive> intersect(Set<? extends OsmPrimitive> s1, Set<? extends OsmPrimitive> s2) { 51 HashSet<OsmPrimitive> ret = new HashSet<OsmPrimitive>(s1); 52 ret.retainAll(s2); 53 return ret; 54 } 55 56 protected boolean confirmCombiningWithConflictsInRelationMemberships() { 57 ExtendedDialog ed = new ExtendedDialog(Main.parent, 58 tr("Combine ways with different memberships?"), 59 new String[] {tr("Combine Anyway"), tr("Cancel")}); 60 ed.setButtonIcons(new String[] {"combineway.png", "cancel.png"}); 61 ed.setContent(tr("The selected ways have differing relation memberships. " 62 + "Do you still want to combine them?")); 63 ed.showDialog(); 64 65 return ed.getValue() == 1; 66 } 67 68 protected boolean confirmChangeDirectionOfWays() { 69 ExtendedDialog ed = new ExtendedDialog(Main.parent, 70 tr("Change directions?"), 71 new String[] {tr("Reverse and Combine"), tr("Cancel")}); 72 ed.setButtonIcons(new String[] {"wayflip.png", "cancel.png"}); 73 ed.setContent(tr("The ways can not be combined in their current directions. " 74 + "Do you want to reverse some of them?")); 75 ed.showDialog(); 76 return ed.getValue() == 1; 77 } 78 79 protected void warnCombiningImpossible() { 80 String msg = tr("Could not combine ways " 81 + "(They could not be merged into a single string of nodes)"); 82 JOptionPane.showMessageDialog( 83 Main.parent, 84 msg, //FIXME: not sure whether this fits in a dialog 85 tr("Information"), 86 JOptionPane.INFORMATION_MESSAGE 87 ); 88 return; 89 } 90 91 protected Way getTargetWay(Collection<Way> combinedWays) { 92 // init with an arbitrary way 93 Way targetWay = combinedWays.iterator().next(); 94 95 // look for the first way already existing on 96 // the server 97 for (Way w : combinedWays) { 98 targetWay = w; 99 if (w.getId() != 0) { 100 break; 101 } 102 } 103 return targetWay; 104 } 105 106 protected void completeTagCollectionWithMissingTags(TagCollection tc, Collection<Way> combinedWays) { 107 for (String key: tc.getKeys()) { 108 // make sure the empty value is in the tag set such that we can delete the tag 109 // in the conflict dialog if necessary 110 // 111 tc.add(new Tag(key,"")); 112 for (Way w: combinedWays) { 113 if (w.get(key) == null) { 114 tc.add(new Tag(key)); // add a tag with key and empty value 115 } 116 } 117 } 118 // remove irrelevant tags 119 // 120 tc.removeByKey("created_by"); 121 } 122 123 public void combineWays(Collection<Way> ways) { 124 125 // prepare and clean the list of ways to combine 126 // 127 if (ways == null || ways.isEmpty()) 128 return; 129 ways.remove(null); // just in case - remove all null ways from the collection 130 ways = new HashSet<Way>(ways); // remove duplicates 131 132 // build the list of relations referring to the ways to combine 133 // 134 WayReferringRelations referringRelations = new WayReferringRelations(ways); 135 referringRelations.build(getCurrentDataSet()); 136 137 // build the collection of tags used by the ways to combine 138 // 139 TagCollection wayTags = TagCollection.unionOfAllPrimitives(ways); 140 completeTagCollectionWithMissingTags(wayTags, ways); 141 142 // try to build a new way out of the combination of ways 143 // which are combined 144 // 145 NodeGraph graph = NodeGraph.createDirectedGraphFromWays(ways); 146 List<Node> path = graph.buildSpanningPath(); 147 if (path == null) { 148 graph = NodeGraph.createUndirectedGraphFromNodeWays(ways); 149 path = graph.buildSpanningPath(); 150 if (path != null) { 151 if (!confirmChangeDirectionOfWays()) 152 return; 153 } else { 154 warnCombiningImpossible(); 155 return; 156 } 157 } 158 159 // create the new way and apply the new node list 160 // 161 Way targetWay = getTargetWay(ways); 162 Way modifiedTargetWay = new Way(targetWay); 163 modifiedTargetWay.setNodes(path); 164 165 CombineWaysConflictResolverDialog dialog = CombineWaysConflictResolverDialog.getInstance(); 166 dialog.getTagConflictResolverModel().populate(wayTags); 167 dialog.setTargetWay(targetWay); 168 dialog.getRelationMemberConflictResolverModel().populate( 169 referringRelations.getRelations(), 170 referringRelations.getWays() 171 ); 172 dialog.prepareDefaultDecisions(); 173 174 // resolve tag conflicts if necessary 175 // 176 if (!wayTags.isApplicableToPrimitive() || !referringRelations.getRelations().isEmpty()) { 177 dialog.setVisible(true); 178 if (dialog.isCancelled()) 179 return; 180 } 181 182 183 184 LinkedList<Command> cmds = new LinkedList<Command>(); 185 LinkedList<Way> deletedWays = new LinkedList<Way>(ways); 186 deletedWays.remove(targetWay); 187 188 cmds.add(new DeleteCommand(deletedWays)); 189 cmds.add(new ChangeCommand(targetWay, modifiedTargetWay)); 190 cmds.addAll(dialog.buildResolutionCommands(targetWay)); 191 final SequenceCommand sequenceCommand = new SequenceCommand(tr("Combine {0} ways", ways.size()), cmds); 192 193 // update gui 194 final Way selectedWay = targetWay; 195 Runnable guiTask = new Runnable() { 196 public void run() { 197 Main.main.undoRedo.add(sequenceCommand); 198 getCurrentDataSet().setSelected(selectedWay); 199 } 200 }; 201 if (SwingUtilities.isEventDispatchThread()) { 202 guiTask.run(); 203 } else { 204 SwingUtilities.invokeLater(guiTask); 205 } 206 } 207 208 57 209 public void actionPerformed(ActionEvent event) { 58 210 if (getCurrentDataSet() == null) 59 211 return; 60 212 Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected(); 61 LinkedList<Way> selectedWays = new LinkedList<Way>(); 62 63 for (OsmPrimitive osm : selection) 64 if (osm instanceof Way) { 65 selectedWays.add((Way)osm); 66 } 67 213 Set<Way> selectedWays = OsmPrimitive.getFilteredSet(selection, Way.class); 68 214 if (selectedWays.size() < 2) { 69 215 JOptionPane.showMessageDialog( … … 75 221 return; 76 222 } 77 78 // Check whether all ways have identical relationship membership. More 79 // specifically: If one of the selected ways is a member of relation X 80 // in role Y, then all selected ways must be members of X in role Y. 81 82 // FIXME: In a later revision, we should display some sort of conflict 83 // dialog like we do for tags, to let the user choose which relations 84 // should be kept. 85 86 // Step 1, iterate over all relations and figure out which of our 87 // selected ways are members of a relation. 88 HashMap<Pair<Relation,String>, HashSet<Way>> backlinks = 89 new HashMap<Pair<Relation,String>, HashSet<Way>>(); 90 HashSet<Relation> relationsUsingWays = new HashSet<Relation>(); 91 for (Relation r : getCurrentDataSet().relations) { 92 if (r.isDeleted() || r.incomplete) { 93 continue; 94 } 95 for (RelationMember rm : r.getMembers()) { 96 if (rm.isWay()) { 97 for(Way w : selectedWays) { 98 if (rm.getMember() == w) { 99 Pair<Relation,String> pair = new Pair<Relation,String>(r, rm.getRole()); 100 HashSet<Way> waylinks = new HashSet<Way>(); 101 if (backlinks.containsKey(pair)) { 102 waylinks = backlinks.get(pair); 103 } else { 104 waylinks = new HashSet<Way>(); 105 backlinks.put(pair, waylinks); 106 } 107 waylinks.add(w); 108 109 // this is just a cache for later use 110 relationsUsingWays.add(r); 111 } 112 } 113 } 114 } 115 } 116 117 // Complain to the user if the ways don't have equal memberships. 118 for (HashSet<Way> waylinks : backlinks.values()) { 119 if (!waylinks.containsAll(selectedWays)) { 120 121 ExtendedDialog ed = new ExtendedDialog(Main.parent, 122 tr("Combine ways with different memberships?"), 123 new String[] {tr("Combine Anyway"), tr("Cancel")}); 124 ed.setButtonIcons(new String[] {"combineway.png", "cancel.png"}); 125 ed.setContent(tr("The selected ways have differing relation memberships. " 126 + "Do you still want to combine them?")); 127 ed.showDialog(); 128 129 if (ed.getValue() == 1) { 130 break; 131 } 132 133 return; 134 } 135 } 136 137 // collect properties for later conflict resolving 138 Map<String, Set<String>> props = new TreeMap<String, Set<String>>(); 139 for (Way w : selectedWays) { 140 for (Entry<String,String> e : w.entrySet()) { 141 if (!props.containsKey(e.getKey())) { 142 props.put(e.getKey(), new TreeSet<String>()); 143 } 144 props.get(e.getKey()).add(e.getValue()); 145 } 146 } 147 148 List<Node> nodeList = null; 149 Object firstTry = actuallyCombineWays(selectedWays, false); 150 if (firstTry instanceof List<?>) { 151 nodeList = (List<Node>) firstTry; 152 } else { 153 Object secondTry = actuallyCombineWays(selectedWays, true); 154 if (secondTry instanceof List<?>) { 155 ExtendedDialog ed = new ExtendedDialog(Main.parent, 156 tr("Change directions?"), 157 new String[] {tr("Reverse and Combine"), tr("Cancel")}); 158 ed.setButtonIcons(new String[] {"wayflip.png", "cancel.png"}); 159 ed.setContent(tr("The ways can not be combined in their current directions. " 160 + "Do you want to reverse some of them?")); 161 ed.showDialog(); 162 if (ed.getValue() != 1) return; 163 164 nodeList = (List<Node>) secondTry; 165 } else { 166 JOptionPane.showMessageDialog( 167 Main.parent, 168 secondTry, // FIXME: not sure whether this fits in a dialog 169 tr("Information"), 170 JOptionPane.INFORMATION_MESSAGE 171 ); 172 return; 173 } 174 } 175 176 // Find the most appropriate way to modify. 177 178 // Eventually this might want to be the way with the longest 179 // history or the longest selected way but for now just attempt 180 // to reuse an existing id. 181 Way modifyWay = selectedWays.peek(); 182 for (Way w : selectedWays) { 183 modifyWay = w; 184 if (w.getId() != 0) { 185 break; 186 } 187 } 188 Way newWay = new Way(modifyWay); 189 190 newWay.setNodes(nodeList); 191 192 // display conflict dialog 193 Map<String, JComboBox> components = new HashMap<String, JComboBox>(); 194 JPanel p = new JPanel(new GridBagLayout()); 195 for (Entry<String, Set<String>> e : props.entrySet()) { 196 if (TigerUtils.isTigerTag(e.getKey())) { 197 String combined = TigerUtils.combineTags(e.getKey(), e.getValue()); 198 newWay.put(e.getKey(), combined); 199 } else if (e.getValue().size() > 1) { 200 JComboBox c = new JComboBox(e.getValue().toArray()); 201 c.setEditable(true); 202 p.add(new JLabel(e.getKey()), GBC.std()); 203 p.add(Box.createHorizontalStrut(10), GBC.std()); 204 p.add(c, GBC.eol()); 205 components.put(e.getKey(), c); 206 } else { 207 newWay.put(e.getKey(), e.getValue().iterator().next()); 208 } 209 } 210 211 if (!components.isEmpty()) { 212 213 ExtendedDialog ed = new ExtendedDialog(Main.parent, 214 tr("Enter values for all conflicts."), 215 new String[] {tr("Solve Conflicts"), tr("Cancel")}); 216 ed.setButtonIcons(new String[] {"dialogs/conflict.png", "cancel.png"}); 217 ed.setContent(p); 218 ed.showDialog(); 219 220 if (ed.getValue() != 1) return; 221 222 for (Entry<String, JComboBox> e : components.entrySet()) { 223 newWay.put(e.getKey(), e.getValue().getEditor().getItem().toString()); 224 } 225 } 226 227 LinkedList<Command> cmds = new LinkedList<Command>(); 228 LinkedList<Way> deletedWays = new LinkedList<Way>(selectedWays); 229 deletedWays.remove(modifyWay); 230 cmds.add(new DeleteCommand(deletedWays)); 231 cmds.add(new ChangeCommand(modifyWay, newWay)); 232 233 // modify all relations containing the now-deleted ways 234 for (Relation r : relationsUsingWays) { 235 List<RelationMember> newMembers = new ArrayList<RelationMember>(); 236 HashSet<String> rolesToReAdd = new HashSet<String>(); 237 for (RelationMember rm : r.getMembers()) { 238 // Don't copy the member if it to one of our ways, just keep a 239 // note to re-add it later on. 240 if (selectedWays.contains(rm.getMember())) { 241 rolesToReAdd.add(rm.getRole()); 242 } else { 243 newMembers.add(rm); 244 } 245 } 246 for (String role : rolesToReAdd) { 247 newMembers.add(new RelationMember(role, modifyWay)); 248 } 249 Relation newRel = new Relation(r); 250 newRel.setMembers(newMembers); 251 cmds.add(new ChangeCommand(r, newRel)); 252 } 253 Main.main.undoRedo.add(new SequenceCommand(tr("Combine {0} ways", selectedWays.size()), cmds)); 254 getCurrentDataSet().setSelected(modifyWay); 255 } 256 257 /** 258 * @return a message if combining failed, else a list of nodes. 259 */ 260 private Object actuallyCombineWays(List<Way> ways, boolean ignoreDirection) { 261 // Battle plan: 262 // 1. Split the ways into small chunks of 2 nodes and weed out 263 // duplicates. 264 // 2. Take a chunk and see if others could be appended or prepended, 265 // if so, do it and remove it from the list of remaining chunks. 266 // Rather, rinse, repeat. 267 // 3. If this algorithm does not produce a single way, 268 // complain to the user. 269 // 4. Profit! 270 271 HashSet<Pair<Node,Node>> chunkSet = new HashSet<Pair<Node,Node>>(); 272 for (Way w : ways) { 273 chunkSet.addAll(w.getNodePairs(ignoreDirection)); 274 } 275 276 LinkedList<Pair<Node,Node>> chunks = new LinkedList<Pair<Node,Node>>(chunkSet); 277 278 if (chunks.isEmpty()) 279 return tr("All the ways were empty"); 280 281 List<Node> nodeList = Pair.toArrayList(chunks.poll()); 282 while (!chunks.isEmpty()) { 283 ListIterator<Pair<Node,Node>> it = chunks.listIterator(); 284 boolean foundChunk = false; 285 while (it.hasNext()) { 286 Pair<Node,Node> curChunk = it.next(); 287 if (curChunk.a == nodeList.get(nodeList.size() - 1)) { // append 288 nodeList.add(curChunk.b); 289 } else if (curChunk.b == nodeList.get(0)) { // prepend 290 nodeList.add(0, curChunk.a); 291 } else if (ignoreDirection && curChunk.b == nodeList.get(nodeList.size() - 1)) { // append 292 nodeList.add(curChunk.a); 293 } else if (ignoreDirection && curChunk.a == nodeList.get(0)) { // prepend 294 nodeList.add(0, curChunk.b); 295 } else { 296 continue; 297 } 298 299 foundChunk = true; 300 it.remove(); 301 break; 302 } 303 if (!foundChunk) { 304 break; 305 } 306 } 307 308 if (!chunks.isEmpty()) 309 return tr("Could not combine ways " 310 + "(They could not be merged into a single string of nodes)"); 311 312 return nodeList; 223 combineWays(selectedWays); 313 224 } 314 225 … … 328 239 setEnabled(numWays >= 2); 329 240 } 241 242 /** 243 * This is a collection of relations referring to at least one out of a set of 244 * ways. 245 * 246 * 247 */ 248 static private class WayReferringRelations { 249 /** 250 * the map references between relations and ways. The key is a ways, the value is a 251 * set of relations referring to that way. 252 */ 253 private Map<Way, Set<Relation>> wayRelationMap; 254 255 /** 256 * 257 * @param ways a collection of ways 258 */ 259 public WayReferringRelations(Collection<Way> ways) { 260 wayRelationMap = new HashMap<Way, Set<Relation>>(); 261 if (ways == null) return; 262 ways.remove(null); // just in case - remove null values 263 for (Way way: ways) { 264 if (!wayRelationMap.containsKey(way)) { 265 wayRelationMap.put(way, new HashSet<Relation>()); 266 } 267 } 268 } 269 270 /** 271 * build the sets of referring relations from the relations in the dataset <code>ds</code> 272 * 273 * @param ds the data set 274 */ 275 public void build(DataSet ds) { 276 for (Relation r: ds.relations) { 277 if (r.isDeleted() || r.incomplete) { 278 continue; 279 } 280 Set<Way> referringWays = OsmPrimitive.getFilteredSet(r.getMemberPrimitives(), Way.class); 281 for (Way w : wayRelationMap.keySet()) { 282 if (referringWays.contains(w)) { 283 wayRelationMap.get(w).add(r); 284 } 285 } 286 } 287 } 288 289 /** 290 * Replies the ways 291 * @return the ways 292 */ 293 public Set<Way> getWays() { 294 return wayRelationMap.keySet(); 295 } 296 297 /** 298 * Replies the set of referring relations 299 * 300 * @return the set of referring relations 301 */ 302 public Set<Relation> getRelations() { 303 HashSet<Relation> ret = new HashSet<Relation>(); 304 for (Way w: wayRelationMap.keySet()) { 305 ret.addAll(wayRelationMap.get(w)); 306 } 307 return ret; 308 } 309 310 /** 311 * Replies the set of referring relations for a specific way 312 * 313 * @return the set of referring relations 314 */ 315 public Set<Relation> getRelations(Way way) { 316 return wayRelationMap.get(way); 317 } 318 319 protected Command buildRelationUpdateCommand(Relation relation, Collection<Way> ways, Way targetWay) { 320 List<RelationMember> newMembers = new ArrayList<RelationMember>(); 321 for (RelationMember rm : relation.getMembers()) { 322 if (ways.contains(rm.getMember())) { 323 RelationMember newMember = new RelationMember(rm.getRole(),targetWay); 324 newMembers.add(newMember); 325 } else { 326 newMembers.add(rm); 327 } 328 } 329 Relation newRelation = new Relation(relation); 330 newRelation.setMembers(newMembers); 331 return new ChangeCommand(relation, newRelation); 332 } 333 334 public List<Command> buildRelationUpdateCommands(Way targetWay) { 335 Collection<Way> toRemove = getWays(); 336 toRemove.remove(targetWay); 337 ArrayList<Command> cmds = new ArrayList<Command>(); 338 for (Relation r : getRelations()) { 339 Command cmd = buildRelationUpdateCommand(r, toRemove, targetWay); 340 cmds.add(cmd); 341 } 342 return cmds; 343 } 344 } 345 346 static public class NodePair { 347 private Node a; 348 private Node b; 349 public NodePair(Node a, Node b) { 350 this.a =a; 351 this.b = b; 352 } 353 354 public NodePair(Pair<Node,Node> pair) { 355 this.a = pair.a; 356 this.b = pair.b; 357 } 358 359 public NodePair(NodePair other) { 360 this.a = other.a; 361 this.b = other.b; 362 } 363 364 public Node getA() { 365 return a; 366 } 367 368 public Node getB() { 369 return b; 370 } 371 372 public boolean isAdjacentToA(NodePair other) { 373 return other.getA() == a || other.getB() == a; 374 } 375 376 public boolean isAdjacentToB(NodePair other) { 377 return other.getA() == b || other.getB() == b; 378 } 379 380 public boolean isSuccessorOf(NodePair other) { 381 return other.getB() == a; 382 } 383 384 public boolean isPredecessorOf(NodePair other) { 385 return b == other.getA(); 386 } 387 388 public NodePair swap() { 389 return new NodePair(b,a); 390 } 391 392 @Override 393 public String toString() { 394 return new StringBuilder() 395 .append("[") 396 .append(a.getId()) 397 .append(",") 398 .append(b.getId()) 399 .append("]") 400 .toString(); 401 } 402 403 public boolean contains(Node n) { 404 return a == n || b == n; 405 } 406 407 @Override 408 public int hashCode() { 409 final int prime = 31; 410 int result = 1; 411 result = prime * result + ((a == null) ? 0 : a.hashCode()); 412 result = prime * result + ((b == null) ? 0 : b.hashCode()); 413 return result; 414 } 415 @Override 416 public boolean equals(Object obj) { 417 if (this == obj) 418 return true; 419 if (obj == null) 420 return false; 421 if (getClass() != obj.getClass()) 422 return false; 423 NodePair other = (NodePair) obj; 424 if (a == null) { 425 if (other.a != null) 426 return false; 427 } else if (!a.equals(other.a)) 428 return false; 429 if (b == null) { 430 if (other.b != null) 431 return false; 432 } else if (!b.equals(other.b)) 433 return false; 434 return true; 435 } 436 } 437 438 439 static public class NodeGraph { 440 static public List<NodePair> buildNodePairs(Way way, boolean directed) { 441 ArrayList<NodePair> pairs = new ArrayList<NodePair>(); 442 for (Pair<Node,Node> pair: way.getNodePairs(false /* don't sort */)) { 443 pairs.add(new NodePair(pair)); 444 if (!directed) { 445 pairs.add(new NodePair(pair).swap()); 446 } 447 } 448 return pairs; 449 } 450 451 static public List<NodePair> buildNodePairs(List<Way> ways, boolean directed) { 452 ArrayList<NodePair> pairs = new ArrayList<NodePair>(); 453 for (Way w: ways) { 454 pairs.addAll(buildNodePairs(w, directed)); 455 } 456 return pairs; 457 } 458 459 static public List<NodePair> eliminateDuplicateNodePairs(List<NodePair> pairs) { 460 ArrayList<NodePair> cleaned = new ArrayList<NodePair>(); 461 for(NodePair p: pairs) { 462 if (!cleaned.contains(p) && !cleaned.contains(p.swap())) { 463 cleaned.add(p); 464 } 465 } 466 return cleaned; 467 } 468 469 static public NodeGraph createDirectedGraphFromNodePairs(List<NodePair> pairs) { 470 NodeGraph graph = new NodeGraph(); 471 for (NodePair pair: pairs) { 472 graph.add(pair); 473 } 474 return graph; 475 } 476 477 static public NodeGraph createDirectedGraphFromWays(Collection<Way> ways) { 478 NodeGraph graph = new NodeGraph(); 479 for (Way w: ways) { 480 graph.add(buildNodePairs(w, true /* directed */)); 481 } 482 return graph; 483 } 484 485 static public NodeGraph createUndirectedGraphFromNodeList(List<NodePair> pairs) { 486 NodeGraph graph = new NodeGraph(); 487 for (NodePair pair: pairs) { 488 graph.add(pair); 489 graph.add(pair.swap()); 490 } 491 return graph; 492 } 493 494 static public NodeGraph createUndirectedGraphFromNodeWays(Collection<Way> ways) { 495 NodeGraph graph = new NodeGraph(); 496 for (Way w: ways) { 497 graph.add(buildNodePairs(w, false /* undirected */)); 498 } 499 return graph; 500 } 501 502 private Set<NodePair> edges; 503 private int numUndirectedEges = 0; 504 505 protected void computeNumEdges() { 506 Set<NodePair> undirectedEdges = new HashSet<NodePair>(); 507 for (NodePair pair: edges) { 508 if (!undirectedEdges.contains(pair) && ! undirectedEdges.contains(pair.swap())) { 509 undirectedEdges.add(pair); 510 } 511 } 512 numUndirectedEges = undirectedEdges.size(); 513 } 514 515 public NodeGraph() { 516 edges = new HashSet<NodePair>(); 517 } 518 519 public void add(NodePair pair) { 520 if (!edges.contains(pair)) { 521 edges.add(pair); 522 } 523 } 524 525 public void add(List<NodePair> pairs) { 526 for (NodePair pair: pairs) { 527 add(pair); 528 } 529 } 530 531 protected Node getStartNode() { 532 return edges.iterator().next().getA(); 533 } 534 535 protected Set<Node> getNodes(Stack<NodePair> pairs) { 536 HashSet<Node> nodes = new HashSet<Node>(); 537 for (NodePair pair: pairs) { 538 nodes.add(pair.getA()); 539 nodes.add(pair.getB()); 540 } 541 return nodes; 542 } 543 544 protected List<NodePair> getOutboundPairs(NodePair pair) { 545 LinkedList<NodePair> outbound = new LinkedList<NodePair>(); 546 for (NodePair candidate:edges) { 547 if (candidate.equals(pair)) { 548 continue; 549 } 550 if (candidate.isSuccessorOf(pair)) { 551 outbound.add(candidate); 552 } 553 } 554 return outbound; 555 } 556 557 protected List<NodePair> getOutboundPairs(Node node) { 558 LinkedList<NodePair> outbound = new LinkedList<NodePair>(); 559 for (NodePair candidate:edges) { 560 if (candidate.getA() == node) { 561 outbound.add(candidate); 562 } 563 } 564 return outbound; 565 } 566 567 protected Set<Node> getNodes() { 568 Set<Node> nodes = new HashSet<Node>(); 569 for (NodePair pair: edges) { 570 nodes.add(pair.getA()); 571 nodes.add(pair.getB()); 572 } 573 return nodes; 574 } 575 576 protected boolean isSpanningWay(Stack<NodePair> way) { 577 return numUndirectedEges == way.size(); 578 } 579 580 581 protected boolean advance(Stack<NodePair> path) { 582 // found a spanning path ? 583 // 584 if (isSpanningWay(path)) 585 return true; 586 587 // advance with one of the possible follow up nodes 588 // 589 Stack<NodePair> nextPairs = new Stack<NodePair>(); 590 nextPairs.addAll(getOutboundPairs(path.peek())); 591 while(!nextPairs.isEmpty()) { 592 NodePair next = nextPairs.pop(); 593 if (path.contains(next) || path.contains(next.swap())) { 594 continue; 595 } 596 path.push(next); 597 if (advance(path)) return true; 598 path.pop(); 599 } 600 return false; 601 } 602 603 protected List<Node> buildPathFromNodePairs(Stack<NodePair> path) { 604 LinkedList<Node> ret = new LinkedList<Node>(); 605 for (NodePair pair: path) { 606 ret.add(pair.getA()); 607 } 608 ret.add(path.peek().getB()); 609 return ret; 610 } 611 612 protected List<Node> buildSpanningPath(Node startNode) { 613 if (startNode == null) 614 return null; 615 Stack<NodePair> path = new Stack<NodePair>(); 616 // advance with one of the possible follow up nodes 617 // 618 Stack<NodePair> nextPairs = new Stack<NodePair>(); 619 nextPairs.addAll(getOutboundPairs(startNode)); 620 while(!nextPairs.isEmpty()) { 621 path.push(nextPairs.pop()); 622 if (advance(path)) 623 return buildPathFromNodePairs(path); 624 path.pop(); 625 } 626 return null; 627 } 628 629 public List<Node> buildSpanningPath() { 630 computeNumEdges(); 631 for (Node n : getNodes()) { 632 List<Node> path = buildSpanningPath(n); 633 if (path != null) 634 return path; 635 } 636 return null; 637 } 638 } 330 639 } -
trunk/src/org/openstreetmap/josm/actions/CopyAction.java
r2008 r2070 101 101 members.add(mnew); 102 102 } 103 enew. members.addAll(members);103 enew.setMembers(members); 104 104 pasteBuffer.addPrimitive(enew); 105 105 } -
trunk/src/org/openstreetmap/josm/actions/DiskAccessAction.java
r2029 r2070 50 50 if (!open) { 51 51 File file = fc.getSelectedFile(); 52 if (file == null || (file.exists() && 1 != 53 new ExtendedDialog(Main.parent, 52 if (file != null && file.exists()) { 53 ExtendedDialog dialog = new ExtendedDialog( 54 Main.parent, 54 55 tr("Overwrite"), 55 tr("File exists. Overwrite?"), 56 new String[] {tr("Overwrite"), tr("Cancel")}, 57 new String[] {"save_as.png", "cancel.png"}).getValue())) 58 return null; 56 new String[] {tr("Overwrite"), tr("Cancel")} 57 ); 58 dialog.setContent(tr("File exists. Overwrite?")); 59 dialog.setButtonIcons(new String[] {"save_as.png", "cancel.png"}); 60 if (dialog.getValue() != 1) 61 return null; 62 } 59 63 } 60 64 -
trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java
r2064 r2070 201 201 202 202 if (!components.isEmpty()) { 203 int answer = new ExtendedDialog(Main.parent, 203 ExtendedDialog dialog = new ExtendedDialog( 204 Main.parent, 204 205 tr("Enter values for all conflicts."), 205 p, 206 new String[] {tr("Solve Conflicts"), tr("Cancel")}, 207 new String[] {"dialogs/conflict.png", "cancel.png"}).getValue(); 206 new String[] {tr("Solve Conflicts"), tr("Cancel")} 207 ); 208 dialog.setButtonIcons(new String[] {"dialogs/conflict.png", "cancel.png"}); 209 dialog.setContent(p); 210 dialog.showDialog(); 211 int answer = dialog.getValue(); 212 208 213 if (answer != 1) 209 214 return null; -
trunk/src/org/openstreetmap/josm/actions/OpenFileAction.java
r2047 r2070 17 17 import org.openstreetmap.josm.gui.PleaseWaitRunnable; 18 18 import org.openstreetmap.josm.io.FileImporter; 19 import org.openstreetmap.josm.io.IllegalDataException; 19 20 import org.openstreetmap.josm.io.OsmTransferException; 20 21 import org.openstreetmap.josm.tools.Shortcut; … … 51 52 } 52 53 53 static public void openFile(File f) throws IOException {54 static public void openFile(File f) throws IOException, IllegalDataException { 54 55 for (FileImporter importer : ExtensionFileFilter.importers) 55 56 if (importer.acceptFile(f)) { -
trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java
r1677 r2070 31 31 public OpenLocationAction() { 32 32 super(tr("Open Location..."), "openlocation", tr("Open an URL."), 33 Shortcut.registerShortcut("system:open_location", tr("File: {0}", tr("Open Location...")), KeyEvent.VK_L, Shortcut.GROUP_MENU), true);33 Shortcut.registerShortcut("system:open_location", tr("File: {0}", tr("Open Location...")), KeyEvent.VK_L, Shortcut.GROUP_MENU), true); 34 34 } 35 35 … … 43 43 all.add(urltext, GBC.eol()); 44 44 all.add(layer, GBC.eol()); 45 int answer = new ExtendedDialog(Main.parent, 46 tr("Download Location"), 47 all, 48 new String[] {tr("Download URL"), tr("Cancel")}, 49 new String[] {"download.png", "cancel.png"}).getValue(); 50 if (answer != 1) return; 45 ExtendedDialog dialog = new ExtendedDialog(Main.parent, 46 tr("Download Location"), 47 new String[] {tr("Download URL"), tr("Cancel")} 48 ); 49 dialog.setContent(all); 50 dialog.setButtonIcons(new String[] {"download.png", "cancel.png"}); 51 if (dialog.getValue() != 1) return; 51 52 openUrl(layer.isSelected(), urltext.getText()); 52 53 } -
trunk/src/org/openstreetmap/josm/actions/PasteAction.java
r1938 r2070 69 69 for (Node n : pasteBuffer.nodes) { 70 70 Node nnew = new Node(n); 71 nnew. id = 0;71 nnew.clearOsmId(); 72 72 if (Main.map.mapView.getEditLayer() == source) { 73 73 nnew.setEastNorth(nnew.getEastNorth().add(offsetEast, offsetNorth)); … … 78 78 Way wnew = new Way(); 79 79 wnew.cloneFrom(w); 80 wnew. id = 0;80 wnew.clearOsmId(); 81 81 /* make sure we reference the new nodes corresponding to the old ones */ 82 82 List<Node> nodes = new ArrayList<Node>(); … … 89 89 for (Relation r : pasteBuffer.relations) { 90 90 Relation rnew = new Relation(r); 91 r new.id = 0;91 r.clearOsmId(); 92 92 List<RelationMember> members = new ArrayList<RelationMember>(); 93 93 for (RelationMember m : r.getMembers()) { 94 94 OsmPrimitive mo = map.get(m.getMember()); 95 if(mo != null) /* TODO- This only prevents illegal data, but kills the relation */95 if(mo != null) /* FIXME - This only prevents illegal data, but kills the relation */ 96 96 { 97 RelationMember mnew = new RelationMember(m); 98 mnew.member = map.get(m.getMember()); 97 RelationMember mnew = new RelationMember(m.getRole(), map.get(m.getMember())); 99 98 members.add(mnew); 100 99 } -
trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java
r2025 r2070 37 37 } 38 38 39 static private List<Class<? extends OsmPrimitive>> osmPrimitiveClasses; 40 { 41 osmPrimitiveClasses = new ArrayList<Class<? extends OsmPrimitive>>(); 42 osmPrimitiveClasses.add(Node.class); 43 osmPrimitiveClasses.add(Way.class); 44 osmPrimitiveClasses.add(Relation.class); 45 } 46 39 47 /** 40 48 * Replies true if the source for tag pasting is heterogeneous, i.e. if it doesn't consist of … … 126 134 protected Map<OsmPrimitiveType, Integer> getSourceStatistics() { 127 135 HashMap<OsmPrimitiveType, Integer> ret = new HashMap<OsmPrimitiveType, Integer>(); 128 for (Class<? extends OsmPrimitive> type: new Class[] {Node.class, Way.class, Relation.class}) {136 for (Class<? extends OsmPrimitive> type: osmPrimitiveClasses) { 129 137 if (!getSourceTagsByType(type).isEmpty()) { 130 138 ret.put(OsmPrimitiveType.from(type), getSourcePrimitivesByType(type).size()); … … 136 144 protected Map<OsmPrimitiveType, Integer> getTargetStatistics() { 137 145 HashMap<OsmPrimitiveType, Integer> ret = new HashMap<OsmPrimitiveType, Integer>(); 138 for (Class<? extends OsmPrimitive> type: new Class[] {Node.class, Way.class, Relation.class}) {146 for (Class<? extends OsmPrimitive> type: osmPrimitiveClasses) { 139 147 int count = getSubcollectionByType(getEditLayer().data.getSelected(), type).size(); 140 148 if (count > 0) { … … 156 164 protected void pasteFromHomogeneousSource(Collection<? extends OsmPrimitive> targets) { 157 165 TagCollection tc = null; 158 for (Class<? extends OsmPrimitive> type : new Class[] {Node.class, Way.class, Relation.class}) {166 for (Class<? extends OsmPrimitive> type : osmPrimitiveClasses) { 159 167 TagCollection tc1 = getSourceTagsByType(type); 160 168 if (!tc1.isEmpty()) { -
trunk/src/org/openstreetmap/josm/actions/SaveAction.java
r2017 r2070 34 34 f=null; 35 35 } 36 if(f != null && layer instanceof GpxLayer && 1 != 37 new ExtendedDialog(Main.parent, tr("Overwrite"), 38 tr("File {0} exists. Overwrite?", f.getName()), 39 new String[] {tr("Overwrite"), tr("Cancel")}, 40 new String[] {"save_as.png", "cancel.png"}).getValue()) { 41 f = null; 36 37 // FIXME: why only for GpxLayer? 38 if(f != null && layer instanceof GpxLayer) { 39 ExtendedDialog dialog = new ExtendedDialog( 40 Main.parent, 41 tr("Overwrite"), 42 new String[] {tr("Overwrite"), tr("Cancel")} 43 ); 44 dialog.setButtonIcons(new String[] {"save_as.png", "cancel.png"}); 45 dialog.setContent(tr("File {0} exists. Overwrite?", f.getName())); 46 dialog.showDialog(); 47 int ret = dialog.getValue(); 48 if (ret != 1) { 49 f = null; 50 } 42 51 } 43 52 return f == null ? openFileDialog(layer) : f; -
trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java
r2029 r2070 91 91 */ 92 92 public boolean checkSaveConditions(Layer layer) { 93 if (layer instanceof OsmDataLayer && isDataSetEmpty((OsmDataLayer)layer) && 1 != new ExtendedDialog(Main.parent, tr("Empty document"), tr("The document contains no data."), new String[] {tr("Save anyway"), tr("Cancel")}, new String[] {"save.png", "cancel.png"}).getValue()) 94 return false; 93 if (layer instanceof OsmDataLayer && isDataSetEmpty((OsmDataLayer)layer)) { 94 ExtendedDialog dialog = new ExtendedDialog( 95 Main.parent, 96 tr("Empty document"), 97 new String[] {tr("Save anyway"), tr("Cancel")} 98 ); 99 dialog.setContent(tr("The document contains no data.")); 100 dialog.setButtonIcons(new String[] {"save.png", "cancel.png"}); 101 dialog.showDialog(); 102 if (dialog.getValue() != 1) return false; 103 } 104 95 105 if (layer instanceof GpxLayer && ((GpxLayer)layer).data == null) 96 106 return false; … … 98 108 ConflictCollection conflicts = ((OsmDataLayer)layer).getConflicts(); 99 109 if (conflicts != null && !conflicts.isEmpty()) { 100 int answer = new ExtendedDialog(Main.parent, 110 ExtendedDialog dialog = new ExtendedDialog( 111 Main.parent, 101 112 tr("Conflicts"), 102 tr("There are unresolved conflicts. Conflicts will not be saved and handled as if you rejected all. Continue?"), 103 new String[] {tr("Reject Conflicts and Save"), tr("Cancel")}, 104 new String[] {"save.png", "cancel.png"}).getValue(); 105 106 if (answer != 1) return false; 113 new String[] {tr("Reject Conflicts and Save"), tr("Cancel")} 114 ); 115 dialog.setContent(tr("There are unresolved conflicts. Conflicts will not be saved and handled as if you rejected all. Continue?")); 116 dialog.setButtonIcons(new String[] {"save.png", "cancel.png"}); 117 dialog.showDialog(); 118 if (dialog.getValue() != 1) return false; 107 119 } 108 120 } … … 190 202 } 191 203 } 192 if(file == null || (file.exists() && 1 != new ExtendedDialog(Main.parent, 193 tr("Overwrite"), tr("File exists. Overwrite?"), 194 new String[] {tr("Overwrite"), tr("Cancel")}, 195 new String[] {"save_as.png", "cancel.png"}).getValue())) 196 return null; 204 if(file == null || (file.exists())) { 205 ExtendedDialog dialog = new ExtendedDialog( 206 Main.parent, 207 tr("Overwrite"), 208 new String[] {tr("Overwrite"), tr("Cancel")} 209 ); 210 dialog.setContent(tr("File exists. Overwrite?")); 211 dialog.setButtonIcons(new String[] {"save_as.png", "cancel.png"}); 212 dialog.showDialog(); 213 if (dialog.getValue() != 1) return null; 214 } 197 215 return file; 198 216 } -
trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java
r2025 r2070 156 156 157 157 Node n = new Node(selectedNode); 158 n. id = 0;158 n.clearOsmId(); 159 159 160 160 // If this wasn't called from menu, place it where the cursor is/was … … 301 301 // clone the node for all other ways 302 302 pushNode = new Node(pushNode); 303 pushNode. id = 0;303 pushNode.clearOsmId(); 304 304 newNodes.add(pushNode); 305 305 cmds.add(new AddCommand(pushNode)); … … 331 331 if (newRel == null) { 332 332 newRel = new Relation(r); 333 newRel. members.clear();333 newRel.setMembers(null); 334 334 rolesToReAdd = new HashSet<String>(); 335 335 } … … 340 340 if (newRel != null) { 341 341 for (RelationMember rm : r.getMembers()) { 342 //if (rm.member != selectedNode) { 343 newRel.members.add(rm); 344 //} 342 newRel.addMember(rm); 345 343 } 346 344 for (Node n : newNodes) { 347 345 for (String role : rolesToReAdd) { 348 newRel. members.add(new RelationMember(role, n));346 newRel.addMember(new RelationMember(role, n)); 349 347 } 350 348 } -
trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java
r2068 r2070 118 118 p.add(left); 119 119 p.add(right); 120 121 int result = new ExtendedDialog(Main.parent,120 ExtendedDialog dialog = new ExtendedDialog( 121 Main.parent, 122 122 tr("Search"), 123 p, 124 new String[] {tr("Start Search"), tr("Cancel")}, 125 new String[] {"dialogs/search.png", "cancel.png"}).getValue(); 123 new String[] {tr("Start Search"), tr("Cancel")} 124 ); 125 dialog.setButtonIcons(new String[] {"dialogs/search.png", "cancel.png"}); 126 dialog.setContent(p); 127 dialog.showDialog(); 128 int result = dialog.getValue(); 129 126 130 if(result != 1) return; 127 131 -
trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java
r2025 r2070 7 7 import java.io.PushbackReader; 8 8 import java.io.StringReader; 9 import java.util.List; 9 10 import java.util.Map.Entry; 10 11 import java.util.regex.Matcher; … … 82 83 public Id(long id) {this.id = id;} 83 84 @Override public boolean match(OsmPrimitive osm) { 84 return osm. id== id;85 return osm.getId() == id; 85 86 } 86 87 @Override public String toString() {return "id="+id;} … … 329 330 } 330 331 if (osm.user != null) { 331 String name = osm.user. name;332 String name = osm.user.getName(); 332 333 // is not Java 1.5 333 334 //String name = java.text.Normalizer.normalize(name, java.text.Normalizer.Form.NFC); … … 364 365 private static class UserMatch extends Match { 365 366 private User user; 366 public UserMatch(String user) { this.user = User.get(user); } 367 @Override public boolean match(OsmPrimitive osm) { 368 return osm.user == user; 369 } 370 @Override public String toString() { return "user=" + user.name; } 367 public UserMatch(String user) { 368 List<User> users = User.getByName(user); 369 if (!users.isEmpty()) { 370 // selecting an arbitrary user 371 this.user = users.get(0); 372 } else { 373 user = null; 374 } 375 } 376 @Override public boolean match(OsmPrimitive osm) { 377 if (osm.user == null && user == null) return true; 378 if (osm.user == null) return false; 379 return osm.user.equals(user); 380 } 381 @Override public String toString() { 382 return "user=" + user == null ? "" : user.getName(); 383 } 371 384 } 372 385 -
trunk/src/org/openstreetmap/josm/command/ChangeRelationMemberRoleCommand.java
r2025 r2070 49 49 50 50 oldRole = relation.getMember(position).getRole(); 51 relation.getMember(position). role = newRole;51 relation.getMember(position).getRole().equals(newRole); 52 52 53 53 oldModified = relation.isModified(); … … 57 57 58 58 @Override public void undoCommand() { 59 relation.getMember(position). role = oldRole;59 relation.getMember(position).getRole().equals(oldRole); 60 60 relation.setModified(oldModified); 61 61 } -
trunk/src/org/openstreetmap/josm/command/DeleteCommand.java
r2054 r2070 92 92 super.executeCommand(); 93 93 for (OsmPrimitive osm : toDelete) { 94 osm. delete(true);94 osm.setDeleted(true); 95 95 } 96 96 return true; -
trunk/src/org/openstreetmap/josm/command/DeletedStateConflictResolveCommand.java
r2039 r2070 71 71 if (conflict.getTheir().isDeleted()) { 72 72 layer.data.unlinkReferencesToPrimitive(conflict.getMy()); 73 conflict.getMy(). delete(true);73 conflict.getMy().setDeleted(true); 74 74 } else { 75 conflict.getMy(). delete(conflict.getTheir().isDeleted());75 conflict.getMy().setDeleted(conflict.getTheir().isDeleted()); 76 76 } 77 77 } else -
trunk/src/org/openstreetmap/josm/command/PurgePrimitivesCommand.java
r1938 r2070 185 185 if (pair.getParent() instanceof Way) { 186 186 Way w = (Way)pair.getParent(); 187 System.out.println(tr("removing reference from way {0}",w. id));187 System.out.println(tr("removing reference from way {0}",w.getId())); 188 188 List<Node> wayNodes = w.getNodes(); 189 189 wayNodes.remove(primitive); … … 194 194 if (w.getNodesCount() < 2) { 195 195 System.out.println(tr("Warning: Purging way {0} because number of nodes dropped below 2. Current is {1}", 196 w. id,w.getNodesCount()));196 w.getId(),w.getNodesCount())); 197 197 if (!hive.contains(w)) { 198 198 hive.add(w); … … 201 201 } else if (pair.getParent() instanceof Relation) { 202 202 Relation r = (Relation)pair.getParent(); 203 System.out.println(tr("removing reference from relation {0}",r. id));203 System.out.println(tr("removing reference from relation {0}",r.getId())); 204 204 r.removeMembersFor(primitive); 205 205 } -
trunk/src/org/openstreetmap/josm/command/RelationMemberConflictResolverCommand.java
r1951 r2070 56 56 return new DefaultMutableTreeNode( 57 57 new JLabel( 58 tr("Resolve conflicts in member list of relation {0}", my. id),58 tr("Resolve conflicts in member list of relation {0}", my.getId()), 59 59 ImageProvider.get("data", "object"), 60 60 JLabel.HORIZONTAL -
trunk/src/org/openstreetmap/josm/command/RemoveRelationMemberCommand.java
r1990 r2070 51 51 } else { 52 52 relation.removeMember(removeIndex); 53 relation. modified = true;53 relation.setModified(true); 54 54 return true; 55 55 } … … 59 59 super.undoCommand(); 60 60 relation.addMember(member); 61 relation. modified = this.getOrig(relation).modified;61 relation.setModified(this.getOrig(relation).isModified()); 62 62 } 63 63 … … 66 66 @Override public MutableTreeNode description() { 67 67 String msg = ""; 68 switch(OsmPrimitiveType.from(member. member)) {69 case NODE: msg = marktr("Remove node ''{0}'' at position {1} from relation ''{2}''"); break;70 case WAY: msg = marktr("Remove way ''{0}'' at position {1} from relation ''{2}''"); break;71 case RELATION: msg = marktr("Remove relation ''{0}'' at position {1} from relation ''{2}''"); break;68 switch(OsmPrimitiveType.from(member.getMember())) { 69 case NODE: msg = marktr("Remove node ''{0}'' at position {1} from relation ''{2}''"); break; 70 case WAY: msg = marktr("Remove way ''{0}'' at position {1} from relation ''{2}''"); break; 71 case RELATION: msg = marktr("Remove relation ''{0}'' at position {1} from relation ''{2}''"); break; 72 72 } 73 73 return new DefaultMutableTreeNode( 74 74 new JLabel( 75 75 tr(msg, 76 member. member.getDisplayName(DefaultNameFormatter.getInstance()),76 member.getMember().getDisplayName(DefaultNameFormatter.getInstance()), 77 77 relation.getMembers().indexOf(member), 78 78 relation.getDisplayName(DefaultNameFormatter.getInstance()) -
trunk/src/org/openstreetmap/josm/command/RotateCommand.java
r2017 r2070 76 76 os.latlon = new LatLon(n.getCoor()); 77 77 os.eastNorth = n.getEastNorth(); 78 os.modified = n. modified;78 os.modified = n.isModified(); 79 79 oldState.put(n, os); 80 80 pivot = pivot.add(os.eastNorth.east(), os.eastNorth.north()); … … 114 114 n.setEastNorth(new EastNorth(nx, ny)); 115 115 if (setModified) { 116 n. modified = true;116 n.setModified(true); 117 117 } 118 118 } … … 128 128 OldState os = oldState.get(n); 129 129 n.setCoor(os.latlon); 130 n. modified = os.modified;130 n.setModified(os.modified); 131 131 } 132 132 } -
trunk/src/org/openstreetmap/josm/command/TagConflictResolveCommand.java
r2017 r2070 67 67 String msg = ""; 68 68 switch(OsmPrimitiveType.from(conflict.getMy())) { 69 case NODE: msg = marktr("Resolve {0} tag conflicts in node {1}"); break;70 case WAY: msg = marktr("Resolve {0} tag conflicts in way {1}"); break;71 case RELATION: msg = marktr("Resolve {0} tag conflicts in relation {1}"); break;69 case NODE: msg = marktr("Resolve {0} tag conflicts in node {1}"); break; 70 case WAY: msg = marktr("Resolve {0} tag conflicts in way {1}"); break; 71 case RELATION: msg = marktr("Resolve {0} tag conflicts in relation {1}"); break; 72 72 } 73 73 return new DefaultMutableTreeNode( 74 74 new JLabel( 75 tr(msg,getNumDecidedConflicts(), conflict.getMy(). id),75 tr(msg,getNumDecidedConflicts(), conflict.getMy().getId()), 76 76 ImageProvider.get("data", "object"), 77 77 JLabel.HORIZONTAL -
trunk/src/org/openstreetmap/josm/command/UndeletePrimitivesCommand.java
r2017 r2070 80 80 getLayer().getConflicts().remove(primitive); 81 81 } 82 primitive. id = 0;82 primitive.clearOsmId(); 83 83 } 84 84 return true; -
trunk/src/org/openstreetmap/josm/command/VersionConflictResolveCommand.java
r2017 r2070 39 39 String msg = ""; 40 40 switch(OsmPrimitiveType.from(conflict.getMy())) { 41 case NODE: msg = marktr("Resolve version conflicts for node {0}"); break;42 case WAY: msg = marktr("Resolve version conflicts for way {0}"); break;43 case RELATION: msg = marktr("Resolve version conflicts for relation {0}"); break;41 case NODE: msg = marktr("Resolve version conflicts for node {0}"); break; 42 case WAY: msg = marktr("Resolve version conflicts for way {0}"); break; 43 case RELATION: msg = marktr("Resolve version conflicts for relation {0}"); break; 44 44 } 45 45 return new DefaultMutableTreeNode( 46 46 new JLabel( 47 tr(msg,conflict.getMy(). id),47 tr(msg,conflict.getMy().getId()), 48 48 ImageProvider.get("data", "object"), 49 49 JLabel.HORIZONTAL … … 55 55 public boolean executeCommand() { 56 56 super.executeCommand(); 57 conflict.getMy().version = Math.max(conflict.getMy().version, conflict.getTheir().version); 57 conflict.getMy().setOsmId( 58 conflict.getMy().getId(), 59 (int)Math.max(conflict.getMy().getVersion(), conflict.getTheir().getVersion()) 60 ); 58 61 getLayer().getConflicts().remove(conflict); 59 62 rememberConflict(conflict); -
trunk/src/org/openstreetmap/josm/command/WayNodesConflictResolverCommand.java
r1910 r2070 52 52 return new DefaultMutableTreeNode( 53 53 new JLabel( 54 tr("Resolve conflicts in node list of of way {0}", conflict.getMy(). id),54 tr("Resolve conflicts in node list of of way {0}", conflict.getMy().getId()), 55 55 ImageProvider.get("data", "object"), 56 56 JLabel.HORIZONTAL -
trunk/src/org/openstreetmap/josm/data/osm/Changeset.java
r1990 r2070 30 30 31 31 public int compareTo(OsmPrimitive other) { 32 if (other instanceof Changeset) return Long.valueOf( id).compareTo(other.id);32 if (other instanceof Changeset) return Long.valueOf(getId()).compareTo(other.getId()); 33 33 return 1; 34 34 } … … 37 37 public String getName() { 38 38 // no translation 39 return "changeset " + id;39 return "changeset " + getId(); 40 40 } 41 41 42 42 @Override 43 43 public String getLocalName(){ 44 return tr("Changeset {0}", id);44 return tr("Changeset {0}",getId()); 45 45 } 46 46 -
trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
r2025 r2070 373 373 protected void deleteWay(Way way) { 374 374 way.setNodes(null); 375 way. delete(true);375 way.setDeleted(true); 376 376 } 377 377 … … 471 471 return false; 472 472 } 473 474 public Set<Relation> getReferringRelations(Collection<? extends OsmPrimitive> primitives) { 475 HashSet<Relation> ret = new HashSet<Relation>(); 476 if (primitives == null) return ret; 477 Set<? extends OsmPrimitive> referred; 478 if (primitives instanceof Set<?>) { 479 referred = (Set<? extends OsmPrimitive>)primitives; 480 } else { 481 referred = new HashSet<OsmPrimitive>(primitives); 482 } 483 referred.remove(null); // just in case - remove null element from primitives 484 for (Relation r: relations) { 485 if (r.isDeleted() || r.incomplete) { 486 continue; 487 } 488 Set<OsmPrimitive> memberPrimitives = r.getMemberPrimitives(); 489 memberPrimitives.retainAll(referred); 490 if (!memberPrimitives.isEmpty()) { 491 ret.add(r); 492 } 493 } 494 return ret; 495 } 473 496 } -
trunk/src/org/openstreetmap/josm/data/osm/Node.java
r2017 r2070 17 17 18 18 public final void setCoor(LatLon coor) { 19 if(coor != null) 20 { 19 if(coor != null){ 21 20 if(this.coor == null) { 22 21 this.coor = new CachedLatLon(coor); … … 47 46 48 47 48 /** 49 * Create a new local node with id 0. 50 * 51 */ 52 public Node() { 53 this(0); 54 } 55 49 56 50 57 /** … … 52 59 */ 53 60 public Node(long id) { 54 this.id = id; 55 incomplete = true; 61 super(id); 56 62 } 57 63 … … 60 66 */ 61 67 public Node(Node clone) { 68 super(clone.getId()); 62 69 cloneFrom(clone); 63 70 } 64 71 65 72 public Node(LatLon latlon) { 73 super(0); 66 74 setCoor(latlon); 67 75 } 68 76 69 77 public Node(EastNorth eastNorth) { 78 super(0); 70 79 setEastNorth(eastNorth); 71 80 } … … 81 90 82 91 @Override public String toString() { 83 if (coor == null) return "{Node id="+ id+"}";84 return "{Node id="+ id+",version="+version+",lat="+coor.lat()+",lon="+coor.lon()+"}";92 if (coor == null) return "{Node id="+getId()+"}"; 93 return "{Node id="+getId()+",version="+getVersion()+",lat="+coor.lat()+",lon="+coor.lon()+"}"; 85 94 } 86 95 … … 101 110 102 111 public int compareTo(OsmPrimitive o) { 103 return o instanceof Node ? Long.valueOf( id).compareTo(o.id) : 1;112 return o instanceof Node ? Long.valueOf(getId()).compareTo(o.getId()) : 1; 104 113 } 105 114 -
trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
r2067 r2070 10 10 import java.util.Date; 11 11 import java.util.HashMap; 12 import java.util.HashSet; 13 import java.util.LinkedList; 14 import java.util.List; 12 15 import java.util.Locale; 13 16 import java.util.Map; 17 import java.util.Set; 14 18 import java.util.Map.Entry; 15 19 … … 31 35 abstract public class OsmPrimitive implements Comparable<OsmPrimitive> { 32 36 37 static public <T extends OsmPrimitive> List<T> getFilteredList(Collection<OsmPrimitive> list, Class<T> type) { 38 if (list == null) return null; 39 List<T> ret = new LinkedList<T>(); 40 for(OsmPrimitive p: list) { 41 if (type.isInstance(p)) { 42 ret.add(type.cast(p)); 43 } 44 } 45 return ret; 46 } 47 48 static public <T extends OsmPrimitive> Set<T> getFilteredSet(Collection<OsmPrimitive> set, Class<T> type) { 49 if (set == null) return null; 50 HashSet<T> ret = new HashSet<T>(); 51 for(OsmPrimitive p: set) { 52 if (type.isInstance(p)) { 53 ret.add(type.cast(p)); 54 } 55 } 56 return ret; 57 } 58 59 33 60 /* mappaint data */ 34 61 public ElemStyle mappaintStyle = null; … … 70 97 * the respective class. 71 98 * 72 * @deprecated use {@see #getId()} . Don't assign an id, create a primitive with99 * @deprecated use {@see #getId()} and {@see #setId()}. Don't assign an id, create a primitive with 73 100 * the respective constructors. 74 101 */ … … 120 147 121 148 /** 149 * If set to true, this object is incomplete, which means only the id 150 * and type is known (type is the objects instance class) 151 */ 152 public boolean incomplete = false; 153 154 /** 155 * Contains the version number as returned by the API. Needed to 156 * ensure update consistency 157 * @deprecated use {@see #getVersion()} and {@see #setVersion(long)} 158 */ 159 @Deprecated 160 public int version = 0; 161 162 163 /** 164 * Creates a new primitive with id 0. 165 * 166 */ 167 public OsmPrimitive() { 168 this(0); 169 } 170 171 /** 172 * Creates a new primitive for the given id. If the id > 0, the primitive is marked 173 * as incomplete. 174 * 175 * @param id the id. > 0 required 176 * @throws IllegalArgumentException thrown if id < 0 177 */ 178 public OsmPrimitive(long id) throws IllegalArgumentException { 179 if (id < 0) 180 throw new IllegalArgumentException(tr("expected id >= 0. Got {0}", id)); 181 this.id = id; 182 this.version = 0; 183 this.incomplete = id >0; 184 } 185 186 /* ------------------------------------------------------------------------------------ */ 187 /* accessors */ 188 /* ------------------------------------------------------------------------------------ */ 189 190 /** 122 191 * Sets whether this primitive is selected or not. 123 192 * … … 162 231 * 163 232 * @return <code>true</code>, if the object has been deleted. 164 * @see # delete(boolean)233 * @see #setDeleted(boolean) 165 234 */ 166 235 public boolean isDeleted() { … … 205 274 206 275 /** 276 * Replies the version number as returned by the API. The version is 0 if the id is 0 or 277 * if this primitive is incomplete. 278 * 279 * @see #setVersion(int) 280 */ 281 public long getVersion() { 282 return version; 283 } 284 285 /** 207 286 * Replies the id of this primitive. 208 287 * … … 214 293 215 294 /** 216 * If set to true, this object is highlighted. Currently this is only used to 217 * show which ways/nodes will connect 218 */ 219 public volatile boolean highlighted = false; 220 221 private int timestamp; 295 * Sets the id and the version of this primitive if it is known to the OSM API. 296 * 297 * Since we know the id and its version it can't be incomplete anymore. incomplete 298 * is set to false. 299 * 300 * @param id the id. > 0 required 301 * @param version the version > 0 required 302 * @throws IllegalArgumentException thrown if id <= 0 303 * @throws IllegalArgumentException thrown if version <= 0 304 */ 305 public void setOsmId(long id, int version) { 306 if (id <= 0) 307 throw new IllegalArgumentException(tr("id > 0 expected. Got {0}", id)); 308 if (version <= 0) 309 throw new IllegalArgumentException(tr("version > 0 expected. Got {0}", version)); 310 this.id = id; 311 this.version = version; 312 this.incomplete = false; 313 } 314 315 /** 316 * Clears the id and version known to the OSM API. The id and the version is set to 0. 317 * incomplete is set to false. 318 * 319 * <strong>Caution</strong>: Do not use this method on primitives which are already added to a {@see DataSet}. 320 * Ways and relations might already refer to the primitive and clearing the OSM ID 321 * result in corrupt data. 322 * 323 * Here's an example use case: 324 * <pre> 325 * // create a clone of an already existing node 326 * Node copy = new Node(otherExistingNode); 327 * 328 * // reset the clones OSM id 329 * copy.clearOsmId(); 330 * </pre> 331 * 332 */ 333 public void clearOsmId() { 334 this.id = 0; 335 this.version = 0; 336 this.incomplete = false; 337 } 222 338 223 339 public void setTimestamp(Date timestamp) { … … 240 356 241 357 /** 242 * If set to true, this object is incomplete, which means only the id 243 * and type is known (type is the objects instance class) 244 */ 245 public boolean incomplete = false; 246 247 /** 248 * Contains the version number as returned by the API. Needed to 249 * ensure update consistency 250 */ 251 public int version = -1; 358 * If set to true, this object is highlighted. Currently this is only used to 359 * show which ways/nodes will connect 360 */ 361 public volatile boolean highlighted = false; 362 363 private int timestamp; 252 364 253 365 private static Collection<String> uninteresting = null; … … 288 400 abstract public void visit(Visitor visitor); 289 401 290 public final void delete(boolean deleted) { 402 /** 403 * Sets whether this primitive is deleted or not. 404 * 405 * Also marks this primitive as modified if deleted is true and sets selected to false. 406 * 407 * @param deleted true, if this primitive is deleted; false, otherwise 408 */ 409 public void setDeleted(boolean deleted) { 410 this.modified = deleted; 291 411 this.deleted = deleted; 292 setSelected(false); 293 modified = true; 412 this.selected = false; 294 413 } 295 414 -
trunk/src/org/openstreetmap/josm/data/osm/Relation.java
r2017 r2070 2 2 3 3 import java.util.ArrayList; 4 import java.util.HashSet; 4 5 import java.util.List; 6 import java.util.Set; 5 7 6 8 import org.openstreetmap.josm.data.osm.visitor.Visitor; … … 17 19 * All members of this relation. Note that after changing this, 18 20 * makeBackReferences and/or removeBackReferences should be called. 19 */ 21 * 22 * @deprecated use the improved API instead of accessing this list directly 23 */ 24 @Deprecated 20 25 public final List<RelationMember> members = new ArrayList<RelationMember>(); 21 26 … … 104 109 105 110 /** 111 * Create a new relation with id 0 112 */ 113 public Relation() { 114 115 } 116 117 /** 106 118 * Create an identical clone of the argument (including the id) 107 119 */ 108 120 public Relation(Relation clone) { 121 super(clone.getId()); 109 122 cloneFrom(clone); 110 123 } 111 124 112 125 /** 113 * Create an incomplete Relation. 114 */ 115 public Relation(long id) { 116 this.id = id; 117 incomplete = true; 118 } 119 120 /** 121 * Create an empty Relation. Use this only if you set meaningful values 122 * afterwards. 123 */ 124 public Relation() { 125 } 126 * Creates a new relation for the given id. If the id > 0, the way is marked 127 * as incomplete. 128 * 129 * @param id the id. > 0 required 130 * @throws IllegalArgumentException thrown if id < 0 131 */ 132 public Relation(long id) throws IllegalArgumentException { 133 super(id); 134 } 135 126 136 127 137 @Override public void cloneFrom(OsmPrimitive osm) { … … 138 148 // return "{Relation id="+id+" version="+version+" members="+Arrays.toString(members.toArray())+"}"; 139 149 // adding members in string increases memory usage a lot and overflows for looped relations 140 return "{Relation id="+ id+" version="+version+"}";150 return "{Relation id="+getId()+" version="+getVersion()+"}"; 141 151 } 142 152 … … 152 162 153 163 public int compareTo(OsmPrimitive o) { 154 return o instanceof Relation ? Long.valueOf( id).compareTo(o.id) : -1;164 return o instanceof Relation ? Long.valueOf(getId()).compareTo(o.getId()) : -1; 155 165 } 156 166 … … 158 168 public boolean isIncomplete() { 159 169 for (RelationMember m : members) 160 if (m. member== null)170 if (m.getMember() == null) 161 171 return true; 162 172 return false; … … 183 193 ArrayList<RelationMember> todelete = new ArrayList<RelationMember>(); 184 194 for (RelationMember member: members) { 185 if (member. member== primitive) {195 if (member.getMember() == primitive) { 186 196 todelete.add(member); 187 197 } … … 194 204 return formatter.format(this); 195 205 } 206 207 /** 208 * Replies the set of {@see OsmPrimitive}s referred to by at least one 209 * member of this relation 210 * 211 * @return the set of {@see OsmPrimitive}s referred to by at least one 212 * member of this relation 213 */ 214 public Set<OsmPrimitive> getMemberPrimitives() { 215 HashSet<OsmPrimitive> ret = new HashSet<OsmPrimitive>(); 216 for (RelationMember m: members) { 217 if (m.getMember() != null) { 218 ret.add(m.getMember()); 219 } 220 } 221 return ret; 222 } 196 223 } -
trunk/src/org/openstreetmap/josm/data/osm/RelationMember.java
r1937 r2070 6 6 * list is not sufficient. 7 7 * 8 * @author Frederik Ramm <frederik@remote.org>9 8 */ 10 9 public class RelationMember { 11 10 11 /** 12 * 13 * @deprecated use {@see #getRole()} or create a clone in order to assign a new role 14 */ 15 @Deprecated 12 16 public String role; 17 18 /** 19 * 20 * @deprecated use {@see #getMember()} or create a clone in order to assign a new member 21 */ 22 @Deprecated 13 23 public OsmPrimitive member; 14 24 … … 19 29 */ 20 30 public String getRole() { 21 if (role == null) {31 if (role == null) 22 32 return ""; 23 } else { 24 return role; 25 } 33 return role; 26 34 } 27 35 … … 45 53 46 54 /** 47 *48 * @return True if member is way49 * @since 193750 */55 * 56 * @return True if member is way 57 * @since 1937 58 */ 51 59 public boolean isWay() { 52 60 return member instanceof Way; … … 54 62 55 63 /** 56 *57 * @return True if member is node58 * @since 193759 */64 * 65 * @return True if member is node 66 * @since 1937 67 */ 60 68 public boolean isNode() { 61 69 return member instanceof Node; … … 72 80 73 81 /** 74 *75 * @return Member as way76 * @since 193777 */82 * 83 * @return Member as way 84 * @since 1937 85 */ 78 86 public Way getWay() { 79 87 return (Way)member; … … 81 89 82 90 /** 83 *84 * @return Member as node85 * @since 193786 */91 * 92 * @return Member as node 93 * @since 1937 94 */ 87 95 public Node getNode() { 88 96 return (Node)member; … … 90 98 91 99 /** 92 *93 * @return Member94 * @since 193795 */100 * 101 * @return Member 102 * @since 1937 103 */ 96 104 public OsmPrimitive getMember() { 97 105 return member; … … 101 109 /** 102 110 * Default constructor. Does nothing. 103 * @deprecated Use other constructors because RelationMember class will bec ame immutable111 * @deprecated Use other constructors because RelationMember class will become immutable 104 112 * in the future 105 113 */ -
trunk/src/org/openstreetmap/josm/data/osm/Tag.java
r2008 r2070 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.data.osm; 3 4 import java.util.ArrayList; 5 import java.util.Collections; 6 import java.util.Iterator; 7 import java.util.List; 3 8 4 9 /** … … 27 32 */ 28 33 public Tag(String key) { 34 this(); 29 35 this.key = key == null ? "" : key; 30 36 } -
trunk/src/org/openstreetmap/josm/data/osm/TagCollection.java
r2017 r2070 6 6 import java.util.ArrayList; 7 7 import java.util.Collection; 8 import java.util.Collections; 8 9 import java.util.HashMap; 9 10 import java.util.HashSet; … … 571 572 throw new IllegalStateException(tr("tag collection can't be applied to a primitive because there are keys with multiple values")); 572 573 for (Tag tag: tags) { 573 primitive.put(tag.getKey(), tag.getValue()); 574 if (tag.getValue() == null || tag.getValue().equals("")) { 575 primitive.remove(tag.getKey()); 576 } else { 577 primitive.put(tag.getKey(), tag.getValue()); 578 } 574 579 } 575 580 } … … 682 687 return ret; 683 688 } 689 690 /** 691 * Replies the concatenation of all tag values (concatenated by a semicolon) 692 * 693 * @return the concatenation of all tag values 694 */ 695 public String getJoinedValues(String key) { 696 StringBuffer buffer = new StringBuffer(); 697 List<String> values = new ArrayList<String>(getValues(key)); 698 values.remove(""); 699 Collections.sort(values); 700 Iterator<String> iter = values.iterator(); 701 while (iter.hasNext()) { 702 buffer.append(iter.next()); 703 if (iter.hasNext()) { 704 buffer.append(";"); 705 } 706 } 707 return buffer.toString(); 708 } 684 709 } -
trunk/src/org/openstreetmap/josm/data/osm/User.java
r2034 r2070 2 2 package org.openstreetmap.josm.data.osm; 3 3 4 import java.util.ArrayList; 4 5 import java.util.HashMap; 6 import java.util.List; 5 7 6 8 /** … … 11 13 * is only one user object. 12 14 * 13 * @author fred14 15 * 15 16 */ 16 17 public class User { 18 static private long uidCounter = 0; 19 /** 20 * the map of known users 21 */ 22 private static HashMap<Long,User> userMap = new HashMap<Long,User>(); 17 23 18 /** storage for existing User objects. */19 private static HashMap<String,User> userMap = new HashMap<String,User>();20 24 21 /** the username. */ 22 public String name; 25 private static long getNextLocalUid() { 26 synchronized(User.class) { 27 uidCounter--; 28 return uidCounter; 29 } 30 } 23 31 24 /** the user ID (since API 0.6) */ 25 public String uid; 32 /** 33 * Creates a local user with the given name 34 * 35 * @param name the name 36 */ 37 public static User createLocalUser(String name) { 38 User user = new User(getNextLocalUid(), name); 39 userMap.put(user.getId(), user); 40 return user; 41 } 42 43 /** 44 * Creates a user known to the OSM server 45 * 46 * @param uid the user id 47 * @param name the name 48 */ 49 public static User createOsmUser(long uid, String name) { 50 User user = new User(uid, name); 51 userMap.put(user.getId(), user); 52 return user; 53 } 54 55 56 /** 57 * Returns the user with user id <code>uid</code> or null if this user doesn't exist 58 * 59 * @param uid the user id 60 * @return the user; null, if there is no user with this id 61 */ 62 public static User getById(long uid) { 63 return userMap.get(uid); 64 } 65 66 /** 67 * Returns the list of users with name <code>name</code> or the empty list if 68 * no such users exist 69 * 70 * @param name the user name 71 * @return the list of users with name <code>name</code> or the empty list if 72 * no such users exist 73 */ 74 public static List<User> getByName(String name) { 75 name = name == null ? "" : name; 76 List<User> ret = new ArrayList<User>(); 77 for (User user: userMap.values()) { 78 if (user.getName().equals(name)) { 79 ret.add(user); 80 } 81 } 82 return ret; 83 } 84 85 /** the user name */ 86 private String name; 87 /** the user id */ 88 private long uid; 89 90 /** 91 * Replies the user name 92 * 93 * @return the user name. Never null, but may be the empty string 94 */ 95 public String getName() { 96 return name == null ? "" : name; 97 } 98 99 /** 100 * Replies the user id. If this user is known to the OSM server the positive user id 101 * from the server is replied. Otherwise, a negative local value is replied. 102 * 103 * A negative local is only unique during an editing session. It is lost when the 104 * application is closed and there is no guarantee that a negative local user id is 105 * always bound to a user with the same name. 106 * 107 */ 108 public long getId() { 109 return uid; 110 } 26 111 27 112 /** private constructor, only called from get method. */ 28 private User(String name) { 113 private User(long uid, String name) { 114 this.uid = uid; 29 115 this.name = name; 30 116 } 31 117 32 /** returns a new or existing User object that represents the given name. */ 33 public static User get(String name) { 34 User user = userMap.get(name); 35 if (user == null) { 36 user = new User(name); 37 userMap.put(name, user); 38 } 39 return user; 118 public boolean isOsmUser() { 119 return uid > 0; 120 } 121 122 public boolean isLocalUser() { 123 return uid < 0; 40 124 } 41 125 … … 45 129 int result = 1; 46 130 result = prime * result + ((name == null) ? 0 : name.hashCode()); 47 result = prime * result + ( (uid == null) ? 0 : uid.hashCode());131 result = prime * result + (int) (uid ^ (uid >>> 32)); 48 132 return result; 49 133 } … … 63 147 } else if (!name.equals(other.name)) 64 148 return false; 65 if (uid == null) { 66 if (other.uid != null) 67 return false; 68 } else if (!uid.equals(other.uid)) 149 if (uid != other.uid) 69 150 return false; 70 151 return true; -
trunk/src/org/openstreetmap/josm/data/osm/Way.java
r2017 r2070 119 119 120 120 /** 121 * Creates a new way with id 0. 122 * 123 */ 124 public Way(){ 125 } 126 127 /** 121 128 * Create an identical clone of the argument (including the id). 122 129 * … … 124 131 */ 125 132 public Way(Way original) { 133 super(original.getId()); 126 134 cloneFrom(original); 127 135 } 128 136 129 137 /** 130 * Create an empty way without id. Use this only if you set meaningful 131 * values yourself. 132 */ 133 public Way() { 134 } 135 136 /** 137 * Create an incomplete Way with a given id. 138 * 139 * @param id the id. id > 0 required. 140 */ 141 public Way(long id) { 142 // FIXME: shouldn't we check for id > 0? 143 // 144 this.id = id; 145 incomplete = true; 138 * Creates a new way for the given id. If the id > 0, the way is marked 139 * as incomplete. 140 * 141 * @param id the id. > 0 required 142 * @throws IllegalArgumentException thrown if id < 0 143 */ 144 public Way(long id) throws IllegalArgumentException { 145 super(id); 146 146 } 147 147 … … 153 153 154 154 @Override public String toString() { 155 if (incomplete) return "{Way id="+ id+" version="+version+" (incomplete)}";156 return "{Way id="+ id+" version="+version+" nodes="+Arrays.toString(nodes.toArray())+"}";155 if (incomplete) return "{Way id="+getId()+" version="+getVersion()+" (incomplete)}"; 156 return "{Way id="+getId()+" version="+getVersion()+" nodes="+Arrays.toString(nodes.toArray())+"}"; 157 157 } 158 158 … … 170 170 if (o instanceof Relation) 171 171 return 1; 172 return o instanceof Way ? Long.valueOf( id).compareTo(o.id) : -1;172 return o instanceof Way ? Long.valueOf(getId()).compareTo(o.getId()) : -1; 173 173 } 174 174 -
trunk/src/org/openstreetmap/josm/data/osm/visitor/CollectBackReferencesVisitor.java
r1937 r2070 46 46 public void visit(Node n) { 47 47 for (Way w : ds.ways) { 48 if (w.deleted || w.incomplete) continue; 48 if (w.isDeleted() || w.incomplete) { 49 continue; 50 } 49 51 for (Node n2 : w.getNodes()) { 50 52 if (n == n2) { … … 72 74 // references. 73 75 for (Relation r : ds.relations) { 74 if (r.incomplete || r.deleted) continue; 76 if (r.incomplete || r.isDeleted()) { 77 continue; 78 } 75 79 for (RelationMember m : r.getMembers()) { 76 80 if (m.getMember() == p) { -
trunk/src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java
r2025 r2070 236 236 if (myPrimitivesWithDefinedIds.containsKey(other.getId())) { 237 237 P my = myPrimitivesWithDefinedIds.get(other.getId()); 238 if (my. version <= other.version) {238 if (my.getVersion() <= other.getVersion()) { 239 239 if (! my.isVisible() && other.isVisible()) { 240 240 // should not happen … … 243 243 + "their primitive with lower version {2} is not visible. " 244 244 + "Can't deal with this inconsistency. Keeping my primitive. ", 245 Long.toString(my.getId()),Long.toString(my. version), Long.toString(other.version)245 Long.toString(my.getId()),Long.toString(my.getVersion()), Long.toString(other.getVersion()) 246 246 )); 247 247 merged.put(other, my); … … 270 270 // 271 271 merged.put(other, my); 272 } else if (my.isDeleted() && ! other.isDeleted() && my. version == other.version) {272 } else if (my.isDeleted() && ! other.isDeleted() && my.getVersion() == other.getVersion()) { 273 273 // same version, but my is deleted. Assume mine takes precedence 274 274 // otherwise too many conflicts when refreshing from the server … … 288 288 my.cloneFrom(other); 289 289 merged.put(other, my); 290 } else if (! my.isModified() && !other.isModified() && my. version == other.version) {290 } else if (! my.isModified() && !other.isModified() && my.getVersion() == other.getVersion()) { 291 291 // both not modified. Keep mine 292 292 // 293 293 merged.put(other,my); 294 } else if (! my.isModified() && !other.isModified() && my. version < other.version) {294 } else if (! my.isModified() && !other.isModified() && my.getVersion() < other.getVersion()) { 295 295 // my not modified but other is newer. clone other onto mine. 296 296 // 297 297 my.cloneFrom(other); 298 298 merged.put(other,my); 299 } else if (my.isModified() && ! other.isModified() && my. version == other.version) {299 } else if (my.isModified() && ! other.isModified() && my.getVersion() == other.getVersion()) { 300 300 // my is same as other but mine is modified 301 301 // => keep mine -
trunk/src/org/openstreetmap/josm/gui/ConditionalOptionPaneUtil.java
r2032 r2070 27 27 * 28 28 */ 29 @Deprecatedpublic class ConditionalOptionPaneUtil {29 public class ConditionalOptionPaneUtil { 30 30 static public final int DIALOG_DISABLED_OPTION = Integer.MIN_VALUE; 31 31 -
trunk/src/org/openstreetmap/josm/gui/DefaultNameFormatter.java
r1997 r2070 74 74 protected String decorateNameWithId(String name, OsmPrimitive primitive) { 75 75 if (Main.pref.getBoolean("osm-primitives.showid")) 76 return name + tr(" [id: {0}]", primitive. id);76 return name + tr(" [id: {0}]", primitive.getId()); 77 77 else 78 78 return name; … … 96 96 } 97 97 if (name == null) { 98 name = node. id == 0 ? tr("node") : ""+ node.id;98 name = node.getId() == 0 ? tr("node") : ""+ node.getId(); 99 99 } 100 100 name += " (" + node.getCoor().latToString(CoordinateFormat.getDefaultFormat()) + ", " + node.getCoor().lonToString(CoordinateFormat.getDefaultFormat()) + ")"; … … 175 175 } 176 176 if (nameTag == null) { 177 name += Long.toString(relation. id) + ", ";177 name += Long.toString(relation.getId()) + ", "; 178 178 } else { 179 179 name += "\"" + nameTag + "\", "; … … 197 197 */ 198 198 public String format(Changeset changeset) { 199 return tr("Changeset {0}",changeset. id);199 return tr("Changeset {0}",changeset.getId()); 200 200 } 201 201 } -
trunk/src/org/openstreetmap/josm/gui/OsmPrimitivRenderer.java
r1990 r2070 3 3 4 4 import java.awt.Component; 5 import java.util.ArrayList; 6 import java.util.Collections; 5 7 6 8 import javax.swing.DefaultListCellRenderer; … … 62 64 ((JLabel)def).setText(value.getDisplayName(DefaultNameFormatter.getInstance())); 63 65 ((JLabel)def).setIcon(ImageProvider.get(OsmPrimitiveType.from(value))); 66 ((JLabel)def).setToolTipText(buildToolTipText(value)); 64 67 } 65 68 return def; 66 69 } 67 70 71 /** 72 * build the tool tip text for an {@see OsmPrimitive}. It consist of the formatted 73 * key/value pairs for this primitive. 74 * 75 * @param primitive 76 * @return the tool tip text 77 */ 78 public String buildToolTipText(OsmPrimitive primitive) { 79 StringBuilder sb = new StringBuilder(); 80 81 sb.append("<html>"); 82 // show the id 83 // 84 sb.append("<strong>id</strong>=") 85 .append(primitive.getId()) 86 .append("<br>"); 87 88 // show the key/value-pairs, sorted by key 89 // 90 ArrayList<String> keyList = new ArrayList<String>(primitive.keySet()); 91 Collections.sort(keyList); 92 for (int i = 0; i < keyList.size(); i++) { 93 if (i > 0) { 94 sb.append("<br>"); 95 } 96 String key = keyList.get(i); 97 sb.append("<strong>") 98 .append(key) 99 .append("</strong>") 100 .append("="); 101 // make sure long values are split into several rows. Otherwise 102 // the tool tip window can become to wide 103 // 104 String value = primitive.get(key); 105 while(value.length() != 0) { 106 sb.append(value.substring(0,Math.min(50, value.length()))); 107 if (value.length() > 50) { 108 sb.append("<br>"); 109 value = value.substring(50); 110 } else { 111 value = ""; 112 } 113 } 114 } 115 sb.append("</html>"); 116 return sb.toString(); 117 } 68 118 } -
trunk/src/org/openstreetmap/josm/gui/conflict/pair/nodes/NodeListMergeModel.java
r1954 r2070 76 76 @Override 77 77 public boolean isEqualEntry(Node e1, Node e2) { 78 if (e1. id> 0)79 return e1. id == e2.id;78 if (e1.getId() > 0) 79 return e1.getId() == e2.getId(); 80 80 else 81 81 return e1 == e2; -
trunk/src/org/openstreetmap/josm/gui/conflict/pair/properties/PropertiesMergeModel.java
r2017 r2070 166 166 } 167 167 168 myDeletedState = my. deleted;169 theirDeletedState = their. deleted;170 171 myVisibleState = my. visible;172 theirVisibleState = their. visible;168 myDeletedState = my.isDeleted(); 169 theirDeletedState = their.isDeleted(); 170 171 myVisibleState = my.isVisible(); 172 theirVisibleState = their.isVisible(); 173 173 174 174 coordMergeDecision = UNDECIDED; … … 474 474 + "<br>" 475 475 + "Do you want to undelete these nodes too?</html>", 476 Long.toString(dependent.size()), Long.toString(way. id)),476 Long.toString(dependent.size()), Long.toString(way.getId())), 477 477 tr("Undelete additional nodes?"), 478 478 JOptionPane.YES_NO_OPTION, … … 503 503 + "<br>" 504 504 + "Do you want to undelete them too?</html>", 505 Long.toString(dependent.size()), Long.toString(r. id)),505 Long.toString(dependent.size()), Long.toString(r.getId())), 506 506 tr("Undelete dependent primitives?"), 507 507 JOptionPane.YES_NO_OPTION, … … 535 535 HashMap<Long,OsmPrimitive> candidates = new HashMap<Long,OsmPrimitive>(); 536 536 for (Node n : way.getNodes()) { 537 if (n. id> 0 && ! candidates.values().contains(n)) {538 candidates.put(n. id, n);537 if (n.getId() > 0 && ! candidates.values().contains(n)) { 538 candidates.put(n.getId(), n); 539 539 } 540 540 } … … 545 545 ArrayList<OsmPrimitive> toDelete = new ArrayList<OsmPrimitive>(); 546 546 for (OsmPrimitive their : ds.allPrimitives()) { 547 if (candidates.keySet().contains(their. id) && ! their.visible) {548 toDelete.add(candidates.get(their. id));547 if (candidates.keySet().contains(their.getId()) && ! their.isVisible()) { 548 toDelete.add(candidates.get(their.getId())); 549 549 } 550 550 } … … 572 572 HashMap<Long,OsmPrimitive> candidates = new HashMap<Long, OsmPrimitive>(); 573 573 for (RelationMember m : r.getMembers()) { 574 if (m.getMember(). id> 0 && !candidates.values().contains(m.getMember())) {575 candidates.put(m.getMember(). id, m.getMember());574 if (m.getMember().getId() > 0 && !candidates.values().contains(m.getMember())) { 575 candidates.put(m.getMember().getId(), m.getMember()); 576 576 } 577 577 } … … 583 583 ArrayList<OsmPrimitive> toDelete = new ArrayList<OsmPrimitive>(); 584 584 for (OsmPrimitive their : ds.allPrimitives()) { 585 if (candidates.keySet().contains(their. id) && ! their.visible) {586 toDelete.add(candidates.get(their. id));585 if (candidates.keySet().contains(their.getId()) && ! their.isVisible()) { 586 toDelete.add(candidates.get(their.getId())); 587 587 } 588 588 } -
trunk/src/org/openstreetmap/josm/gui/conflict/pair/properties/PropertiesMerger.java
r2017 r2070 586 586 + "it a new id.<br>" 587 587 + "Do yo agree?</html>", 588 model.getMyPrimitive(). id588 model.getMyPrimitive().getId() 589 589 ), 590 590 tr("Reset id to 0"), … … 625 625 + "from the dataset.<br>" 626 626 + "Do you agree?</html>", 627 model.getMyPrimitive(). id627 model.getMyPrimitive().getId() 628 628 ), 629 629 tr("Remove from dataset"), -
trunk/src/org/openstreetmap/josm/gui/conflict/pair/relation/RelationMemberListMergeModel.java
r1954 r2070 25 25 public boolean isEqualEntry(RelationMember e1, RelationMember e2) { 26 26 boolean ret = e1.getRole().equals(e2.getRole()); 27 if (e1.getMember(). id> 0 ) {28 ret = ret && (e1.getMember(). id == e2.getMember().id);27 if (e1.getMember().getId() > 0 ) { 28 ret = ret && (e1.getMember().getId() == e2.getMember().getId()); 29 29 } else { 30 30 ret = ret && (e1 == e2); … … 42 42 public boolean isCellEditable(int row, int column) { 43 43 switch(column) { 44 case 1: return true;45 default: return false;44 case 1: return true; 45 default: return false; 46 46 } 47 47 } -
trunk/src/org/openstreetmap/josm/gui/conflict/pair/relation/RelationMemberTableCellRenderer.java
r1990 r2070 71 71 sb.append("<html>"); 72 72 sb.append("<strong>id</strong>=") 73 .append(primitive. id)73 .append(primitive.getId()) 74 74 .append("<br>"); 75 75 ArrayList<String> keyList = new ArrayList<String>(primitive.keySet()); … … 197 197 renderForeground(getModel(table), member, row, column, isSelected); 198 198 switch(column) { 199 case 0:200 renderRowId(row);201 break;202 case 1:203 if (member == null) {204 renderEmptyRow();205 } else {206 renderRole(member);207 }208 break;209 case 2:210 if (member == null) {211 renderEmptyRow();212 } else {213 renderPrimitive(member);214 }215 break;216 default:217 // should not happen199 case 0: 200 renderRowId(row); 201 break; 202 case 1: 203 if (member == null) { 204 renderEmptyRow(); 205 } else { 206 renderRole(member); 207 } 208 break; 209 case 2: 210 if (member == null) { 211 renderEmptyRow(); 212 } else { 213 renderPrimitive(member); 214 } 215 break; 216 default: 217 // should not happen 218 218 } 219 219 return this; -
trunk/src/org/openstreetmap/josm/gui/conflict/tags/MultiValueResolutionDecision.java
r2008 r2070 127 127 128 128 /** 129 * Replies the concatenation of all tag values (concatenated by a semicolon)130 *131 * @return the concatenation of all tag values132 */133 protected String joinValues() {134 StringBuffer buffer = new StringBuffer();135 List<String> values = new ArrayList<String>(tags.getValues());136 values.remove("");137 Collections.sort(values);138 Iterator<String> iter = values.iterator();139 while (iter.hasNext()) {140 buffer.append(iter.next());141 if (iter.hasNext()) {142 buffer.append(";");143 }144 }145 return buffer.toString();146 }147 148 /**149 129 * Replies the chosen value 150 130 * … … 157 137 case KEEP_ONE: return value; 158 138 case KEEP_NONE: return null; 159 case KEEP_ALL: return joinValues();139 case KEEP_ALL: return tags.getJoinedValues(getKey()); 160 140 } 161 141 // should not happen … … 171 151 ArrayList<String> ret = new ArrayList<String>(tags.getValues()); 172 152 ret.remove(""); 153 ret.remove(null); 173 154 Collections.sort(ret); 174 155 return ret; … … 303 284 public Tag getResolution() { 304 285 switch(type) { 305 case KEEP_ALL: return new Tag(getKey(), joinValues());286 case KEEP_ALL: return new Tag(getKey(), tags.getJoinedValues(getKey())); 306 287 case KEEP_ONE: return new Tag(getKey(),value); 307 288 case KEEP_NONE: return new Tag(getKey(), ""); -
trunk/src/org/openstreetmap/josm/gui/conflict/tags/PasteTagsConflictResolverDialog.java
r2008 r2070 148 148 String msg = ""; 149 149 switch(type) { 150 151 152 150 case NODE: msg= trn("{0} node", "{0} nodes", count, count); break; 151 case WAY: msg= trn("{0} way", "{0} ways", count, count); break; 152 case RELATION: msg= trn("{0} relation", "{0} relations", count, count); break; 153 153 } 154 154 return msg; … … 295 295 296 296 public void propertyChange(PropertyChangeEvent evt) { 297 if (evt.getPropertyName().equals(TagConflictResolverModel. RESOLVED_COMPLETELY_PROP)) {297 if (evt.getPropertyName().equals(TagConflictResolverModel.NUM_CONFLICTS_PROP)) { 298 298 updateEnabledState(); 299 299 } … … 324 324 325 325 public void propertyChange(PropertyChangeEvent evt) { 326 if (evt.getPropertyName().equals(TagConflictResolverModel. RESOLVED_COMPLETELY_PROP)) {326 if (evt.getPropertyName().equals(TagConflictResolverModel.NUM_CONFLICTS_PROP)) { 327 327 TagConflictResolverModel model = (TagConflictResolverModel)evt.getSource(); 328 328 for (int i=0; i < tpResolvers.getTabCount();i++) { … … 446 446 String msg = ""; 447 447 switch(type) { 448 449 450 448 case NODE: msg = trn("{0} node", "{0} nodes", numPrimitives,numPrimitives); break; 449 case WAY: msg = trn("{0} way", "{0} ways", numPrimitives, numPrimitives); break; 450 case RELATION: msg = trn("{0} relation", "{0} relations", numPrimitives, numPrimitives); break; 451 451 } 452 452 text = text.equals("") ? msg : text + ", " + msg; … … 472 472 String msg = ""; 473 473 switch(type) { 474 475 476 474 case NODE: msg = trn("{0} node", "{0} nodes", numPrimitives,numPrimitives); break; 475 case WAY: msg = trn("{0} way", "{0} ways", numPrimitives, numPrimitives); break; 476 case RELATION: msg = trn("{0} relation", "{0} relations", numPrimitives, numPrimitives); break; 477 477 } 478 478 text = text.equals("") ? msg : text + ", " + msg; … … 491 491 492 492 switch(column) { 493 494 495 493 case 0: renderNumTags(info); break; 494 case 1: renderFrom(info); break; 495 case 2: renderTo(info); break; 496 496 } 497 497 } -
trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolverModel.java
r2017 r2070 17 17 18 18 public class TagConflictResolverModel extends DefaultTableModel { 19 static public final String RESOLVED_COMPLETELY_PROP = TagConflictResolverModel.class.getName() + ".resolvedCompletely";19 static public final String NUM_CONFLICTS_PROP = TagConflictResolverModel.class.getName() + ".numConflicts"; 20 20 21 21 private TagCollection tags; 22 22 private List<String> keys; 23 23 private HashMap<String, MultiValueResolutionDecision> decisions; 24 private boolean resolvedCompletely;24 private int numConflicts; 25 25 private PropertyChangeSupport support; 26 26 27 27 public TagConflictResolverModel() { 28 resolvedCompletely= false;28 numConflicts = 0; 29 29 support = new PropertyChangeSupport(this); 30 30 } … … 38 38 } 39 39 40 protected void setResolvedCompletely(boolean resolvedCompletey) { 41 boolean oldValue = this.resolvedCompletely; 42 this.resolvedCompletely = resolvedCompletey; 43 if (oldValue != this.resolvedCompletely) { 44 support.firePropertyChange(RESOLVED_COMPLETELY_PROP, oldValue, this.resolvedCompletely); 40 41 protected void setNumConflicts(int numConflicts) { 42 int oldValue = this.numConflicts; 43 this.numConflicts = numConflicts; 44 if (oldValue != this.numConflicts) { 45 support.firePropertyChange(NUM_CONFLICTS_PROP, oldValue, this.numConflicts); 45 46 } 46 47 } 47 48 48 protected void refreshResolvedCompletely() { 49 protected void refreshNumConflicts() { 50 int count = 0; 49 51 for (MultiValueResolutionDecision d : decisions.values()) { 50 52 if (!d.isDecided()) { 51 setResolvedCompletely(false); 52 return; 53 count++; 53 54 } 54 55 } 55 set ResolvedCompletely(true);56 setNumConflicts(count); 56 57 } 57 58 … … 78 79 decisions.put(key,decision); 79 80 } 80 refresh ResolvedCompletely();81 refreshNumConflicts(); 81 82 } 82 83 … … 126 127 } 127 128 fireTableDataChanged(); 128 refresh ResolvedCompletely();129 refreshNumConflicts(); 129 130 } 130 131 … … 136 137 */ 137 138 public boolean isResolvedCompletely() { 138 return resolvedCompletely; 139 return numConflicts == 0; 140 } 141 142 public int getNumConflicts() { 143 return numConflicts; 144 } 145 146 public int getNumDecisions() { 147 return getRowCount(); 139 148 } 140 149 … … 146 155 return tc; 147 156 } 157 158 public MultiValueResolutionDecision getDecision(int row) { 159 return decisions.get(keys.get(row)); 160 } 161 162 public void refresh() { 163 fireTableDataChanged(); 164 refreshNumConflicts(); 165 } 148 166 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java
r2019 r2070 220 220 return; 221 221 for (OsmPrimitive primitive: Main.main.getCurrentDataSet().getSelected()) { 222 if (primitive. id== 0) {222 if (primitive.getId() == 0) { 223 223 continue; 224 224 } 225 History h = HistoryDataSet.getInstance().getHistory(primitive. id);225 History h = HistoryDataSet.getInstance().getHistory(primitive.getId()); 226 226 if (h !=null) { 227 227 data.add(h); -
trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java
r2025 r2070 379 379 380 380 public void launchEditorForDuplicate(Relation original) { 381 Relation copy = new Relation( );381 Relation copy = new Relation(original.getId()); 382 382 copy.cloneFrom(original); 383 // FIXME: id is going to be hidden. How to reset a primitive? 384 // 385 copy.id = 0; 383 copy.clearOsmId(); 386 384 copy.setModified(true); 387 385 RelationEditor editor = RelationEditor.getEditor( -
trunk/src/org/openstreetmap/josm/gui/dialogs/UserListDialog.java
r2042 r2070 201 201 User user = (User)infoObject; 202 202 try { 203 return getBaseUserUrl() + "/" + URLEncoder.encode(user. name, "UTF-8");203 return getBaseUserUrl() + "/" + URLEncoder.encode(user.getName(), "UTF-8"); 204 204 } catch(UnsupportedEncodingException e) { 205 205 e.printStackTrace(); … … 251 251 if (count < o.count) return 1; 252 252 if (count > o.count) return -1; 253 if (user== null || user. name== null) return 1;254 if (o.user == null || o.user. name== null) return -1;255 return user. name.compareTo(o.user.name);253 if (user== null || user.getName() == null) return 1; 254 if (o.user == null || o.user.getName() == null) return -1; 255 return user.getName().compareTo(o.user.getName()); 256 256 } 257 257 258 258 public String getName() { 259 259 if (user == null) return null; 260 return user. name;260 return user.getName(); 261 261 } 262 262 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/ChildRelationBrowser.java
r2017 r2070 361 361 */ 362 362 protected void rememberChildRelationsToDownload(Relation parent) { 363 downloadedRelationIds.add(parent. id);363 downloadedRelationIds.add(parent.getId()); 364 364 for (RelationMember member: parent.getMembers()) { 365 365 if (member.isRelation()) { … … 403 403 while(! relationsToDownload.isEmpty() && !cancelled) { 404 404 Relation r = relationsToDownload.pop(); 405 if (r. id== 0) {405 if (r.getId() == 0) { 406 406 continue; 407 407 } 408 408 rememberChildRelationsToDownload(r); 409 409 progressMonitor.setCustomText(tr("Downloading relation {0}", r.getDisplayName(DefaultNameFormatter.getInstance()))); 410 OsmServerObjectReader reader = new OsmServerObjectReader(r. id, OsmPrimitiveType.RELATION,410 OsmServerObjectReader reader = new OsmServerObjectReader(r.getId(), OsmPrimitiveType.RELATION, 411 411 true); 412 412 DataSet dataSet = null; … … 514 514 while(it.hasNext() && !cancelled) { 515 515 Relation r = it.next(); 516 if (r. id== 0) {516 if (r.getId() == 0) { 517 517 continue; 518 518 } 519 519 progressMonitor.setCustomText(tr("Downloading relation {0}", r.getDisplayName(DefaultNameFormatter.getInstance()))); 520 OsmServerObjectReader reader = new OsmServerObjectReader(r. id, OsmPrimitiveType.RELATION,520 OsmServerObjectReader reader = new OsmServerObjectReader(r.getId(), OsmPrimitiveType.RELATION, 521 521 true); 522 522 DataSet dataSet = reader.parseOsm(progressMonitor -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableCellRenderer.java
r1822 r2070 35 35 StringBuilder sb = new StringBuilder(); 36 36 sb.append("<html>"); 37 sb.append("<strong>id</strong>=").append(primitive. id).append("<br>");37 sb.append("<strong>id</strong>=").append(primitive.getId()).append("<br>"); 38 38 ArrayList<String> keyList = new ArrayList<String>(primitive.keySet()); 39 39 Collections.sort(keyList); -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
r1951 r2070 198 198 public void updateMemberReferences(DataSet ds) { 199 199 for (RelationMember member : members) { 200 if (member.getMember(). id== 0) {200 if (member.getMember().getId() == 0) { 201 201 continue; 202 202 } 203 OsmPrimitive primitive = ds.getPrimitiveById(member.getMember(). id);203 OsmPrimitive primitive = ds.getPrimitiveById(member.getMember().getId()); 204 204 if (primitive != null) { 205 205 member.member = primitive; -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/ParentRelationLoadingTask.java
r2017 r2070 70 70 * @exception IllegalArgumentException thrown if child is null 71 71 * @exception IllegalArgumentException thrown if layer is null 72 * @exception IllegalArgumentException thrown if child. id== 072 * @exception IllegalArgumentException thrown if child.getId() == 0 73 73 */ 74 74 public ParentRelationLoadingTask(Relation child, OsmDataLayer layer, boolean full, PleaseWaitProgressMonitor monitor ) { … … 78 78 if (layer == null) 79 79 throw new IllegalArgumentException(tr("parameter ''{0}'' must not be null", "layer")); 80 if (child. id== 0)81 throw new IllegalArgumentException(tr("child. id >0 expected. Got {1}", child.id));80 if (child.getId() == 0) 81 throw new IllegalArgumentException(tr("child.getId() >0 expected. Got {1}", child.getId())); 82 82 referrers = null; 83 83 this.layer = layer; … … 150 150 parents.clear(); 151 151 for (Relation parent : referrers.relations) { 152 parents.add((Relation)getLayer().data.getPrimitiveById(parent. id));152 parents.add((Relation)getLayer().data.getPrimitiveById(parent.getId())); 153 153 } 154 154 if (continuation != null) { -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/ReferringRelationsBrowserModel.java
r1938 r2070 89 89 90 90 public boolean canReload() { 91 return relation != null && relation. id> 0;91 return relation != null && relation.getId() > 0; 92 92 } 93 93 -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationDialogManager.java
r1857 r2070 90 90 @Override 91 91 public String toString() { 92 return "[Context: layer=" + layer.getName() + ",relation=" + relation. id+ "]";92 return "[Context: layer=" + layer.getName() + ",relation=" + relation.getId() + "]"; 93 93 } 94 94 } … … 103 103 openDialogs = new HashMap<DialogContext, RelationEditor>(); 104 104 } 105 106 105 /** 107 106 * Register the relation editor for a relation managed by a -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationEditor.java
r1871 r2070 117 117 if (getRelation() == null) { 118 118 setTitle(tr("Create new relation in layer ''{0}''", layer.getName())); 119 } else if (getRelation(). id== 0) {119 } else if (getRelation().getId() == 0) { 120 120 setTitle(tr("Edit new relation in layer ''{0}''", layer.getName())); 121 121 } else { 122 setTitle(tr("Edit relation #{0} in layer ''{1}''", relation. id, layer.getName()));122 setTitle(tr("Edit relation #{0} in layer ''{1}''", relation.getId(), layer.getName())); 123 123 } 124 124 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationTree.java
r1828 r2070 91 91 TreePath path = event.getPath(); 92 92 Relation parent = (Relation)event.getPath().getLastPathComponent(); 93 if (! parent.incomplete || parent. id== 0)93 if (! parent.incomplete || parent.getId() == 0) 94 94 // we don't load complete or new relations 95 95 return; … … 154 154 protected void realRun() throws SAXException, IOException, OsmTransferException { 155 155 try { 156 OsmServerObjectReader reader = new OsmServerObjectReader(relation. id, OsmPrimitiveType.from(relation), true /* full load */);156 OsmServerObjectReader reader = new OsmServerObjectReader(relation.getId(), OsmPrimitiveType.from(relation), true /* full load */); 157 157 ds = reader.parseOsm(progressMonitor 158 158 .createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/SelectionTableCellRenderer.java
r1990 r2070 60 60 sb.append("<html>"); 61 61 sb.append("<strong>id</strong>=") 62 .append(primitive. id)62 .append(primitive.getId()) 63 63 .append("<br>"); 64 64 ArrayList<String> keyList = new ArrayList<String>(primitive.keySet()); -
trunk/src/org/openstreetmap/josm/gui/history/HistoryLoadTask.java
r2019 r2070 68 68 if (primitive == null) 69 69 throw new IllegalArgumentException(tr("parameter ''{0}'' must not be null", "primitive")); 70 return add(primitive. id, OsmPrimitiveType.from(primitive));70 return add(primitive.getId(), OsmPrimitiveType.from(primitive)); 71 71 } 72 72 -
trunk/src/org/openstreetmap/josm/gui/tagging/AutoCompletingTextField.java
r2048 r2070 7 7 import java.awt.event.KeyAdapter; 8 8 import java.awt.event.KeyEvent; 9 import java.util.ArrayList; 10 import java.util.EventObject; 11 import java.util.LinkedList; 12 import java.util.List; 9 13 import java.util.logging.Logger; 10 14 11 15 import javax.swing.ComboBoxEditor; 16 import javax.swing.JTable; 12 17 import javax.swing.JTextField; 18 import javax.swing.event.CellEditorListener; 19 import javax.swing.event.ChangeEvent; 20 import javax.swing.table.TableCellEditor; 13 21 import javax.swing.text.AttributeSet; 14 22 import javax.swing.text.BadLocationException; … … 17 25 18 26 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList; 27 import org.openstreetmap.josm.gui.util.TableCellEditorSupport; 19 28 20 29 /** … … 27 36 * 28 37 */ 29 public class AutoCompletingTextField extends JTextField implements ComboBoxEditor {38 public class AutoCompletingTextField extends JTextField implements ComboBoxEditor, TableCellEditor { 30 39 31 40 static private Logger logger = Logger.getLogger(AutoCompletingTextField.class.getName()); … … 133 142 } 134 143 ); 144 tableCellEditorSupport = new TableCellEditorSupport(this); 135 145 } 136 146 … … 187 197 } 188 198 189 199 /* ------------------------------------------------------------------------------------ */ 200 /* TableCellEditor interface */ 201 /* ------------------------------------------------------------------------------------ */ 202 203 private TableCellEditorSupport tableCellEditorSupport; 204 private String originalValue; 205 206 public void addCellEditorListener(CellEditorListener l) { 207 tableCellEditorSupport.addCellEditorListener(l); 208 } 209 210 protected void rememberOriginalValue(String value) { 211 this.originalValue = value; 212 } 213 214 protected void restoreOriginalValue() { 215 setText(originalValue); 216 } 217 218 public void removeCellEditorListener(CellEditorListener l) { 219 tableCellEditorSupport.removeCellEditorListener(l); 220 } 221 public void cancelCellEditing() { 222 restoreOriginalValue(); 223 tableCellEditorSupport.fireEditingCanceled(); 224 225 } 226 227 public Object getCellEditorValue() { 228 return getText(); 229 } 230 231 public boolean isCellEditable(EventObject anEvent) { 232 return true; 233 } 234 235 236 public boolean shouldSelectCell(EventObject anEvent) { 237 return true; 238 } 239 240 public boolean stopCellEditing() { 241 tableCellEditorSupport.fireEditingStopped(); 242 return true; 243 } 244 245 public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 246 setText( value == null ? "" : value.toString()); 247 rememberOriginalValue(getText()); 248 return this; 249 } 190 250 } -
trunk/src/org/openstreetmap/josm/io/DiffResultReader.java
r2039 r2070 94 94 public void visit(Node n) { 95 95 String key = "node:" + (newIdMap.containsKey(n) ? newIdMap.get(n) : n.getId()); 96 System.out.println("key: "+key);97 96 Long[] nv = versions.get(key); 98 97 if (nv != null) { 99 98 processed.add(n); 100 99 if (!n.isDeleted()) { 101 n. id = nv[0]; n.version = nv[1].intValue();100 n.setOsmId(nv[0], nv[1].intValue()); 102 101 } 103 102 } … … 109 108 processed.add(w); 110 109 if (!w.isDeleted()) { 111 w. id = nv[0]; w.version = nv[1].intValue();110 w.setOsmId(nv[0], nv[1].intValue()); 112 111 } 113 112 } … … 119 118 processed.add(r); 120 119 if (!r.isDeleted()) { 121 r. id = nv[0]; r.version = nv[1].intValue();120 r.setOsmId(nv[0], nv[1].intValue()); 122 121 } 123 122 } -
trunk/src/org/openstreetmap/josm/io/FileImporter.java
r1637 r2070 21 21 } 22 22 23 public void importData(File file) throws IOException {23 public void importData(File file) throws IOException, IllegalDataException { 24 24 throw new IOException(tr("Could not read \"{0}\"", file.getName())); 25 25 } -
trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java
r2025 r2070 204 204 remember(relation.getId(), OsmPrimitiveType.RELATION); 205 205 for (RelationMember member : relation.getMembers()) { 206 if (OsmPrimitiveType.from(member. member).equals(OsmPrimitiveType.RELATION)) {206 if (OsmPrimitiveType.from(member.getMember()).equals(OsmPrimitiveType.RELATION)) { 207 207 // avoid infinite recursion in case of cyclic dependencies in relations 208 208 // 209 if (relations.contains(member. member.getId())) {209 if (relations.contains(member.getMember().getId())) { 210 210 continue; 211 211 } … … 325 325 progressMonitor.subTask(tr("Downloading OSM data...")); 326 326 try { 327 final OsmReader osm = OsmReader.parseDataSetOsm(in, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); 328 merge(osm.getDs()); 327 328 merge( 329 OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)) 330 ); 329 331 } catch(Exception e) { 330 332 throw new OsmTransferException(e); … … 348 350 progressMonitor.subTask(tr("Downloading OSM data...")); 349 351 try { 350 final OsmReader osm = OsmReader.parseDataSetOsm(in, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); 351 merge(osm.getDs()); 352 merge( 353 OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)) 354 ); 352 355 } catch(Exception e) { 353 356 throw new OsmTransferException(e); -
trunk/src/org/openstreetmap/josm/io/OsmApi.java
r2061 r2070 233 233 try { 234 234 ret = sendRequest("PUT", OsmPrimitiveType.from(osm).getAPIName()+"/create", toXml(osm, true),monitor); 235 osm.id = Long.parseLong(ret.trim()); 236 osm.version = 1; 235 osm.setOsmId(Long.parseLong(ret.trim()), 1); 237 236 } catch(NumberFormatException e){ 238 237 throw new OsmTransferException(tr("unexpected format of id replied by the server, got ''{0}''", ret)); … … 258 257 try { 259 258 ret = sendRequest("PUT", OsmPrimitiveType.from(osm).getAPIName()+"/" + osm.getId(), toXml(osm, true), monitor); 260 osm. version = Integer.parseInt(ret.trim());259 osm.setOsmId(osm.getId(), Integer.parseInt(ret.trim())); 261 260 } catch(NumberFormatException e) { 262 261 throw new OsmTransferException(tr("unexpected format of new version of modified primitive ''{0}'', got ''{1}''", osm.getId(), ret)); … … 341 340 return; 342 341 } 343 changeset.id = this.changeset.getId(); 344 this.changeset.cloneFrom(changeset); 342 this.changeset.setKeys(changeset.getKeys()); 345 343 progressMonitor.setCustomText(tr("Updating changeset {0}...", changeset.getId())); 346 344 sendRequest( … … 473 471 */ 474 472 private String sendRequest(String requestMethod, String urlSuffix,String requestBody, ProgressMonitor monitor) throws OsmTransferException { 475 476 473 StringBuffer responseBody = new StringBuffer(); 477 474 -
trunk/src/org/openstreetmap/josm/io/OsmBzip2Importer.java
r2001 r2070 11 11 import org.apache.tools.bzip2.CBZip2InputStream; 12 12 import org.openstreetmap.josm.actions.ExtensionFileFilter; 13 import org.xml.sax.SAXException;14 13 15 14 public class OsmBzip2Importer extends OsmImporter { … … 21 20 22 21 @Override 23 public void importData(File file) throws IOException {22 public void importData(File file) throws IOException, IllegalDataException { 24 23 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); 25 24 int b = bis.read(); 26 if (b != 'B') {25 if (b != 'B') 27 26 throw new IOException(tr("Invalid bz2 file.")); 28 }29 27 b = bis.read(); 30 if (b != 'Z') {28 if (b != 'Z') 31 29 throw new IOException(tr("Invalid bz2 file.")); 32 }33 30 CBZip2InputStream in = new CBZip2InputStream(bis); 34 35 try { 36 importData(in, file); 37 } catch (SAXException e) { 38 e.printStackTrace(); 39 throw new IOException(tr("Could not read \"{0}\"", file.getName())); 40 } 31 importData(in, file); 41 32 } 42 33 } -
trunk/src/org/openstreetmap/josm/io/OsmGzipImporter.java
r1653 r2070 10 10 11 11 import org.openstreetmap.josm.actions.ExtensionFileFilter; 12 import org.xml.sax.SAXException;13 12 14 13 public class OsmGzipImporter extends OsmImporter { … … 19 18 20 19 @Override 21 public void importData(File file) throws IOException {20 public void importData(File file) throws IOException, IllegalDataException { 22 21 GZIPInputStream in = new GZIPInputStream(new FileInputStream(file)); 23 try { 24 importData(in, file); 25 } catch (SAXException e) { 26 e.printStackTrace(); 27 throw new IOException(tr("Could not read \"{0}\"", file.getName())); 28 } 22 importData(in, file); 29 23 } 30 24 } -
trunk/src/org/openstreetmap/josm/io/OsmImporter.java
r2050 r2070 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.awt.HeadlessException;7 6 import java.io.File; 8 7 import java.io.FileInputStream; … … 18 17 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 19 18 import org.openstreetmap.josm.gui.progress.NullProgressMonitor; 20 import org.xml.sax.SAXException;21 19 22 20 public class OsmImporter extends FileImporter { … … 30 28 } 31 29 32 @Override public void importData(File file) throws IOException {30 @Override public void importData(File file) throws IOException, IllegalDataException { 33 31 try { 34 32 FileInputStream in = new FileInputStream(file); 35 33 importData(in, file); 36 } catch (HeadlessException e) {37 e.printStackTrace();38 throw new IOException(tr("Could not read \"{0}\"", file.getName()));39 34 } catch (FileNotFoundException e) { 40 35 e.printStackTrace(); 41 36 throw new IOException(tr("File \"{0}\" does not exist", file.getName())); 42 } catch (SAXException e) {43 e.printStackTrace();44 throw new IOException(tr("Parsing file \"{0}\" failed", file.getName()));45 37 } 46 38 } 47 39 48 protected void importData(InputStream in, File associatedFile) throws SAXException, IOException { 49 OsmReader osm = OsmReader.parseDataSetOsm(in, NullProgressMonitor.INSTANCE); 50 DataSet dataSet = osm.getDs(); 40 protected void importData(InputStream in, File associatedFile) throws IllegalDataException { 41 DataSet dataSet = OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE); 51 42 final OsmDataLayer layer = new OsmDataLayer(dataSet, associatedFile.getName(), associatedFile); 52 43 // FIXME: remove UI stuff from IO subsystem -
trunk/src/org/openstreetmap/josm/io/OsmReader.java
r1951 r2070 1 // License: GPL. Copyright 2007 by Immanuel Scholz and others2 1 package org.openstreetmap.josm.io; 3 2 4 3 import static org.openstreetmap.josm.tools.I18n.tr; 5 4 6 import java.io.IOException;7 5 import java.io.InputStream; 8 6 import java.io.InputStreamReader; … … 14 12 import java.util.List; 15 13 import java.util.Map; 16 import java.util.Map.Entry;17 14 import java.util.logging.Logger; 18 15 … … 34 31 import org.xml.sax.Attributes; 35 32 import org.xml.sax.InputSource; 33 import org.xml.sax.Locator; 36 34 import org.xml.sax.SAXException; 37 35 import org.xml.sax.helpers.DefaultHandler; … … 40 38 * Parser for the Osm Api. Read from an input stream and construct a dataset out of it. 41 39 * 42 * Reading process takes place in three phases. During the first phase (including xml parse),43 * all nodes are read and stored. Other information than nodes are stored in a raw list44 *45 * The second phase read all ways out of the remaining objects in the raw list.46 *47 * @author Imi48 40 */ 49 41 public class OsmReader { … … 54 46 */ 55 47 private DataSet ds = new DataSet(); 56 public DataSet getDs() { return ds; } 57 58 /** 59 * All read nodes after phase 1. 60 */ 61 private Map<Long, Node> nodes = new HashMap<Long, Node>(); 48 49 /** 50 * Replies the parsed data set 51 * 52 * @return the parsed data set 53 */ 54 public DataSet getDataSet() { 55 return ds; 56 } 57 58 /** the map from external ids to read OsmPrimitives. External ids are 59 * longs too, but in contrast to internal ids negative values are used 60 * to identify primitives unknown to the OSM server 61 * 62 * The keys are strings composed as follows 63 * <ul> 64 * <li>"n" + id for nodes</li> 65 * <li>"w" + id for nodes</li> 66 * <li>"r" + id for nodes</li> 67 * </ul> 68 */ 69 private Map<String, OsmPrimitive> externalIdMap = new HashMap<String, OsmPrimitive>(); 62 70 63 71 … … 69 77 */ 70 78 private OsmReader() { 79 externalIdMap = new HashMap<String, OsmPrimitive>(); 71 80 } 72 81 73 82 private static class OsmPrimitiveData { 74 83 public long id = 0; 75 public Map<String,String> keys = new HashMap<String, String>();76 84 public boolean modified = false; 77 public boolean selected = false;78 85 public boolean deleted = false; 79 86 public Date timestamp = new Date(); 80 87 public User user = null; 81 88 public boolean visible = true; 82 public int version = -1;89 public int version = 0; 83 90 public LatLon latlon = new LatLon(0,0); 91 private OsmPrimitive primitive; 84 92 85 93 public void copyTo(OsmPrimitive osm) { 86 osm.id = id; 87 osm.setKeys(keys); 88 osm.modified = modified; 89 osm.setSelected(selected); 90 osm.deleted = deleted; 94 osm.setModified(modified); 95 osm.setDeleted(deleted); 96 // id < 0 possible if read from a file 97 if (id <= 0) { 98 osm.clearOsmId(); 99 } else { 100 osm.setOsmId(id, version); 101 } 91 102 osm.setTimestamp(timestamp); 92 103 osm.user = user; 93 osm.visible = visible; 94 osm.version = version; 104 osm.setVisible(visible); 95 105 osm.mappaintStyle = null; 96 106 } 97 107 98 108 public Node createNode() { 99 Node node = new Node(latlon); 109 Node node = new Node(); 110 node.setCoor(latlon); 100 111 copyTo(node); 112 primitive = node; 101 113 return node; 102 114 } 103 115 104 116 public Way createWay() { 105 Way way = new Way( id);117 Way way = new Way(); 106 118 copyTo(way); 119 primitive = way; 107 120 return way; 108 121 } 109 110 122 public Relation createRelation() { 111 Relation rel = new Relation(id); 112 copyTo(rel); 113 return rel; 123 Relation relation= new Relation(); 124 copyTo(relation); 125 primitive = relation; 126 return relation; 127 } 128 129 public void rememberTag(String key, String value) { 130 primitive.put(key, value); 114 131 } 115 132 } … … 128 145 * Data structure for the remaining way objects 129 146 */ 130 private Map< OsmPrimitiveData, Collection<Long>> ways = new HashMap<OsmPrimitiveData, Collection<Long>>();147 private Map<Long, Collection<Long>> ways = new HashMap<Long, Collection<Long>>(); 131 148 132 149 /** 133 150 * Data structure for relation objects 134 151 */ 135 private Map<OsmPrimitiveData, Collection<RelationMemberData>> relations = new HashMap<OsmPrimitiveData, Collection<RelationMemberData>>(); 152 private Map<Long, Collection<RelationMemberData>> relations = new HashMap<Long, Collection<RelationMemberData>>(); 153 154 static public class OsmDataParsingException extends SAXException { 155 private int columnNumber; 156 private int lineNumber; 157 158 public OsmDataParsingException() { 159 super(); 160 } 161 162 public OsmDataParsingException(Exception e) { 163 super(e); 164 } 165 166 public OsmDataParsingException(String message, Exception e) { 167 super(message, e); 168 } 169 170 public OsmDataParsingException(String message) { 171 super(message); 172 } 173 174 public OsmDataParsingException rememberLocation(Locator locator) { 175 if (locator == null) return this; 176 this.columnNumber = locator.getColumnNumber(); 177 this.lineNumber = locator.getLineNumber(); 178 return this; 179 } 180 181 @Override 182 public String getMessage() { 183 String msg = super.getMessage(); 184 if (lineNumber == 0 && columnNumber == 0) 185 return msg; 186 if (msg == null) { 187 msg = getClass().getName(); 188 } 189 msg = msg + " " + tr("(at line {0}, column {1})", lineNumber, columnNumber); 190 return msg; 191 } 192 193 public int getColumnNumber() { 194 return columnNumber; 195 } 196 197 public int getLineNumber() { 198 return lineNumber; 199 } 200 } 136 201 137 202 private class Parser extends DefaultHandler { 203 private Locator locator; 204 205 @Override 206 public void setDocumentLocator(Locator locator) { 207 this.locator = locator; 208 } 209 210 protected void throwException(String msg) throws OsmDataParsingException{ 211 throw new OsmDataParsingException(msg).rememberLocation(locator); 212 } 138 213 /** 139 214 * The current osm primitive to be read. … … 143 218 144 219 @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { 145 try { 146 if (qName.equals("osm")) { 147 if (atts == null) 148 throw new SAXException(tr("Unknown version")); 149 String v = atts.getValue("version"); 150 if (v == null) 151 throw new SAXException(tr("Version number missing from OSM data")); 152 if (!(v.equals("0.5") || v.equals("0.6"))) 153 throw new SAXException(tr("Unknown version: {0}", v)); 154 // save generator attribute for later use when creating DataSource objects 155 generator = atts.getValue("generator"); 156 ds.version = v; 157 158 } else if (qName.equals("bounds")) { 159 // new style bounds. 160 String minlon = atts.getValue("minlon"); 161 String minlat = atts.getValue("minlat"); 162 String maxlon = atts.getValue("maxlon"); 163 String maxlat = atts.getValue("maxlat"); 164 String origin = atts.getValue("origin"); 165 if (minlon != null && maxlon != null && minlat != null && maxlat != null) { 166 if (origin == null) { 167 origin = generator; 168 } 169 Bounds bounds = new Bounds( 170 new LatLon(Double.parseDouble(minlat), Double.parseDouble(minlon)), 171 new LatLon(Double.parseDouble(maxlat), Double.parseDouble(maxlon))); 172 DataSource src = new DataSource(bounds, origin); 173 ds.dataSources.add(src); 220 if (qName.equals("osm")) { 221 if (atts == null) { 222 throwException(tr("Missing mandatory attribute ''{0}'' of XML element {1}", "version", "osm")); 223 } 224 String v = atts.getValue("version"); 225 if (v == null) { 226 throwException(tr("Missing mandatory attribute ''{0}''", "version")); 227 } 228 if (!(v.equals("0.5") || v.equals("0.6"))) { 229 throwException(tr("Unsupported version: {0}", v)); 230 } 231 // save generator attribute for later use when creating DataSource objects 232 generator = atts.getValue("generator"); 233 ds.version = v; 234 235 } else if (qName.equals("bounds")) { 236 // new style bounds. 237 String minlon = atts.getValue("minlon"); 238 String minlat = atts.getValue("minlat"); 239 String maxlon = atts.getValue("maxlon"); 240 String maxlat = atts.getValue("maxlat"); 241 String origin = atts.getValue("origin"); 242 if (minlon != null && maxlon != null && minlat != null && maxlat != null) { 243 if (origin == null) { 244 origin = generator; 174 245 } 175 176 // ---- PARSING NODES AND WAYS ---- 177 178 } else if (qName.equals("node")) { 179 current = new OsmPrimitiveData(); 180 current.latlon = new LatLon(getDouble(atts, "lat"), getDouble(atts, "lon")); 181 readCommon(atts, current); 182 } else if (qName.equals("way")) { 183 current = new OsmPrimitiveData(); 184 readCommon(atts, current); 185 ways.put(current, new ArrayList<Long>()); 186 } else if (qName.equals("nd")) { 187 Collection<Long> list = ways.get(current); 188 if (list == null) 189 throw new SAXException(tr("Found <nd> element in non-way.")); 190 long id = getLong(atts, "ref"); 191 if (id == 0) 192 throw new SAXException(tr("<nd> has zero ref")); 193 list.add(id); 194 195 // ---- PARSING RELATIONS ---- 196 197 } else if (qName.equals("relation")) { 198 current = new OsmPrimitiveData(); 199 readCommon(atts, current); 200 relations.put(current, new LinkedList<RelationMemberData>()); 201 } else if (qName.equals("member")) { 202 Collection<RelationMemberData> list = relations.get(current); 203 if (list == null) 204 throw new SAXException(tr("Found <member> element in non-relation.")); 205 RelationMemberData emd = new RelationMemberData(); 206 String value = atts.getValue("ref"); 207 if (value == null) 208 throw new SAXException(tr("Missing attribute \"ref\" on member in relation {0}",current.id)); 209 try { 210 emd.id = Long.parseLong(value); 211 } catch(NumberFormatException e) { 212 throw new SAXException(tr("Illegal value for attribute \"ref\" on member in relation {0}, got {1}", Long.toString(current.id),value)); 213 } 214 value = atts.getValue("type"); 215 if (value == null) 216 throw new SAXException(tr("Missing attribute \"type\" on member {0} in relation {1}", Long.toString(emd.id), Long.toString(current.id))); 217 if (! (value.equals("way") || value.equals("node") || value.equals("relation"))) 218 throw new SAXException(tr("Unexpected \"type\" on member {0} in relation {1}, got {2}.", Long.toString(emd.id), Long.toString(current.id), value)); 219 emd.type= value; 220 value = atts.getValue("role"); 221 emd.role = value; 222 223 if (emd.id == 0) 224 throw new SAXException(tr("Incomplete <member> specification with ref=0")); 225 226 list.add(emd); 227 228 // ---- PARSING TAGS (applicable to all objects) ---- 229 230 } else if (qName.equals("tag")) { 231 String key = atts.getValue("k"); 232 String value = atts.getValue("v"); 233 current.keys.put(key,value); 234 } 235 } catch (NumberFormatException x) { 236 x.printStackTrace(); // SAXException does not chain correctly 237 throw new SAXException(x.getMessage(), x); 238 } catch (NullPointerException x) { 239 x.printStackTrace(); // SAXException does not chain correctly 240 throw new SAXException(tr("NullPointerException, possibly some missing tags."), x); 241 } 242 } 243 244 @Override 245 public void endElement(String uri, String localName, String qName) throws SAXException { 246 if (qName.equals("node")) { 247 nodes.put(current.id, current.createNode()); 246 Bounds bounds = new Bounds( 247 new LatLon(Double.parseDouble(minlat), Double.parseDouble(minlon)), 248 new LatLon(Double.parseDouble(maxlat), Double.parseDouble(maxlon))); 249 DataSource src = new DataSource(bounds, origin); 250 ds.dataSources.add(src); 251 } else { 252 throwException(tr( 253 "Missing manadatory attributes on element ''bounds''. Got minlon=''{0}'',minlat=''{1}00,maxlon=''{3}'',maxlat=''{4}'', origin=''{5}''", 254 minlon, minlat, maxlon, maxlat, origin 255 )); 256 } 257 258 // ---- PARSING NODES AND WAYS ---- 259 260 } else if (qName.equals("node")) { 261 current = new OsmPrimitiveData(); 262 current.latlon = new LatLon(getDouble(atts, "lat"), getDouble(atts, "lon")); 263 readCommon(atts, current); 264 Node n = current.createNode(); 265 externalIdMap.put("n"+current.id, n); 266 } else if (qName.equals("way")) { 267 current = new OsmPrimitiveData(); 268 readCommon(atts, current); 269 Way w = current.createWay(); 270 externalIdMap.put("w"+current.id, w); 271 ways.put(current.id, new ArrayList<Long>()); 272 } else if (qName.equals("nd")) { 273 Collection<Long> list = ways.get(current.id); 274 if (list == null) { 275 throwException( 276 tr("found XML element <nd> element not as direct child of element <way>") 277 ); 278 } 279 if (atts.getValue("ref") == null) { 280 throwException( 281 tr("Missing mandatory attribute ''{0}'' on <nd> of way {1}", "ref", current.id) 282 ); 283 } 284 long id = getLong(atts, "ref"); 285 if (id == 0) { 286 throwException( 287 tr("Illegal value of attribute ''ref'' of element <nd>. Got {0}", id) 288 ); 289 } 290 list.add(id); 291 292 // ---- PARSING RELATIONS ---- 293 294 } else if (qName.equals("relation")) { 295 current = new OsmPrimitiveData(); 296 readCommon(atts, current); 297 Relation r = current.createRelation(); 298 externalIdMap.put("r"+current.id, r ); 299 relations.put(current.id, new LinkedList<RelationMemberData>()); 300 } else if (qName.equals("member")) { 301 Collection<RelationMemberData> list = relations.get(current.id); 302 if (list == null) { 303 throwException( 304 tr("Found XML element <member> not as direct child of element <relation>") 305 ); 306 } 307 RelationMemberData emd = new RelationMemberData(); 308 String value = atts.getValue("ref"); 309 if (value == null) { 310 throwException(tr("Missing attribute ''ref'' on member in relation {0}",current.id)); 311 } 312 try { 313 emd.id = Long.parseLong(value); 314 } catch(NumberFormatException e) { 315 throwException(tr("Illegal value for attribute ''ref'' on member in relation {0}. Got {1}", Long.toString(current.id),value)); 316 } 317 value = atts.getValue("type"); 318 if (value == null) { 319 throwException(tr("Missing attribute ''type'' on member {0} in relation {1}", Long.toString(emd.id), Long.toString(current.id))); 320 } 321 if (! (value.equals("way") || value.equals("node") || value.equals("relation"))) { 322 throwException(tr("Illegal value for attribute ''type'' on member {0} in relation {1}. Got {2}.", Long.toString(emd.id), Long.toString(current.id), value)); 323 } 324 emd.type= value; 325 value = atts.getValue("role"); 326 emd.role = value; 327 328 if (emd.id == 0) { 329 throwException(tr("Incomplete <member> specification with ref=0")); 330 } 331 332 list.add(emd); 333 334 // ---- PARSING TAGS (applicable to all objects) ---- 335 336 } else if (qName.equals("tag")) { 337 String key = atts.getValue("k"); 338 String value = atts.getValue("v"); 339 current.rememberTag(key, value); 248 340 } 249 341 } … … 252 344 return Double.parseDouble(atts.getValue(value)); 253 345 } 254 } 255 256 /** 257 * Read out the common attributes from atts and put them into this.current. 258 */ 259 void readCommon(Attributes atts, OsmPrimitiveData current) throws SAXException { 260 current.id = getLong(atts, "id"); 261 if (current.id == 0) 262 throw new SAXException(tr("Illegal object with id=0")); 263 264 String time = atts.getValue("timestamp"); 265 if (time != null && time.length() != 0) { 266 current.timestamp = DateUtils.fromString(time); 267 } 268 269 // user attribute added in 0.4 API 270 String user = atts.getValue("user"); 271 if (user != null) { 272 // do not store literally; get object reference for string 273 current.user = User.get(user); 274 } 275 276 // uid attribute added in 0.6 API 277 String uid = atts.getValue("uid"); 278 if (uid != null) { 279 if (current.user != null) { 280 current.user.uid = uid; 281 } 282 } 283 284 // visible attribute added in 0.4 API 285 String visible = atts.getValue("visible"); 286 if (visible != null) { 287 current.visible = Boolean.parseBoolean(visible); 288 } 289 290 String version = atts.getValue("version"); 291 current.version = 0; 292 if (version != null) { 346 347 private User createUser(String uid, String name) throws SAXException { 348 if (uid == null) { 349 if (name == null) 350 return null; 351 return User.createLocalUser(name); 352 } 293 353 try { 294 current.version = Integer.parseInt(version); 354 long id = Long.parseLong(uid); 355 return User.createOsmUser(id, name); 295 356 } catch(NumberFormatException e) { 296 throw new SAXException(tr("Illegal value for attribute \"version\" on OSM primitive with id {0}, got {1}", Long.toString(current.id), version)); 297 } 298 } else { 299 // version expected for OSM primitives with an id assigned by the server (id > 0), since API 0.6 300 // 301 if (current.id > 0 && ds.version != null && ds.version.equals("0.6")) 302 throw new SAXException(tr("Missing attribute \"version\" on OSM primitive with id {0}", Long.toString(current.id))); 303 } 304 305 String action = atts.getValue("action"); 306 if (action == null) 307 return; 308 if (action.equals("delete")) { 309 current.deleted = true; 310 } else if (action.startsWith("modify")) { 311 current.modified = true; 312 } 313 } 314 private long getLong(Attributes atts, String value) throws SAXException { 315 String s = atts.getValue(value); 316 if (s == null) 317 throw new SAXException(tr("Missing required attribute \"{0}\".",value)); 318 return Long.parseLong(s); 319 } 320 321 private Node findNode(long id) { 322 Node n = nodes.get(id); 323 if (n != null) 324 return n; 325 return null; 326 } 327 328 protected void createWays() { 329 for (Entry<OsmPrimitiveData, Collection<Long>> e : ways.entrySet()) { 330 Way w = new Way(e.getKey().id); 357 throwException(tr("Illegal value for attribute ''uid''. Got ''{0}''", uid)); 358 } 359 return null; 360 } 361 /** 362 * Read out the common attributes from atts and put them into this.current. 363 */ 364 void readCommon(Attributes atts, OsmPrimitiveData current) throws SAXException { 365 current.id = getLong(atts, "id"); 366 if (current.id == 0) { 367 throwException(tr("Illegal object with id=0")); 368 } 369 370 String time = atts.getValue("timestamp"); 371 if (time != null && time.length() != 0) { 372 current.timestamp = DateUtils.fromString(time); 373 } 374 375 // user attribute added in 0.4 API 376 String user = atts.getValue("user"); 377 // uid attribute added in 0.6 API 378 String uid = atts.getValue("uid"); 379 current.user = createUser(uid, user); 380 381 // visible attribute added in 0.4 API 382 String visible = atts.getValue("visible"); 383 if (visible != null) { 384 current.visible = Boolean.parseBoolean(visible); 385 } 386 387 String version = atts.getValue("version"); 388 current.version = 0; 389 if (version != null) { 390 try { 391 current.version = Integer.parseInt(version); 392 } catch(NumberFormatException e) { 393 throwException(tr("Illegal value for attribute ''version'' on OSM primitive with id {0}. Got {1}", Long.toString(current.id), version)); 394 } 395 if (current.version <= 0) { 396 throwException(tr("Illegal value for attribute ''version'' on OSM primitive with id {0}. Got {1}", Long.toString(current.id), version)); 397 } 398 } else { 399 // version expected for OSM primitives with an id assigned by the server (id > 0), since API 0.6 400 // 401 if (current.id > 0 && ds.version != null && ds.version.equals("0.6")) { 402 throwException(tr("Missing attribute ''version'' on OSM primitive with id {0}", Long.toString(current.id))); 403 } 404 } 405 406 String action = atts.getValue("action"); 407 if (action == null) 408 return; 409 if (action.equals("delete")) { 410 current.deleted = true; 411 } else if (action.startsWith("modify")) { 412 current.modified = true; 413 } 414 } 415 416 private long getLong(Attributes atts, String name) throws SAXException { 417 String value = atts.getValue(name); 418 if (value == null) { 419 throwException(tr("Missing required attribute ''{0}''.",name)); 420 } 421 try { 422 return Long.parseLong(value); 423 } catch(NumberFormatException e) { 424 throwException(tr("Illegal long value for attribute ''{0}''. Got ''{1}''",name, value)); 425 } 426 return 0; // should not happen 427 } 428 } 429 430 431 /** 432 * Processes the ways after parsing. Rebuilds the list of nodes of each way and 433 * adds the way to the dataset 434 * 435 * @throws IllegalDataException thrown if a data integrity problem is detected 436 */ 437 protected void processWaysAfterParsing() throws IllegalDataException{ 438 for (Long externalWayId: ways.keySet()) { 439 Way w = (Way)externalIdMap.get("w" + externalWayId); 331 440 boolean incomplete = false; 332 441 List<Node> wayNodes = new ArrayList<Node>(); 333 for (long id : e.getValue()) {334 Node n = findNode(id);442 for (long id : ways.get(externalWayId)) { 443 Node n = (Node)externalIdMap.get("n" +id); 335 444 if (n == null) { 445 if (id <= 0) 446 throw new IllegalDataException ( 447 tr( 448 "way with external id ''{0}'' includes missing node with external id ''{1}''", 449 externalWayId, 450 id 451 ) 452 ); 336 453 n = new Node(id); 337 454 n.incomplete = true; … … 343 460 if (incomplete) { 344 461 logger.warning(tr("marked way {0} with {1} nodes incomplete because at least one node was missing in the " + 345 "loaded data and is therefore incomplete too", e.getKey().id, w.getNodesCount())); 346 e.getKey().copyTo(w); 462 "loaded data and is therefore incomplete too", externalWayId, w.getNodesCount())); 347 463 w.incomplete = true; 348 464 ds.addPrimitive(w); 349 465 } else { 350 e.getKey().copyTo(w);351 466 w.incomplete = false; 352 467 ds.addPrimitive(w); … … 356 471 357 472 /** 358 * Return the Way object with the given id, or null if it doesn't 359 * exist yet. This method only looks at ways stored in the already parsed 360 * ways. 361 * 362 * @param id 363 * @return way object or null 364 */ 365 private Way findWay(long id) { 366 for (Way way : ds.ways) 367 if (way.id == id) 368 return way; 369 return null; 370 } 371 372 /** 373 * Return the Relation object with the given id, or null if it doesn't 374 * exist yet. This method only looks at relations in the already parsed 375 * relations. 376 * 377 * @param id 378 * @return relation object or null 379 */ 380 private Relation findRelation(long id) { 381 for (Relation e : ds.relations) 382 if (e.id == id) 383 return e; 384 return null; 385 } 386 387 /** 388 * Create relations. This is slightly different than n/s/w because 389 * unlike other objects, relations may reference other relations; it 390 * is not guaranteed that a referenced relation will have been created 391 * before it is referenced. So we have to create all relations first, 392 * and populate them later. 393 */ 394 private void createRelations() throws SAXException { 395 396 // pass 1 - create all relations 397 for (Entry<OsmPrimitiveData, Collection<RelationMemberData>> e : relations.entrySet()) { 398 Relation en = new Relation(); 399 e.getKey().copyTo(en); 400 ds.addPrimitive(en); 401 } 402 403 // Cache the ways here for much better search performance 404 HashMap<Long, Way> hm = new HashMap<Long, Way>(10000); 405 for (Way wy : ds.ways) { 406 hm.put(wy.id, wy); 407 } 408 409 // pass 2 - sort out members 410 for (Entry<OsmPrimitiveData, Collection<RelationMemberData>> e : relations.entrySet()) { 411 Relation en = findRelation(e.getKey().id); 412 if (en == null) throw new Error("Failed to create relation " + e.getKey().id); 413 473 * Processes the parsed nodes after parsing. Just adds them to 474 * the dataset 475 * 476 */ 477 protected void processNodesAfterParsing() { 478 for (OsmPrimitive primitive: externalIdMap.values()) { 479 if (primitive instanceof Node) { 480 this.ds.addPrimitive(primitive); 481 } 482 } 483 } 484 485 /** 486 * Completes the parsed relations with its members. 487 * 488 * @throws IllegalDataException thrown if a data integrity problem is detected, i.e. if a 489 * relation member refers to a local primitive which wasn't available in the data 490 * 491 */ 492 private void processRelationsAfterParsing() throws IllegalDataException { 493 for (Long externalRelationId : relations.keySet()) { 494 Relation relation = (Relation) externalIdMap.get("r" +externalRelationId); 414 495 List<RelationMember> relationMembers = new ArrayList<RelationMember>(); 415 416 for (RelationMemberData emd : e.getValue()) { 417 OsmPrimitive member; 418 if (emd.type.equals("node")) { 419 member = findNode(emd.id); 420 if (member == null) { 421 member = new Node(emd.id); 422 ds.addPrimitive(member); 496 for (RelationMemberData rm : relations.get(externalRelationId)) { 497 OsmPrimitive primitive = null; 498 499 // lookup the member from the map of already created primitives 500 // 501 if (rm.type.equals("node")) { 502 primitive = externalIdMap.get("n" + rm.id); 503 } else if (rm.type.equals("way")) { 504 primitive = externalIdMap.get("w" + rm.id); 505 } else if (rm.type.equals("relation")) { 506 primitive = externalIdMap.get("r" + rm.id); 507 } else 508 throw new IllegalDataException( 509 tr("Unknown relation member type ''{0}'' in relation with external id ''{1}''", rm.type,externalRelationId) 510 ); 511 512 if (primitive == null) { 513 if (rm.id <= 0) 514 // relation member refers to a primitive with a negative id which was not 515 // found in the data. This is always a data integrity problem and we abort 516 // with an exception 517 // 518 throw new IllegalDataException( 519 tr( 520 "Relation with external id ''{0}'' refers to missing primitive with external id ''{1}''", 521 externalRelationId, 522 rm.id 523 ) 524 ); 525 526 // member refers to OSM primitive which was not present in the parsed data 527 // -> create a new incomplete primitive and add it to the dataset 528 // 529 if (rm.type.equals("node")) { 530 primitive = new Node(rm.id); 531 } else if (rm.type.equals("way")) { 532 primitive = new Way(rm.id); 533 } else if (rm.type.equals("relation")) { 534 primitive = new Relation(rm.id); 535 } else { 536 // can't happen, we've been testing for valid member types 537 // at the beginning of this method 538 // 423 539 } 424 } else if (emd.type.equals("way")) { 425 member = hm.get(emd.id); 426 if (member == null) { 427 member = findWay(emd.id); 428 } 429 if (member == null) { 430 member = new Way(emd.id); 431 ds.addPrimitive(member); 432 } 433 } else if (emd.type.equals("relation")) { 434 member = findRelation(emd.id); 435 if (member == null) { 436 member = new Relation(emd.id); 437 ds.addPrimitive(member); 438 } 439 } else { 440 throw new SAXException(tr("Unknown relation member type {0}", emd.type)); 441 } 442 relationMembers.add(new RelationMember(emd.role, member)); 443 } 444 en.setMembers(relationMembers); 445 } 446 hm = null; 540 ds.addPrimitive(primitive); 541 } 542 relationMembers.add(new RelationMember(rm.role, primitive)); 543 } 544 relation.setMembers(relationMembers); 545 ds.addPrimitive(relation); 546 } 447 547 } 448 548 449 549 /** 450 550 * Parse the given input source and return the dataset. 451 * @param ref The dataset that is search in for references first. If 452 * the Reference is not found here, Main.ds is searched and a copy of the 453 * element found there is returned. 454 */ 455 public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor) throws SAXException, IOException { 456 return parseDataSetOsm(source, progressMonitor).ds; 457 } 458 459 public static OsmReader parseDataSetOsm(InputStream source, ProgressMonitor progressMonitor) throws SAXException, IOException { 551 * 552 * @param source the source input stream 553 * @param progressMonitor the progress monitor 554 * 555 * @return the dataset with the parsed data 556 * @throws IllegalDataException thrown if the an error was found while parsing the data from the source 557 */ 558 public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor) throws IllegalDataException { 460 559 OsmReader reader = new OsmReader(); 461 462 // phase 1: Parse nodes and read in raw ways463 InputSource inputSource = new InputSource(new InputStreamReader(source, "UTF-8"));464 560 try { 561 progressMonitor.beginTask(tr("Prepare OSM data...", 2)); 562 progressMonitor.subTask(tr("Parsing OSM data...")); 563 InputSource inputSource = new InputSource(new InputStreamReader(source, "UTF-8")); 465 564 SAXParserFactory.newInstance().newSAXParser().parse(inputSource, reader.new Parser()); 466 } catch (ParserConfigurationException e1) {467 e1.printStackTrace(); // broken SAXException chaining468 throw new SAXException(e1);469 }470 471 progressMonitor.beginTask(tr("Prepare OSM data...", 2));472 try {473 for (Node n : reader.nodes.values()) {474 reader.ds.addPrimitive(n);475 }476 477 565 progressMonitor.worked(1); 478 566 479 try { 480 reader.createWays(); 481 reader.createRelations(); 482 } catch (NumberFormatException e) { 483 e.printStackTrace(); 484 throw new SAXException(tr("Ill-formed node id")); 485 } 486 487 // clear all negative ids (new to this file) 488 for (OsmPrimitive o : reader.ds.allPrimitives()) 489 if (o.id < 0) { 490 o.id = 0; 491 } 492 493 return reader; 567 progressMonitor.subTask(tr("Preparing data set...")); 568 reader.processNodesAfterParsing(); 569 reader.processWaysAfterParsing(); 570 reader.processRelationsAfterParsing(); 571 progressMonitor.worked(1); 572 return reader.getDataSet(); 573 } catch(IllegalDataException e) { 574 throw e; 575 } catch(ParserConfigurationException e) { 576 throw new IllegalDataException(e.getMessage(), e); 577 } catch(SAXException e) { 578 throw new IllegalDataException(e.getMessage(), e); 579 } catch(Exception e) { 580 throw new IllegalDataException(e); 494 581 } finally { 495 582 progressMonitor.finishTask(); -
trunk/src/org/openstreetmap/josm/io/OsmServerBackreferenceReader.java
r1811 r2070 51 51 if (primitive == null) 52 52 throw new IllegalArgumentException(tr("parameter ''{0}'' must not be null", "primitive")); 53 if (primitive. id== 0)54 throw new IllegalArgumentException(tr("id parameter ''{0}'' > 0 required. Got {1}", "primitive", primitive. id));55 this.id = primitive. id;53 if (primitive.getId() == 0) 54 throw new IllegalArgumentException(tr("id parameter ''{0}'' > 0 required. Got {1}", "primitive", primitive.getId())); 55 this.id = primitive.getId(); 56 56 this.primitiveType = OsmPrimitiveType.from(primitive); 57 57 this.readFull = false; … … 222 222 if (isReadFull() ||primitiveType.equals(OsmPrimitiveType.NODE)) { 223 223 for (Way way: waysToCheck) { 224 if (way. id> 0 && way.incomplete) {225 OsmServerObjectReader reader = new OsmServerObjectReader(way. id, OsmPrimitiveType.from(way), true /* read full */);224 if (way.getId() > 0 && way.incomplete) { 225 OsmServerObjectReader reader = new OsmServerObjectReader(way.getId(), OsmPrimitiveType.from(way), true /* read full */); 226 226 DataSet wayDs = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false)); 227 227 MergeVisitor visitor = new MergeVisitor(ds, wayDs); … … 233 233 Collection<Relation> relationsToCheck = new ArrayList<Relation>(ds.relations); 234 234 for (Relation relation: relationsToCheck) { 235 if (relation. id> 0 && relation.incomplete) {236 OsmServerObjectReader reader = new OsmServerObjectReader(relation. id, OsmPrimitiveType.from(relation), true /* read full */);235 if (relation.getId() > 0 && relation.incomplete) { 236 OsmServerObjectReader reader = new OsmServerObjectReader(relation.getId(), OsmPrimitiveType.from(relation), true /* read full */); 237 237 DataSet wayDs = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false)); 238 238 MergeVisitor visitor = new MergeVisitor(ds, wayDs); -
trunk/src/org/openstreetmap/josm/io/OsmServerObjectReader.java
r1827 r2070 46 46 if (in == null) 47 47 return null; 48 final OsmReader osm = OsmReader.parseDataSetOsm(in, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); 49 final DataSet data = osm.getDs(); 48 final DataSet data = OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); 50 49 return data; 51 50 } catch(OsmTransferException e) { -
trunk/src/org/openstreetmap/josm/io/OsmWriter.java
r2025 r2070 14 14 import org.openstreetmap.josm.data.osm.Relation; 15 15 import org.openstreetmap.josm.data.osm.RelationMember; 16 import org.openstreetmap.josm.data.osm.User; 16 17 import org.openstreetmap.josm.data.osm.Way; 17 18 import org.openstreetmap.josm.data.osm.visitor.Visitor; … … 208 209 // user and visible added with 0.4 API 209 210 if (osm.user != null) { 210 out.print(" user='"+XmlWriter.encode(osm.user.name)+"'"); 211 if(osm.user.isLocalUser()) { 212 out.print(" user='"+XmlWriter.encode(osm.user.getName())+"'"); 213 } else if (osm.user.isOsmUser()) { 214 // uid added with 0.6 215 out.print(" uid='"+ osm.user.getId()+"'"); 216 out.print(" user='"+XmlWriter.encode(osm.user.getName())+"'"); 217 } 211 218 } 212 219 out.print(" visible='"+osm.isVisible()+"'"); 213 if (osm. version != -1) {214 out.print(" version='"+osm. version+"'");220 if (osm.getVersion() != 0) { 221 out.print(" version='"+osm.getVersion()+"'"); 215 222 } 216 223 if (this.changeset != null && this.changeset.getId() != 0) { -
trunk/src/org/openstreetmap/josm/plugins/PluginDownloader.java
r2017 r2070 122 122 if(pd.mainversion > AboutAction.getVersionNumber()) 123 123 { 124 int answer = new ExtendedDialog(Main.parent, 124 ExtendedDialog dialog = new ExtendedDialog( 125 Main.parent, 125 126 tr("Skip download"), 126 tr("JOSM version {0} required for plugin {1}.", pd.mainversion, pd.name), 127 new String[] {tr("Download Plugin"), tr("Skip Download")}, 128 new String[] {"download.png", "cancel.png"}).getValue(); 127 new String[] {tr("Download Plugin"), tr("Skip Download")} 128 ); 129 dialog.setContent(tr("JOSM version {0} required for plugin {1}.", pd.mainversion, pd.name)); 130 dialog.setButtonIcons(new String[] {"download.png", "cancel.png"}); 131 dialog.showDialog(); 132 int answer = dialog.getValue(); 129 133 if (answer != 1) 130 134 return false; -
trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java
r2017 r2070 171 171 } catch (Throwable e) { 172 172 e.printStackTrace(); 173 174 int result = new ExtendedDialog(Main.parent,173 ExtendedDialog dialog = new ExtendedDialog( 174 Main.parent, 175 175 tr("Disable plugin"), 176 tr("Could not load plugin {0}. Delete from preferences?", info.name), 177 new String[] {tr("Disable plugin"), tr("Keep plugin")}, 178 new String[] {"dialogs/delete.png", "cancel.png"}).getValue(); 176 new String[] {tr("Disable plugin"), tr("Keep plugin")} 177 ); 178 dialog.setContent(tr("Could not load plugin {0}. Delete from preferences?", info.name)); 179 dialog.setButtonIcons( new String[] {"dialogs/delete.png", "cancel.png"}); 180 dialog.showDialog(); 181 int result = dialog.getValue(); 179 182 180 183 if(result == 1) … … 278 281 279 282 if (plugin != null) { 280 int answer = new ExtendedDialog(Main.parent, 283 ExtendedDialog dialog = new ExtendedDialog( 284 Main.parent, 281 285 tr("Disable plugin"), 286 new String[] {tr("Disable plugin"), tr("Cancel")} 287 ); 288 dialog.setButtonIcons(new String[] {"dialogs/delete.png", "cancel.png"}); 289 dialog.setContent( 290 tr("<html>") + 282 291 tr("An unexpected exception occurred that may have come from the ''{0}'' plugin.", plugin.info.name) 283 + " \n"292 + "<br>" 284 293 + (plugin.info.author != null 285 294 ? tr("According to the information within the plugin, the author is {0}.", plugin.info.author) 286 295 : "") 287 + " \n"296 + "<br>" 288 297 + tr("Try updating to the newest version of this plugin before reporting a bug.") 289 + "\n" 290 + tr("Should the plugin be disabled?"), 291 new String[] {tr("Disable plugin"), tr("Cancel")}, 292 new String[] {"dialogs/delete.png", "cancel.png"}).getValue(); 298 + "<br>" 299 + tr("Should the plugin be disabled?") 300 + "</html>" 301 ); 302 dialog.showDialog(); 303 int answer = dialog.getValue(); 304 293 305 if (answer == 1) { 294 306 List<String> plugins = new ArrayList<String>(Main.pref.getCollection("plugins", Collections.<String>emptyList())); -
trunk/src/org/openstreetmap/josm/tools/WindowGeometry.java
r2066 r2070 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.awt.Component; 6 7 import java.awt.Dimension; 8 import java.awt.Frame; 7 9 import java.awt.Point; 8 10 import java.awt.Toolkit; … … 10 12 import java.util.regex.Matcher; 11 13 import java.util.regex.Pattern; 14 15 import javax.swing.JOptionPane; 12 16 13 17 import org.openstreetmap.josm.Main; … … 43 47 * @return the geometry object 44 48 */ 45 static public WindowGeometry centerInWindow(Window parent, Dimension extent) { 49 static public WindowGeometry centerInWindow(Component parent, Dimension extent) { 50 Frame parentWindow = JOptionPane.getFrameForComponent(parent); 46 51 Point topLeft = new Point( 47 Math.max(0, (parent .getSize().width - extent.width) /2),48 Math.max(0, (parent .getSize().height - extent.height) /2)52 Math.max(0, (parentWindow.getSize().width - extent.width) /2), 53 Math.max(0, (parentWindow.getSize().height - extent.height) /2) 49 54 ); 50 topLeft.x += parent .getLocation().x;51 topLeft.y += parent .getLocation().y;55 topLeft.x += parentWindow.getLocation().x; 56 topLeft.y += parentWindow.getLocation().y; 52 57 return new WindowGeometry(topLeft, extent); 53 58 }
Note:
See TracChangeset
for help on using the changeset viewer.