source: josm/trunk/src/org/openstreetmap/josm/data/osm/WaySegment.java@ 13421

Last change on this file since 13421 was 13030, checked in by Don-vip, 6 years ago

see #15465 - validate WaySegment constructor arguments

  • Property svn:eol-style set to native
File size: 4.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm;
3
4import java.awt.geom.Line2D;
5import java.util.Objects;
6
7/**
8 * A segment consisting of 2 consecutive nodes out of a way.
9 */
10public final class WaySegment implements Comparable<WaySegment> {
11
12 /**
13 * The way.
14 */
15 public Way way;
16
17 /**
18 * The index of one of the 2 nodes in the way. The other node has the
19 * index <code>lowerIndex + 1</code>.
20 */
21 public int lowerIndex;
22
23 /**
24 * Constructs a new {@code WaySegment}.
25 * @param w The way
26 * @param i The node lower index
27 * @throws IllegalArgumentException in case of invalid index
28 */
29 public WaySegment(Way w, int i) {
30 way = w;
31 lowerIndex = i;
32 if (i < 0 || i >= w.getNodesCount() - 1) {
33 throw new IllegalArgumentException(toString());
34 }
35 }
36
37 /**
38 * Returns the first node of the way segment.
39 * @return the first node
40 */
41 public Node getFirstNode() {
42 return way.getNode(lowerIndex);
43 }
44
45 /**
46 * Returns the second (last) node of the way segment.
47 * @return the second node
48 */
49 public Node getSecondNode() {
50 return way.getNode(lowerIndex + 1);
51 }
52
53 /**
54 * Determines and returns the way segment for the given way and node pair.
55 * @param way way
56 * @param first first node
57 * @param second second node
58 * @return way segment
59 * @throws IllegalArgumentException if the node pair is not part of way
60 */
61 public static WaySegment forNodePair(Way way, Node first, Node second) {
62 int endIndex = way.getNodesCount() - 1;
63 while (endIndex > 0) {
64 final int indexOfFirst = way.getNodes().subList(0, endIndex).lastIndexOf(first);
65 if (second.equals(way.getNode(indexOfFirst + 1))) {
66 return new WaySegment(way, indexOfFirst);
67 }
68 endIndex--;
69 }
70 throw new IllegalArgumentException("Node pair is not part of way!");
71 }
72
73 /**
74 * Returns this way segment as complete way.
75 * @return the way segment as {@code Way}
76 */
77 public Way toWay() {
78 Way w = new Way();
79 w.addNode(getFirstNode());
80 w.addNode(getSecondNode());
81 return w;
82 }
83
84 @Override
85 public boolean equals(Object o) {
86 if (this == o) return true;
87 if (o == null || getClass() != o.getClass()) return false;
88 WaySegment that = (WaySegment) o;
89 return lowerIndex == that.lowerIndex &&
90 Objects.equals(way, that.way);
91 }
92
93 @Override
94 public int hashCode() {
95 return Objects.hash(way, lowerIndex);
96 }
97
98 @Override
99 public int compareTo(WaySegment o) {
100 return o == null ? -1 : (equals(o) ? 0 : toWay().compareTo(o.toWay()));
101 }
102
103 /**
104 * Checks whether this segment crosses other segment
105 *
106 * @param s2 The other segment
107 * @return true if both segments crosses
108 */
109 public boolean intersects(WaySegment s2) {
110 if (getFirstNode().equals(s2.getFirstNode()) || getSecondNode().equals(s2.getSecondNode()) ||
111 getFirstNode().equals(s2.getSecondNode()) || getSecondNode().equals(s2.getFirstNode()))
112 return false;
113
114 return Line2D.linesIntersect(
115 getFirstNode().getEastNorth().east(), getFirstNode().getEastNorth().north(),
116 getSecondNode().getEastNorth().east(), getSecondNode().getEastNorth().north(),
117 s2.getFirstNode().getEastNorth().east(), s2.getFirstNode().getEastNorth().north(),
118 s2.getSecondNode().getEastNorth().east(), s2.getSecondNode().getEastNorth().north());
119 }
120
121 /**
122 * Checks whether this segment and another way segment share the same points
123 * @param s2 The other segment
124 * @return true if other way segment is the same or reverse
125 */
126 public boolean isSimilar(WaySegment s2) {
127 return (getFirstNode().equals(s2.getFirstNode()) && getSecondNode().equals(s2.getSecondNode()))
128 || (getFirstNode().equals(s2.getSecondNode()) && getSecondNode().equals(s2.getFirstNode()));
129 }
130
131 @Override
132 public String toString() {
133 return "WaySegment [way=" + way.getUniqueId() + ", lowerIndex=" + lowerIndex + ']';
134 }
135}
Note: See TracBrowser for help on using the repository browser.