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 public static LineString getSubstring(final LineString line, final double startLength, final double endLength)
35 {
36 SubstringLine ls = new SubstringLine(line);
37 return ls.getSubstring(startLength, endLength);
38 }
39
40
41 private LineString line;
42
43
44
45
46 public SubstringLine(final LineString line)
47 {
48 this.line = line;
49 }
50
51
52
53
54
55
56 public LineString getSubstring(double startDistance, final double endDistance)
57 {
58
59 Assert.isTrue(startDistance <= endDistance, "inverted distances not currently supported");
60
61 Coordinate[] coordinates = line.getCoordinates();
62
63 if (endDistance <= 0.0) {
64 return line.getFactory().createLineString(new Coordinate[] {coordinates[0], coordinates[0]});
65 }
66 if (startDistance >= line.getLength()) {
67 return line.getFactory().createLineString(new Coordinate[] {coordinates[coordinates.length - 1],
68 coordinates[coordinates.length - 1]});
69 }
70 if (startDistance < 0.0) {
71 startDistance = 0.0;
72 }
73 return computeSubstring(startDistance, endDistance);
74 }
75
76
77
78
79
80
81
82 private LineString computeSubstring(final double startDistance, final double endDistance)
83 {
84 Coordinate[] coordinates = line.getCoordinates();
85 CoordinateList newCoordinates = new CoordinateList();
86 double segmentStartDistance = 0.0;
87 double segmentEndDistance = 0.0;
88 boolean started = false;
89 int i = 0;
90 LineSegment segment = new LineSegment();
91 while (i < coordinates.length - 1 && endDistance > segmentEndDistance) {
92 segment.p0 = coordinates[i];
93 segment.p1 = coordinates[i + 1];
94 i++;
95 segmentStartDistance = segmentEndDistance;
96 segmentEndDistance = segmentStartDistance + segment.getLength();
97
98 if (startDistance > segmentEndDistance) {
99 continue;
100 }
101 if (startDistance >= segmentStartDistance && startDistance < segmentEndDistance) {
102 newCoordinates.add(LocatePoint.pointAlongSegment(segment.p0, segment.p1, startDistance
103 - segmentStartDistance), false);
104 }
105
106
107
108
109 if (endDistance >= segmentEndDistance) {
110 newCoordinates.add(new Coordinate(segment.p1), false);
111 }
112 if (endDistance >= segmentStartDistance && endDistance < segmentEndDistance) {
113 newCoordinates.add(LocatePoint.pointAlongSegment(segment.p0, segment.p1, endDistance - segmentStartDistance),
114 false);
115 }
116 }
117 Coordinate[] newCoordinateArray = newCoordinates.toCoordinateArray();
118
119
120
121
122 if (newCoordinateArray.length <= 1) {
123 newCoordinateArray = new Coordinate[] {newCoordinateArray[0], newCoordinateArray[0]};
124 }
125 return line.getFactory().createLineString(newCoordinateArray);
126 }
127 }