Revision 13591 trunk/libraries/libTopology/src/org/gvsig/jts/LineStringSplitter.java

View differences:

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