001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.osm; 003 004import java.awt.geom.Line2D; 005 006/** 007 * A segment consisting of 2 consecutive nodes out of a way. 008 */ 009public final class WaySegment implements Comparable<WaySegment> { 010 011 /** 012 * The way. 013 */ 014 public Way way; 015 016 /** 017 * The index of one of the 2 nodes in the way. The other node has the 018 * index <code>lowerIndex + 1</code>. 019 */ 020 public int lowerIndex; 021 022 /** 023 * Constructs a new {@code WaySegment}. 024 * @param w The way 025 * @param i The node lower index 026 */ 027 public WaySegment(Way w, int i) { 028 way = w; 029 lowerIndex = i; 030 } 031 032 /** 033 * Returns the first node of the way segment. 034 * @return the first node 035 */ 036 public Node getFirstNode() { 037 return way.getNode(lowerIndex); 038 } 039 040 /** 041 * Returns the second (last) node of the way segment. 042 * @return the second node 043 */ 044 public Node getSecondNode(){ 045 return way.getNode(lowerIndex + 1); 046 } 047 048 /** 049 * Returns this way segment as complete way. 050 * @return the way segment as {@code Way} 051 */ 052 public Way toWay() { 053 Way w = new Way(); 054 w.addNode(getFirstNode()); 055 w.addNode(getSecondNode()); 056 return w; 057 } 058 059 @Override 060 public boolean equals(Object o) { 061 return o instanceof WaySegment 062 && ((WaySegment) o).way == way 063 && ((WaySegment) o).lowerIndex == lowerIndex; 064 } 065 066 @Override 067 public int hashCode() { 068 return way.hashCode() ^ lowerIndex; 069 } 070 071 @Override 072 public int compareTo(WaySegment o) { 073 return equals(o) ? 0 : toWay().compareTo(o.toWay()); 074 } 075 076 /** 077 * Checks whether this segment crosses other segment 078 * 079 * @param s2 The other segment 080 * @return true if both segments crosses 081 */ 082 public boolean intersects(WaySegment s2) { 083 if (getFirstNode().equals(s2.getFirstNode()) || getSecondNode().equals(s2.getSecondNode()) || 084 getFirstNode().equals(s2.getSecondNode()) || getSecondNode().equals(s2.getFirstNode())) 085 return false; 086 087 return Line2D.linesIntersect( 088 getFirstNode().getEastNorth().east(), getFirstNode().getEastNorth().north(), 089 getSecondNode().getEastNorth().east(), getSecondNode().getEastNorth().north(), 090 s2.getFirstNode().getEastNorth().east(), s2.getFirstNode().getEastNorth().north(), 091 s2.getSecondNode().getEastNorth().east(), s2.getSecondNode().getEastNorth().north()); 092 } 093 094 @Override 095 public String toString() { 096 return "WaySegment [way=" + way.getUniqueId() + ", lowerIndex=" + lowerIndex + "]"; 097 } 098}