Changeset 26192 in osm
- Timestamp:
- 2011-06-27T19:48:13+02:00 (13 years ago)
- Location:
- applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/gui/GuiContainer.java
r26154 r26192 27 27 static final Color GREEN = new Color(66, 234, 108); 28 28 29 private static final GuiContainer EMPTY = new GuiContainer(ModelContainer.empty()); 30 31 public static GuiContainer empty() { 32 return EMPTY; 33 } 34 29 35 private final ModelContainer mc; 30 36 … … 46 52 47 53 final LatLon originCoor = Main.getProjection().eastNorth2latlon(new EastNorth(origin.getX(), origin.getY())); 48 final LatLon relCoor = Main.getProjection().eastNorth2latlon(new EastNorth(origin.getX() + 1, origin.getY() + 1)); 54 final LatLon relCoor = Main.getProjection().eastNorth2latlon( 55 new EastNorth(origin.getX() + 1, origin.getY() + 1)); 49 56 50 57 // meters per source unit … … 65 72 66 73 private static Point2D avgOrigin(List<Point2D> locs) { 74 if (locs.isEmpty()) { 75 return new Point2D.Double(0, 0); 76 } 77 67 78 double x = 0; 68 79 double y = 0; … … 143 154 144 155 public Rectangle2D getBounds() { 156 if (isEmpty()) { 157 return new Rectangle2D.Double(-1, -1, 2, 2); 158 } 159 145 160 final List<Junction> primaries = new ArrayList<Junction>(mc.getPrimaryJunctions()); 146 161 final List<Double> top = new ArrayList<Double>(); … … 178 193 return junctions.values(); 179 194 } 195 196 public boolean isEmpty() { 197 return mc.isEmpty(); 198 } 180 199 } -
applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/gui/JunctionPane.java
r26182 r26192 5 5 import java.awt.Graphics; 6 6 import java.awt.Graphics2D; 7 import java.awt.GridBagConstraints; 8 import java.awt.GridBagLayout; 9 import java.awt.Insets; 7 10 import java.awt.RenderingHints; 8 11 import java.awt.event.ActionEvent; … … 24 27 import javax.swing.AbstractAction; 25 28 import javax.swing.JComponent; 29 import javax.swing.JLabel; 26 30 import javax.swing.KeyStroke; 31 32 import org.openstreetmap.josm.plugins.turnlanes.model.UnexpectedDataException; 27 33 28 34 class JunctionPane extends JComponent { … … 142 148 private GuiContainer container; 143 149 150 private final JLabel error = new JLabel(""); 151 144 152 private int width = 0; 145 153 private int height = 0; … … 159 167 setJunction(container); 160 168 169 setLayout(new GridBagLayout()); 170 error.setOpaque(false); 171 add(error, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, 172 new Insets(8, 8, 8, 8), 0, 0)); 173 161 174 setFocusable(true); 162 175 … … 250 263 removeMouseMotionListener(mip); 251 264 removeMouseWheelListener(mip); 252 interactives.clear(); 253 dragging = null; 265 this.interactives.clear(); 266 this.dragging = null; 267 254 268 this.container = container; 255 256 if (container == null) { 257 this.state = null; 258 } else { 259 setState(new State.Dirty(new State.Default())); 260 261 center(); 262 263 addMouseListener(mip); 264 addMouseMotionListener(mip); 265 addMouseWheelListener(mip); 266 } 269 center(); 270 setState(new State.Invalid(new State.Default())); 271 272 addMouseListener(mip); 273 addMouseMotionListener(mip); 274 addMouseWheelListener(mip); 267 275 } 268 276 … … 289 297 290 298 private void setState(State state) { 299 error.setText(""); 291 300 292 301 if (state instanceof State.AllTurns) { … … 294 303 this.state = state; 295 304 } else if (state instanceof State.Invalid) { 296 container = container.recalculate();297 305 dirty = true; 298 306 setState(((State.Invalid) state).unwrap()); 307 308 try { 309 final GuiContainer old = container; 310 311 container = container.recalculate(); 312 313 if (old.isEmpty() != container.isEmpty()) { 314 center(); 315 } 316 } catch (UnexpectedDataException e) { 317 displayError(e); 318 } catch (RuntimeException e) { 319 displayError(e); 320 } 299 321 } else if (state instanceof State.Dirty) { 300 322 dirty = true; … … 305 327 306 328 repaint(); 329 } 330 331 private void displayError(UnexpectedDataException e) { 332 if (e.getKind() == UnexpectedDataException.Kind.MISSING_TAG 333 && UnexpectedDataException.Kind.MISSING_TAG.format("lanes").equals(e.getMessage())) { 334 335 error.setText("<html>The number of lanes is not specified for one or more roads;" 336 + " please add missing lanes tags.</html>"); 337 } else { 338 displayError((RuntimeException) e); 339 } 340 } 341 342 private void displayError(RuntimeException e) { 343 error.setText("<html>An error occured while constructing the model." 344 + " Please run the validator to make sure the data is consistent.<br><br>Error: " + e.getMessage() 345 + "</html>"); 307 346 } 308 347 … … 344 383 } 345 384 346 if (container == null) {347 super.paintComponent(g);348 return;349 }350 351 385 if (dirty) { 352 386 paintPassive((Graphics2D) passive.getGraphics()); … … 359 393 g2d.drawImage(passive, 0, 0, getWidth(), getHeight(), null); 360 394 g2d.drawImage(interactive, 0, 0, getWidth(), getHeight(), null); 395 396 paintChildren(g); 361 397 } 362 398 … … 447 483 448 484 void refresh() { 449 if (state != null) { 450 setState(new State.Invalid(state)); 451 } 485 setState(new State.Invalid(state)); 452 486 } 453 487 } -
applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/gui/TurnLanesDialog.java
r26182 r26192 15 15 import javax.swing.Action; 16 16 import javax.swing.ButtonGroup; 17 import javax.swing.JLabel;18 17 import javax.swing.JPanel; 19 18 import javax.swing.JToggleButton; … … 40 39 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 41 40 import org.openstreetmap.josm.plugins.turnlanes.model.ModelContainer; 42 import org.openstreetmap.josm.plugins.turnlanes.model.UnexpectedDataException;43 41 44 42 public class TurnLanesDialog extends ToggleDialog { … … 59 57 editing = true; 60 58 editButton.setSelected(true); 59 refresh(); 61 60 } 62 61 } … … 137 136 private static final String CARD_EDIT = "EDIT"; 138 137 private static final String CARD_VALIDATE = "VALIDATE"; 139 private static final String CARD_ERROR = "ERROR";140 138 141 139 private final JPanel body = new JPanel(); 142 private final JunctionPane junctionPane = new JunctionPane(null); 143 private final JLabel error = new JLabel(); 140 private final JunctionPane junctionPane = new JunctionPane(GuiContainer.empty()); 144 141 145 142 private final JToggleButton editButton = new JToggleButton(editAction); … … 149 146 150 147 private boolean editing = true; 148 private boolean wasShowing = false; 151 149 152 150 public TurnLanesDialog() { … … 175 173 selected.addAll(newSelection); 176 174 177 final Collection<OsmPrimitive> s = Collections.unmodifiableCollection(newSelection); 178 final List<Node> nodes = OsmPrimitive.getFilteredList(s, Node.class); 179 final List<Way> ways = OsmPrimitive.getFilteredList(s, Way.class); 180 181 if (nodes.isEmpty()) { 182 setJunction(null); 183 return; 184 } 185 186 try { 187 setJunction(ModelContainer.create(nodes, ways)); 188 } catch (UnexpectedDataException e) { 189 displayError(e); 190 return; 191 } catch (RuntimeException e) { 192 displayError(e); 193 return; 194 } 175 refresh(); 195 176 } 196 177 }); … … 210 191 body.add(junctionPane, CARD_EDIT); 211 192 body.add(new ValidationPanel(), CARD_VALIDATE); 212 body.add(error, CARD_ERROR);213 193 214 194 editButton.doClick(); 215 195 } 216 196 217 void displayError(UnexpectedDataException e) { 218 if (editing) { 219 if (e.getKind() == UnexpectedDataException.Kind.MISSING_TAG 220 && UnexpectedDataException.Kind.MISSING_TAG.format("lanes").equals(e.getMessage())) { 221 222 error.setText("<html>The number of lanes is not specified for one or more roads;" 223 + " please add missing lanes tags.</html>"); 224 } else { 225 displayError((RuntimeException) e); 226 } 197 @Override 198 protected void stateChanged() { 199 if (isShowing && !wasShowing) { 200 refresh(); 201 } 202 wasShowing = isShowing; 203 } 204 205 void refresh() { 206 if (isShowing && editing) { 207 final Collection<OsmPrimitive> s = Collections.unmodifiableCollection(selected); 208 final List<Node> nodes = OsmPrimitive.getFilteredList(s, Node.class); 209 final List<Way> ways = OsmPrimitive.getFilteredList(s, Way.class); 227 210 228 final CardLayout cl = (CardLayout) body.getLayout(); 229 cl.show(body, CARD_ERROR); 230 } 231 } 232 233 void displayError(RuntimeException e) { 234 if (editing) { 235 e.printStackTrace(); 211 final ModelContainer mc = nodes.isEmpty() ? ModelContainer.empty() : ModelContainer 212 .createEmpty(nodes, ways); 236 213 237 error.setText("<html>An error occured while constructing the model."238 + " Please run the validator to make sure the data is consistent.<br><br>Error: " + e.getMessage()239 + "</html>");240 241 final CardLayout cl = (CardLayout) body.getLayout();242 cl.show(body, CARD_ERROR);243 }244 }245 246 void setJunction(ModelContainer mc) {247 if (mc != null && editing) {248 214 junctionPane.setJunction(new GuiContainer(mc)); 249 final CardLayout cl = (CardLayout) body.getLayout();250 cl.show(body, CARD_EDIT);251 215 } 252 216 } -
applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/Junction.java
r26154 r26192 18 18 this.container = container; 19 19 this.node = n; 20 21 container.register(this);22 23 if (isPrimary()) {24 // if turn data is invalid, this will force an exception now, not later during painting25 // getTurns(); TODO force this again26 }27 20 } 28 21 … … 80 73 81 74 throw new IllegalArgumentException("While there exists a road for the given way, the way neither " 82 + "starts nor ends at the junction node.");75 + "starts nor ends at the junction node."); 83 76 } 84 77 -
applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/Lane.java
r26182 r26192 104 104 private final Kind kind; 105 105 106 private Set<Turn> turns; 106 107 private double length = -1; 107 108 … … 222 223 223 224 public Set<Turn> getTurns() { 225 return turns; 226 } 227 228 public void remove() { 229 if (!isExtra()) { 230 throw new UnsupportedOperationException(); 231 } 232 233 final GenericCommand cmd = new GenericCommand(getOutgoingJunction().getNode().getDataSet(), tr("Delete lane.")); 234 235 for (Turn t : getTurns()) { 236 t.remove(cmd); 237 } 238 239 getOutgoingRoadEnd().removeLane(cmd, this); 240 241 Main.main.undoRedo.add(cmd); 242 } 243 244 void initialize() { 224 245 final Set<Turn> turns = Turn.load(getContainer(), Constants.TURN_ROLE_FROM, getOutgoingRoadEnd().getWay()); 225 246 … … 233 254 } 234 255 235 return turns; 236 } 237 238 public void remove() { 239 if (!isExtra()) { 240 throw new UnsupportedOperationException(); 241 } 242 243 final GenericCommand cmd = new GenericCommand(getOutgoingJunction().getNode().getDataSet(), tr("Delete lane.")); 244 245 for (Turn t : getTurns()) { 246 t.remove(cmd); 247 } 248 249 getOutgoingRoadEnd().removeLane(cmd, this); 250 251 Main.main.undoRedo.add(cmd); 256 this.turns = Collections.unmodifiableSet(turns); 252 257 } 253 258 } -
applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/ModelContainer.java
r26182 r26192 2 2 3 3 import java.util.ArrayList; 4 import java.util.Collection; 4 5 import java.util.Collections; 5 6 import java.util.HashMap; 6 7 import java.util.HashSet; 8 import java.util.Iterator; 7 9 import java.util.List; 8 10 import java.util.Map; … … 18 20 19 21 public class ModelContainer { 22 private static final ModelContainer EMPTY = new ModelContainer(Collections.<Node> emptySet(), Collections 23 .<Way> emptySet(), false); 24 20 25 public static ModelContainer create(Iterable<Node> primaryNodes, Iterable<Way> primaryWays) { 21 final Set<Node> closedNodes = new HashSet<Node>(CollectionUtils.toList(primaryNodes)); 22 final Set<Way> closedWays = new HashSet<Way>(CollectionUtils.toList(primaryWays)); 23 24 close(closedNodes, closedWays); 25 26 return new ModelContainer(closedNodes, closedWays); 26 return new ModelContainer(new HashSet<Node>(CollectionUtils.toList(primaryNodes)), new HashSet<Way>( 27 CollectionUtils.toList(primaryWays)), false); 28 } 29 30 public static ModelContainer createEmpty(Iterable<Node> primaryNodes, Iterable<Way> primaryWays) { 31 return new ModelContainer(new HashSet<Node>(CollectionUtils.toList(primaryNodes)), new HashSet<Way>( 32 CollectionUtils.toList(primaryWays)), true); 33 } 34 35 public static ModelContainer empty() { 36 return EMPTY; 27 37 } 28 38 … … 41 51 } 42 52 43 for (Way w : new ArrayList<Way>(closedWays) 53 for (Way w : new ArrayList<Way>(closedWays)) { 44 54 closed &= close(closedNodes, closedWays, w, Constants.TURN_ROLE_VIA); 45 55 } … … 90 100 } 91 101 102 private static <E extends OsmPrimitive, C extends Collection<E>> C filterUsables(C collection) { 103 final Iterator<E> it = collection.iterator(); 104 105 while (it.hasNext()) { 106 final E e = it.next(); 107 108 if (e.getDataSet() == null || !e.isUsable()) { 109 it.remove(); 110 } 111 } 112 113 return collection; 114 } 115 92 116 private final Map<Node, Junction> junctions = new HashMap<Node, Junction>(); 93 117 private final Map<Way, Road> roads = new HashMap<Way, Road>(); … … 96 120 private final Set<Way> primaryWays; 97 121 98 private ModelContainer(Set<Node> primaryNodes, Set<Way> primaryWays) { 99 this.primaryNodes = Collections.unmodifiableSet(new HashSet<Node>(primaryNodes)); 100 this.primaryWays = Collections.unmodifiableSet(new HashSet<Way>(primaryWays)); 101 102 final Set<Pair<Way, Junction>> ws = new HashSet<Pair<Way, Junction>>(); 122 private final boolean empty; 123 124 private ModelContainer(Set<Node> primaryNodes, Set<Way> primaryWays, boolean empty) { 125 if (empty) { 126 this.primaryNodes = Collections.unmodifiableSet(new HashSet<Node>(primaryNodes)); 127 this.primaryWays = Collections.unmodifiableSet(new HashSet<Way>(primaryWays)); 128 this.empty = true; 129 } else { 130 final Set<Node> closedNodes = filterUsables(new HashSet<Node>(primaryNodes)); 131 final Set<Way> closedWays = filterUsables(new HashSet<Way>(primaryWays)); 132 133 close(closedNodes, closedWays); 134 135 this.primaryNodes = Collections.unmodifiableSet(closedNodes); 136 this.primaryWays = Collections.unmodifiableSet(closedWays); 137 138 for (Pair<Way, Junction> w : createPrimaryJunctions()) { 139 if (!this.primaryWays.contains(w.a)) { 140 addRoad(new Road(this, w.a, w.b)); 141 } 142 } 143 144 for (Route r : Utils.orderWays(this.primaryWays, this.primaryNodes)) { 145 addRoad(new Road(this, r)); 146 } 147 148 for (Road r : roads.values()) { 149 r.initialize(); 150 } 151 152 this.empty = junctions.isEmpty(); 153 } 154 } 155 156 private Set<Pair<Way, Junction>> createPrimaryJunctions() { 157 final Set<Pair<Way, Junction>> roads = new HashSet<Pair<Way, Junction>>(); 158 103 159 for (Node n : primaryNodes) { 104 final Junction j = getOrCreateJunction(n); 105 160 final List<Way> ws = new ArrayList<Way>(); 106 161 for (Way w : Utils.filterRoads(n.getReferrers())) { 107 162 if (w.isFirstLastNode(n)) { 108 ws.add(new Pair<Way, Junction>(w, j)); 109 } 110 } 111 } 112 113 final List<Route> rs = Utils.orderWays(primaryWays, primaryNodes); 114 for (Route r : rs) { 115 addRoad(new Road(this, r)); 116 } 117 118 for (Pair<Way, Junction> w : ws) { 119 if (!primaryWays.contains(w.a)) { 120 addRoad(new Road(this, w.a, w.b)); 121 } 122 } 163 ws.add(w); 164 } 165 } 166 167 if (ws.size() > 1) { 168 final Junction j = register(new Junction(this, n)); 169 for (Way w : ws) { 170 roads.add(new Pair<Way, Junction>(w, j)); 171 } 172 } 173 } 174 175 return roads; 123 176 } 124 177 … … 130 183 } 131 184 132 return new Junction(this, n);185 return register(new Junction(this, n)); 133 186 } 134 187 … … 161 214 if (oldRoad != null) { 162 215 if (mergedA == null) { 163 final Road mergedRoad = mergeRoads(oldRoad, newRoad); 164 addRoad(mergedRoad, oldRoad, newRoad); 216 addRoad(mergeRoads(oldRoad, newRoad), oldRoad, newRoad); 165 217 } else if (!oldRoad.equals(mergedA) && !oldRoad.equals(mergedB)) { 166 218 throw new RuntimeException("A road can't be connected to more than two junctions."); … … 198 250 } 199 251 200 voidregister(Junction j) {252 private Junction register(Junction j) { 201 253 if (junctions.put(j.getNode(), j) != null) { 202 254 throw new IllegalStateException(); 203 255 } 256 257 return j; 204 258 } 205 259 206 260 public Set<Junction> getPrimaryJunctions() { 261 if (empty) { 262 return Collections.emptySet(); 263 } 264 207 265 final Set<Junction> pjs = new HashSet<Junction>(); 208 209 266 for (Node n : primaryNodes) { 210 pjs.add(getOrCreateJunction(n)); 211 } 212 267 pjs.add(getJunction(n)); 268 } 213 269 return pjs; 214 270 } 215 271 216 272 public Set<Road> getPrimaryRoads() { 273 if (empty) { 274 return Collections.emptySet(); 275 } 276 217 277 final Set<Road> prs = new HashSet<Road>(); 218 219 278 for (Way w : primaryWays) { 220 279 prs.add(roads.get(w)); 221 280 } 222 223 281 return prs; 224 282 } 225 283 226 284 public ModelContainer recalculate() { 227 return new ModelContainer(primaryNodes, primaryWays );285 return new ModelContainer(primaryNodes, primaryWays, false); 228 286 } 229 287 … … 235 293 return primaryWays.contains(r.getRoute().getFirstSegment().getWay()); 236 294 } 295 296 public boolean isEmpty() { 297 return empty; 298 } 237 299 } -
applications/editors/josm/plugins/turnlanes/src/org/openstreetmap/josm/plugins/turnlanes/model/Road.java
r26182 r26192 6 6 import java.util.ArrayList; 7 7 import java.util.Arrays; 8 import java.util.Collections; 8 9 import java.util.List; 9 10 import java.util.Set; … … 33 34 34 35 private final List<Lane> lanes; 36 private Set<Turn> turns; 35 37 36 38 private End(boolean from, Junction junction, Relation lengthsLeft, Relation lengthsRight) { … … 86 88 */ 87 89 public Set<Turn> getTurns() { 88 return Turn.load(getContainer(), Constants.TURN_ROLE_TO, getWay());90 return turns; 89 91 } 90 92 … … 260 262 && bRel.get(Constants.LENGTHS_KEY_LENGTHS_RIGHT) == null) { 261 263 bRel.setDeleted(true); 264 } 265 } 266 267 void initialize() { 268 this.turns = Collections.unmodifiableSet(Turn.load(getContainer(), Constants.TURN_ROLE_TO, getWay())); 269 270 for (Lane l : lanes) { 271 l.initialize(); 262 272 } 263 273 } … … 394 404 return getContainer().isPrimary(this); 395 405 } 406 407 void initialize() { 408 fromEnd.initialize(); 409 toEnd.initialize(); 410 } 396 411 }
Note:
See TracChangeset
for help on using the changeset viewer.