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