Changeset 23 in josm
- Timestamp:
- 2005-10-27T00:38:03+02:00 (19 years ago)
- Files:
-
- 8 added
- 3 deleted
- 37 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
src/org/openstreetmap/josm/Main.java
r22 r23 4 4 import java.awt.BorderLayout; 5 5 import java.awt.Container; 6 import java.util.Collection;7 import java.util.LinkedList;8 6 9 7 import javax.swing.JFrame; … … 22 20 import org.openstreetmap.josm.actions.PreferencesAction; 23 21 import org.openstreetmap.josm.actions.SaveGpxAction; 24 import org.openstreetmap.josm.command.Command;25 import org.openstreetmap.josm.command.DataSet;26 22 import org.openstreetmap.josm.data.Preferences; 27 23 import org.openstreetmap.josm.data.Preferences.PreferencesException; 24 import org.openstreetmap.josm.data.osm.DataSet; 28 25 import org.openstreetmap.josm.gui.ImageProvider; 29 26 import org.openstreetmap.josm.gui.MapFrame; … … 45 42 */ 46 43 public final static Preferences pref = new Preferences(); 47 48 /**49 * The global command queue since last save. So if you reload the data from disk50 * (or from OSM server, if nothing changed on server) and reapply the commands,51 * you should get the same result as currently displaying.52 */53 public Collection<Command> commands = new LinkedList<Command>();54 44 55 45 /** … … 121 111 // creating toolbar 122 112 JToolBar toolBar = new JToolBar(); 123 toolBar.setFloatable( true);113 toolBar.setFloatable(false); 124 114 toolBar.add(openServerAction); 125 115 toolBar.add(openGpxAction); -
src/org/openstreetmap/josm/actions/OpenGpxAction.java
r21 r23 7 7 import java.io.FileReader; 8 8 import java.io.IOException; 9 import java.util.Collection; 9 10 10 11 import javax.swing.AbstractAction; … … 17 18 import javax.swing.filechooser.FileFilter; 18 19 20 import org.jdom.JDOMException; 19 21 import org.openstreetmap.josm.Main; 20 import org.openstreetmap.josm.command.DataSet; 22 import org.openstreetmap.josm.data.GeoPoint; 23 import org.openstreetmap.josm.data.osm.DataSet; 24 import org.openstreetmap.josm.data.osm.OsmPrimitive; 21 25 import org.openstreetmap.josm.gui.GBC; 22 26 import org.openstreetmap.josm.gui.ImageProvider; 23 27 import org.openstreetmap.josm.gui.MapFrame; 24 28 import org.openstreetmap.josm.gui.layer.Layer; 25 import org.openstreetmap.josm.gui.layer.LayerFactory; 29 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 30 import org.openstreetmap.josm.gui.layer.RawGpsDataLayer; 26 31 import org.openstreetmap.josm.io.GpxReader; 27 import org.openstreetmap.josm.io.DataReader.ConnectionException; 28 import org.openstreetmap.josm.io.DataReader.ParseException; 32 import org.openstreetmap.josm.io.RawGpsReader; 29 33 30 34 /** … … 83 87 84 88 try { 85 DataSet dataSet = new GpxReader(new FileReader(gpxFile), rawGps.isSelected()).parse(); 86 87 Layer layer = LayerFactory.create(dataSet, gpxFile.getName(), rawGps.isSelected()); 89 Layer layer; 90 if (rawGps.isSelected()) { 91 Collection<Collection<GeoPoint>> data = new RawGpsReader(new FileReader(gpxFile)).parse(); 92 layer = new RawGpsDataLayer(data, gpxFile.getName()); 93 } else { 94 DataSet dataSet = new GpxReader(new FileReader(gpxFile)).parse(); 95 Collection<OsmPrimitive> l = Main.main.ds.mergeFrom(dataSet); 96 layer = new OsmDataLayer(l, gpxFile.getName()); 97 } 88 98 89 99 if (Main.main.getMapFrame() == null || !newLayer.isSelected()) … … 92 102 Main.main.getMapFrame().mapView.addLayer(layer); 93 103 94 } catch ( ParseException x) {104 } catch (JDOMException x) { 95 105 x.printStackTrace(); 96 106 JOptionPane.showMessageDialog(Main.main, x.getMessage()); … … 98 108 x.printStackTrace(); 99 109 JOptionPane.showMessageDialog(Main.main, "Could not read '"+gpxFile.getName()+"'\n"+x.getMessage()); 100 } catch (ConnectionException x) {101 x.printStackTrace();102 JOptionPane.showMessageDialog(Main.main, x.getMessage());103 110 } 104 111 } -
src/org/openstreetmap/josm/actions/OpenOsmServerAction.java
r22 r23 6 6 import java.awt.event.ActionListener; 7 7 import java.awt.event.KeyEvent; 8 import java.io.IOException; 9 import java.util.Collection; 8 10 9 11 import javax.swing.AbstractAction; … … 19 21 import javax.swing.event.ListSelectionListener; 20 22 23 import org.jdom.JDOMException; 21 24 import org.openstreetmap.josm.Main; 22 import org.openstreetmap.josm.command.DataSet;23 25 import org.openstreetmap.josm.data.GeoPoint; 26 import org.openstreetmap.josm.data.osm.DataSet; 27 import org.openstreetmap.josm.data.osm.OsmPrimitive; 24 28 import org.openstreetmap.josm.gui.BookmarkList; 25 29 import org.openstreetmap.josm.gui.GBC; … … 29 33 import org.openstreetmap.josm.gui.BookmarkList.Bookmark; 30 34 import org.openstreetmap.josm.gui.layer.Layer; 31 import org.openstreetmap.josm.gui.layer.LayerFactory; 35 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 36 import org.openstreetmap.josm.gui.layer.RawGpsDataLayer; 32 37 import org.openstreetmap.josm.io.OsmReader; 33 import org.openstreetmap.josm.io.DataReader.ConnectionException;34 import org.openstreetmap.josm.io.DataReader.ParseException;35 38 36 39 /** … … 82 85 for (JTextField f : latlon) 83 86 f.setCaretPosition(0); 84 rawGps.setSelected( !mv.getActiveLayer().isEditable());87 rawGps.setSelected(mv.getActiveLayer() instanceof RawGpsDataLayer); 85 88 } 86 89 … … 145 148 } 146 149 OsmReader osmReader = new OsmReader(Main.pref.osmDataServer, 147 rawGps.isSelected(),b.latlon[0], b.latlon[1], b.latlon[2], b.latlon[3]);150 b.latlon[0], b.latlon[1], b.latlon[2], b.latlon[3]); 148 151 try { 149 DataSet dataSet = osmReader.parse();150 if (dataSet == null)151 return; // user cancelled download152 if (dataSet.nodes.isEmpty())153 JOptionPane.showMessageDialog(Main.main, "No data imported.");154 155 152 String name = latlon[0].getText()+" "+latlon[1].getText()+" x "+ 156 153 latlon[2].getText()+" "+latlon[3].getText(); 157 154 158 Layer layer = LayerFactory.create(dataSet, name, rawGps.isSelected()); 155 Layer layer; 156 if (rawGps.isSelected()) { 157 layer = new RawGpsDataLayer(osmReader.parseRawGps(), name); 158 } else { 159 DataSet dataSet = osmReader.parseOsm(); 160 if (dataSet == null) 161 return; // user cancelled download 162 if (dataSet.nodes.isEmpty()) 163 JOptionPane.showMessageDialog(Main.main, "No data imported."); 164 165 Collection<OsmPrimitive> data = Main.main.ds.mergeFrom(dataSet); 166 layer = new OsmDataLayer(data, name); 167 } 159 168 160 169 if (Main.main.getMapFrame() == null) … … 162 171 else 163 172 Main.main.getMapFrame().mapView.addLayer(layer); 164 } catch ( ParseException x) {173 } catch (JDOMException x) { 165 174 x.printStackTrace(); 166 175 JOptionPane.showMessageDialog(Main.main, x.getMessage()); 167 } catch ( ConnectionException x) {176 } catch (IOException x) { 168 177 x.printStackTrace(); 169 178 JOptionPane.showMessageDialog(Main.main, x.getMessage()); -
src/org/openstreetmap/josm/actions/mapmode/AddLineSegmentAction.java
r22 r23 12 12 import org.openstreetmap.josm.Main; 13 13 import org.openstreetmap.josm.command.AddCommand; 14 import org.openstreetmap.josm.command.Command;15 14 import org.openstreetmap.josm.data.osm.LineSegment; 16 15 import org.openstreetmap.josm.data.osm.Node; … … 132 131 if (start != end) { 133 132 // try to find a line segment 134 for (Track t : Main.main.ds.tracks ())135 for (LineSegment ls : t.segments ())136 if (start == ls. getStart() && end == ls.getEnd()) {133 for (Track t : Main.main.ds.tracks) 134 for (LineSegment ls : t.segments) 135 if (start == ls.start && end == ls.end) { 137 136 JOptionPane.showMessageDialog(Main.main, "There is already an line segment with the same direction between the selected nodes."); 138 137 return; … … 140 139 141 140 LineSegment ls = new LineSegment(start, end); 142 Command c = new AddCommand(ls); 143 c.executeCommand(); 144 Main.main.commands.add(c); 141 mv.editLayer().add(new AddCommand(ls)); 145 142 } 146 143 … … 167 164 hintDrawn = !hintDrawn; 168 165 } 169 170 @Override171 protected boolean isEditMode() {172 return true;173 }174 166 } -
src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java
r22 r23 4 4 import java.awt.event.MouseEvent; 5 5 6 import org.openstreetmap.josm.Main;7 6 import org.openstreetmap.josm.command.AddCommand; 8 import org.openstreetmap.josm.command.Command;9 7 import org.openstreetmap.josm.data.osm.Node; 10 8 import org.openstreetmap.josm.gui.MapFrame; … … 51 49 Node node = new Node(); 52 50 node.coor = mv.getPoint(e.getX(), e.getY(), true); 53 Command c = new AddCommand(node); 54 c.executeCommand(); 55 Main.main.commands.add(c); 51 mv.editLayer().add(new AddCommand(node)); 56 52 mv.repaint(); 57 53 } 58 54 } 59 60 @Override61 protected boolean isEditMode() {62 return true;63 }64 55 } -
src/org/openstreetmap/josm/actions/mapmode/AddTrackAction.java
r22 r23 4 4 import java.awt.event.KeyEvent; 5 5 import java.util.Collection; 6 import java.util.Iterator; 6 7 import java.util.LinkedList; 7 8 8 9 import org.openstreetmap.josm.Main; 9 10 import org.openstreetmap.josm.command.AddCommand; 10 import org.openstreetmap.josm.command.Command;11 11 import org.openstreetmap.josm.data.osm.LineSegment; 12 12 import org.openstreetmap.josm.data.osm.OsmPrimitive; … … 98 98 for (OsmPrimitive osm : selection) { 99 99 if (osm instanceof Track) 100 lineSegments.addAll(((Track)osm).segments ());100 lineSegments.addAll(((Track)osm).segments); 101 101 else if (osm instanceof LineSegment) 102 102 lineSegments.add((LineSegment)osm); 103 103 } 104 105 // sort the line segments in best possible order. This is done by: 106 // 0 if no elements in list, quit 107 // 1 taking the first ls as pivot, remove it from list 108 // 2 searching for a connection at start or end of pivot 109 // 3 if found, attach it, remove it from list, goto 2 110 // 4 if not found, save the pivot-string and goto 0 111 LinkedList<LineSegment> sortedLineSegments = new LinkedList<LineSegment>(); 112 while (!lineSegments.isEmpty()) { 113 LinkedList<LineSegment> pivotList = new LinkedList<LineSegment>(); 114 pivotList.add(lineSegments.getFirst()); 115 lineSegments.removeFirst(); 116 for (boolean found = true; found;) { 117 found = false; 118 for (Iterator<LineSegment> it = lineSegments.iterator(); it.hasNext();) { 119 LineSegment ls = it.next(); 120 if (ls.start == pivotList.getLast().end) { 121 pivotList.addLast(ls); 122 it.remove(); 123 found = true; 124 } else if (ls.end == pivotList.getFirst().start) { 125 pivotList.addFirst(ls); 126 it.remove(); 127 found = true; 128 } 129 } 130 } 131 sortedLineSegments.addAll(pivotList); 132 } 133 104 134 Track t = new Track(); 105 for (LineSegment ls : lineSegments)135 for (LineSegment ls : sortedLineSegments) 106 136 t.add(ls); 107 Command c = new AddCommand(t); 108 c.executeCommand(); 109 Main.main.commands.add(c); 137 mv.editLayer().add(new AddCommand(t)); 110 138 Main.main.ds.clearSelection(); 111 139 } 112 113 @Override114 protected boolean isEditMode() {115 return true;116 }117 140 } -
src/org/openstreetmap/josm/actions/mapmode/CombineAction.java
r22 r23 11 11 import org.openstreetmap.josm.Main; 12 12 import org.openstreetmap.josm.command.CombineCommand; 13 import org.openstreetmap.josm.command.Command;14 13 import org.openstreetmap.josm.data.osm.LineSegment; 15 14 import org.openstreetmap.josm.data.osm.Node; … … 150 149 else if (first instanceof Track && second instanceof Track && !first.keyPropertiesMergable(second)) 151 150 JOptionPane.showMessageDialog(Main.main, "Cannot combine because of different properties."); 152 else { 153 Command c = new CombineCommand(first, second); 154 c.executeCommand(); 155 Main.main.commands.add(c); 156 } 151 else 152 mv.editLayer().add(new CombineCommand(first, second)); 157 153 mv.repaint(); 158 154 } … … 188 184 if (osm instanceof LineSegment) { 189 185 LineSegment ls = (LineSegment)osm; 190 Point start = mv.getScreenPoint(ls. getStart().coor);191 Point end = mv.getScreenPoint(ls. getEnd().coor);192 if (Main.main.ds.pendingLineSegments ().contains(osm) && g.getColor() == Color.GRAY)186 Point start = mv.getScreenPoint(ls.start.coor); 187 Point end = mv.getScreenPoint(ls.end.coor); 188 if (Main.main.ds.pendingLineSegments.contains(osm) && g.getColor() == Color.GRAY) 193 189 g.drawLine(start.x, start.y, end.x, end.y); 194 190 else 195 191 g.drawLine(start.x, start.y, end.x, end.y); 196 192 } else if (osm instanceof Track) { 197 for (LineSegment ls : ((Track)osm).segments ())193 for (LineSegment ls : ((Track)osm).segments) 198 194 draw(g, ls); 199 195 } 200 196 } 201 202 @Override203 protected boolean isEditMode() {204 return true;205 }206 197 } -
src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
r22 r23 4 4 import java.awt.event.MouseEvent; 5 5 import java.util.ArrayList; 6 import java.util. HashMap;6 import java.util.Collection; 7 7 import java.util.LinkedList; 8 import java.util.Map;9 8 10 9 import javax.swing.JOptionPane; 11 10 12 11 import org.openstreetmap.josm.Main; 13 import org.openstreetmap.josm.data.osm.Key; 12 import org.openstreetmap.josm.command.CombineAndDeleteCommand; 13 import org.openstreetmap.josm.command.DeleteCommand; 14 import org.openstreetmap.josm.command.CombineAndDeleteCommand.LineSegmentCombineEntry; 14 15 import org.openstreetmap.josm.data.osm.LineSegment; 15 16 import org.openstreetmap.josm.data.osm.Node; … … 133 134 if (osm instanceof Node) { 134 135 // delete any track and line segment the node is in. 135 for (Track t : Main.main.ds.tracks ())136 for (LineSegment ls : t.segments ())137 if (ls. getStart() == osm || ls.getEnd()== osm)136 for (Track t : Main.main.ds.tracks) 137 for (LineSegment ls : t.segments) 138 if (ls.start == osm || ls.end == osm) 138 139 tracksToDelete.add(t); 139 for (LineSegment ls : Main.main.ds.pendingLineSegments ())140 if (ls. getStart() == osm || ls.getEnd()== osm)140 for (LineSegment ls : Main.main.ds.pendingLineSegments) 141 if (ls.start == osm || ls.end == osm) 141 142 lineSegmentsToDelete.add(ls); 142 143 … … 144 145 LineSegment lineSegment = (LineSegment)osm; 145 146 lineSegmentsToDelete.add(lineSegment); 146 for (Track t : Main.main.ds.tracks ())147 for (LineSegment ls : t.segments ())147 for (Track t : Main.main.ds.tracks) 148 for (LineSegment ls : t.segments) 148 149 if (lineSegment == ls) 149 150 tracksToDelete.add(t); … … 154 155 ArrayList<Node> checkUnreferencing = new ArrayList<Node>(); 155 156 for (Track t : tracksToDelete) { 156 for (LineSegment ls : t.segments ()) {157 checkUnreferencing.add(ls. getStart());158 checkUnreferencing.add(ls. getEnd());157 for (LineSegment ls : t.segments) { 158 checkUnreferencing.add(ls.start); 159 checkUnreferencing.add(ls.end); 159 160 } 160 161 } 161 162 for (LineSegment ls : lineSegmentsToDelete) { 162 checkUnreferencing.add(ls.getStart()); 163 checkUnreferencing.add(ls.getEnd()); 164 } 165 166 // delete tracks and areas 167 for (Track t : tracksToDelete) 168 Main.main.ds.removeTrack(t); 169 for (LineSegment ls : lineSegmentsToDelete) 170 Main.main.ds.destroyPendingLineSegment(ls); 171 163 checkUnreferencing.add(ls.start); 164 checkUnreferencing.add(ls.end); 165 } 166 167 Collection<OsmPrimitive> deleteData = new LinkedList<OsmPrimitive>(); 168 deleteData.addAll(tracksToDelete); 169 deleteData.addAll(lineSegmentsToDelete); 172 170 // removing all unreferenced nodes 173 for (Node n : checkUnreferencing) {171 for (Node n : checkUnreferencing) 174 172 if (!isReferenced(n)) 175 Main.main.ds.nodes.remove(n); 176 } 173 deleteData.add(n); 177 174 // now, all references are killed. Delete the node (if it was a node) 178 175 if (osm instanceof Node) 179 Main.main.ds.nodes.remove(osm); 176 deleteData.add(osm); 177 178 mv.editLayer().add(new DeleteCommand(deleteData)); 180 179 } 181 180 … … 188 187 */ 189 188 private void delete(OsmPrimitive osm) { 190 if (osm instanceof Node) { 191 Node n = (Node)osm; 192 if (isReferenced(n)) { 193 String combined = combine(n); 194 if (combined != null) { 195 JOptionPane.showMessageDialog(Main.main, combined); 196 return; 197 } 198 } 199 // now, the node isn't referenced anymore, so delete it. 200 Main.main.ds.nodes.remove(n); 201 } else if (osm instanceof LineSegment) { 202 LinkedList<Track> tracksToDelete = new LinkedList<Track>(); 203 for (Track t : Main.main.ds.tracks()) { 204 t.remove((LineSegment)osm); 205 if (t.segments().isEmpty()) 206 tracksToDelete.add(t); 207 } 208 for (Track t : tracksToDelete) 209 Main.main.ds.removeTrack(t); 210 Main.main.ds.destroyPendingLineSegment((LineSegment)osm); 211 } else if (osm instanceof Track) { 212 Main.main.ds.removeTrack((Track)osm); 213 for (LineSegment ls : ((Track)osm).segments()) 214 Main.main.ds.addPendingLineSegment(ls); 215 } 189 if (osm instanceof Node && isReferenced((Node)osm)) { 190 combineAndDelete((Node)osm); 191 return; 192 } 193 Collection<OsmPrimitive> c = new LinkedList<OsmPrimitive>(); 194 c.add(osm); 195 mv.editLayer().add(new DeleteCommand(c)); 216 196 } 217 197 … … 223 203 */ 224 204 private boolean isReferenced(Node n) { 225 for (Track t : Main.main.ds.tracks ())226 for (LineSegment ls : t.segments ())227 if (ls. getStart() == n || ls.getEnd()== n)205 for (Track t : Main.main.ds.tracks) 206 for (LineSegment ls : t.segments) 207 if (ls.start == n || ls.end == n) 228 208 return true; 229 for (LineSegment ls : Main.main.ds.pendingLineSegments ())230 if (ls. getStart() == n || ls.getEnd()== n)209 for (LineSegment ls : Main.main.ds.pendingLineSegments) 210 if (ls.start == n || ls.end == n) 231 211 return true; 232 212 // TODO areas … … 243 223 * are problems combining the node. 244 224 */ 245 private String combine(Node n) {225 private void combineAndDelete(Node n) { 246 226 // first, check for pending line segments 247 for (LineSegment ls : Main.main.ds.pendingLineSegments()) 248 if (n == ls.getStart() || n == ls.getEnd()) 249 return "Node used by a line segment which is not part of any track. Remove this first."; 227 for (LineSegment ls : Main.main.ds.pendingLineSegments) 228 if (n == ls.start || n == ls.end) { 229 JOptionPane.showMessageDialog(Main.main, "Node used by a line segment which is not part of any track. Remove this first."); 230 return; 231 } 250 232 251 233 // These line segments must be combined within the track combining … … 256 238 // These line segments are combinable. The inner arraylist has always 257 239 // two elements. The keys maps to the track, the line segments are in. 258 HashMap<ArrayList<LineSegment>, Track> lineSegments = new HashMap<ArrayList<LineSegment>, Track>();259 260 for (Track t : Main.main.ds.tracks ()) {240 Collection<LineSegmentCombineEntry> lineSegments = new ArrayList<LineSegmentCombineEntry>(); 241 242 for (Track t : Main.main.ds.tracks) { 261 243 ArrayList<LineSegment> current = new ArrayList<LineSegment>(); 262 for (LineSegment ls : t.segments ())263 if (ls. getStart() == n || ls.getEnd()== n)244 for (LineSegment ls : t.segments) 245 if (ls.start == n || ls.end == n) 264 246 current.add(ls); 265 247 if (!current.isEmpty()) { 266 if (current.size() > 2) 267 return "Node used by more than two line segments."; 248 if (current.size() > 2) { 249 JOptionPane.showMessageDialog(Main.main, "Node used by more than two line segments."); 250 return; 251 } 268 252 if (current.size() == 1 && 269 253 (current.get(0) == t.getStartingSegment() || current.get(0) == t.getEndingSegment())) 270 254 pendingLineSegmentsForTrack.add(current.get(0)); 271 else if (current.get(0).getEnd() != current.get(1).getStart() && 272 current.get(1).getEnd() != current.get(0).getStart()) 273 return "Node used by line segments that points together."; 274 else if (!current.get(0).keyPropertiesMergable(current.get(1))) 275 return "Node used by line segments with different properties."; 276 else 277 lineSegments.put(current, t); 255 else if (current.get(0).end != current.get(1).start && 256 current.get(1).end != current.get(0).start) { 257 JOptionPane.showMessageDialog(Main.main, "Node used by line segments that points together."); 258 return; 259 } else if (!current.get(0).keyPropertiesMergable(current.get(1))) { 260 JOptionPane.showMessageDialog(Main.main, "Node used by line segments with different properties."); 261 return; 262 } else { 263 LineSegmentCombineEntry e = new LineSegmentCombineEntry(); 264 e.first = current.get(0); 265 e.second = current.get(1); 266 e.track = t; 267 lineSegments.add(e); 268 } 278 269 } 279 270 } … … 281 272 // try to combine tracks 282 273 ArrayList<Track> tracks = new ArrayList<Track>(); 283 for (Track t : Main.main.ds.tracks ())274 for (Track t : Main.main.ds.tracks) 284 275 if (t.getStartingNode() == n || t.getEndingNode() == n) 285 276 tracks.add(t); 286 277 if (!tracks.isEmpty()) { 287 if (tracks.size() > 2) 288 return "Node used by more than two tracks."; 289 if (tracks.size() == 1) 290 return "Node used by a track."; 278 if (tracks.size() > 2) { 279 JOptionPane.showMessageDialog(Main.main, "Node used by more than two tracks."); 280 return; 281 } 282 if (tracks.size() == 1) { 283 JOptionPane.showMessageDialog(Main.main, "Node used by a track."); 284 return; 285 } 291 286 Track t1 = tracks.get(0); 292 287 Track t2 = tracks.get(1); … … 294 289 t2.getStartingNode() != t1.getEndingNode()) { 295 290 if (t1.getStartingNode() == t2.getStartingNode() || 296 t1.getEndingNode() == t2.getEndingNode()) 297 return "Node used by tracks that point together."; 298 return "Node used by tracks that cannot be combined."; 299 } 300 if (!t1.keyPropertiesMergable(t2)) 301 return "Node used by tracks with different properties."; 291 t1.getEndingNode() == t2.getEndingNode()) { 292 JOptionPane.showMessageDialog(Main.main, "Node used by tracks that point together."); 293 return; 294 } 295 JOptionPane.showMessageDialog(Main.main, "Node used by tracks that cannot be combined."); 296 return; 297 } 298 if (!t1.keyPropertiesMergable(t2)) { 299 JOptionPane.showMessageDialog(Main.main, "Node used by tracks with different properties."); 300 return; 301 } 302 302 } 303 303 … … 306 306 LineSegment l1 = pendingLineSegmentsForTrack.get(0); 307 307 LineSegment l2 = pendingLineSegmentsForTrack.get(1); 308 if (l1.getStart() == l2.getStart() || l1.getEnd() == l2.getEnd()) 309 return "Node used by line segments that points together."; 310 if (l1.getStart() == l2.getEnd() || l2.getStart() == l1.getEnd()) 308 if (l1.start == l2.start || l1.end == l2.end) { 309 JOptionPane.showMessageDialog(Main.main, "Node used by line segments that points together."); 310 return; 311 } 312 if (l1.start == l2.end || l2.start == l1.end) 311 313 pendingLineSegmentsForTrack.clear(); // resolved. 312 314 } 313 315 314 316 // still pending line segments? 315 if (!pendingLineSegmentsForTrack.isEmpty()) 316 return "Node used by tracks that cannot be combined."; 317 if (!pendingLineSegmentsForTrack.isEmpty()) { 318 JOptionPane.showMessageDialog(Main.main, "Node used by tracks that cannot be combined."); 319 return; 320 } 317 321 318 322 // Ok, we can combine. Do it. 319 // line segments 320 for (ArrayList<LineSegment> list : lineSegments.keySet()) { 321 LineSegment first = list.get(0); 322 LineSegment second = list.get(1); 323 if (first.getStart() == second.getEnd()) { 324 first = second; 325 second = list.get(0); 326 } 327 first.setEnd(second.getEnd()); 328 first.keys = mergeKeys(first.keys, second.keys); 329 lineSegments.get(list).remove(second); 330 } 331 332 // tracks 333 if (!tracks.isEmpty()) { 334 Track first = tracks.get(0); 335 Track second = tracks.get(1); 336 if (first.getStartingNode() == second.getEndingNode()) { 337 first = second; 338 second = tracks.get(0); 339 } 340 // concatenate the line segments. 341 LineSegment lastOfFirst = first.getEndingSegment(); 342 LineSegment firstOfSecond = second.getStartingSegment(); 343 lastOfFirst.setEnd(firstOfSecond.getEnd()); 344 lastOfFirst.keys = mergeKeys(lastOfFirst.keys, firstOfSecond.keys); 345 second.remove(firstOfSecond); 346 // move the remaining line segments to first track. 347 first.addAll(second.segments()); 348 Main.main.ds.removeTrack(second); 349 } 350 351 return null; 352 } 353 354 /** 355 * Merges the second parameter into the first and return the merged map. 356 * @param first The first map that will hold keys. 357 * @param second The map to merge with the first. 358 * @return The merged key map. 359 */ 360 private Map<Key, String> mergeKeys(Map<Key, String> first, Map<Key, String> second) { 361 if (first == null) 362 first = second; 363 else if (second != null && first != null) 364 first.putAll(second); 365 return first; 366 } 367 368 @Override 369 protected boolean isEditMode() { 370 return true; 323 Track firstTrack = tracks.isEmpty() ? null : tracks.get(0); 324 Track secondTrack = tracks.isEmpty() ? null : tracks.get(1); 325 mv.editLayer().add(new CombineAndDeleteCommand(n, lineSegments, firstTrack, secondTrack)); 371 326 } 372 327 } -
src/org/openstreetmap/josm/actions/mapmode/MapMode.java
r22 r23 13 13 import org.openstreetmap.josm.gui.MapFrame; 14 14 import org.openstreetmap.josm.gui.MapView; 15 import org.openstreetmap.josm.gui.MapView.LayerChangeListener;16 import org.openstreetmap.josm.gui.layer.Layer;17 15 18 16 /** … … 50 48 this.mapFrame = mapFrame; 51 49 mv = mapFrame.mapView; 52 mv.addLayerChangeListener(new LayerChangeListener(){53 public void activeLayerChange(Layer oldLayer, Layer newLayer) {54 setEnabled(!isEditMode() || newLayer.isEditable());55 }56 public void layerAdded(Layer newLayer) {}57 public void layerRemoved(Layer oldLayer) {}58 });59 50 } 60 61 /**62 * Subclasses should return whether they want to edit the map data or63 * whether they are read-only.64 */65 abstract protected boolean isEditMode();66 51 67 52 /** -
src/org/openstreetmap/josm/actions/mapmode/MoveAction.java
r22 r23 8 8 9 9 import org.openstreetmap.josm.Main; 10 import org.openstreetmap.josm.command.Command;11 10 import org.openstreetmap.josm.command.MoveCommand; 12 11 import org.openstreetmap.josm.data.GeoPoint; … … 84 83 85 84 Collection<OsmPrimitive> selection = Main.main.ds.getSelected(); 86 Command c = new MoveCommand(selection, dx, dy); 87 c.executeCommand(); 88 Main.main.commands.add(c); 85 mv.editLayer().add(new MoveCommand(selection, dx, dy)); 89 86 90 87 mv.repaint(); … … 131 128 } 132 129 } 133 134 @Override135 protected boolean isEditMode() {136 return true;137 }138 130 } -
src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java
r22 r23 95 95 mv.repaint(); 96 96 } 97 98 @Override99 protected boolean isEditMode() {100 return false;101 }102 97 } -
src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java
r17 r23 68 68 selectionManager.unregister(mv); 69 69 } 70 71 @Override72 protected boolean isEditMode() {73 return false;74 }75 70 } -
src/org/openstreetmap/josm/command/AddCommand.java
r22 r23 43 43 SelectionComponentVisitor v = new SelectionComponentVisitor(); 44 44 osm.visit(v); 45 return new JLabel( v.name, v.icon, JLabel.LEADING);45 return new JLabel("Add "+v.name, v.icon, JLabel.LEADING); 46 46 } 47 47 48 48 public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 49 if ( !added.contains(osm))49 if (added != null && !added.contains(osm)) 50 50 added.add(osm); 51 51 } … … 65 65 public void visit(LineSegment ls) { 66 66 Main.main.ds.pendingLineSegments.add(ls); 67 Main.main.ds.addBackReference(ls.start, ls); 68 Main.main.ds.addBackReference(ls.end, ls); 67 69 } 68 70 … … 74 76 Main.main.ds.tracks.add(t); 75 77 for (Iterator<LineSegment> it = Main.main.ds.pendingLineSegments.iterator(); it.hasNext();) 76 if (t.segments ().contains(it.next()))78 if (t.segments.contains(it.next())) 77 79 it.remove(); 80 for (LineSegment ls : t.segments) { 81 Main.main.ds.addBackReference(ls, t); 82 Main.main.ds.addBackReference(ls.start, t); 83 Main.main.ds.addBackReference(ls.end, t); 84 } 78 85 } 79 86 -
src/org/openstreetmap/josm/command/CombineCommand.java
r22 r23 46 46 public void executeCommand() { 47 47 if (del instanceof LineSegment) { 48 LineSegment ls = (LineSegment) mod;49 Track t = (Track) del;50 if (!Main.main.ds.pendingLineSegments ().contains(ls))48 LineSegment ls = (LineSegment)del; 49 Track t = (Track)mod; 50 if (!Main.main.ds.pendingLineSegments.contains(ls)) 51 51 throw new IllegalStateException("Should not be able to select non-pending line segments."); 52 52 53 53 Main.main.ds.pendingLineSegments.remove(ls); 54 if (t.getStartingNode() != ls. getEnd())54 if (t.getStartingNode() != ls.end) 55 55 t.add(ls); 56 56 else 57 t. addStart(ls);57 t.segments.add(0,ls); 58 58 } else { 59 59 Track t1 = (Track)mod; 60 60 Track t2 = (Track)del; 61 t1. addAll(t2.segments());61 t1.segments.addAll(t2.segments); 62 62 if (t1.keys == null) 63 63 t1.keys = t2.keys; 64 64 else 65 65 t1.keys.putAll(t2.keys); 66 t2.destroy();67 66 Main.main.ds.tracks.remove(t2); 68 67 } 68 Main.main.ds.rebuildBackReferences(); 69 69 } 70 70 … … 82 82 83 83 public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 84 if ( !modified.contains(mod))84 if (modified != null && !modified.contains(mod)) 85 85 modified.add(mod); 86 if (deleted .contains(del))86 if (deleted != null && deleted.contains(del)) 87 87 throw new IllegalStateException("Deleted object twice: "+del); 88 88 deleted.add(del); -
src/org/openstreetmap/josm/command/Command.java
r22 r23 27 27 /** 28 28 * Fill in the changed data this command operates on (for sending to the server). 29 * Add to the lists, don't clear them. 30 * @param modified The modified primitives 31 * @param deleted The deleted primitives 32 * @param added The added primitives 29 * Add to the lists, don't clear them. The lists can be <code>null</code> 30 * in which case they are ignored. 31 * 32 * @param modified The modified primitives or <code>null</code> 33 * @param deleted The deleted primitives or <code>null</code> 34 * @param added The added primitives or <code>null</code> 33 35 */ 34 36 void fillModifiedData(Collection<OsmPrimitive> modified, -
src/org/openstreetmap/josm/command/MoveCommand.java
r22 r23 3 3 import java.awt.Component; 4 4 import java.util.Collection; 5 import java.util.HashSet;6 5 7 6 import javax.swing.JLabel; … … 9 8 import org.openstreetmap.josm.data.osm.Node; 10 9 import org.openstreetmap.josm.data.osm.OsmPrimitive; 10 import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor; 11 11 12 12 /** … … 49 49 50 50 public void executeCommand() { 51 Collection<Node> movingNodes = new HashSet<Node>();51 AllNodesVisitor visitor = new AllNodesVisitor(); 52 52 for (OsmPrimitive osm : objects) 53 movingNodes.addAll(osm.getAllNodes());54 for (Node n : movingNodes) {53 osm.visit(visitor); 54 for (Node n : visitor.nodes) { 55 55 n.coor.x += x; 56 56 n.coor.y += y; … … 65 65 66 66 public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 67 for (OsmPrimitive osm : objects) 68 if (!modified.contains(osm)) 69 modified.add(osm); 67 if (modified != null) 68 for (OsmPrimitive osm : objects) 69 if (!modified.contains(osm)) 70 modified.add(osm); 70 71 } 71 72 } -
src/org/openstreetmap/josm/data/Bounds.java
r1 r23 45 45 this.max = max; 46 46 } 47 48 /** 49 * @return The bounding rectangle that covers <code>this</code> and 50 * the <code>other</code> bounds, regarding the x/y values. 51 */ 52 public Bounds mergeXY(Bounds other) { 53 GeoPoint nmin = new GeoPoint(); 54 nmin.x = Math.min(min.x, other.min.x); 55 nmin.y = Math.min(min.y, other.min.y); 56 GeoPoint nmax = new GeoPoint(); 57 nmax.x = Math.max(max.x, other.max.x); 58 nmax.y = Math.max(max.y, other.max.y); 59 return new Bounds(nmin, nmax); 60 } 61 62 /** 63 * @return The bounding rectangle that covers <code>this</code> and 64 * the <code>other</code> bounds, regarding the lat/lon values. 65 */ 66 public Bounds mergeLatLon(Bounds other) { 67 GeoPoint nmin = new GeoPoint( 68 Math.min(min.lat, other.min.lat), 69 Math.min(min.lon, other.min.lon)); 70 GeoPoint nmax = new GeoPoint( 71 Math.max(max.lat, other.max.lat), 72 Math.max(max.lon, other.max.lon)); 73 return new Bounds(nmin, nmax); 74 } 47 75 } -
src/org/openstreetmap/josm/data/Preferences.java
r20 r23 45 45 */ 46 46 private boolean drawRawGpsLines = false; 47 /** 48 * Whether deleted objects should be drawn in a dark color. 49 */ 50 private boolean drawDeleted = false; 47 51 /** 48 52 * Force the drawing of lines between raw gps points if there are no … … 134 138 mergeNodes = root.getChild("mergeNodes") != null; 135 139 drawRawGpsLines = root.getChild("drawRawGpsLines") != null; 140 forceRawGpsLines = root.getChild("forceRawGpsLines") != null; 141 drawDeleted = root.getChild("drawDeleted") != null; 136 142 } catch (Exception e) { 137 143 if (e instanceof PreferencesException) … … 156 162 if (drawRawGpsLines) 157 163 children.add(new Element("drawRawGpsLines")); 164 if (drawDeleted) 165 children.add(new Element("drawDeleted")); 166 if (forceRawGpsLines) 167 children.add(new Element("forceRawGpsLines")); 158 168 Element osmServer = new Element("osm-server"); 159 169 osmServer.getChildren().add(new Element("url").setText(osmDataServer)); … … 177 187 } 178 188 179 180 189 // projection change listener stuff 181 190 … … 184 193 */ 185 194 private Collection<PropertyChangeListener> listener = new LinkedList<PropertyChangeListener>(); 195 186 196 /** 187 197 * Add a listener of projection changes to the list of listeners. … … 246 256 return forceRawGpsLines; 247 257 } 258 public boolean isDrawDeleted() { 259 return drawDeleted; 260 } 261 public void setDrawDeleted(boolean drawDeleted) { 262 boolean old = this.drawDeleted; 263 this.drawDeleted = drawDeleted; 264 firePropertyChanged("drawDeleted", old, drawDeleted); 265 } 248 266 } -
src/org/openstreetmap/josm/data/osm/DataSet.java
r22 r23 1 package org.openstreetmap.josm. command;1 package org.openstreetmap.josm.data.osm; 2 2 3 3 import java.util.Collection; 4 import java.util.Collections;5 4 import java.util.HashMap; 6 5 import java.util.HashSet; 7 import java.util.Iterator;8 6 import java.util.LinkedList; 9 7 import java.util.Map; … … 12 10 import org.openstreetmap.josm.data.Bounds; 13 11 import org.openstreetmap.josm.data.SelectionTracker; 14 import org.openstreetmap.josm.data.osm.LineSegment; 15 import org.openstreetmap.josm.data.osm.Node; 16 import org.openstreetmap.josm.data.osm.OsmPrimitive; 17 import org.openstreetmap.josm.data.osm.Track; 12 import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor; 18 13 19 14 /** … … 41 36 * are in this list but are in no track. 42 37 */ 43 Collection<LineSegment> pendingLineSegments = new LinkedList<LineSegment>();38 public Collection<LineSegment> pendingLineSegments = new LinkedList<LineSegment>(); 44 39 45 40 /** … … 50 45 * track list. 51 46 */ 52 Collection<Track> tracks = new LinkedList<Track>(); 53 54 /** 55 * Add the track to the tracklist. 56 */ 57 public void addTrack(Track t) { 58 tracks.add(t); 59 } 60 /** 61 * Remove the track from the tracklist. 62 */ 63 public void removeTrack(Track t) { 64 t.destroy(); 65 tracks.remove(t); 66 } 67 /** 68 * Return a read-only collection of all tracks 69 */ 70 public Collection<Track> tracks() { 71 return Collections.unmodifiableCollection(tracks); 72 } 73 74 /** 75 * Add a newly created line segment to the pending lines list. 76 */ 77 public void addPendingLineSegment(LineSegment ls) { 78 pendingLineSegments.add(ls); 79 } 80 /** 81 * Remove a line segment from the pending lines list, because it has been 82 * assigned to the track. 83 * @param ls The line segment from the pending list 84 * @param t The track, that will hold the line segment 85 * @param end <code>true</code> to attach on the end. <code>false</code> 86 * to attach on the beginning. 87 */ 88 public void assignPendingLineSegment(LineSegment ls, Track t, boolean end) { 89 pendingLineSegments.remove(ls); 90 if (end) 91 t.add(ls); 92 else 93 t.addStart(ls); 94 } 95 /** 96 * Delete the pending line segment without moving it anywhere. 97 */ 98 public void destroyPendingLineSegment(LineSegment ls) { 99 pendingLineSegments.remove(ls); 100 ls.destroy(); 101 } 102 /** 103 * Return an read-only iterator over all pending line segments. 104 */ 105 public Collection<LineSegment> pendingLineSegments() { 106 return Collections.unmodifiableCollection(pendingLineSegments); 107 } 108 47 public Collection<Track> tracks = new LinkedList<Track>(); 48 49 50 /** 51 * This is a list of all back references of nodes to their track usage. 52 */ 53 public Map<Node, Set<Track>> nodeTrackRef = new HashMap<Node, Set<Track>>(); 54 /** 55 * This is a list of all back references of nodes to their line segments. 56 */ 57 public Map<Node, Set<LineSegment>> nodeLsRef = new HashMap<Node, Set<LineSegment>>(); 58 /** 59 * This is a list of all back references of lines to their tracks. 60 */ 61 public Map<LineSegment, Set<Track>> lsTrackRef = new HashMap<LineSegment, Set<Track>>(); 62 63 /** 64 * Add a back reference from the node to the line segment. 65 */ 66 public void addBackReference(Node from, LineSegment to) { 67 Set<LineSegment> references = nodeLsRef.get(from); 68 if (references == null) 69 references = new HashSet<LineSegment>(); 70 references.add(to); 71 nodeLsRef.put(from, references); 72 } 73 /** 74 * Add a back reference from the node to the track. 75 */ 76 public void addBackReference(Node from, Track to) { 77 Set<Track> references = nodeTrackRef.get(from); 78 if (references == null) 79 references = new HashSet<Track>(); 80 references.add(to); 81 nodeTrackRef.put(from, references); 82 } 83 /** 84 * Add a back reference from the line segment to the track. 85 */ 86 public void addBackReference(LineSegment from, Track to) { 87 Set<Track> references = lsTrackRef.get(from); 88 if (references == null) 89 references = new HashSet<Track>(); 90 references.add(to); 91 lsTrackRef.put(from, references); 92 } 93 94 /** 95 * Removes all references to and from this line segment. 96 */ 97 public void removeBackReference(LineSegment ls) { 98 Set<LineSegment> s = nodeLsRef.get(ls.start); 99 if (s != null) 100 s.remove(ls); 101 s = nodeLsRef.get(ls.end); 102 if (s != null) 103 s.remove(ls); 104 lsTrackRef.remove(ls); 105 } 106 /** 107 * Removes all references to and from the node. 108 */ 109 public void removeBackReference(Node n) { 110 nodeLsRef.remove(n); 111 nodeTrackRef.remove(n); 112 } 113 /** 114 * Removes all references to and from the track. 115 */ 116 public void removeBackReference(Track t) { 117 Collection<Node> nodes = AllNodesVisitor.getAllNodes(t); 118 for (Node n : nodes) { 119 Set<Track> s = nodeTrackRef.get(n); 120 if (s != null) 121 s.remove(t); 122 } 123 for (LineSegment ls : t.segments) { 124 Set<Track> s = lsTrackRef.get(ls); 125 if (s != null) 126 s.remove(t); 127 } 128 } 129 130 /** 131 * Rebuild the caches of back references. 132 */ 133 public void rebuildBackReferences() { 134 nodeTrackRef.clear(); 135 nodeLsRef.clear(); 136 lsTrackRef.clear(); 137 for (Track t : tracks) { 138 for (LineSegment ls : t.segments) { 139 addBackReference(ls.start, ls); 140 addBackReference(ls.end, ls); 141 addBackReference(ls.start, t); 142 addBackReference(ls.end, t); 143 addBackReference(ls, t); 144 } 145 } 146 for (LineSegment ls : pendingLineSegments) { 147 addBackReference(ls.start, ls); 148 addBackReference(ls.end, ls); 149 } 150 } 151 109 152 /** 110 153 * Return the bounds of this DataSet, depending on X/Y values. … … 177 220 clearSelection(tracks); 178 221 for (Track t : tracks) 179 clearSelection(t.segments ());222 clearSelection(t.segments); 180 223 } 181 224 … … 190 233 sel.addAll(getSelected(tracks)); 191 234 for (Track t : tracks) 192 sel.addAll(getSelected(t.segments ()));235 sel.addAll(getSelected(t.segments)); 193 236 return sel; 194 237 } … … 198 241 * The objects imported are not cloned, so from now on, these data belong 199 242 * to both datasets. So use mergeFrom only if you are about to abandon the 200 * other dataset or this dataset. 243 * other dataset. 244 * 245 * Elements are tried to merged. 246 * Nodes are merged first, if their lat/lon are equal. 247 * Line segments are merged, if they have the same nodes. 248 * Tracs are merged, if they consist of the same line segments. 249 * 250 * Additional to that, every two objects with the same id are merged. 201 251 * 202 252 * @param ds The DataSet to merge into this one. 203 * @param mergeEqualNodes If <code>true</code>, nodes with the same lat/lon 204 * are merged together. 205 */ 206 public void mergeFrom(DataSet ds, boolean mergeEqualNodes) { 207 if (mergeEqualNodes && !nodes.isEmpty()) { 208 Map<Node, Node> mergeMap = new HashMap<Node, Node>(); 209 Set<Node> nodesToAdd = new HashSet<Node>(); 210 for (Node n : nodes) { 211 for (Iterator<Node> it = ds.nodes.iterator(); it.hasNext();) { 212 Node dsn = it.next(); 213 if (n.coor.equalsLatLon(dsn.coor)) { 214 mergeMap.put(dsn, n); 215 n.mergeFrom(dsn); 216 it.remove(); 217 } else { 218 nodesToAdd.add(dsn); 219 } 253 * @return A list of all primitives that were used in the conjunction. That 254 * is all used primitives (the merged primitives and all added ones). 255 */ 256 public Collection<OsmPrimitive> mergeFrom(DataSet ds) { 257 Collection<OsmPrimitive> data = new LinkedList<OsmPrimitive>(); 258 259 Set<LineSegment> myLineSegments = new HashSet<LineSegment>(); 260 myLineSegments.addAll(pendingLineSegments); 261 for (Track t : tracks) 262 myLineSegments.addAll(t.segments); 263 264 Set<LineSegment> otherLineSegments = new HashSet<LineSegment>(); 265 otherLineSegments.addAll(ds.pendingLineSegments); 266 for (Track t : ds.tracks) 267 otherLineSegments.addAll(t.segments); 268 269 270 // merge nodes 271 272 Map<Node, Node> nodeMap = new HashMap<Node, Node>(); 273 // find mergable 274 for (Node otherNode : ds.nodes) 275 for (Node myNode : nodes) 276 if (otherNode.coor.equalsLatLon(myNode.coor)) 277 nodeMap.put(otherNode, myNode); 278 // add 279 data.addAll(new HashSet<Node>(nodeMap.values())); 280 for (Node n : ds.nodes) { 281 if (!nodeMap.containsKey(n)) { 282 nodes.add(n); 283 data.add(n); 284 } 285 } 286 // reassign 287 for (LineSegment ls : otherLineSegments) { 288 Node n = nodeMap.get(ls.start); 289 if (n != null) 290 ls.start = n; 291 n = nodeMap.get(ls.end); 292 if (n != null) 293 ls.end = n; 294 } 295 296 297 // merge line segments 298 299 Map<LineSegment, LineSegment> lsMap = new HashMap<LineSegment, LineSegment>(); 300 // find mergable 301 for (LineSegment otherLS : otherLineSegments) 302 for (LineSegment myLS : myLineSegments) 303 if (otherLS.start == myLS.start && otherLS.end == myLS.end) 304 lsMap.put(otherLS, myLS); 305 // add pendings (ls from track are added later 306 for (LineSegment ls : ds.pendingLineSegments) { 307 if (!lsMap.containsKey(ls)) { 308 pendingLineSegments.add(ls); 309 data.add(ls); 310 } 311 } 312 // reassign 313 for (Track t : ds.tracks) { 314 for (int i = 0; i < t.segments.size(); ++i) { 315 LineSegment newLS = lsMap.get(t.segments.get(i)); 316 if (newLS != null) 317 t.segments.set(i, newLS); 318 } 319 } 320 321 322 // merge tracks 323 LinkedList<Track> trackToAdd = new LinkedList<Track>(); 324 for (Track otherTrack : ds.tracks) { 325 boolean found = false; 326 for (Track myTrack : tracks) { 327 if (myTrack.segments.equals(otherTrack.segments)) { 328 found = true; 329 data.add(myTrack); 330 break; 220 331 } 221 332 } 222 nodes.addAll(nodesToAdd); 223 for (Track t : ds.tracks) { 224 for (LineSegment ls : t.segments()) { 225 Node n = mergeMap.get(ls.getStart()); 226 if (n != null) 227 ls.start = n; 228 n = mergeMap.get(ls.getEnd()); 229 if (n != null) 230 ls.end = n; 231 } 232 } 233 tracks.addAll(ds.tracks); 234 for (LineSegment ls : ds.pendingLineSegments) { 235 Node n = mergeMap.get(ls.getStart()); 236 if (n != null) 237 ls.start = n; 238 n = mergeMap.get(ls.getEnd()); 239 if (n != null) 240 ls.end = n; 241 } 242 pendingLineSegments.addAll(ds.pendingLineSegments); 243 } else { 244 nodes.addAll(ds.nodes); 245 tracks.addAll(ds.tracks); 246 pendingLineSegments.addAll(ds.pendingLineSegments); 247 } 333 if (!found) 334 trackToAdd.add(otherTrack); 335 } 336 data.addAll(trackToAdd); 337 tracks.addAll(trackToAdd); 338 339 rebuildBackReferences(); 340 return data; 248 341 } 249 342 -
src/org/openstreetmap/josm/data/osm/Key.java
r9 r23 1 1 package org.openstreetmap.josm.data.osm; 2 2 3 import java.util.Collection;4 3 import java.util.HashMap; 5 import java.util.LinkedList;6 4 import java.util.Map; 7 5 … … 49 47 } 50 48 51 /**52 * Return an empty list, since keys cannot have nodes.53 */54 @Override55 public Collection<Node> getAllNodes() {56 return new LinkedList<Node>();57 }58 59 49 @Override 60 50 public void visit(Visitor visitor) { -
src/org/openstreetmap/josm/data/osm/LineSegment.java
r21 r23 1 1 package org.openstreetmap.josm.data.osm; 2 3 import java.util.Collection;4 import java.util.Collections;5 import java.util.LinkedList;6 2 7 3 import org.openstreetmap.josm.data.osm.visitor.Visitor; … … 26 22 27 23 /** 28 * The tracks, this line segment is part of.29 */30 transient Collection<Track> parent = new LinkedList<Track>();31 32 /**33 24 * Create an line segment from the given starting and ending node 34 25 * @param start Starting node of the line segment. … … 38 29 this.start = start; 39 30 this.end = end; 40 start.parentSegment.add(this);41 end.parentSegment.add(this);42 }43 44 /**45 * Return all parent tracks this line segment is part of. The list is readonly.46 */47 public Collection<Track> getParents() {48 return Collections.unmodifiableCollection(parent);49 }50 51 public void setStart(Node start) {52 this.start.parentSegment.remove(this);53 this.start = start;54 start.parentSegment.add(this);55 }56 public Node getStart() {57 return start;58 }59 public void setEnd(Node end) {60 this.end.parentSegment.remove(this);61 this.end = end;62 end.parentSegment.add(this);63 }64 public Node getEnd() {65 return end;66 }67 68 /**69 * The LineSegment is going to be destroyed. Unlink all back references.70 */71 public void destroy() {72 start.parentSegment.remove(this);73 end.parentSegment.remove(this);74 }75 76 /**77 * Return start and end in a list.78 */79 @Override80 public Collection<Node> getAllNodes() {81 LinkedList<Node> nodes = new LinkedList<Node>();82 nodes.add(getStart());83 nodes.add(getEnd());84 return nodes;85 31 } 86 32 -
src/org/openstreetmap/josm/data/osm/Node.java
r17 r23 1 1 package org.openstreetmap.josm.data.osm; 2 3 import java.util.Collection;4 import java.util.Collections;5 import java.util.LinkedList;6 2 7 3 import org.openstreetmap.josm.data.GeoPoint; … … 21 17 public GeoPoint coor; 22 18 23 /**24 * The list of line segments, this node is part of.25 */26 transient Collection<LineSegment> parentSegment = new LinkedList<LineSegment>();27 28 /**29 * Returns a read-only list of all segments this node is in.30 * @return A list of all segments. Readonly.31 */32 public Collection<LineSegment> getParentSegments() {33 return Collections.unmodifiableCollection(parentSegment);34 }35 36 /**37 * Merge the node given at parameter with this node.38 * All parents of the parameter-node become parents of this node.39 *40 * The argument node is not changed.41 *42 * @param node Merge the node to this.43 */44 public void mergeFrom(Node node) {45 parentSegment.addAll(node.parentSegment);46 if (keys == null)47 keys = node.keys;48 else if (node.keys != null)49 keys.putAll(node.keys);50 }51 52 /**53 * Return a list only this added.54 */55 @Override56 public Collection<Node> getAllNodes() {57 LinkedList<Node> nodes = new LinkedList<Node>();58 nodes.add(this);59 return nodes;60 }61 62 19 @Override 63 20 public void visit(Visitor visitor) { -
src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
r22 r23 1 1 package org.openstreetmap.josm.data.osm; 2 2 3 import java.util.Collection;4 3 import java.util.Map; 5 4 … … 20 19 */ 21 20 public Map<Key, String> keys; 22 21 22 /** 23 * Unique identifier in OSM. This is used to reidentify objects in the server. 24 * An id of 0 means an unknown id. The object has not been uploaded yet to 25 * know what id it will get. 26 */ 27 public long id = 0; 28 23 29 /** 24 30 * If set to true, this object has been modified in the current session. … … 30 36 */ 31 37 transient private boolean selected = false; 32 33 /**34 * Return a list of all nodes, this osmPrimitive consists of. Does return35 * an empty list, if it is an primitive that cannot have nodes (e.g. Key)36 * TODO replace with visitor37 */38 abstract public Collection<Node> getAllNodes();39 38 40 39 /** -
src/org/openstreetmap/josm/data/osm/Track.java
r21 r23 2 2 3 3 import java.util.ArrayList; 4 import java.util.Collection;5 import java.util.Collections;6 4 import java.util.List; 7 5 … … 18 16 * All track segments in this track 19 17 */ 20 p rivatefinal List<LineSegment> segments = new ArrayList<LineSegment>();18 public final List<LineSegment> segments = new ArrayList<LineSegment>(); 21 19 22 20 … … 26 24 public void add(LineSegment ls) { 27 25 segments.add(ls); 28 ls.parent.add(this);29 }30 31 /**32 * Add the line segment at first position to the track. First position means,33 * the line segment's start becomes the starting node.34 * @param ls The line segment to add at starting position.35 * @see #getStartingNode()36 */37 public void addStart(LineSegment ls) {38 segments.add(ls);39 ls.parent.add(this);40 }41 42 /**43 * Add all LineSegment's to the list of segments.44 * @param lineSegments The line segments to add.45 */46 public void addAll(Collection<? extends LineSegment> lineSegments) {47 segments.addAll(lineSegments);48 for (LineSegment ls : lineSegments)49 ls.parent.add(this);50 }51 52 /**53 * Remove the line segment from the track.54 */55 public void remove(LineSegment ls) {56 if (segments.remove(ls))57 if (!ls.parent.remove(this))58 throw new IllegalStateException("Parent violation detected.");59 }60 61 /**62 * Return an read-only collection. Do not alter the object returned.63 * @return The read-only Collection of all segments.64 */65 public Collection<LineSegment> segments() {66 return Collections.unmodifiableCollection(segments);67 }68 69 /**70 * Return a merge of getAllNodes - calls to the line segments.71 */72 @Override73 public Collection<Node> getAllNodes() {74 ArrayList<Node> nodes = new ArrayList<Node>();75 for (LineSegment ls : segments)76 nodes.addAll(ls.getAllNodes());77 return nodes;78 }79 /**80 * The track is going to be destroyed. Unlink all back references.81 */82 public void destroy() {83 for (LineSegment ls : segments) {84 ls.parent.remove(this);85 if (ls.parent.isEmpty())86 ls.destroy();87 }88 segments.clear();89 26 } 90 27 … … 101 38 if (segments.isEmpty()) 102 39 return null; 103 return segments.get(segments.size()-1). getEnd();40 return segments.get(segments.size()-1).end; 104 41 } 105 42 … … 126 63 if (segments.isEmpty()) 127 64 return null; 128 return segments.get(0). getStart();65 return segments.get(0).start; 129 66 } 130 67 -
src/org/openstreetmap/josm/data/osm/visitor/SelectionComponentVisitor.java
r21 r23 47 47 String name = getName(ls.keys); 48 48 if (name == null) 49 name = "("+ls. getStart().coor.lat+","+ls.getStart().coor.lon+") -> ("+ls.getEnd().coor.lat+","+ls.getEnd().coor.lon+")";49 name = "("+ls.start.coor.lat+","+ls.start.coor.lon+") -> ("+ls.end.coor.lat+","+ls.end.coor.lon+")"; 50 50 51 51 this.name = name; … … 74 74 if (name == null) { 75 75 Set<Node> nodes = new HashSet<Node>(); 76 for (LineSegment ls : t.segments ()) {77 nodes.add(ls. getStart());78 nodes.add(ls. getEnd());76 for (LineSegment ls : t.segments) { 77 nodes.add(ls.start); 78 nodes.add(ls.end); 79 79 } 80 80 name = "("+nodes.size()+" nodes)"; -
src/org/openstreetmap/josm/data/projection/Projection.java
r22 r23 8 8 import javax.swing.event.ChangeListener; 9 9 10 import org.openstreetmap.josm.data.Bounds; 10 11 import org.openstreetmap.josm.data.GeoPoint; 11 12 … … 70 71 71 72 /** 72 * Initialize itself with the given dataSet.73 * Initialize itself with the given bounding rectangle (regarding lat/lon). 73 74 * 74 75 * This function should initialize own parameters needed to do the … … 81 82 * to initialize their data members. 82 83 */ 83 public void init( ) {}84 public void init(Bounds b) {} 84 85 85 86 /** -
src/org/openstreetmap/josm/data/projection/UTM.java
r22 r23 186 186 * @author imi 187 187 */ 188 private class ZoneData {188 private static class ZoneData { 189 189 int zone = 0; 190 190 Hemisphere hemisphere = Hemisphere.north; … … 194 194 * @return The zone data extrakted from the dataset. 195 195 */ 196 ZoneData autoDetect( ) {196 ZoneData autoDetect(Bounds b) { 197 197 ZoneData zd = new ZoneData(); 198 199 Bounds b = Main.main.ds.getBoundsLatLon();200 198 if (b == null) 201 199 return zd; … … 232 230 */ 233 231 @Override 234 public void init( ) {232 public void init(Bounds b) { 235 233 if (zone == 0) { 236 ZoneData zd = autoDetect( );234 ZoneData zd = autoDetect(b); 237 235 zone = zd.zone; 238 236 hemisphere = zd.hemisphere; … … 272 270 public void actionPerformed(ActionEvent e) { 273 271 if (Main.main.getMapFrame() != null) { 274 ZoneData zd = autoDetect( );272 ZoneData zd = autoDetect(Main.main.ds.getBoundsLatLon()); 275 273 if (zd.zone == 0) 276 274 JOptionPane.showMessageDialog(Main.main, "Autodetection failed. Maybe the data set contain too few information."); -
src/org/openstreetmap/josm/gui/MapView.java
r22 r23 18 18 19 19 import org.openstreetmap.josm.Main; 20 import org.openstreetmap.josm.command.DataSet;21 20 import org.openstreetmap.josm.data.Bounds; 22 21 import org.openstreetmap.josm.data.GeoPoint; … … 26 25 import org.openstreetmap.josm.data.osm.Track; 27 26 import org.openstreetmap.josm.data.projection.Projection; 27 import org.openstreetmap.josm.gui.layer.EditLayer; 28 28 import org.openstreetmap.josm.gui.layer.Layer; 29 29 … … 72 72 private ArrayList<Layer> layers = new ArrayList<Layer>(); 73 73 /** 74 * Direct link to the edit layer (if any) in the layers list. 75 */ 76 private EditLayer editLayer; 77 /** 74 78 * The layer from the layers list that is currently active. 75 79 */ … … 98 102 addLayer(layer); 99 103 Main.pref.addPropertyChangeListener(this); 100 101 // init screen102 recalculateCenterScale();103 104 } 104 105 … … 108 109 */ 109 110 public void addLayer(Layer layer) { 111 if (layer instanceof EditLayer) { 112 if (editLayer != null) { 113 // there can only be one EditLayer 114 editLayer.mergeFrom(layer); 115 return; 116 } 117 editLayer = (EditLayer)layer; 118 } 119 110 120 layers.add(0,layer); 111 121 112 if (layer.dataSet != null) { 113 // initialize the projection if it was the first layer 114 if (layers.size() == 1) 115 Main.pref.getProjection().init(); 116 117 // initialize the dataset in the new layer 118 for (Node n : layer.dataSet.nodes) 119 Main.pref.getProjection().latlon2xy(n.coor); 120 } 122 // initialize the projection if it is the first layer 123 if (layers.size() == 1) 124 Main.pref.getProjection().init(layer.getBoundsLatLon()); 125 126 // reinitialize layer's data 127 layer.init(Main.pref.getProjection()); 121 128 122 129 for (LayerChangeListener l : listeners) … … 125 132 setActiveLayer(layer); 126 133 } 127 134 128 135 /** 129 136 * Remove the layer from the mapview. If the layer was in the list before, … … 239 246 240 247 // pending line segments 241 for (LineSegment ls : Main.main.ds.pendingLineSegments ()) {242 Point A = getScreenPoint(ls. getStart().coor);243 Point B = getScreenPoint(ls. getEnd().coor);248 for (LineSegment ls : Main.main.ds.pendingLineSegments) { 249 Point A = getScreenPoint(ls.start.coor); 250 Point B = getScreenPoint(ls.end.coor); 244 251 double c = A.distanceSq(B); 245 252 double a = p.distanceSq(B); … … 254 261 // tracks & line segments 255 262 minDistanceSq = Double.MAX_VALUE; 256 for (Track t : Main.main.ds.tracks ()) {257 for (LineSegment ls : t.segments ()) {258 Point A = getScreenPoint(ls. getStart().coor);259 Point B = getScreenPoint(ls. getEnd().coor);263 for (Track t : Main.main.ds.tracks) { 264 for (LineSegment ls : t.segments) { 265 Point A = getScreenPoint(ls.start.coor); 266 Point B = getScreenPoint(ls.end.coor); 260 267 double c = A.distanceSq(B); 261 268 double a = p.distanceSq(B); … … 323 330 // reset all datasets. 324 331 Projection p = Main.pref.getProjection(); 325 for (Layer l : layers) { 326 DataSet ds = l.dataSet; 327 if (ds != null) 328 for (Node n : ds.nodes) 329 p.latlon2xy(n.coor); 330 } 332 for (Node n : Main.main.ds.nodes) 333 p.latlon2xy(n.coor); 331 334 recalculateCenterScale(); 332 335 } … … 399 402 h = 20; 400 403 401 Bounds bounds = Main.main.ds.getBoundsXY(); 402 404 Bounds bounds = null; 405 for (Layer l : layers) { 406 if (bounds == null) 407 bounds = l.getBoundsXY(); 408 else 409 bounds = bounds.mergeXY(l.getBoundsXY()); 410 } 411 403 412 boolean oldAutoScale = autoScale; 404 413 GeoPoint oldCenter = center; … … 460 469 activeLayer = layer; 461 470 if (old != layer) { 462 if (old != null && old.dataSet != null)463 old.dataSet.clearSelection();464 471 for (LayerChangeListener l : listeners) 465 472 l.activeLayerChange(old, layer); … … 474 481 return activeLayer; 475 482 } 483 484 /** 485 * @return The current edit layer. If no edit layer exist, one is created. 486 * So editLayer does never return <code>null</code>. 487 */ 488 public EditLayer editLayer() { 489 if (editLayer == null) 490 addLayer(new EditLayer(this)); 491 return editLayer; 492 } 476 493 } -
src/org/openstreetmap/josm/gui/PreferenceDialog.java
r22 r23 62 62 Main.pref.setDrawRawGpsLines(drawRawGpsLines.isSelected()); 63 63 Main.pref.setForceRawGpsLines(forceRawGpsLines.isSelected()); 64 Main.pref.setDrawDeleted(drawDeleted.isSelected()); 64 65 try { 65 66 Main.pref.save(); … … 125 126 */ 126 127 JCheckBox forceRawGpsLines = new JCheckBox("Force lines if no line segments imported."); 128 /** 129 * The checkbox stating whether deleted nodes should be drawn. 130 */ 131 JCheckBox drawDeleted = new JCheckBox("Draw deleted lines."); 127 132 /** 128 133 * The checkbox stating whether nodes should be merged together. … … 198 203 forceRawGpsLines.setSelected(Main.pref.isForceRawGpsLines()); 199 204 forceRawGpsLines.setEnabled(drawRawGpsLines.isSelected()); 205 drawDeleted.setToolTipText("Draw dark hints where objects were deleted."); 206 drawDeleted.setSelected(Main.pref.isDrawDeleted()); 200 207 mergeNodes.setToolTipText("When importing GPX data, all nodes with exact the same lat/lon are merged."); 201 208 mergeNodes.setSelected(Main.pref.mergeNodes); … … 212 219 display.add(drawRawGpsLines, GBC.eol().insets(20,0,0,0)); 213 220 display.add(forceRawGpsLines, GBC.eol().insets(40,0,0,0)); 221 display.add(drawDeleted, GBC.eol().insets(20,0,0,0)); 214 222 display.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL)); 215 223 -
src/org/openstreetmap/josm/gui/SelectionManager.java
r22 r23 278 278 279 279 // pending line segments 280 for (LineSegment ls : Main.main.ds.pendingLineSegments ())280 for (LineSegment ls : Main.main.ds.pendingLineSegments) 281 281 if (rectangleContainLineSegment(r, alt, ls)) 282 282 selection.add(ls); 283 283 284 284 // tracks 285 for (Track t : Main.main.ds.tracks ()) {286 boolean wholeTrackSelected = !t.segments ().isEmpty();287 for (LineSegment ls : t.segments ())285 for (Track t : Main.main.ds.tracks) { 286 boolean wholeTrackSelected = !t.segments.isEmpty(); 287 for (LineSegment ls : t.segments) 288 288 if (rectangleContainLineSegment(r, alt, ls)) 289 289 selection.add(ls); … … 310 310 private boolean rectangleContainLineSegment(Rectangle r, boolean alt, LineSegment ls) { 311 311 if (alt) { 312 Point p1 = mv.getScreenPoint(ls. getStart().coor);313 Point p2 = mv.getScreenPoint(ls. getEnd().coor);312 Point p1 = mv.getScreenPoint(ls.start.coor); 313 Point p2 = mv.getScreenPoint(ls.end.coor); 314 314 if (r.intersectsLine(p1.x, p1.y, p2.x, p2.y)) 315 315 return true; 316 316 } else { 317 if (r.contains(mv.getScreenPoint(ls. getStart().coor))318 && r.contains(mv.getScreenPoint(ls. getEnd().coor)))317 if (r.contains(mv.getScreenPoint(ls.start.coor)) 318 && r.contains(mv.getScreenPoint(ls.end.coor))) 319 319 return true; 320 320 } -
src/org/openstreetmap/josm/gui/dialogs/LayerList.java
r22 r23 8 8 import java.awt.event.ActionListener; 9 9 import java.awt.event.KeyEvent; 10 import java.io.IOException;11 10 import java.util.Collection; 12 11 … … 17 16 import javax.swing.JLabel; 18 17 import javax.swing.JList; 19 import javax.swing.JOptionPane;20 18 import javax.swing.JPanel; 21 19 import javax.swing.JScrollPane; … … 26 24 27 25 import org.openstreetmap.josm.Main; 28 import org.openstreetmap.josm.command.DataSet;29 26 import org.openstreetmap.josm.gui.ImageProvider; 30 27 import org.openstreetmap.josm.gui.MapFrame; … … 32 29 import org.openstreetmap.josm.gui.MapView.LayerChangeListener; 33 30 import org.openstreetmap.josm.gui.layer.Layer; 34 import org.openstreetmap.josm.io.OsmWriter;35 31 36 32 /** … … 72 68 */ 73 69 private JButton deleteButton = new JButton(ImageProvider.get("dialogs", "delete")); 74 /**75 * Button for connecting disconnecting to the server.76 */77 private JButton uploadButton = new JButton(ImageProvider.get("dialogs", "condiscon"));78 70 79 71 /** … … 96 88 icon = ImageProvider.overlay(icon, invisible, ImageProvider.OverlayPosition.SOUTHEAST); 97 89 label.setIcon(icon); 98 99 DataSet ds = layer.dataSet; 100 if (ds != null) { 101 label.setToolTipText(ds.nodes.size()+" nodes, "+ 102 ds.tracks().size()+" tracks"); 103 } 90 label.setToolTipText(layer.getToolTipText()); 104 91 return label; 105 92 } … … 182 169 public void actionPerformed(ActionEvent e) { 183 170 Layer lFrom = (Layer)layers.getSelectedValue(); 184 DataSet dsFrom = lFrom.dataSet;185 171 Layer lTo = (Layer)model.get(layers.getSelectedIndex()+1); 186 DataSet dsTo = lTo.dataSet; 187 dsTo.mergeFrom(dsFrom, Main.pref.mergeNodes); 172 lTo.mergeFrom(lFrom); 188 173 layers.setSelectedValue(lTo, true); 189 174 mapView.removeLayer(lFrom); … … 192 177 buttonPanel.add(mergeButton); 193 178 194 uploadButton.setToolTipText("Upload changes to the server.");195 uploadButton.addActionListener(new ActionListener(){196 public void actionPerformed(ActionEvent e) {197 OsmWriter con = new OsmWriter(Main.pref.osmDataServer, Main.main.commands);198 try {199 con.output();200 } catch (IOException x) {201 x.printStackTrace();202 JOptionPane.showMessageDialog(Main.main, "Not all changes could be uploaded.");203 }204 }205 });206 buttonPanel.add(uploadButton);207 208 179 add(buttonPanel, BorderLayout.SOUTH); 209 180 … … 219 190 boolean enable = model.getSize() > 1; 220 191 enable = enable && sel < model.getSize()-1; 221 enable = enable && l.dataSet != null; 222 enable = enable && ((Layer)model.get(sel+1)).dataSet != null; 223 enable = enable && l.isEditable() == ((Layer)model.get(sel+1)).isEditable(); 192 enable = enable && l.isMergable((Layer)model.get(sel+1)); 224 193 mergeButton.setEnabled(enable); 225 194 upButton.setEnabled(sel > 0); -
src/org/openstreetmap/josm/gui/layer/Layer.java
r22 r23 5 5 import javax.swing.Icon; 6 6 7 import org.openstreetmap.josm.data.Bounds; 8 import org.openstreetmap.josm.data.projection.Projection; 7 9 import org.openstreetmap.josm.gui.MapView; 8 10 … … 32 34 */ 33 35 public final String name; 34 36 35 37 /** 36 38 * Create the layer and fill in the necessary components. … … 52 54 53 55 /** 54 * @return <code>true</code>, if the map data can be edited.56 * @return A small tooltip hint about some statistics for this layer. 55 57 */ 56 public boolean isEditable() { 57 return false; 58 } 58 abstract public String getToolTipText(); 59 60 /** 61 * Merges the given layer into this layer. Throws if the layer types are 62 * incompatible. 63 * @param from The layer that get merged into this one. After the merge, 64 * the other layer is not usable anymore and passing to one others 65 * mergeFrom should be one of the last things to do with a layer. 66 */ 67 abstract public void mergeFrom(Layer from); 68 69 /** 70 * @param other The other layer that is tested to be mergable with this. 71 * @return Whether the other layer can be merged into this layer. 72 */ 73 abstract public boolean isMergable(Layer other); 74 75 /** 76 * @return The bounding rectangle this layer occupies on screen when looking 77 * at lat/lon values or <code>null</code>, if infinite area or unknown 78 * area is occupied. 79 */ 80 abstract public Bounds getBoundsLatLon(); 81 82 /** 83 * @return The bounding rectangle this layer occupies on screen when looking 84 * at x/y values or <code>null</code>, if infinite area or unknown 85 * area is occupied. 86 */ 87 abstract public Bounds getBoundsXY(); 88 89 /** 90 * Initialize the internal dataset with the given projection. 91 */ 92 abstract public void init(Projection projection); 59 93 } -
src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
r22 r23 1 1 package org.openstreetmap.josm.gui.layer; 2 2 3 import java.awt.Color;4 3 import java.awt.Graphics; 5 import java.awt.Point;6 4 import java.util.Collection; 7 import java.util.HashSet;8 5 9 6 import javax.swing.Icon; 10 7 11 import org.openstreetmap.josm.Main; 12 import org.openstreetmap.josm.data.osm.Key; 13 import org.openstreetmap.josm.data.osm.LineSegment; 8 import org.openstreetmap.josm.data.Bounds; 14 9 import org.openstreetmap.josm.data.osm.Node; 15 10 import org.openstreetmap.josm.data.osm.OsmPrimitive; 16 import org.openstreetmap.josm.data.osm.Track; 17 import org.openstreetmap.josm.data.osm.visitor.Visitor; 11 import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor; 12 import org.openstreetmap.josm.data.osm.visitor.BoundingVisitor; 13 import org.openstreetmap.josm.data.osm.visitor.SimplePaintVisitor; 14 import org.openstreetmap.josm.data.projection.Projection; 18 15 import org.openstreetmap.josm.gui.ImageProvider; 19 16 import org.openstreetmap.josm.gui.MapView; … … 26 23 * @author imi 27 24 */ 28 public class OsmDataLayer extends Layer implements Visitor{25 public class OsmDataLayer extends Layer { 29 26 30 27 private static Icon icon; 31 private final static Color darkblue = new Color(0,0,128);32 private final static Color darkgreen = new Color(0,128,0);33 28 34 29 /** … … 38 33 39 34 /** 40 * The mapview we are currently drawing on.41 */42 private MapView mv;43 /**44 * The graphic environment we are drawing with.45 */46 private Graphics g;47 48 /**49 35 * Construct a OsmDataLayer. 50 36 */ 51 p rotectedOsmDataLayer(Collection<OsmPrimitive> data, String name) {37 public OsmDataLayer(Collection<OsmPrimitive> data, String name) { 52 38 super(name); 53 39 this.data = data; … … 65 51 } 66 52 53 /** 54 * Draw all primitives in this layer but do not draw modified ones (they 55 * are drawn by the edit layer). 56 * Draw nodes last to overlap the line segments they belong to. 57 */ 67 58 @Override 68 public boolean isEditable() { 69 return true; 59 public void paint(Graphics g, MapView mv) { 60 SimplePaintVisitor visitor = new SimplePaintVisitor(g, mv, null); 61 // first draw the tracks (and line segments) 62 for (OsmPrimitive osm : data) 63 if (!osm.modified && !(osm instanceof Node)) 64 osm.visit(visitor); 65 for (OsmPrimitive osm : data) 66 if (!osm.modified && osm instanceof Node) 67 osm.visit(visitor); 70 68 } 71 69 72 70 @Override 73 public void paint(Graphics g, MapView mv) { 74 this.mv = mv; 75 this.g = g; 76 for (OsmPrimitive osm : data) 77 osm.visit(this); 71 public String getToolTipText() { 72 return data.size()+" primitives."; 78 73 } 79 74 80 /** 81 * Draw a small rectangle. 82 * 83 * - White if selected (as always) 84 * - Yellow, if not used by any tracks or areas. 85 * - Green, if only used by pending line segments. 86 * - Darkblue, if used in tracks but are only as inbound node. Inbound are 87 * all nodes, that have only line segments of the same track and 88 * at least two different line segments attached. 89 * - Red otherwise (means, this is a dead end or is part of more than 90 * one track). 91 * 92 * @param n The node to draw. 93 */ 94 public void visit(Node n) { 95 if (n.isSelected()) { 96 drawNode(n, Color.WHITE); // selected 97 return; 98 } 99 100 Collection<LineSegment> lineSegments = n.getParentSegments(); 101 if (lineSegments.isEmpty()) { 102 drawNode(n, Color.YELLOW); // single waypoint only 103 return; 104 } 105 106 HashSet<Track> tracks = new HashSet<Track>(); 107 for (LineSegment ls : lineSegments) 108 tracks.addAll(ls.getParents()); 109 if (tracks.isEmpty()) { 110 drawNode(n, Color.GREEN); // pending line 111 return; 112 } 113 if (tracks.size() > 1) { 114 drawNode(n, Color.RED); // more than one track 115 return; 116 } 117 int segmentUsed = 0; 118 for (LineSegment ls : tracks.iterator().next().segments()) 119 if (n == ls.getStart() || n == ls.getEnd()) 120 ++segmentUsed; 121 drawNode(n, segmentUsed > 1 ? darkblue : Color.RED); 75 @Override 76 public void mergeFrom(Layer from) { 77 OsmDataLayer layer = (OsmDataLayer)from; 78 data.addAll(layer.data); 122 79 } 123 80 124 public void visit(LineSegment ls) { 125 g.setColor(ls.isSelected() ? Color.WHITE : darkblue); 126 if (Main.main.ds.pendingLineSegments().contains(ls)) 127 g.setColor(darkgreen); 128 Point p1 = mv.getScreenPoint(ls.getStart().coor); 129 Point p2 = mv.getScreenPoint(ls.getEnd().coor); 130 g.drawLine(p1.x, p1.y, p2.x, p2.y); 81 @Override 82 public boolean isMergable(Layer other) { 83 return other instanceof OsmDataLayer; 131 84 } 132 85 133 /** 134 * Draw a darkblue line for all line segments. 135 * @param t The track to draw. 136 */ 137 public void visit(Track t) { 138 for (LineSegment ls : t.segments()) 139 ls.visit(this); 86 @Override 87 public Bounds getBoundsLatLon() { 88 BoundingVisitor b = new BoundingVisitor(BoundingVisitor.Type.LATLON); 89 for (OsmPrimitive osm : data) 90 osm.visit(b); 91 return b.bounds; 140 92 } 141 93 142 public void visit(Key k) { 94 @Override 95 public Bounds getBoundsXY() { 96 BoundingVisitor b = new BoundingVisitor(BoundingVisitor.Type.XY); 97 for (OsmPrimitive osm : data) 98 osm.visit(b); 99 return b.bounds; 143 100 } 144 145 /** 146 * Draw the node as small rectangle with the given color. 147 * 148 * @param n The node to draw. 149 * @param color The color of the node. 150 */ 151 private void drawNode(Node n, Color color) { 152 Point p = mv.getScreenPoint(n.coor); 153 g.setColor(color); 154 g.drawRect(p.x-1, p.y-1, 2, 2); 101 102 @Override 103 public void init(Projection projection) { 104 for (OsmPrimitive osm : data) 105 for (Node n : AllNodesVisitor.getAllNodes(osm)) 106 projection.latlon2xy(n.coor); 155 107 } 156 108 } -
src/org/openstreetmap/josm/gui/layer/RawGpsDataLayer.java
r22 r23 1 1 package org.openstreetmap.josm.gui.layer; 2 3 import java.awt.Color; 4 import java.awt.Graphics; 5 import java.awt.Point; 6 import java.beans.PropertyChangeEvent; 7 import java.beans.PropertyChangeListener; 8 import java.util.Collection; 2 9 3 10 import javax.swing.Icon; 4 11 5 import org.openstreetmap.josm.command.DataSet; 12 import org.openstreetmap.josm.Main; 13 import org.openstreetmap.josm.data.Bounds; 14 import org.openstreetmap.josm.data.GeoPoint; 15 import org.openstreetmap.josm.data.projection.Projection; 6 16 import org.openstreetmap.josm.gui.ImageProvider; 17 import org.openstreetmap.josm.gui.MapView; 7 18 8 19 /** … … 16 27 private static Icon icon; 17 28 18 protected RawGpsDataLayer(DataSet dataSet, String name) { 29 /** 30 * A list of tracks which containing a list of points. 31 */ 32 private final Collection<Collection<GeoPoint>> data; 33 34 public RawGpsDataLayer(Collection<Collection<GeoPoint>> data, String name) { 19 35 super(name); 36 this.data = data; 37 Main.pref.addPropertyChangeListener(new PropertyChangeListener(){ 38 public void propertyChange(PropertyChangeEvent evt) { 39 if (Main.main.getMapFrame() == null) { 40 Main.pref.removePropertyChangeListener(this); 41 return; 42 } 43 if (evt.getPropertyName().equals("drawRawGpsLines") || 44 evt.getPropertyName().equals("drawRawGpsLines")) 45 Main.main.getMapFrame().repaint(); 46 } 47 }); 20 48 } 21 49 … … 29 57 return icon; 30 58 } 59 60 @Override 61 public void paint(Graphics g, MapView mv) { 62 g.setColor(Color.GRAY); 63 Point old = null; 64 for (Collection<GeoPoint> c : data) { 65 if (!Main.pref.isForceRawGpsLines()) 66 old = null; 67 for (GeoPoint p : c) { 68 Point screen = mv.getScreenPoint(p); 69 if (Main.pref.isDrawRawGpsLines() && old != null) { 70 g.drawLine(old.x, old.y, screen.x, screen.y); 71 } else { 72 g.drawRect(screen.x, screen.y, 0, 0); 73 old = screen; 74 } 75 } 76 } 77 } 78 79 @Override 80 public String getToolTipText() { 81 return data.size()+" tracks."; 82 } 83 84 @Override 85 public void mergeFrom(Layer from) { 86 RawGpsDataLayer layer = (RawGpsDataLayer)from; 87 data.addAll(layer.data); 88 } 89 90 @Override 91 public boolean isMergable(Layer other) { 92 return other instanceof RawGpsDataLayer; 93 } 94 95 @Override 96 public Bounds getBoundsLatLon() { 97 GeoPoint min = null; 98 GeoPoint max = null; 99 for (Collection<GeoPoint> c : data) { 100 for (GeoPoint p : c) { 101 if (min == null) { 102 min = p.clone(); 103 max = p.clone(); 104 } else { 105 min.lat = Math.min(min.lat, p.lat); 106 min.lon = Math.min(min.lon, p.lon); 107 max.lat = Math.max(max.lat, p.lat); 108 max.lon = Math.max(max.lon, p.lon); 109 } 110 } 111 } 112 if (min == null) 113 return null; 114 return new Bounds(min, max); 115 } 116 117 @Override 118 public Bounds getBoundsXY() { 119 GeoPoint min = null; 120 GeoPoint max = null; 121 for (Collection<GeoPoint> c : data) { 122 for (GeoPoint p : c) { 123 if (min == null) { 124 min = p.clone(); 125 max = p.clone(); 126 } else { 127 min.x = Math.min(min.x, p.x); 128 min.y = Math.min(min.y, p.y); 129 max.x = Math.max(max.x, p.x); 130 max.y = Math.max(max.y, p.y); 131 } 132 } 133 } 134 if (min == null) 135 return null; 136 return new Bounds(min, max); 137 } 138 139 @Override 140 public void init(Projection projection) { 141 for (Collection<GeoPoint> c : data) 142 for (GeoPoint p : c) 143 projection.latlon2xy(p); 144 } 31 145 } -
src/org/openstreetmap/josm/io/GpxReader.java
r21 r23 10 10 import org.jdom.input.SAXBuilder; 11 11 import org.openstreetmap.josm.Main; 12 import org.openstreetmap.josm.command.DataSet;13 12 import org.openstreetmap.josm.data.GeoPoint; 13 import org.openstreetmap.josm.data.osm.DataSet; 14 14 import org.openstreetmap.josm.data.osm.Key; 15 15 import org.openstreetmap.josm.data.osm.LineSegment; … … 25 25 * @author imi 26 26 */ 27 public class GpxReader implements DataReader{27 public class GpxReader { 28 28 29 29 /** 30 30 * The GPX namespace used. 31 31 */ 32 p rivate staticNamespace GPX = Namespace.getNamespace("http://www.topografix.com/GPX/1/0");32 public static final Namespace GPX = Namespace.getNamespace("http://www.topografix.com/GPX/1/0"); 33 33 /** 34 34 * The OSM namespace used (for extensions). … … 40 40 */ 41 41 public Reader source; 42 /**43 * If <code>true</code>, only nodes and tracks are imported (but no key/value44 * pairs). That is to support background gps information as an hint for45 * real OSM data.46 */47 private final boolean rawGps;48 42 49 43 /** 50 44 * Construct a parser from a specific data source. 51 45 * @param source The data source, as example a FileReader to read from a file. 52 * @param rawGps Whether the gpx file describes raw gps data. Only very few 53 * information (only nodes and line segments) imported for raw gps to 54 * save memory. 55 */ 56 public GpxReader(Reader source, boolean rawGps) { 46 */ 47 public GpxReader(Reader source) { 57 48 this.source = source; 58 this.rawGps = rawGps;59 49 } 60 50 … … 62 52 * Read the input stream and return a DataSet from the stream. 63 53 */ 64 public DataSet parse() throws ParseException, ConnectionException {54 public DataSet parse() throws JDOMException, IOException { 65 55 try { 66 56 final SAXBuilder builder = new SAXBuilder(); 67 57 Element root = builder.build(source).getRootElement(); 68 69 // HACK, since the osm server seem to not provide a namespace.70 if (root.getNamespacePrefix().equals(""))71 GPX = null;72 73 58 return parseDataSet(root); 74 59 } catch (NullPointerException npe) { 75 throw new ParseException("NullPointerException. Probably a tag name mismatch.", npe);60 throw new JDOMException("NullPointerException. Probably a tag name mismatch.", npe); 76 61 } catch (ClassCastException cce) { 77 throw new ParseException("ClassCastException. Probably a tag does not contain the correct type.", cce); 78 } catch (JDOMException e) { 79 throw new ParseException("The data could not be parsed. Reason: "+e.getMessage(), e); 80 } catch (IOException e) { 81 throw new ConnectionException("The data could not be retrieved. Reason: "+e.getMessage(), e); 62 throw new JDOMException("ClassCastException. Probably a tag does not contain the correct type.", cce); 82 63 } 83 64 } … … 94 75 Float.parseFloat(e.getAttributeValue("lat")), 95 76 Float.parseFloat(e.getAttributeValue("lon"))); 96 97 if (rawGps)98 return data;99 77 100 78 for (Object o : e.getChildren()) { … … 149 127 else { 150 128 LineSegment lineSegment = new LineSegment(start, node); 151 if (!rawGps) 152 parseKeyValueExtensions(lineSegment, ((Element)w).getChild("extensions", GPX)); 129 parseKeyValueExtensions(lineSegment, ((Element)w).getChild("extensions", GPX)); 153 130 track.add(lineSegment); 154 131 start = null; … … 156 133 } 157 134 } 158 159 if (rawGps)160 continue;161 135 162 136 if (child.getName().equals("extensions")) … … 167 141 parseKeyValueTag(track, child); 168 142 } 169 ds. addTrack(track);143 ds.tracks.add(track); 170 144 } 171 145 … … 184 158 */ 185 159 private Node addNode (DataSet data, Node node) { 186 if (Main.pref.mergeNodes || rawGps)160 if (Main.pref.mergeNodes) 187 161 for (Node n : data.nodes) 188 162 if (node.coor.equalsLatLon(n.coor)) -
src/org/openstreetmap/josm/io/GpxWriter.java
r22 r23 85 85 86 86 // tracks 87 for (Track t : Main.main.ds.tracks ()) {87 for (Track t : Main.main.ds.tracks) { 88 88 Element tElem = new Element("trk", GPX); 89 89 if (t.keys != null) { … … 99 99 } 100 100 // line segments 101 for (LineSegment ls : t.segments ()) {101 for (LineSegment ls : t.segments) { 102 102 Element lsElem = new Element("trkseg", GPX); 103 103 if (ls.keys != null) 104 104 addPropertyExtensions(lsElem, ls.keys); 105 lsElem.getChildren().add(parseWaypoint(ls. getStart(), "trkpt"));106 lsElem.getChildren().add(parseWaypoint(ls. getEnd(), "trkpt"));107 nodes.remove(ls. getStart());108 nodes.remove(ls. getEnd());105 lsElem.getChildren().add(parseWaypoint(ls.start, "trkpt")); 106 lsElem.getChildren().add(parseWaypoint(ls.end, "trkpt")); 107 nodes.remove(ls.start); 108 nodes.remove(ls.end); 109 109 tElem.getChildren().add(lsElem); 110 110 } -
src/org/openstreetmap/josm/io/OsmConnection.java
r22 r23 23 23 */ 24 24 public class OsmConnection { 25 26 27 25 28 26 /** -
src/org/openstreetmap/josm/io/OsmReader.java
r22 r23 6 6 import java.net.HttpURLConnection; 7 7 import java.net.URL; 8 import java.util.Collection; 9 import java.util.LinkedList; 8 10 9 import org.openstreetmap.josm.command.DataSet; 11 import org.jdom.JDOMException; 12 import org.openstreetmap.josm.data.GeoPoint; 13 import org.openstreetmap.josm.data.osm.DataSet; 10 14 11 15 /** … … 14 18 * @author imi 15 19 */ 16 public class OsmReader extends OsmConnection implements DataReader{20 public class OsmReader extends OsmConnection { 17 21 18 22 /** … … 20 24 */ 21 25 private String urlStr; 22 /**23 * Whether importing the raw trackpoints or the regular osm map information24 */25 private boolean rawGps;26 private final double lat1; 27 private final double lon1; 28 private final double lat2; 29 private final double lon2; 26 30 27 31 /** 28 32 * Construct the reader and store the information for attaching 29 33 */ 30 public OsmReader(String server, boolean rawGps,34 public OsmReader(String server, 31 35 double lat1, double lon1, double lat2, double lon2) { 32 this.rawGps = rawGps; 36 this.lon2 = lon2; 37 this.lat2 = lat2; 38 this.lon1 = lon1; 39 this.lat1 = lat1; 33 40 urlStr = server.endsWith("/") ? server : server+"/"; 34 if (rawGps)35 urlStr += "trackpoints?bbox="+lat1+","+lon1+","+lat2+","+lon2+"&page=";36 else37 urlStr += "map?bbox="+lon1+","+lat1+","+lon2+","+lat2;38 41 } 39 42 40 43 41 public DataSet parse() throws ParseException, ConnectionException { 42 Reader in; 43 initAuthentication(); 44 try { 45 if (rawGps) { 46 DataSet ds = new DataSet(); 47 for (int i = 0;;++i) { 48 URL url = new URL(urlStr+i); 49 System.out.println(url); 50 HttpURLConnection con = (HttpURLConnection)url.openConnection(); 51 con.setConnectTimeout(20000); 52 if (con.getResponseCode() == 401 && isCancelled()) 53 return null; 54 in = new InputStreamReader(con.getInputStream()); 55 DataSet currentData = new GpxReader(in, true).parse(); 56 if (currentData.nodes.isEmpty()) 57 return ds; 58 ds.mergeFrom(currentData, true); 44 /** 45 * Retrieve raw gps trackpoints from the server API. 46 * @return A list of all primitives retrieved. Currently, the list of lists 47 * contain only one list, since the server cannot distinguish between 48 * tracks. 49 */ 50 public Collection<Collection<GeoPoint>> parseRawGps() throws IOException, JDOMException { 51 String url = urlStr+"trackpoints?bbox="+lat1+","+lon1+","+lat2+","+lon2+"&page="; 52 Collection<Collection<GeoPoint>> data = new LinkedList<Collection<GeoPoint>>(); 53 Collection<GeoPoint> list = new LinkedList<GeoPoint>(); 54 55 for (int i = 0;;++i) { 56 Reader r = getReader(url+i); 57 if (r == null) 58 break; 59 RawGpsReader gpsReader = new RawGpsReader(r); 60 Collection<Collection<GeoPoint>> allTracks = gpsReader.parse(); 61 boolean foundSomething = false; 62 for (Collection<GeoPoint> t : allTracks) { 63 if (!t.isEmpty()) { 64 foundSomething = true; 65 list.addAll(t); 59 66 } 60 67 } 61 URL url = new URL(urlStr); 62 HttpURLConnection con = (HttpURLConnection)url.openConnection(); 63 con.setConnectTimeout(20000); 64 if (con.getResponseCode() == 401 && isCancelled()) 65 return null; 66 in = new InputStreamReader(con.getInputStream()); 67 return new GpxReader(in, false).parse(); 68 } catch (IOException e) { 69 throw new ConnectionException("Failed to open server connection\n"+e.getMessage(), e); 68 if (!foundSomething) 69 break; 70 70 } 71 72 data.add(list); 73 return data; 74 } 75 76 77 /** 78 * Read the data from the osm server address. 79 * @return A data set containing all data retrieved from that url 80 */ 81 public DataSet parseOsm() throws JDOMException, IOException { 82 Reader r = getReader(urlStr+"map?bbox="+lon1+","+lat1+","+lon2+","+lat2); 83 if (r == null) 84 return null; 85 return new GpxReader(r).parse(); 86 } 87 88 89 /** 90 * Open a connection to the given url and return a reader on the input stream 91 * from that connection. In case of user cancel, return <code>null</code>. 92 * @param url The exact url to connect to. 93 * @return An reader reading the input stream (servers answer) or <code>null</code>. 94 */ 95 private Reader getReader(String urlStr) throws IOException { 96 System.out.println(urlStr); 97 initAuthentication(); 98 URL url = new URL(urlStr); 99 HttpURLConnection con = (HttpURLConnection)url.openConnection(); 100 con.setConnectTimeout(20000); 101 if (con.getResponseCode() == 401 && isCancelled()) 102 return null; 103 return new InputStreamReader(con.getInputStream()); 71 104 } 72 105 }
Note:
See TracChangeset
for help on using the changeset viewer.