1 /**
2 *
3 */
4 package org.opentrafficsim.road.network.factory.vissim;
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 }