View Javadoc
1   /**
2    *
3    */
4   package org.opentrafficsim.road.network.factory.shape;
5   
6   /*
7    * The JCS Conflation Suite (JCS) is a library of Java classes that
8    * can be used to build automated or semi-automated conflation solutions.
9    *
10   * Copyright (C) 2003 Vivid Solutions
11   *
12   * This program is free software; you can redistribute it and/or
13   * modify it under the terms of the GNU General Public License
14   * as published by the Free Software Foundation; either version 2
15   * of the License, or (at your option) any later version.
16   *
17   * This program is distributed in the hope that it will be useful,
18   * but WITHOUT ANY WARRANTY; without even the implied warranty of
19   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20   * GNU General Public License for more details.
21   *
22   * You should have received a copy of the GNU General Public License
23   * along with this program; if not, write to the Free Software
24   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25   *
26   * For more information, contact:
27   *
28   * Vivid Solutions
29   * Suite #1A
30   * 2328 Government Street
31   * Victoria BC  V8T 5G5
32   * Canada
33   *
34   * (250)385-6040
35   * www.vividsolutions.com
36   */
37  import com.vividsolutions.jts.geom.Coordinate;
38  import com.vividsolutions.jts.geom.LineString;
39  
40  /**
41   * Computes the location of the point a given distance along a LineString
42   */
43  public class LocatePoint
44  {
45  
46      public static Coordinate pointAlongSegment(Coordinate p0, Coordinate p1, double distance)
47      {
48          double segLen = p1.distance(p0);
49          double frac = distance / segLen;
50          if (frac <= 0.0)
51          {
52              return p0;
53          }
54          if (frac >= 1.0)
55          {
56              return p1;
57          }
58  
59          double x = (p1.x - p0.x) * frac + p0.x;
60          double y = (p1.y - p0.y) * frac + p0.y;
61          return new Coordinate(x, y);
62      }
63  
64      public static Coordinate pointAlongLine(LineString line, double distance)
65      {
66          LocatePoint loc = new LocatePoint(line, distance);
67          return loc.getPoint();
68      }
69  
70      private Coordinate pt;
71  
72      private int index;
73  
74      public LocatePoint(LineString line, double distance)
75      {
76          compute(line, distance);
77      }
78  
79      private void compute(LineString line, double distance)
80      {
81          // <TODO> handle negative distances (measure from opposite end of line)
82          double totalDist = 0.0;
83          Coordinate[] coord = line.getCoordinates();
84          for (int i = 0; i < coord.length - 1; i++)
85          {
86              Coordinate p0 = coord[i];
87              Coordinate p1 = coord[i + 1];
88              double segLen = p1.distance(p0);
89              if (totalDist + segLen > distance)
90              {
91                  pt = pointAlongSegment(p0, p1, distance - totalDist);
92                  index = i;
93                  return;
94              }
95              totalDist += segLen;
96          }
97          // distance is greater than line length
98          pt = new Coordinate(coord[coord.length - 1]);
99          index = coord.length;
100     }
101 
102     public Coordinate getPoint()
103     {
104         return pt;
105     }
106 
107     /**
108      * Returns the index of the segment containing the computed point
109      * @return the index
110      */
111     public int getIndex()
112     {
113         return index;
114     }
115 
116 }