Class Way

All Implemented Interfaces:
Comparable<Way>

public final class Way extends GenericTaggedNode<Way> implements Comparable<Way>
This class implements a Way element of an OSM file.
Author:
Andrew Pavlin, KA2DDO
  • Field Details

    • MAX_VERTICES_IN_WAY

      public static final int MAX_VERTICES_IN_WAY
      The maximum number of vertices that can be stored to disk in a Way (due to storage field size).
      See Also:
    • id

      public int id
      The OpenStreetMap assigned ID number for this Way. Negative values may be used for YAAC-created Ways.
    • nodeLatLonList

      public int[] nodeLatLonList
      Array of latitude/longitude pairs in millionths of degrees North/East.
    • numLatLonPairs

      public int numLatLonPairs
      Number of vertices in the Way.
    • minLat

      public int minLat
      The furthest South of any vertex of this Way.
    • maxLat

      public int maxLat
      The furthest North of any vertex of this Way.
    • minLon

      public int minLon
      The furthest West of any vertex of this Way.
    • maxLon

      public int maxLon
      The furthest East of any vertex of this Way.
    • segmentNum

      public transient int segmentNum
      Index used only by OSM importer to note whether this is a full Way or a tile segment of a Way. 0 means the whole Way, >0 means a particular segment extracted by the getTileWays(int, int, int, int, PrintStream) method.
    • WAY_COMPARATOR

      public static final Comparator<Way> WAY_COMPARATOR
      Comparator for sorting Ways, such that the sort code doesn't have to keep casting Ways to the Comparable interface.
  • Constructor Details

    • Way

      public Way()
      Create an empty Way object with the default preallocation for the node lat/lon list.
    • Way

      public Way(int numElements)
      Create an empty Way with the specified number of elements in the node lat/lon list.
      Parameters:
      numElements - size for node lat/lon array (must be twice the number of vertices to store)
    • Way

      public Way(int numElements, Way refWay)
      Create an empty Way with the specified number of elements in the node lat/lon list.
      Parameters:
      numElements - size for node lat/lon array (must be twice the number of vertices to store)
      refWay - Way whose non-vertex properties should be copied
    • Way

      public Way(int numElements, GenericTaggedNode<?> refWay)
      Create an empty Way with the specified number of elements in the node lat/lon list.
      Parameters:
      numElements - size for node lat/lon array (must be twice the number of vertices to store)
      refWay - Way (or Relation) whose non-vertex properties should be copied
  • Method Details

    • addLatLon

      public final void addLatLon(int lat, int lon)
      Add another vertex to the Way, updating the Way's bounding box.
      Parameters:
      lat - latitude in millionths of degrees North
      lon - longitude in millionths of degrees East
    • prependLatLon

      public final void prependLatLon(int lat, int lon)
      Add another vertex to the Way at the beginning, updating the Way's bounding box.
      Parameters:
      lat - latitude in millionths of degrees North
      lon - longitude in millionths of degrees East
    • getTileWays

      public final Way[] getTileWays(int minTileLat, int minTileLon, int maxTileLat, int maxTileLon, PrintStream out)
      Find all the pieces of this Way that are contained inside the specified axis-aligned bounding box. Note this algorithm will not work correctly for area Ways that are complex (i.e., cross themselves such as a figure-8) or perforated (i.e.. multipolygon Relation with outer and inner components); only simple Ways can be tiled with this method.
      Parameters:
      minTileLat - southernmost edge in millionths of degrees North
      minTileLon - westernmost edge in millionths of degrees East
      maxTileLat - northernmost edge in millionths of degrees North
      maxTileLon - easternmost edge in millionths of degrees East
      out - PrintStream for logging any exceptional conditions
      Returns:
      null if no intersection, or array of Ways corresponding to pieces of this Way inside the box
    • isClockWise

      public boolean isClockWise()
      Test if the Way is clockwise or counterclockwise. The answer is meaningless if the Way is not a closed area.
      Returns:
      boolean true if clockwise, boolean false if counterclockwise
    • getAccruedTurn

      public double getAccruedTurn()
      Calculate the net direction of turning of this Way. The sum of the bending angles at each vertex of the Way are summed up, which (for a closed GenericTaggedNode.IS_AREA Way) will indicate whether the Way is clockwise (positive net angle) or counterclockwise (negative net angle).
      Returns:
      net turning direction in degrees
    • clearPolygon

      public void clearPolygon()
      Release any storage used for a point-in-polygon checking polygon object.
    • reverseWay

      public void reverseWay()
      Swap the order of the vertices in the Way (last to first and first to last).
    • write

      public void write(DataOutput os) throws IOException, IllegalArgumentException
      Encode this Way into a file using the DataOutput storage formats.
      Parameters:
      os - DataOutput to write the Way to
      Throws:
      IOException - if Way could not be written
      IllegalArgumentException - if Way has too many vertices to fit in file encoding format
    • writeId

      protected void writeId(DataOutput dos) throws IOException
      Handle writing the ID field to the binary data stream (handles larger ID ranges in varying subclasses).
      Specified by:
      writeId in class GenericTaggedNode<Way>
      Parameters:
      dos - DataOutput to use to append the binary ID value
      Throws:
      IOException - if write fails for any reason
    • getId

      public Number getId()
      Return the ID of this OSM record as a sub-class of Number.
      Specified by:
      getId in class GenericTaggedNode<Way>
      Returns:
      Number subclass instance
    • read

      public static Way read(DataInput is) throws IOException
      Instantiate a new Way read from the input stream.
      Parameters:
      is - DataInput to read the next Way from
      Returns:
      Way read from the input
      Throws:
      IOException - if Way could not be successfully read from the DataInput
    • read

      public static Way read(NonshareableBufferedDataInputStream is) throws IOException
      Instantiate a new Way read from the input stream.
      Parameters:
      is - NonshareableBufferedDataInputStream to read the next Way from
      Returns:
      Way read from the input
      Throws:
      IOException - if Way could not be successfully read from the DataInput
    • reread

      public final void reread(DataInput is) throws IOException
      Clear the contents of this Way object and load it with another Way's data read from the input stream. Used to reduce heap thrashing by reusing the same Way object without running it through the garbage collector.
      Parameters:
      is - DataInput to read the next Way from
      Throws:
      IOException - if Way could not be successfully read from the DataInput
    • reread

      public final void reread(NonshareableBufferedDataInputStream is) throws IOException
      Clear the contents of this Way object and load it with another Way's data read from the input stream. Used to reduce heap thrashing by reusing the same Way object without running it through the garbage collector.
      Parameters:
      is - NonshareableBufferedDataInputStream to read the next Way from
      Throws:
      IOException - if Way could not be successfully read from the DataInput
    • intersects

      public final boolean intersects(int lLat, int hLat, int lLon, int hLon)
      Test if this Way intersects the specified axis-aligned bounding box.
      Parameters:
      lLat - minimum latitude in millionths of degrees North
      hLat - maximum latitude in millionths of degrees North
      lLon - minimum longitude in millionths of degrees East
      hLon - maximum longitude in millionths of degrees East
      Returns:
      boolean true if this Way intersects the bounding box or is contained entirely inside it
    • removeRedundantWayVertices

      public int removeRedundantWayVertices(int dupThreshold)
      Squeeze down the vertices in the Way to remove duplicate adjacent vertices, and vertices in the middle of a straight line segment (as opposed to at the ending joints of a line segment).
      Parameters:
      dupThreshold - int max difference between coordinate values to be considered the same
      Returns:
      int number of removed vertices
    • recalculateBounds

      public void recalculateBounds()
      Recompute the min/max bounds of the Way based on the current vertices. Assumed to be called after the vertex array is modified.
    • splitAreaWayIntoAcceptableSegments

      public ArrayList<Way> splitAreaWayIntoAcceptableSegments(PrintStream out, String useCase) throws IllegalArgumentException
      Split an oversize area Way into a collection of contiguous Ways that are each under the maximum vertex count and don't accidentally put points outside the original Way inside any of the segments.
      Parameters:
      out - PrintStream for logging errors
      useCase - String identifying use case that had the logged error
      Returns:
      ArrayList of smaller Ways
      Throws:
      IllegalArgumentException - if Way for a polyline instead of a closed area
    • doLineSegmentsIntersect

      public static boolean doLineSegmentsIntersect(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2)
      Check if two line segments intersect, according to the algorithm from "Algorithms", Cormen, Leiserson & Rivest, 1992, pp. 889-890.
      Parameters:
      ax1 - X coordinate of start of first segment
      ay1 - Y coordinate of start of first segment
      ax2 - X coordinate of end of first segment
      ay2 - Y coordinate of end of first segment
      bx1 - X coordinate of start of second segment
      by1 - Y coordinate of start of second segment
      bx2 - X coordinate of end of second segment
      by2 - Y coordinate of end of second segment
      Returns:
      boolean true if line segments intersect between their endpoints
    • toString

      public String toString()
      Returns a string representation of the object.
      Overrides:
      toString in class Object
      Returns:
      a string representation of the object.
    • compareTo

      public int compareTo(Way o2)
      Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. The intention here is to sort Ways so that finer details aren't overwritten by larger blots of data (ex.: a road through a forest area).
      Specified by:
      compareTo in interface Comparable<Way>
      Parameters:
      o2 - the object to be compared.
      Returns:
      a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
      Throws:
      ClassCastException - if the specified object's type prevents it from being compared to this object.
    • equals

      public boolean equals(Object obj)
      Indicates whether some other object is "equal to" this one.
      Overrides:
      equals in class Object
      Parameters:
      obj - the reference object with which to compare.
      Returns:
      true if this object is the same as the obj argument; false otherwise.
      See Also:
    • hashCode

      public int hashCode()
      Returns a hash code value for the object.
      Overrides:
      hashCode in class Object
      Returns:
      a hash code value for this object.
      See Also:
    • main

      public static void main(String[] args) throws IOException
      For unit testing of Way class only.
      Parameters:
      args - String array of parameters. [0] is path of way file to read, [1] is optional -quiet flag to suppress most printed output
      Throws:
      IOException - if node file cannot be read for any reason
    • isVertexListMatching

      public static boolean isVertexListMatching(Way way1, Way way2)
      Compare the vertex arrays of 2 Ways to see if they are identical.
      Parameters:
      way1 - first Way to compare
      way2 - second Way to compare
      Returns:
      boolean true if both Ways have identical vertex lists, false if not
    • isVertexListReverseMatching

      public static boolean isVertexListReverseMatching(Way way1, Way way2)
      Compare the vertex arrays of 2 Ways to see if they are palindromes (equal in reverse).
      Parameters:
      way1 - first Way to compare
      way2 - second Way to compare
      Returns:
      boolean true if both Ways have palindromic vertex lists, false if not
    • dup

      public Way dup()
      Make a deep copy of this Way.
      Specified by:
      dup in class GenericTaggedNode<Way>
      Returns:
      unique copy of this Way object
    • canDoDelta

      public final boolean canDoDelta()
      Report if this Way can be stored using 16-bit signed deltas for the vertices instead of 32-bit absolute values.
      Returns:
      boolean true if 16-deltas will work
    • writeGPX

      public void writeGPX(PrintStream ps)
      Write this Way to the specified stream as the XML tags one element in GPX schema format.
      Specified by:
      writeGPX in class GenericTaggedNode<Way>
      Parameters:
      ps - PrintStream to write to