Revision 31705

View differences:

branches/v2_0_0_prep/extensions/org.gvsig.symbology/src/main/java/org/gvsig/symbology/fmap/mapcontext/rendering/symbol/style/Line2DOffset.java
49 49
import java.util.List;
50 50
import java.util.Map;
51 51

  
52
import org.gvsig.fmap.geom.Geometry;
52 53
import org.gvsig.fmap.geom.primitive.GeneralPathX;
53 54
import org.slf4j.Logger;
54 55
import org.slf4j.LoggerFactory;
......
85 86

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

  
92 116
				case PathIterator.SEG_LINETO:
93 117

  
......
102 126
				case PathIterator.SEG_CLOSE:
103 127
					line = new LineSegment(from, first);
104 128
					segments.add(line);
105
					from = first;
129
					//					from = first;
106 130
					try {
107 131
						offsetSegments.append(offsetAndConsumeClosedSegments(
108 132
								offset, segments).getPathIterator(null), false);
......
110 134
						logger.error(
111 135
								e.getMessage(), e);
112 136
					}
137
					segments.clear();
138
					first =null;
139
					from = null;
140

  
113 141
					break;
114 142

  
115 143
				} // end switch
......
117 145
				pi.next();
118 146
			}
119 147
			offsetSegments.append(offsetAndConsumeSegments(offset, segments)
120
					.getPathIterator(null), true);
148
					.getPathIterator(null), false);
121 149

  
122 150
			return offsetSegments;
123 151
		} catch (ParallelLinesCannotBeResolvedException e) {
......
130 158
			List<LineSegment> segments)
