Ticket #9599: 9599.patch
File 9599.patch, 5.1 KB (added by , 4 years ago) |
---|
-
src/org/openstreetmap/josm/actions/JoinAreasAction.java
674 674 675 675 List<WayInPolygon> preparedWays = new ArrayList<>(); 676 676 677 // maps oldest way referring to start of each part 678 Map<Node, Way> oldestWayMap = new HashMap<>(); 679 677 680 for (Way way : outerStartingWays) { 678 681 List<Way> splitWays = splitWayOnNodes(way, nodes); 682 683 // see #9599 684 if (!way.isNew() && splitWays.size() > 1) { 685 for (Way part : splitWays) { 686 Node n = part.firstNode(); 687 Way old = oldestWayMap.get(n); 688 if (old == null || old.getUniqueId() > way.getUniqueId()) { 689 oldestWayMap.put(n, way); 690 } 691 } 692 } 693 679 694 preparedWays.addAll(markWayInsideSide(splitWays, false)); 680 695 } 681 696 … … 721 736 722 737 commitCommands(marktr("Delete relations")); 723 738 739 // see #9599: result should contain original way(s) where possible 740 if (discardedWays.stream().anyMatch(w -> !w.isNew())) { 741 for (int i = 0; i < polygons.size(); i++) { 742 Multipolygon mp = polygons.get(i); 743 for (int k = 0; k < mp.getInnerWays().size(); k++) { 744 Way inner = mp.getInnerWays().get(k); 745 Way older = keepOlder(inner, oldestWayMap, discardedWays); 746 if (inner != older) { 747 mp.getInnerWays().set(k, older); 748 } 749 } 750 Way older = keepOlder(mp.outerWay, oldestWayMap, discardedWays); 751 if (older != mp.outerWay) { 752 Multipolygon mpNew = new Multipolygon(older); 753 mpNew.innerWays.addAll(mp.getInnerWays()); 754 polygons.set(i, mpNew); 755 } 756 } 757 commitCommands(marktr("Keep older versions")); 758 } 759 724 760 // Delete the discarded inner ways 725 761 if (!discardedWays.isEmpty()) { 726 762 Command deleteCmd = DeleteCommand.delete(discardedWays, true); … … 742 778 } 743 779 744 780 /** 781 * Create copy of given way using an older id so that we don't create a new way instead of a modified old one. 782 * @param way the way to check 783 * @param oldestWayMap nodes from old ways 784 * @param discardedWays collection of ways which will be deleted (modified) 785 * @return a copy of the way with an older id or the way itself 786 */ 787 private Way keepOlder(Way way, Map<Node, Way> oldestWayMap , List<Way> discardedWays) { 788 Way oldest = null; 789 for (Node n : way.getNodes()) { 790 Way orig = oldestWayMap .get(way.firstNode()); 791 if (orig != null && (oldest == null || oldest.getUniqueId() > orig.getUniqueId()) 792 && discardedWays.contains(orig)) { 793 oldest = orig; 794 } 795 } 796 if (oldest != null) { 797 discardedWays.remove(oldest); 798 discardedWays.add(way); 799 Way copy = new Way(oldest); 800 copy.setNodes(way.getNodes()); 801 cmds.add(new ChangeCommand(oldest, copy)); 802 return copy; 803 } 804 return way; 805 } 806 807 /** 745 808 * Checks if tags of two given ways differ, and presents the user a dialog to solve conflicts 746 809 * @param polygons ways to check 747 810 * @return {@code true} if all conflicts are resolved, {@code false} if conflicts remain. … … 1055 1118 * Uses {@link SplitWayCommand#splitWay} for the heavy lifting. 1056 1119 * @param way way to split 1057 1120 * @param nodes split points 1058 * @return list of split ways (or original way sif no splitting is done).1121 * @return list of split ways (or original way if no splitting is done). 1059 1122 */ 1060 1123 private List<Way> splitWayOnNodes(Way way, Set<Node> nodes) { 1061 1124 … … 1372 1435 1373 1436 //TODO: ReverseWay and Combine way are really slow and we use them a lot here. This slows down large joins. 1374 1437 List<Way> actionWays = new ArrayList<>(ways.size()); 1375 1438 int oldestPos = 0; 1439 Way oldest = ways.get(0).way; 1376 1440 for (WayInPolygon way : ways) { 1377 1441 actionWays.add(way.way); 1442 if (oldest.isNew() || !way.way.isNew() && oldest.getUniqueId() > way.way.getUniqueId()) { 1443 oldest = way.way; 1444 oldestPos = actionWays.size() - 1; 1445 } 1378 1446 1379 1447 if (!way.insideToTheRight) { 1380 1448 ReverseWayResult res = ReverseWayAction.reverseWay(way.way); … … 1383 1451 } 1384 1452 } 1385 1453 1454 // see #9599: Help CombineWayAction to use the oldest way 1455 Collections.rotate(actionWays, actionWays.size() - oldestPos); 1456 1386 1457 Pair<Way, Command> result = CombineWayAction.combineWaysWorker(actionWays); 1387 1458 if (result == null) { 1388 1459 throw new JosmRuntimeException("Join areas internal error.");