LocatePoint.java

  1. /**
  2.  *
  3.  */
  4. package org.opentrafficsim.road.network.factory.shape;

  5. import org.locationtech.jts.geom.Coordinate;
  6. import org.locationtech.jts.geom.LineString;

  7. /**
  8.  * Computes the location of the point a given distance along a LineString
  9.  */
  10. public class LocatePoint
  11. {

  12.     public static Coordinate pointAlongSegment(Coordinate p0, Coordinate p1, double distance)
  13.     {
  14.         double segLen = p1.distance(p0);
  15.         double frac = distance / segLen;
  16.         if (frac <= 0.0)
  17.         {
  18.             return p0;
  19.         }
  20.         if (frac >= 1.0)
  21.         {
  22.             return p1;
  23.         }

  24.         double x = (p1.x - p0.x) * frac + p0.x;
  25.         double y = (p1.y - p0.y) * frac + p0.y;
  26.         return new Coordinate(x, y);
  27.     }

  28.     public static Coordinate pointAlongLine(LineString line, double distance)
  29.     {
  30.         LocatePoint loc = new LocatePoint(line, distance);
  31.         return loc.getPoint();
  32.     }

  33.     private Coordinate pt;

  34.     private int index;

  35.     public LocatePoint(LineString line, double distance)
  36.     {
  37.         compute(line, distance);
  38.     }

  39.     private void compute(LineString line, double distance)
  40.     {
  41.         // <TODO> handle negative distances (measure from opposite end of line)
  42.         double totalDist = 0.0;
  43.         Coordinate[] coord = line.getCoordinates();
  44.         for (int i = 0; i < coord.length - 1; i++)
  45.         {
  46.             Coordinate p0 = coord[i];
  47.             Coordinate p1 = coord[i + 1];
  48.             double segLen = p1.distance(p0);
  49.             if (totalDist + segLen > distance)
  50.             {
  51.                 pt = pointAlongSegment(p0, p1, distance - totalDist);
  52.                 index = i;
  53.                 return;
  54.             }
  55.             totalDist += segLen;
  56.         }
  57.         // distance is greater than line length
  58.         pt = new Coordinate(coord[coord.length - 1]);
  59.         index = coord.length;
  60.     }

  61.     public Coordinate getPoint()
  62.     {
  63.         return pt;
  64.     }

  65.     /**
  66.      * Returns the index of the segment containing the computed point
  67.      * @return the index
  68.      */
  69.     public int getIndex()
  70.     {
  71.         return index;
  72.     }

  73. }