131 159
	throws ParallelLinesCannotBeResolvedException {
132 160
		Map<LineSegment, LineEquation> offsetLines =
133
				new HashMap<LineSegment, LineEquation>();
161
			new HashMap<LineSegment, LineEquation>();
134 162
		int segmentCount = segments.size();
135 163
		// first calculate offset lines with the starting point
136 164
		for (int i = 0; i < segmentCount; i++) {
137 165
			LineSegment segment = (LineSegment)segments.get(i);
138 166
			double theta = segment.angle();
139 167
			//FIXME: ?Esto para qu? es?
140
//			if (Math.abs(theta) % (Math.PI*0.5) < 0.00001){
141
//				theta=theta+0.00000000000001;
142
//			}
168
			//			if (Math.abs(theta) % (Math.PI*0.5) < 0.00001){
169
			//				theta=theta+0.00000000000001;
170
			//			}
143 171

  
144 172
			double xOffset = offset * Math.sin(theta);
145 173
			double yOffset = offset * Math.cos(theta);
......
180 208
				} catch (ParallelLinesCannotBeResolvedException e) { //Las lineas son paralelas y NO son la misma.
181 209
					pEnd = new Point2D.Double(eq.xEnd, eq.yEnd);
182 210
					gpx.append(new Line2D.Double(pIni, pEnd)
183
							.getPathIterator(null), true); // a?adimos una linea
184
															// hasta el final
185
															// del primer
186
															// segmento
187
//					 y asignamos como punto final el principio del siguiente segmento
188
//					 para que en la siguiente iteraci?n lo tome como punto inicial.
211
					.getPathIterator(null), true); // a?adimos una linea
212
					// hasta el final
213
					// del primer
214
					// segmento
215
					//					 y asignamos como punto final el principio del siguiente segmento
216
					//					 para que en la siguiente iteraci?n lo tome como punto inicial.
189 217
					pIni = pEnd;
190 218
					pEnd = new Point2D.Double(eq1.x, eq1.y);
191 219
					segments.remove(0);
......
203 231

  
204 232
	private static GeneralPathX offsetAndConsumeClosedSegments(double offset,
205 233
			List<LineSegment> segments)
206
	throws ParallelLinesCannotBeResolvedException,
207
	NotEnoughSegmentsToClosePathException {
234
	throws ParallelLinesCannotBeResolvedException, NotEnoughSegmentsToClosePathException {
208 235
		int segmentCount = segments.size();
209 236
		if (segmentCount > 1) {
210
			GeneralPathX openPath = offsetAndConsumeSegments(offset, segments);
211
			openPath.closePath();
212
			return openPath;
237
			Map<LineSegment, LineEquation> offsetLines = new HashMap<LineSegment, LineEquation>();
238
			// first calculate offset lines with the starting point
239
			for (int i = 0; i < segmentCount; i++) {
240
				LineSegment segment = (LineSegment)segments.get(i);
241
				double theta = segment.angle();
242
				//FIXME: ?Esto para qu? es?
243
				//			if (Math.abs(theta) % (Math.PI*0.5) < 0.00001){
244
				//				theta=theta+0.00000000000001;
245
				//			}
246

  
247
				double xOffset = offset * Math.sin(theta);
248
				double yOffset = offset * Math.cos(theta);
249

  
250
				Coordinate p0 = segment.p0;
251
				double x0 = p0.x + xOffset;
252
				double y0 = p0.y - yOffset;
253

  
254
				Coordinate p1 = segment.p1;
255
				double x1 = p1.x + xOffset;
256
				double y1 = p1.y - yOffset;
257

  
258
				LineEquation offsetLine = new LineEquation(theta, x0, y0, x1, y1);
259
				offsetLines.put(segment, offsetLine);
260
			}
261

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

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

  
306
				gpx.append(new Line2D.Double(pIni, pEnd).getPathIterator(null), true);
307
				segments.remove(0);
308
			}
309
			return gpx;
213 310
		}
214 311
		throw new NotEnoughSegmentsToClosePathException(segments);
312

  
215 313
	}
314

  
315
	//	private static GeneralPathX offsetAndConsumeClosedSegments(double offset,
316
	//			List<LineSegment> segments)
317
	//	throws ParallelLinesCannotBeResolvedException,
318
	//	NotEnoughSegmentsToClosePathException {
319
	//		int segmentCount = segments.size();
320
	//		if (segmentCount > 1) {
321
	//			GeneralPathX openPath = offsetAndConsumeSegments(offset, segments);
322
	//			openPath.closePath();
323
	//			return openPath;
324
	//		}
325
	//		throw new NotEnoughSegmentsToClosePathException(segments);
326
	//	}
216 327
}
217 328

  
218 329
class LineEquation {
......
222 333

  
223 334
	public LineEquation(double theta, double x, double y, double xEnd,
224 335
			double yEnd) {
225
//		this.theta = Math.tan(theta); //Esto es un error, no podemos confundir el angulo de la recta con su pendiente
336
		//		this.theta = Math.tan(theta); //Esto es un error, no podemos confundir el angulo de la recta con su pendiente
226 337
		this.theta = theta;
227 338
		this.m = Math.tan(theta);
228 339
		this.x = x;
......
241 352
		double X;
242 353
		double Y;
243 354
		if(Math.abs(this.x - this.xEnd)<0.00001) { //Esta linea es vertical
244
//			System.out.println("1 VERTICAL");
355
			//			System.out.println("1 VERTICAL");
245 356
			X = this.xEnd;
246 357
			if (Math.abs(otherLine.x - otherLine.xEnd)<0.00001){//La otra linea es vertical
247
//				System.out.println("    2 PERPENDICULAR");
358
				//				System.out.println("    2 PERPENDICULAR");
248 359
				if(Math.abs(this.x - otherLine.x)<0.00001){ //Son la misma linea, devolvemos el primer punto de la otra linea.
249
//					System.out.println("        MISMA LINEA");
360
					//					System.out.println("        MISMA LINEA");
250 361
					Y = otherLine.y;
251 362
				} else { //No son la misma linea, entonces son paralelas, excepcion.
252
//					System.out.println("        CASCO POR 1");
363
					//					System.out.println("        CASCO POR 1");
253 364
					throw new ParallelLinesCannotBeResolvedException(this, otherLine);
254 365
				}
255 366
			} else if (Math.abs(otherLine.y - otherLine.yEnd)<0.00001) { //La otra linea es horizontal
256
//				System.out.println("    2 HORIZONTAL");
367
				//				System.out.println("    2 HORIZONTAL");
257 368
				Y = otherLine.y;
258 369
			} else { //Si no
259
//				System.out.println("    2 CUALQUIERA");
370
				//				System.out.println("    2 CUALQUIERA");
260 371
				Y = otherLine.m*(X - otherLine.x)+otherLine.y;
261 372
			}
262 373

  
263 374
		} else if (Math.abs(this.y - this.yEnd)<0.00001) { //Esta linea es horizontal
264
//			System.out.println("1 HORIZONTAL");
375
			//			System.out.println("1 HORIZONTAL");
265 376
			Y = this.yEnd;
266 377
			if (Math.abs(otherLine.y - otherLine.yEnd)<0.00001) { //La otra linea es horizontal
267
//				System.out.println("    2 HORIZONTAL");
378
				//				System.out.println("    2 HORIZONTAL");
268 379
				if(Math.abs(this.y - otherLine.y)<0.00001){ //Son la misma linea, devolvemos el primer punto de la otra linea.
269
//					System.out.println("        MISMA LINEA");
380
					//					System.out.println("        MISMA LINEA");
270 381
					X = otherLine.x;
271 382
				} else { //No son la misma linea, entonces son paralelas, excepcion.
272
//					System.out.println("        CASCO POR 2");
383
					//					System.out.println("        CASCO POR 2");
273 384
					throw new ParallelLinesCannotBeResolvedException(this, otherLine);
274 385
				}
275 386
			} else if (Math.abs(otherLine.x - otherLine.xEnd)<0.00001){//La otra linea es vertical
276
//				System.out.println("    2 VERTICAL");
387
				//				System.out.println("    2 VERTICAL");
277 388
				X = otherLine.x;
278 389
			} else { //Si no
279
//				System.out.println("    2 CUALQUIERA");
390
				//				System.out.println("    2 CUALQUIERA");
280 391
				X = (Y - otherLine.y)/otherLine.m +otherLine.x;
281 392
			}
282 393
		} else { //Esta linea no es ni vertical ni horizontal
283
//			System.out.println("1 CUALQUIERA");
394
			//			System.out.println("1 CUALQUIERA");
284 395
			if (Math.abs(otherLine.y - otherLine.yEnd)<0.00001) { //La otra linea es horizontal
285
//				System.out.println("    2 HORIZONTAL");
396
				//				System.out.println("    2 HORIZONTAL");
286 397
				Y = otherLine.y;
287 398
				X = (Y - this.y)/this.m +this.x;
288 399
			} else if (Math.abs(otherLine.x - otherLine.xEnd)<0.00001){//La otra linea es vertical
289
//				System.out.println("    2 VERTICAL");
400
				//				System.out.println("    2 VERTICAL");
290 401
				X = otherLine.x;
291 402
				Y = this.m*(X - this.x)+this.y;
292 403
			} else if ((Math.abs(otherLine.m - this.m)<0.00001)) { //Tienen la misma pendiente
293
//				System.out.println("    MISMA PENDIENTE");
404
				//				System.out.println("    MISMA PENDIENTE");
294 405
				Y = otherLine.m*(this.x - otherLine.x)+otherLine.y;
295 406
				if (Math.abs(this.y - Y)<0.00001){ //Las lineas son la misma
296
//					System.out.println("        MISMA LINEA");
407
					//					System.out.println("        MISMA LINEA");
297 408
					X = otherLine.x;
298 409
					Y = otherLine.y;
299 410
				} else {
300
//					System.out.println("        CASCO POR 3");
411
					//					System.out.println("        CASCO POR 3");
301 412
					throw new ParallelLinesCannotBeResolvedException(this, otherLine);
302 413
				}
303 414
			} else {
304
//				System.out.println("    AMBAS CUALESQUIERA");
415
				//				System.out.println("    AMBAS CUALESQUIERA");
305 416
				double mTimesX = this.m * this.x;
306 417
				X = (mTimesX - this.y - otherLine.m * otherLine.x + otherLine.y) / (this.m - otherLine.m);
307 418
				Y = this.m * X - mTimesX + this.y;
308 419
			}
309 420
		}
310 421

  
311
//		System.out.println("DEVOLVEMOS X = "+X+" Y = "+Y);
422
		//		System.out.println("DEVOLVEMOS X = "+X+" Y = "+Y);
312 423
		return new Point2D.Double(X, Y);
313 424

  
314 425
	}

Also available in: Unified diff