Changeset 7223 in josm for trunk/src/org/openstreetmap
- Timestamp:
- 2014-06-08T21:36:21+02:00 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java
r7217 r7223 30 30 import org.openstreetmap.josm.Main; 31 31 import org.openstreetmap.josm.actions.JosmAction; 32 import org.openstreetmap.josm.actions.MergeNodesAction; 32 33 import org.openstreetmap.josm.command.AddCommand; 33 34 import org.openstreetmap.josm.command.ChangeCommand; … … 79 80 private boolean ignoreSharedNodes; 80 81 82 private final boolean keepSegmentDirection; 83 81 84 /** 82 85 * drawing settings for helper lines … … 217 220 tr("Mode: {0}", tr("Extrude Dual alignment")), KeyEvent.CHAR_UNDEFINED, Shortcut.NONE); 218 221 useRepeatedShortcut = Main.pref.getBoolean("extrude.dualalign.toggleOnRepeatedX", true); 222 keepSegmentDirection = Main.pref.getBoolean("extrude.dualalign.keep-segment-direction", true); 219 223 } 220 224 … … 446 450 447 451 EastNorth mouseEn = Main.map.mapView.getEastNorth(e.getPoint().x, e.getPoint().y); 448 EastNorth bestMovement = calculateBestMovement(mouseEn); 449 EastNorth n1movedEn = new EastNorth(initialN1en.getX() + bestMovement.getX(), initialN1en.getY() + bestMovement.getY()); 450 451 // find out the movement distance, in metres 452 double distance = Main.getProjection().eastNorth2latlon(initialN1en).greatCircleDistance(Main.getProjection().eastNorth2latlon(n1movedEn)); 453 Main.map.statusLine.setDist(distance); 454 updateStatusLine(); 455 452 EastNorth bestMovement = calculateBestMovementAndNewNodes(mouseEn); 453 456 454 Main.map.mapView.setNewCursor(Cursor.MOVE_CURSOR, this); 457 455 458 456 if (dualAlignActive) { 459 calculateDualAlignNodesPositions(bestMovement);460 461 457 if (mode == Mode.extrude || mode == Mode.create_new) { 462 458 // nothing here … … 478 474 } 479 475 } else { 480 newN1en = n1movedEn;481 newN2en = new EastNorth(initialN2en.getX() + bestMovement.getX(), initialN2en.getY() + bestMovement.getY());482 483 476 if (mode == Mode.extrude || mode == Mode.create_new) { 484 477 //nothing here … … 595 588 /** 596 589 * Does actual extrusion of {@link #selectedSegment}. 590 * Uses {@link #initialN1en}, {@link #initialN2en} saved in calculatePossibleDirections* call 591 * Uses {@link #newN1en}, {@link #newN2en} calculated by {@link #calculateBestMovementAndNewNodes} 597 592 */ 598 593 private void performExtrusion() { … … 610 605 boolean segmentAngleZero = prevNode != null && Math.abs(Geometry.getCornerAngle(prevNode.getEastNorth(), initialN1en, newN1en)) < 1e-5; 611 606 boolean hasOtherWays = hasNodeOtherWays(selectedSegment.getFirstNode(), selectedSegment.way); 612 607 ArrayList<Node> changedNodes = new ArrayList<>(); 613 608 if (nodeOverlapsSegment && !alwaysCreateNodes && !hasOtherWays) { 614 609 //move existing node 615 610 Node n1Old = selectedSegment.getFirstNode(); 616 611 cmds.add(new MoveCommand(n1Old, Main.getProjection().eastNorth2latlon(newN1en))); 612 changedNodes.add(n1Old); 617 613 } else if (ignoreSharedNodes && segmentAngleZero && !alwaysCreateNodes && hasOtherWays) { 618 614 // replace shared node with new one … … 623 619 wayWasModified = true; 624 620 cmds.add(new AddCommand(n1New)); 621 changedNodes.add(n1New); 625 622 } else { 626 623 //introduce new node … … 630 627 insertionPoint ++; 631 628 cmds.add(new AddCommand(n1New)); 629 changedNodes.add(n1New); 632 630 } 633 631 … … 642 640 Node n2Old = selectedSegment.getSecondNode(); 643 641 cmds.add(new MoveCommand(n2Old, Main.getProjection().eastNorth2latlon(newN2en))); 642 changedNodes.add(n2Old); 644 643 } else if (ignoreSharedNodes && segmentAngleZero && !alwaysCreateNodes && hasOtherWays) { 645 644 // replace shared node with new one … … 650 649 wayWasModified = true; 651 650 cmds.add(new AddCommand(n2New)); 651 changedNodes.add(n2New); 652 652 } else { 653 653 //introduce new node … … 657 657 insertionPoint ++; 658 658 cmds.add(new AddCommand(n2New)); 659 changedNodes.add(n2New); 659 660 } 660 661 … … 670 671 Command c = new SequenceCommand(tr("Extrude Way"), cmds); 671 672 Main.main.undoRedo.add(c); 673 if (newN1en.distance(newN2en) < 1e-6) { 674 // If the dual alignment created moved two nodes to the same point, merge them 675 Node targetNode = MergeNodesAction.selectTargetNode(changedNodes); 676 Command mergeCmd = MergeNodesAction.mergeNodes(Main.main.getEditLayer(), changedNodes, targetNode, changedNodes.get(0)); 677 Main.main.undoRedo.add(mergeCmd); 678 } 672 679 } 673 680 … … 859 866 ), initialN2en, nextNodeEn, false); 860 867 } 861 862 /** 863 * Calculates positions of new nodes, aligning them to neighboring segments. 864 * @param movement movement to be used 865 */ 866 private void calculateDualAlignNodesPositions(EastNorth movement) { 867 // new positions of selected segment's nodes, without applying dual alignment 868 EastNorth n1movedEn = new EastNorth(initialN1en.getX() + movement.getX(), initialN1en.getY() + movement.getY()); 869 EastNorth n2movedEn = new EastNorth(initialN2en.getX() + movement.getX(), initialN2en.getY() + movement.getY()); 870 871 // calculate intersections 872 newN1en = Geometry.getLineLineIntersection(n1movedEn, n2movedEn, dualAlignSegment1.p1, dualAlignSegment1.p2); 873 newN2en = Geometry.getLineLineIntersection(n1movedEn, n2movedEn, dualAlignSegment2.p1, dualAlignSegment2.p2); 868 869 /** 870 * Calculate newN1en, newN2en best suitable for given mouse coordinates 871 * For dual align, calculates positions of new nodes, aligning them to neighboring segments. 872 * Elsewhere, just adds the vetor returned by calculateBestMovement to {@link #initialN1en}, {@link #initialN2en}. 873 * @return best movement vector 874 */ 875 private EastNorth calculateBestMovementAndNewNodes(EastNorth mouseEn) { 876 EastNorth bestMovement = calculateBestMovement(mouseEn); 877 EastNorth n1movedEn = initialN1en.add(bestMovement), n2movedEn; 878 879 // find out the movement distance, in metres 880 double distance = Main.getProjection().eastNorth2latlon(initialN1en).greatCircleDistance(Main.getProjection().eastNorth2latlon(n1movedEn)); 881 Main.map.statusLine.setDist(distance); 882 updateStatusLine(); 883 884 if (dualAlignActive) { 885 // new positions of selected segment's nodes, without applying dual alignment 886 n1movedEn = initialN1en.add(bestMovement); 887 n2movedEn = initialN2en.add(bestMovement); 888 889 // calculate intersections of parallel shifted segment and the adjacent lines 890 newN1en = Geometry.getLineLineIntersection(n1movedEn, n2movedEn, dualAlignSegment1.p1, dualAlignSegment1.p2); 891 newN2en = Geometry.getLineLineIntersection(n1movedEn, n2movedEn, dualAlignSegment2.p1, dualAlignSegment2.p2); 892 if (newN1en == null || newN2en == null) return bestMovement; 893 if (keepSegmentDirection && isOppositeDirection(newN1en, newN2en, initialN1en, initialN2en)) { 894 EastNorth collapsedSegmentPosition = Geometry.getLineLineIntersection(dualAlignSegment1.p1, dualAlignSegment1.p2, dualAlignSegment2.p1, dualAlignSegment2.p2); 895 newN1en = collapsedSegmentPosition; 896 newN2en = collapsedSegmentPosition; 897 } 898 } else { 899 newN1en = n1movedEn; 900 newN2en = initialN2en.add(bestMovement); 901 } 902 return bestMovement; 874 903 } 875 904 … … 961 990 if (dualAlignActive) { 962 991 // Draw reference ways 963 drawReferenceSegment(g2, mv, dualAlignSegment1 .p1, dualAlignSegment1.p2);964 drawReferenceSegment(g2, mv, dualAlignSegment2 .p1, dualAlignSegment2.p2);992 drawReferenceSegment(g2, mv, dualAlignSegment1); 993 drawReferenceSegment(g2, mv, dualAlignSegment2); 965 994 } else if (activeMoveDirection != null) { 966 995 // Draw reference way 967 drawReferenceSegment(g2, mv, activeMoveDirection .p1, activeMoveDirection.p2);996 drawReferenceSegment(g2, mv, activeMoveDirection); 968 997 969 998 // Draw right angle marker on first node position, only when moving at right angle … … 993 1022 if (dualAlignActive) { 994 1023 // Draw reference ways 995 drawReferenceSegment(g2, mv, dualAlignSegment1 .p1, dualAlignSegment1.p2);996 drawReferenceSegment(g2, mv, dualAlignSegment2 .p1, dualAlignSegment2.p2);1024 drawReferenceSegment(g2, mv, dualAlignSegment1); 1025 drawReferenceSegment(g2, mv, dualAlignSegment2); 997 1026 } else if (activeMoveDirection != null) { 998 1027 … … 1035 1064 return normalUnitVector; 1036 1065 } 1066 1067 /** 1068 * Returns true if from1-to1 and from2-to2 vertors directions are opposite 1069 */ 1070 private boolean isOppositeDirection(EastNorth from1, EastNorth to1, EastNorth from2, EastNorth to2) { 1071 return (from1.getX()-to1.getX())*(from2.getX()-to2.getX()) 1072 +(from1.getY()-to1.getY())*(from2.getY()-to2.getY()) < 0; 1073 } 1037 1074 1038 1075 /** … … 1070 1107 * @param p2en segment's second point 1071 1108 */ 1072 private void drawReferenceSegment(Graphics2D g2, MapView mv, EastNorth p1en, EastNorth p2en)1109 private void drawReferenceSegment(Graphics2D g2, MapView mv, ReferenceSegment seg) 1073 1110 { 1074 Point p1 = mv.getPoint( p1en);1075 Point p2 = mv.getPoint( p2en);1111 Point p1 = mv.getPoint(seg.p1); 1112 Point p2 = mv.getPoint(seg.p2); 1076 1113 GeneralPath b = new GeneralPath(); 1077 1114 b.moveTo(p1.x, p1.y);
Note:
See TracChangeset
for help on using the changeset viewer.