Changeset 34724 in osm for applications
- Timestamp:
- 2018-11-18T07:26:59+01:00 (6 years ago)
- Location:
- applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/Building.java
r34721 r34724 13 13 import java.util.Collection; 14 14 import java.util.Collections; 15 import java.util.LinkedHashSet; 15 16 import java.util.LinkedList; 16 17 import java.util.List; 17 18 import java.util.Map.Entry; 19 import java.util.Set; 18 20 19 21 import javax.swing.JOptionPane; … … 27 29 import org.openstreetmap.josm.data.UndoRedoHandler; 28 30 import org.openstreetmap.josm.data.coor.EastNorth; 29 import org.openstreetmap.josm.data.coor.LatLon;30 31 import org.openstreetmap.josm.data.osm.BBox; 31 32 import org.openstreetmap.josm.data.osm.DataSet; … … 50 51 private AngleSnap angleSnap = new AngleSnap(); 51 52 private Double drawingAngle; 53 private final static double EQUAL_NODE_DIST_TOLERANCE = 1e-6; 52 54 53 55 public void clearAngleSnap() { … … 103 105 public void setBase(EastNorth base) { 104 106 en[0] = base; 105 updMetrics();106 }107 108 public void setBase(Node base) {109 en[0] = latlon2eastNorth(base.getCoor());110 107 updMetrics(); 111 108 } … … 145 142 } 146 143 147 p ublicvoid setLengthWidth(double length, double width) {144 private void setLengthWidth(double length, double width) { 148 145 this.len = length; 149 146 this.width = width; … … 231 228 232 229 private Node findNode(EastNorth pos) { 233 DataSet ds = MainApplication.getLayerManager().getEditDataSet(); 234 LatLon l = eastNorth2latlon(pos); 235 List<Node> nodes = ds.searchNodes(new BBox(l.lon() - 0.0000001, l.lat() - 0.0000001, 236 l.lon() + 0.0000001, l.lat() + 0.0000001)); 237 Node bestnode = null; 238 double mindist = 0.0003; 239 for (Node n : nodes) { 240 double dist = n.getCoor().distanceSq(l); 241 if (dist < mindist && n.isUsable()) { 242 bestnode = n; 243 mindist = dist; 244 } 245 } 246 return bestnode; 230 MapView mv = MainApplication.getMap().mapView; 231 Node n = mv.getNearestNode(mv.getPoint(eastNorth2latlon(pos)), OsmPrimitive::isSelectable); 232 if (n == null) 233 return null; 234 return n.getEastNorth().distance(pos) <= EQUAL_NODE_DIST_TOLERANCE ? n : null; 247 235 } 248 236 … … 326 314 } 327 315 316 snapBuildings(w, nodes, addNodesCmd); 328 317 if (addNodesCmd.size() > 0) { 329 318 Command addNodes = new SequenceCommand(tr("Add nodes for building"), addNodesCmd); … … 332 321 333 322 // Nodes must be selected for create circle action 334 for (int i = 0; i < 2; i++) { 335 if (created[i]) { 336 ds.addSelected(nodes[i]); 337 } 338 } 323 ds.addSelected(w.getNodes()); 339 324 340 325 CreateCircleAction action = new CreateCircleAction(); … … 342 327 action.actionPerformed(null); 343 328 329 // restore selection 344 330 ds.clearSelection(); 345 331 ds.addSelected(selectedPrimitives); … … 403 389 404 390 if (snap) { 405 // calculate BBox which is slightly larger than the new building 406 BBox searchBox = new BBox(); 407 final double maxDist = 0.001; 408 List<Node> wayNodes = w.getNodes(); 409 for (Node n : nodes) { 410 LatLon l = eastNorth2latlon(n.getEastNorth()); 411 searchBox.add(new BBox(l.lon() - 0.0000001, l.lat() - 0.0000001, 412 l.lon() + 0.0000001, l.lat() + 0.0000001)); 413 } 414 // find the ways which might be snapped to the new building 415 List<Way> others = ds.searchWays(searchBox); 416 // add nodes of existing buildings to the new one 417 others.removeIf(o -> o.get("building") == null || !o.isUsable()); 418 for (Way other : others) { 419 snapToWay(wayNodes, other.getNodes(), maxDist); 420 w.setNodes(wayNodes); 421 } 422 // add new nodes to existing buildings 423 for (Way other : others) { 424 List<Node> otherNodes = other.getNodes(); 425 snapToWay(otherNodes, Arrays.asList(nodes), maxDist); 426 if (otherNodes.size() != other.getNodesCount()) { 427 Way newWay = new Way(other); 428 newWay.setNodes(otherNodes); 429 cmds.add(new ChangeCommand(other, newWay)); 430 } 431 } 391 snapBuildings(w, nodes, cmds); 432 392 } 433 393 Command c = new SequenceCommand(tr("Create building"), cmds); … … 436 396 } 437 397 398 private void snapBuildings(Way w, Node[] nodes, Collection<Command> cmds) { 399 // calculate BBox which is slightly larger than the new building 400 List<Node> wayNodes = w.getNodes(); 401 // find the ways which might be snapped to the new building 402 Set<Way> others = new LinkedHashSet<>(); 403 MapView mv = MainApplication.getMap().mapView; 404 for (Node n : nodes) { 405 Way w2 = mv.getNearestWay(mv.getPoint(n), OsmPrimitive::isSelectable); 406 if (w2 != null && w2.get("building") != null) 407 others.add(w2); 408 } 409 // add nodes of existing buildings to the new one 410 for (Way other : others) { 411 snapToWay(wayNodes, other.getNodes()); 412 w.setNodes(wayNodes); 413 } 414 // add new nodes to existing buildings 415 for (Way other : others) { 416 List<Node> otherNodes = other.getNodes(); 417 snapToWay(otherNodes, Arrays.asList(nodes)); 418 if (otherNodes.size() != other.getNodesCount()) { 419 Way newWay = new Way(other); 420 newWay.setNodes(otherNodes); 421 cmds.add(new ChangeCommand(other, newWay)); 422 } 423 } 424 425 } 426 438 427 /** 439 * Add all nodes in otherNodes to wayNodes that are within maxDist to the440 * segments described by wayNodes.428 * Add all nodes in otherNodes to wayNodes that are within snap distance to 429 * the segments described by wayNodes. 441 430 * 442 431 * @param wayNodes … … 444 433 * @param otherNodes 445 434 * other nodes 446 * @param maxDist447 * maximum distance as square of the euclidean distance between448 * way segment and node449 435 */ 450 private static void snapToWay(List<Node> wayNodes, Collection<Node> otherNodes , double maxDist) {436 private static void snapToWay(List<Node> wayNodes, Collection<Node> otherNodes) { 451 437 for (int i = 0; i < wayNodes.size(); i++) { 452 438 Node n0 = wayNodes.get(i); … … 455 441 if (n2 == n0 || n2 == n1) 456 442 continue; 457 EastNorth x = Geometry.closestPointToSegment(n0.getEastNorth(), n1.getEastNorth(), 458 n2.getEastNorth()); 459 if (x.distanceSq(n2.getEastNorth()) < maxDist) { 443 EastNorth x = Geometry.closestPointToSegment(n0.getEastNorth(), n1.getEastNorth(), n2.getEastNorth()); 444 if (x.distance(n2.getEastNorth()) <= EQUAL_NODE_DIST_TOLERANCE && !wayNodes.contains(n2)) { 460 445 wayNodes.add(i + 1, n2); 461 i--; // we may add multiple nodes to one segment, so repeat462 // it446 // we may add multiple nodes to one segment, so repeat it 447 i--; 463 448 break; 464 449 } -
applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/DrawBuildingAction.java
r34721 r34724 29 29 import org.openstreetmap.josm.data.osm.OsmPrimitive; 30 30 import org.openstreetmap.josm.data.osm.Way; 31 import org.openstreetmap.josm.data.osm.WaySegment; 31 32 import org.openstreetmap.josm.data.osm.event.SelectionEventManager; 32 33 import org.openstreetmap.josm.data.preferences.NamedColorProperty; … … 39 40 import org.openstreetmap.josm.gui.util.KeyPressReleaseListener; 40 41 import org.openstreetmap.josm.gui.util.ModifierExListener; 42 import org.openstreetmap.josm.tools.Geometry; 41 43 import org.openstreetmap.josm.tools.ImageProvider; 42 44 import org.openstreetmap.josm.tools.Logging; … … 51 53 private final Cursor cursorCrosshair; 52 54 private final Cursor cursorJoinNode; 55 private final Cursor cursorJoinWay; 53 56 private Cursor currCursor; 54 57 private Cursor customCursor; … … 72 75 cursorCrosshair = getCursor(); 73 76 cursorJoinNode = ImageProvider.getCursor("crosshair", "joinnode"); 77 cursorJoinWay = ImageProvider.getCursor("crosshair", "joinway"); 74 78 currCursor = cursorCrosshair; 75 79 } … … 201 205 202 206 private EastNorth getEastNorth() { 203 Node n; 204 if (ctrl) { 205 n = null; 206 } else { 207 n = MainApplication.getMap().mapView.getNearestNode(mousePos, OsmPrimitive::isUsable); 208 } 209 if (n == null) { 210 return latlon2eastNorth(MainApplication.getMap().mapView.getLatLon(mousePos.x, mousePos.y)); 211 } else { 212 return latlon2eastNorth(n.getCoor()); 213 } 207 if (!ctrl) { 208 Node n = MainApplication.getMap().mapView.getNearestNode(mousePos, OsmPrimitive::isUsable); 209 if (n != null) 210 return latlon2eastNorth(n.getCoor()); 211 WaySegment ws = MainApplication.getMap().mapView.getNearestWaySegment(mousePos, 212 OsmPrimitive::isSelectable); 213 if (ws != null && ws.way.get("building") != null) { 214 EastNorth p1 = ws.getFirstNode().getEastNorth(); 215 EastNorth p2 = ws.getSecondNode().getEastNorth(); 216 EastNorth enX = Geometry.closestPointToSegment(p1, p2, 217 MainApplication.getMap().mapView.getEastNorth(mousePos.x, mousePos.y)); 218 if (enX != null) { 219 return enX; 220 } 221 } 222 } 223 return latlon2eastNorth(MainApplication.getMap().mapView.getLatLon(mousePos.x, mousePos.y)); 214 224 } 215 225 … … 222 232 EastNorth p = getEastNorth(); 223 233 if (isRectDrawing()) { 224 225 234 building.setPlaceRect(p); 235 return shift ? Mode.DrawingAngFix : Mode.None; 226 236 } else if (ToolSettings.Shape.CIRCLE.equals(ToolSettings.getShape())) { 227 237 if (ToolSettings.getWidth() != 0) { … … 291 301 mousePos = e.getPoint(); 292 302 drawStartPos = mousePos; 293 if (ToolSettings.Shape.CIRCLE.equals(ToolSettings.getShape())) { 294 building.setBase(latlon2eastNorth(MainApplication.getMap().mapView.getLatLon(mousePos.x, mousePos.y))); 295 } else { 296 Node n = MainApplication.getMap().mapView.getNearestNode(mousePos, OsmPrimitive::isUsable); 297 if (n == null) { 298 building.setBase(latlon2eastNorth(MainApplication.getMap().mapView.getLatLon(mousePos.x, mousePos.y))); 299 } else { 300 building.setBase(n); 301 } 302 } 303 EastNorth en = getEastNorth(); 304 building.setBase(en); 303 305 mode = Mode.Drawing; 304 306 updateStatusLine(); … … 385 387 return; 386 388 Node n = null; 387 if (!ctrl) 388 n = MainApplication.getMap().mapView.getNearestNode(mousePos, OsmPrimitive::isUsable); 389 if (n != null) { 390 setCursor(cursorJoinNode); 391 } else { 392 if (customCursor != null && (!ctrl || isRectDrawing())) 393 setCursor(customCursor); 394 else 395 setCursor(getCursor()); 396 } 389 if (!ctrl) { 390 n = MainApplication.getMap().mapView.getNearestNode(mousePos, OsmPrimitive::isSelectable); 391 if (n != null) { 392 setCursor(cursorJoinNode); 393 return; 394 } else { 395 Way w = MainApplication.getMap().mapView.getNearestWay(mousePos, OsmPrimitive::isSelectable); 396 if (w != null && w.get("building") != null) { 397 setCursor(cursorJoinWay); 398 return; 399 } 400 } 401 } 402 if (customCursor != null && (!ctrl || isRectDrawing())) 403 setCursor(customCursor); 404 else 405 setCursor(getCursor()); 397 406 398 407 }
Note:
See TracChangeset
for help on using the changeset viewer.