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 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 }