Revision 31704
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