1
2
3
4 package org.opentrafficsim.road.network.factory.vissim;
5
6 import com.vividsolutions.jts.geom.Coordinate;
7 import com.vividsolutions.jts.geom.CoordinateList;
8 import com.vividsolutions.jts.geom.LineSegment;
9 import com.vividsolutions.jts.geom.LineString;
10 import com.vividsolutions.jts.util.Assert;
11
12
13
14
15 public class SubstringLine
16 {
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 public static LineString getSubstring(final LineString line, final double startLength, final double endLength)
36 {
37 SubstringLine ls = new SubstringLine(line);
38 return ls.getSubstring(startLength, endLength);
39 }
40
41
42 private LineString line;
43
44
45
46
47 public SubstringLine(final LineString line)
48 {
49 this.line = line;
50 }
51
52
53
54
55
56
57 public LineString getSubstring(double startDistance, final double endDistance)
58 {
59
60 Assert.isTrue(startDistance <= endDistance, "inverted distances not currently supported");
61
62 Coordinate[] coordinates = line.getCoordinates();
63
64 if (endDistance <= 0.0)
65 {
66 return line.getFactory().createLineString(new Coordinate[] { coordinates[0], coordinates[0] });
67 }
68 if (startDistance >= line.getLength())
69 {
70 return line.getFactory().createLineString(
71 new Coordinate[] { coordinates[coordinates.length - 1], coordinates[coordinates.length - 1] });
72 }
73 if (startDistance < 0.0)
74 {
75 startDistance = 0.0;
76 }
77 return computeSubstring(startDistance, endDistance);
78 }
79
80
81
82
83
84
85
86 private LineString computeSubstring(final double startDistance, final double endDistance)
87 {
88 Coordinate[] coordinates = line.getCoordinates();
89 CoordinateList newCoordinates = new CoordinateList();
90 double segmentStartDistance = 0.0;
91 double segmentEndDistance = 0.0;
92 boolean started = false;
93 int i = 0;
94 LineSegment segment = new LineSegment();
95 while (i < coordinates.length - 1 && endDistance > segmentEndDistance)
96 {
97 segment.p0 = coordinates[i];
98 segment.p1 = coordinates[i + 1];
99 i++;
100 segmentStartDistance = segmentEndDistance;
101 segmentEndDistance = segmentStartDistance + segment.getLength();
102
103 if (startDistance > segmentEndDistance)
104 {
105 continue;
106 }
107 if (startDistance >= segmentStartDistance && startDistance < segmentEndDistance)
108 {
109 newCoordinates.add(LocatePoint.pointAlongSegment(segment.p0, segment.p1, startDistance - segmentStartDistance),
110 false);
111 }
112
113
114
115
116 if (endDistance >= segmentEndDistance)
117 {
118 newCoordinates.add(new Coordinate(segment.p1), false);
119 }
120 if (endDistance >= segmentStartDistance && endDistance < segmentEndDistance)
121 {
122 newCoordinates.add(LocatePoint.pointAlongSegment(segment.p0, segment.p1, endDistance - segmentStartDistance),
123 false);
124 }
125 }
126 Coordinate[] newCoordinateArray = newCoordinates.toCoordinateArray();
127
128
129
130
131 if (newCoordinateArray.length <= 1)
132 {
133 newCoordinateArray = new Coordinate[] { newCoordinateArray[0], newCoordinateArray[0] };
134 }
135 return line.getFactory().createLineString(newCoordinateArray);
136 }
137 }