Revision 31704

View differences:

trunk/libraries/libFMap/src/com/iver/cit/gvsig/fmap/core/styles/Line2DOffset.java
49 49

  
50 50
import org.apache.log4j.Logger;
51 51

  
52
import com.iver.cit.gvsig.fmap.core.FPolygon2D;
52 53
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
53 54
import com.vividsolutions.jts.geom.Coordinate;
54 55
import com.vividsolutions.jts.geom.LineSegment;
......
81 82

  
82 83
				switch (type) {
83 84
				case PathIterator.SEG_MOVETO:
84
					from = new Coordinate(dataCoords[0], dataCoords[1]);
85
					first = from;
86
					break;
85
					if(from == null){
86
						from = new Coordinate(dataCoords[0], dataCoords[1]);
87
						first = from;
88
						break;
89
					} else {
90
						/* Puede significar un agujero en un pol?gono o un salto en una linea.
91
						 * Entonces, consumimos los segmentos que llevamos
92
						 * y empezamos un nuevo pol?gono o una nueva linea.
93
						 */
94
						try {
95
							if(p instanceof FPolygon2D){
96
								offsetSegments.append(offsetAndConsumeClosedSegments(offset, segments),
97
										false);
98
							} else {
99
								offsetSegments.append(offsetAndConsumeSegments(offset, segments),
100
										false);
101
							}
102
						} catch (NotEnoughSegmentsToClosePathException e) {
103
							Logger.getLogger(Line2DOffset.class).error(
104
									e.getMessage(), e);
105
						}
106
						segments.clear();
107
						from = new Coordinate(dataCoords[0], dataCoords[1]);
108
						first = from;
109
						break;
110
					}
87 111

  
88 112
				case PathIterator.SEG_LINETO:
89 113

  
......
98 122
				case PathIterator.SEG_CLOSE:
99 123
					line = new LineSegment(from, first);
100 124
					segments.add(line);
101
					from = first;
125
					//					from = first;
102 126
					try {
103 127
						offsetSegments.append(offsetAndConsumeClosedSegments(
104 128
								offset, segments), false);
......
106 130
						Logger.getLogger(Line2DOffset.class).error(
107 131
								e.getMessage(), e);
108 132
					}
133
					segments.clear();
134
					first =null;
135
					from = null;
136

  
109 137
					break;
110 138

  
111 139
				} // end switch
......
113 141
				pi.next();
114 142
			}
115 143
			offsetSegments.append(offsetAndConsumeSegments(offset, segments),
116
					true);
144
					false);
117 145

  
118 146
			return offsetSegments;
119 147
		} catch (ParallelLinesCannotBeResolvedException e) {
......
192 220
		return gpx;
193 221
	}
194 222

  
223
	
195 224
	private static GeneralPathX offsetAndConsumeClosedSegments(double offset,
196 225
			ArrayList<LineSegment> segments)
197
	throws ParallelLinesCannotBeResolvedException,
198
	NotEnoughSegmentsToClosePathException {
226
	throws ParallelLinesCannotBeResolvedException, NotEnoughSegmentsToClosePathException {
199 227
		int segmentCount = segments.size();
200 228
		if (segmentCount > 1) {
201
			GeneralPathX openPath = offsetAndConsumeSegments(offset, segments);
202
			openPath.closePath();
203
			return openPath;
229
			Hashtable<LineSegment, LineEquation> offsetLines = new Hashtable<LineSegment, LineEquation>();
230
			// first calculate offset lines with the starting point
231
			for (int i = 0; i < segmentCount; i++) {
232
				LineSegment segment = segments.get(i);
233
				double theta = segment.angle();
234
				//FIXME: ?Esto para qu? es?
235
				//			if (Math.abs(theta) % (Math.PI*0.5) < 0.00001){
236
				//				theta=theta+0.00000000000001;
237
				//			}
238

  
239
				double xOffset = offset * Math.sin(theta);
240
				double yOffset = offset * Math.cos(theta);
241

  
242
				Coordinate p0 = segment.p0;
243
				double x0 = p0.x + xOffset;
244
				double y0 = p0.y - yOffset;
245

  
246
				Coordinate p1 = segment.p1;
247
				double x1 = p1.x + xOffset;
248
				double y1 = p1.y - yOffset;
249

  
250
				LineEquation offsetLine = new LineEquation(theta, x0, y0, x1, y1);
251
				offsetLines.put(segment, offsetLine);
252
			}
253

  
254
			/*
255
			 * let's now calculate the end point of each segment with the point
256
			 * where each line crosses the next one. this point will be the end
257
			 * point of the first line, and the start point of its next one.
258
			 */
259
			Point2D pIni = null;
260
			Point2D pEnd = null;
261
			Point2D firstP = null;
262
			GeneralPathX gpx = new GeneralPathX();
263
			for (int i = 0; i < segmentCount; i++) {
264
				LineSegment segment = segments.get(0);
265
				LineEquation eq = offsetLines.get(segment);
266
				if (i == 0) { //Calculo de la intersecci?n entre el primer segmento y el ?ltimo
267
					LineEquation eq0 = offsetLines.get(segments.get(segmentCount-1));
268
					try{
269
						pIni = eq0.resolve(eq);
270
					} catch (ParallelLinesCannotBeResolvedException e) { //Las lineas son paralelas y NO son la misma.
271
//						pIni = new Point2D.Double(eq0.xEnd, eq0.yEnd);
272
						pIni = new Point2D.Double(eq.x, eq.y);
273
					}
274
					firstP = pIni;
275
				} else {
276
					pIni = pEnd;
277
				}
278

  
279
				if (i < segmentCount - 1) {
280
					LineEquation eq1 = offsetLines.get(segments.get(1));
281
					try{
282
						pEnd = eq.resolve(eq1);
283
					} catch (ParallelLinesCannotBeResolvedException e) { //Las lineas son paralelas y NO son la misma.
284
						pEnd = new Point2D.Double(eq.xEnd, eq.yEnd);
285
						gpx.append(new Line2D.Double(pIni, pEnd), true); // a?adimos una linea hasta el final del primer segmento
286
						//					 y asignamos como punto final el principio del siguiente segmento
287
						//					 para que en la siguiente iteraci?n lo tome como punto inicial.
288
						pIni = pEnd;
289
						pEnd = new Point2D.Double(eq1.x, eq1.y);
290
						segments.remove(0);
291
						continue;
292
					}
293
				} else {
294
//					pEnd = new Point2D.Double(eq.xEnd, eq.yEnd);
295
					pEnd = new Point2D.Double(firstP.getX(), firstP.getY());
296
				}
297

  
298
				gpx.append(new Line2D.Double(pIni, pEnd), true);
299
				segments.remove(0);
300
			}
301
			return gpx;
204 302
		}
205 303
		throw new NotEnoughSegmentsToClosePathException(segments);
304

  
206 305
	}
306

  
307
//	private static GeneralPathX offsetAndConsumeClosedSegments(double offset,
308
//			ArrayList<LineSegment> segments)
309
//	throws ParallelLinesCannotBeResolvedException,
310
//	NotEnoughSegmentsToClosePathException {
311
//		int segmentCount = segments.size();
312
//		if (segmentCount > 1) {
313
//			GeneralPathX openPath = offsetAndConsumeSegments(offset, segments);
314
//			openPath.closePath();
315
//			return openPath;
316
//		}
317
//		throw new NotEnoughSegmentsToClosePathException(segments);
318
//	}
207 319
}
208 320

  
209 321
class LineEquation {

Also available in: Unified diff