Revision 13591 trunk/libraries/libTopology/src/org/gvsig/jts/LineStringSplitter.java
LineStringSplitter.java | ||
---|---|---|
5 | 5 |
import java.util.Collection; |
6 | 6 |
import java.util.Collections; |
7 | 7 |
import java.util.Comparator; |
8 |
import java.util.HashMap; |
|
8 | 9 |
import java.util.Iterator; |
9 | 10 |
import java.util.List; |
10 | 11 |
|
... | ... | |
13 | 14 |
import com.vividsolutions.jts.geom.LineSegment; |
14 | 15 |
import com.vividsolutions.jts.geom.LineString; |
15 | 16 |
import com.vividsolutions.jts.geom.Polygon; |
16 |
import com.vividsolutions.jts.linearref.LengthIndexedLine; |
|
17 | 17 |
import com.vividsolutions.jts.linearref.LinearIterator; |
18 | 18 |
import com.vividsolutions.jts.linearref.LinearLocation; |
19 | 19 |
import com.vividsolutions.jts.linearref.LocationIndexedLine; |
... | ... | |
71 | 71 |
for(int i = 0; i < lineStrings.length; i++){ |
72 | 72 |
LineString geom = lineStrings[i]; |
73 | 73 |
if(GeometrySnapper.isClosed(geom, snapTolerance)){ |
74 |
closedLineStrings.add(lineStrings[i]);
|
|
74 |
closedLineStrings.add(geom);
|
|
75 | 75 |
}else{ |
76 |
unclosedLineStrings.add(lineStrings[i]);
|
|
76 |
unclosedLineStrings.add(geom);
|
|
77 | 77 |
} |
78 | 78 |
} |
79 | 79 |
|
... | ... | |
114 | 114 |
Coordinate[] splitPoints) { |
115 | 115 |
|
116 | 116 |
ArrayList lineStringList = new ArrayList(); |
117 |
LengthIndexedLine lengthLine = new LengthIndexedLine(lineString);
|
|
117 |
RobustLengthIndexedLine lengthLine = new RobustLengthIndexedLine(lineString);
|
|
118 | 118 |
ArrayList nodeIntersections = new ArrayList(); |
119 | 119 |
double linearReferencingIndex = 0d; |
120 | 120 |
for (int i = 0; i < splitPoints.length; i++) { |
... | ... | |
147 | 147 |
|
148 | 148 |
LinearLocation lastLocation = null; |
149 | 149 |
LineIntersection lastIntersection = null; |
150 |
LocationIndexedLine indexedLine = new LocationIndexedLine(lineString);
|
|
150 |
RobustLocationIndexedLine indexedLine = new RobustLocationIndexedLine(lineString);
|
|
151 | 151 |
for (int i = 0; i < nodeIntersections.size(); i++) { |
152 | 152 |
Geometry geometry = null; |
153 | 153 |
LineIntersection li = (LineIntersection) nodeIntersections.get(i); |
154 | 154 |
// LinearLocation location = indexedLine.indexOf(li.coordinate); |
155 |
LinearLocation location = indexOfAfter(indexedLine, lineString,
|
|
155 |
LinearLocation location = indexedLine.indexOfAfter(indexedLine,
|
|
156 | 156 |
li.coordinate, lastLocation); |
157 | 157 |
|
158 | 158 |
if (lastLocation == null) { |
... | ... | |
191 | 191 |
|
192 | 192 |
private static LineString[] splitSimple(LineString lineString, Coordinate[] points) { |
193 | 193 |
LineString[] splittedLS = null; |
194 |
LengthIndexedLine lengthLine = new LengthIndexedLine(lineString); |
|
194 |
RobustLengthIndexedLine lengthLine = new RobustLengthIndexedLine(lineString); |
|
195 |
/* |
|
196 |
* LenghtIndexedLine indexOfAlter method returns the index of a line greater than the specified index. |
|
197 |
* For this reason, we must save in a cache the last computed index for a given coord, and pass |
|
198 |
* this precomputed index to the indexOfAlter method |
|
199 |
* */ |
|
200 |
HashMap coordsIndex = new HashMap(); |
|
195 | 201 |
ArrayList nodeIntersections = new ArrayList(); |
196 |
double linearDistance = 0d; |
|
197 | 202 |
for (int i = 0; i < points.length; i++) { |
198 | 203 |
Coordinate coord = points[i]; |
199 |
double lengthOfNode = lengthLine |
|
200 |
.indexOfAfter(coord, linearDistance); |
|
201 |
linearDistance = lengthOfNode; |
|
202 |
LineIntersection inters = new LineIntersection(); |
|
204 |
Double index = (Double) coordsIndex.get(coord); |
|
205 |
double indexD = 0d; |
|
206 |
if(index != null) |
|
207 |
indexD = index.doubleValue(); |
|
208 |
double computedIndex = lengthLine.indexOfAfter(coord, indexD); |
|
209 |
coordsIndex.put(coord, new Double(computedIndex)); |
|
210 |
LineIntersection inters = new LineIntersection(); |
|
203 | 211 |
inters.coordinate = coord; |
204 |
inters.lenght = lengthOfNode;
|
|
212 |
inters.lenght = computedIndex;
|
|
205 | 213 |
nodeIntersections.add(inters); |
206 | 214 |
}// for |
207 | 215 |
|
... | ... | |
223 | 231 |
|
224 | 232 |
LinearLocation lastLocation = null; |
225 | 233 |
LineIntersection lastIntersection = null; |
226 |
LocationIndexedLine indexedLine = new LocationIndexedLine(lineString);
|
|
234 |
RobustLocationIndexedLine indexedLine = new RobustLocationIndexedLine(lineString);
|
|
227 | 235 |
ArrayList splittedLsList = new ArrayList(); |
228 | 236 |
for (int i = 0; i < nodeIntersections.size(); i++) { |
229 | 237 |
Geometry solution = null; |
230 | 238 |
LineIntersection li = (LineIntersection) nodeIntersections.get(i); |
231 |
LinearLocation location = indexOfAfter(indexedLine, lineString,
|
|
239 |
LinearLocation location = indexedLine.indexOfAfter(indexedLine,
|
|
232 | 240 |
li.coordinate, lastLocation); |
233 | 241 |
if (lastLocation == null) { |
234 | 242 |
LinearLocation from = new LinearLocation(0, 0d); |
... | ... | |
254 | 262 |
|
255 | 263 |
} |
256 | 264 |
|
257 |
/* |
|
258 |
* FIXME: Este algoritmo (duplicar las intersecciones). |
|
259 |
* |
|
260 |
* Probar con: |
|
261 |
* |
|
262 |
* LINESTRING (-16801 780, -19541 2631, -19133 6356, -15839 7702, -14157 |
|
263 |
* 6284, -15503 5972, -15503 6765, -14085 7318, -11969 3929, -16945 1861, |
|
264 |
* -19734 635, -20190 -1143) |
|
265 |
* |
|
266 |
* |
|
267 |
* |
|
268 |
*/ |
|
269 | 265 |
/** |
270 | 266 |
* to propper work, LineStringSplitter needs coordinates to split a line. in |
271 | 267 |
* a self intersected line case, we must to repeat self interesections |
... | ... | |
291 | 287 |
if (splitPoints.length < 1) { |
292 | 288 |
return new LineString[] { lineString }; |
293 | 289 |
} |
290 |
|
|
294 | 291 |
Coordinate[] duplicatedSelfIntersections = duplicateSelfIntersections(splitPoints); |
295 | 292 |
//TODO Create a test case for a linestring not closed for precision reasons |
296 | 293 |
//but closed with a given snap tolerance |
... | ... | |
314 | 311 |
|
315 | 312 |
|
316 | 313 |
|
317 |
// These methods are needed because JTS LocationIndexedLine doesnt have an |
|
318 |
// indexOfAlter |
|
319 |
// method and LocationIndexPoint, which makes all these computations is not |
|
320 |
// a public class |
|
321 |
// report it to JTS project |
|
314 |
|
|
322 | 315 |
|
323 |
/* |
|
324 |
* M.Davids has said to me that he has added these methods to JTS (1.9 |
|
325 |
* version). |
|
326 |
* |
|
327 |
* TODO REMOVE THESE METHODS WITH JTS 1.9 |
|
328 |
*/ |
|
316 |
// private static LinearLocation indexOfFromStart(Coordinate inputPt, |
|
317 |
// LineString linearGeom, LinearLocation minIndex) { |
|
318 |
// double minDistance = Double.MAX_VALUE; |
|
319 |
// int minComponentIndex = 0; |
|
320 |
// int minSegmentIndex = 0; |
|
321 |
// double minFrac = -1.0; |
|
322 |
// |
|
323 |
// LineSegment seg = new LineSegment(); |
|
324 |
// for (LinearIterator it = new LinearIterator(linearGeom); it.hasNext(); it |
|
325 |
// .next()) { |
|
326 |
// if (!it.isEndOfLine()) { |
|
327 |
// seg.p0 = it.getSegmentStart(); |
|
328 |
// seg.p1 = it.getSegmentEnd(); |
|
329 |
// double segDistance = seg.distance(inputPt); |
|
330 |
// double segFrac = segmentFraction(seg, inputPt); |
|
331 |
// |
|
332 |
// int candidateComponentIndex = it.getComponentIndex(); |
|
333 |
// int candidateSegmentIndex = it.getVertexIndex(); |
|
334 |
// if (segDistance < minDistance) { |
|
335 |
// // ensure after minLocation, if any |
|
336 |
// if (minIndex == null |
|
337 |
// || minIndex.compareLocationValues( |
|
338 |
// candidateComponentIndex, |
|
339 |
// candidateSegmentIndex, segFrac) < 0) { |
|
340 |
// // otherwise, save this as new minimum |
|
341 |
// minComponentIndex = candidateComponentIndex; |
|
342 |
// minSegmentIndex = candidateSegmentIndex; |
|
343 |
// minFrac = segFrac; |
|
344 |
// minDistance = segDistance; |
|
345 |
// } |
|
346 |
// } |
|
347 |
// } |
|
348 |
// } |
|
349 |
// LinearLocation loc = new LinearLocation(minComponentIndex, |
|
350 |
// minSegmentIndex, minFrac); |
|
351 |
// return loc; |
|
352 |
// } |
|
329 | 353 |
|
330 |
public static LinearLocation indexOfAfter(LocationIndexedLine indexedLine, |
|
331 |
LineString lineString, Coordinate inputPt, LinearLocation minIndex) { |
|
332 |
if (minIndex == null) |
|
333 |
return indexedLine.indexOf(inputPt); |
|
334 |
LinearLocation endLoc = LinearLocation.getEndLocation(lineString); |
|
335 |
if (endLoc.compareTo(minIndex) <= 0) |
|
336 |
return endLoc; |
|
354 |
// private static double segmentFraction(LineSegment seg, Coordinate inputPt) { |
|
355 |
// double segFrac = seg.projectionFactor(inputPt); |
|
356 |
// if (segFrac < 0.0) |
|
357 |
// segFrac = 0.0; |
|
358 |
// else if (segFrac > 1.0) |
|
359 |
// segFrac = 1.0; |
|
360 |
// return segFrac; |
|
361 |
// } |
|
337 | 362 |
|
338 |
LinearLocation closestAfter = indexOfFromStart(inputPt, lineString, |
|
339 |
minIndex); |
|
340 |
return closestAfter; |
|
341 |
} |
|
342 |
|
|
343 |
private static LinearLocation indexOfFromStart(Coordinate inputPt, |
|
344 |
LineString linearGeom, LinearLocation minIndex) { |
|
345 |
double minDistance = Double.MAX_VALUE; |
|
346 |
int minComponentIndex = 0; |
|
347 |
int minSegmentIndex = 0; |
|
348 |
double minFrac = -1.0; |
|
349 |
|
|
350 |
LineSegment seg = new LineSegment(); |
|
351 |
for (LinearIterator it = new LinearIterator(linearGeom); it.hasNext(); it |
|
352 |
.next()) { |
|
353 |
if (!it.isEndOfLine()) { |
|
354 |
seg.p0 = it.getSegmentStart(); |
|
355 |
seg.p1 = it.getSegmentEnd(); |
|
356 |
double segDistance = seg.distance(inputPt); |
|
357 |
double segFrac = segmentFraction(seg, inputPt); |
|
358 |
|
|
359 |
int candidateComponentIndex = it.getComponentIndex(); |
|
360 |
int candidateSegmentIndex = it.getVertexIndex(); |
|
361 |
if (segDistance < minDistance) { |
|
362 |
// ensure after minLocation, if any |
|
363 |
if (minIndex == null |
|
364 |
|| minIndex.compareLocationValues( |
|
365 |
candidateComponentIndex, |
|
366 |
candidateSegmentIndex, segFrac) < 0) { |
|
367 |
// otherwise, save this as new minimum |
|
368 |
minComponentIndex = candidateComponentIndex; |
|
369 |
minSegmentIndex = candidateSegmentIndex; |
|
370 |
minFrac = segFrac; |
|
371 |
minDistance = segDistance; |
|
372 |
} |
|
373 |
} |
|
374 |
} |
|
375 |
} |
|
376 |
LinearLocation loc = new LinearLocation(minComponentIndex, |
|
377 |
minSegmentIndex, minFrac); |
|
378 |
return loc; |
|
379 |
} |
|
380 |
|
|
381 |
private static double segmentFraction(LineSegment seg, Coordinate inputPt) { |
|
382 |
double segFrac = seg.projectionFactor(inputPt); |
|
383 |
if (segFrac < 0.0) |
|
384 |
segFrac = 0.0; |
|
385 |
else if (segFrac > 1.0) |
|
386 |
segFrac = 1.0; |
|
387 |
return segFrac; |
|
388 |
} |
|
389 |
|
|
390 | 363 |
} |
Also available in: Unified diff