Changeset 6065 in josm
- Timestamp:
- 2013-07-15T20:09:48+02:00 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java ¶
r6056 r6065 726 726 */ 727 727 public final Node getNearestNode(Point p, Predicate<OsmPrimitive> predicate, boolean use_selected) { 728 Node n = null; 729 728 return getNearestNode(p, predicate, use_selected, null); 729 } 730 731 /** 732 * The *result* depends on the current map selection state IF use_selected is true 733 * 734 * If more than one node within node.snap-distance pixels is found, 735 * the nearest node selected is returned IF use_selected is true. 736 * 737 * If there are no selected nodes near that point, the node that is related to some of the preferredRefs 738 * 739 * Else the nearest new/id=0 node within about the same distance 740 * as the true nearest node is returned. 741 * 742 * If no such node is found either, the true nearest 743 * node to p is returned. 744 * 745 * Finally, if a node is not found at all, null is returned. 746 * @since 6065 747 * @return A node within snap-distance to point p, 748 * that is chosen by the algorithm described. 749 * 750 * @param p the screen point 751 * @param predicate this parameter imposes a condition on the returned object, e.g. 752 * give the nearest node that is tagged. 753 * @param preferredRefs primitives, whose nodes we prefer 754 */ 755 public final Node getNearestNode(Point p, Predicate<OsmPrimitive> predicate, 756 boolean use_selected, Collection<OsmPrimitive> preferredRefs) { 757 730 758 Map<Double, List<Node>> nlists = getNearestNodesImpl(p, predicate); 731 if (!nlists.isEmpty()) { 732 Node ntsel = null, ntnew = null; 733 double minDistSq = nlists.keySet().iterator().next(); 734 735 for (Double distSq : nlists.keySet()) { 736 for (Node nd : nlists.get(distSq)) { 737 // find the nearest selected node 738 if (ntsel == null && nd.isSelected()) { 739 ntsel = nd; 740 // if there are multiple nearest nodes, prefer the one 741 // that is selected. This is required in order to drag 742 // the selected node if multiple nodes have the same 743 // coordinates (e.g. after unglue) 744 use_selected |= (distSq == minDistSq); 745 } 746 // find the nearest newest node that is within about the same 747 // distance as the true nearest node 748 if (ntnew == null && nd.isNew() && (distSq-minDistSq < 1)) { 749 ntnew = nd; 759 if (nlists.isEmpty()) return null; 760 761 if (preferredRefs != null && preferredRefs.isEmpty()) preferredRefs = null; 762 Node ntsel = null, ntnew = null, ntref = null; 763 boolean useNtsel = use_selected; 764 double minDistSq = nlists.keySet().iterator().next(); 765 766 for (Double distSq : nlists.keySet()) { 767 for (Node nd : nlists.get(distSq)) { 768 // find the nearest selected node 769 if (ntsel == null && nd.isSelected()) { 770 ntsel = nd; 771 // if there are multiple nearest nodes, prefer the one 772 // that is selected. This is required in order to drag 773 // the selected node if multiple nodes have the same 774 // coordinates (e.g. after unglue) 775 useNtsel |= (distSq == minDistSq); 776 } 777 if (ntref == null && preferredRefs != null && distSq == minDistSq) { 778 List<OsmPrimitive> ndRefs = nd.getReferrers(); 779 for (OsmPrimitive ref: preferredRefs) { 780 if (ndRefs.contains(ref)) { 781 ntref = nd; 782 break; 783 } 750 784 } 751 785 } 752 } 753 754 // take nearest selected, nearest new or true nearest node to p, in that order 755 n = (ntsel != null && use_selected) ? ntsel 756 : (ntnew != null) ? ntnew 757 : nlists.values().iterator().next().get(0); 758 } 759 return n; 786 // find the nearest newest node that is within about the same 787 // distance as the true nearest node 788 if (ntnew == null && nd.isNew() && (distSq-minDistSq < 1)) { 789 ntnew = nd; 790 } 791 } 792 } 793 794 // take nearest selected, nearest new or true nearest node to p, in that order 795 if (ntsel != null && useNtsel) 796 return ntsel; 797 if (ntref != null) 798 return ntref; 799 if (ntnew != null) 800 return ntnew; 801 return nlists.values().iterator().next().get(0); 760 802 } 761 803 … … 914 956 return (ntsel != null && use_selected) ? ntsel : wayseg; 915 957 } 958 959 /** 960 * The *result* depends on the current map selection state IF use_selected is true. 961 * 962 * @return The nearest way segment to point p, 963 * and, depending on use_selected, prefers a selected way segment, if found. 964 * Also prefers segments of ways that are related to one of preferredRefs primitives 965 * @see #getNearestWaySegments(Point, Collection, Predicate) 966 * @since 6065 967 * @param p the point for which to search the nearest segment. 968 * @param predicate the returned object has to fulfill certain properties. 969 * @param use_selected whether selected way segments should be preferred. 970 * @param preferredRefs - prefer segments related to these primitives, may be null 971 */ 972 public final WaySegment getNearestWaySegment(Point p, Predicate<OsmPrimitive> predicate, 973 boolean use_selected, Collection<OsmPrimitive> preferredRefs) { 974 WaySegment wayseg = null, ntsel = null, ntref = null; 975 if (preferredRefs != null && preferredRefs.isEmpty()) preferredRefs = null; 976 977 searchLoop: for (List<WaySegment> wslist : getNearestWaySegmentsImpl(p, predicate).values()) { 978 for (WaySegment ws : wslist) { 979 if (wayseg == null) { 980 wayseg = ws; 981 } 982 if (ntsel == null && ws.way.isSelected()) { 983 ntsel = ws; 984 break searchLoop; 985 } 986 if (ntref == null && preferredRefs != null) { 987 // prefer ways containing given nodes 988 for (Node nd: ws.way.getNodes()) { 989 if (preferredRefs.contains(nd)) { 990 ntref = ws; 991 break searchLoop; 992 } 993 } 994 Collection<OsmPrimitive> wayRefs = ws.way.getReferrers(); 995 // prefer member of the given relations 996 for (OsmPrimitive ref: preferredRefs) { 997 if (ref instanceof Relation && wayRefs.contains(ref)) { 998 ntref = ws; 999 break searchLoop; 1000 } 1001 } 1002 } 1003 } 1004 } 1005 if (ntsel != null && use_selected) 1006 return ntsel; 1007 if (ntref != null) 1008 return ntref; 1009 return wayseg; 1010 } 916 1011 917 1012 /** … … 1051 1146 */ 1052 1147 private boolean isPrecedenceNode(Node osm, Point p, boolean use_selected) { 1053 boolean ret = false;1054 1055 1148 if (osm != null) { 1056 ret |= !(p.distanceSq(getPoint2D(osm)) > (4)*(4)); 1057 ret |= osm.isTagged(); 1058 if (use_selected) { 1059 ret |= osm.isSelected(); 1060 } 1061 } 1062 1063 return ret; 1149 if (!(p.distanceSq(getPoint2D(osm)) > (4)*(4))) return true; 1150 if (osm.isTagged()) return true; 1151 if (use_selected && osm.isSelected()) return true; 1152 } 1153 return false; 1064 1154 } 1065 1155 … … 1087 1177 * @param p The point on screen. 1088 1178 * @param predicate the returned object has to fulfill certain properties. 1089 * @param use_selected whether to prefer primitives that are currently selected .1179 * @param use_selected whether to prefer primitives that are currently selected or referred by selected primitives 1090 1180 */ 1091 1181 public final OsmPrimitive getNearestNodeOrWay(Point p, Predicate<OsmPrimitive> predicate, boolean use_selected) { 1092 OsmPrimitive osm = getNearestNode(p, predicate, use_selected); 1093 WaySegment ws = null; 1094 1095 if (!isPrecedenceNode((Node)osm, p, use_selected)) { 1182 Collection<OsmPrimitive> sel = 1183 use_selected ? getCurrentDataSet().getSelected() : null; 1184 OsmPrimitive osm = getNearestNode(p, predicate, use_selected, sel); 1185 1186 if (isPrecedenceNode((Node)osm, p, use_selected)) return osm; 1187 WaySegment ws; 1188 if (use_selected) { 1189 ws = getNearestWaySegment(p, predicate, use_selected, sel); 1190 } else { 1096 1191 ws = getNearestWaySegment(p, predicate, use_selected); 1097 1098 if (ws != null) { 1099 if ((ws.way.isSelected() && use_selected) || osm == null) { 1100 // either (no _selected_ nearest node found, if desired) or no nearest node was found 1101 osm = ws.way; 1102 } else { 1103 int maxWaySegLenSq = 3*PROP_SNAP_DISTANCE.get(); 1104 maxWaySegLenSq *= maxWaySegLenSq; 1105 1106 Point2D wp1 = getPoint2D(ws.way.getNode(ws.lowerIndex)); 1107 Point2D wp2 = getPoint2D(ws.way.getNode(ws.lowerIndex+1)); 1108 1109 // is wayseg shorter than maxWaySegLenSq and 1110 // is p closer to the middle of wayseg than to the nearest node? 1111 if (wp1.distanceSq(wp2) < maxWaySegLenSq && 1112 p.distanceSq(project(0.5, wp1, wp2)) < p.distanceSq(getPoint2D((Node)osm))) { 1113 osm = ws.way; 1114 } 1115 } 1116 } 1117 } 1118 1192 } 1193 if (ws == null) return osm; 1194 1195 if ((ws.way.isSelected() && use_selected) || osm == null) { 1196 // either (no _selected_ nearest node found, if desired) or no nearest node was found 1197 osm = ws.way; 1198 } else { 1199 int maxWaySegLenSq = 3*PROP_SNAP_DISTANCE.get(); 1200 maxWaySegLenSq *= maxWaySegLenSq; 1201 1202 Point2D wp1 = getPoint2D(ws.way.getNode(ws.lowerIndex)); 1203 Point2D wp2 = getPoint2D(ws.way.getNode(ws.lowerIndex+1)); 1204 1205 // is wayseg shorter than maxWaySegLenSq and 1206 // is p closer to the middle of wayseg than to the nearest node? 1207 if (wp1.distanceSq(wp2) < maxWaySegLenSq && 1208 p.distanceSq(project(0.5, wp1, wp2)) < p.distanceSq(getPoint2D((Node)osm))) { 1209 osm = ws.way; 1210 } 1211 } 1119 1212 return osm; 1120 1213 } … … 1249 1342 } 1250 1343 1344 @Override 1251 1345 public String helpTopic() { 1252 1346 String n = getClass().getName();
Note:
See TracChangeset
for help on using the changeset viewer.