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      public static Coordinate pointAlongSegment(Coordinate p0, Coordinate p1, double distance) {
46          double segLen = p1.distance(p0);
47          double frac = distance / segLen;
48          if (frac <= 0.0) {
49              return p0;
50          }
51          if (frac >= 1.0) {
52              return p1;
53          }
54  
55          double x = (p1.x - p0.x) * frac + p0.x;
56          double y = (p1.y - p0.y) * frac + p0.y;
57          return new Coordinate(x, y);
58      }
59  
60      public static Coordinate pointAlongLine(LineString line, double distance) {
61          LocatePoint loc = new LocatePoint(line, distance);
62          return loc.getPoint();
63      }
64  
65      private Coordinate pt;
66  
67      private int index;
68  
69      public LocatePoint(LineString line, double distance) {
70          compute(line, distance);
71      }
72  
73      private void compute(LineString line, double distance) {
74          // <TODO> handle negative distances (measure from opposite end of line)
75          double totalDist = 0.0;
76          Coordinate[] coord = line.getCoordinates();
77          for (int i = 0; i < coord.length - 1; i++) {
78              Coordinate p0 = coord[i];
79              Coordinate p1 = coord[i + 1];
80              double segLen = p1.distance(p0);
81              if (totalDist + segLen > distance) {
82                  pt = pointAlongSegment(p0, p1, distance - totalDist);
83                  index = i;
84                  return;
85              }
86              totalDist += segLen;
87          }
88          // distance is greater than line length
89          pt = new Coordinate(coord[coord.length - 1]);
90          index = coord.length;
91      }
92  
93      public Coordinate getPoint() {
94          return pt;
95      }
96  
97      /**
98       * Returns the index of the segment containing the computed point
99       * @return the index
100      */
101     public int getIndex() {
102         return index;
103     }
104 
105 }