Revision 42267 trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.jts/src/main/java/org/gvsig/fmap/geom/jts/primitive/surface/polygon/AbstractPolygon.java
AbstractPolygon.java | ||
---|---|---|
25 | 25 |
import java.awt.Shape; |
26 | 26 |
import java.awt.geom.AffineTransform; |
27 | 27 |
import java.awt.geom.PathIterator; |
28 |
import java.util.ArrayList; |
|
28 | 29 |
import java.util.Iterator; |
29 | 30 |
|
30 | 31 |
import com.vividsolutions.jts.geom.Coordinate; |
31 | 32 |
|
33 |
import org.apache.commons.lang3.StringUtils; |
|
32 | 34 |
import org.cresques.cts.ICoordTrans; |
35 |
import org.slf4j.Logger; |
|
36 |
import org.slf4j.LoggerFactory; |
|
33 | 37 |
|
34 | 38 |
import org.gvsig.fmap.geom.Geometry; |
35 | 39 |
import org.gvsig.fmap.geom.GeometryException; |
... | ... | |
38 | 42 |
import org.gvsig.fmap.geom.aggregate.MultiPolygon; |
39 | 43 |
import org.gvsig.fmap.geom.exception.ReprojectionRuntimeException; |
40 | 44 |
import org.gvsig.fmap.geom.handler.Handler; |
45 |
import org.gvsig.fmap.geom.jts.gputils.GeneralPathXIterator; |
|
46 |
import org.gvsig.fmap.geom.jts.primitive.curve.line.AbstractLine; |
|
47 |
import org.gvsig.fmap.geom.jts.primitive.point.Point2D; |
|
41 | 48 |
import org.gvsig.fmap.geom.jts.primitive.point.PointJTS; |
42 | 49 |
import org.gvsig.fmap.geom.jts.primitive.surface.AbstractSurface; |
43 |
import org.gvsig.fmap.geom.jts.utils.ArrayListCoordinateSequence;
|
|
44 |
import org.gvsig.fmap.geom.jts.utils.JTSUtils;
|
|
45 |
import org.gvsig.fmap.geom.jts.utils.ReadOnlyCoordinates;
|
|
50 |
import org.gvsig.fmap.geom.jts.util.ArrayListCoordinateSequence; |
|
51 |
import org.gvsig.fmap.geom.jts.util.JTSUtils; |
|
52 |
import org.gvsig.fmap.geom.jts.util.ReadOnlyCoordinates; |
|
46 | 53 |
import org.gvsig.fmap.geom.primitive.GeneralPathX; |
54 |
import org.gvsig.fmap.geom.primitive.IGeneralPathX; |
|
47 | 55 |
import org.gvsig.fmap.geom.primitive.Point; |
48 | 56 |
import org.gvsig.fmap.geom.primitive.Polygon; |
49 | 57 |
import org.gvsig.fmap.geom.primitive.Ring; |
... | ... | |
57 | 65 |
*/ |
58 | 66 |
public abstract class AbstractPolygon extends AbstractSurface implements Polygon { |
59 | 67 |
|
68 |
// FIXME: CLASE A ELIMINAR ??? |
|
69 |
|
|
60 | 70 |
/** |
61 | 71 |
* |
62 | 72 |
*/ |
63 | 73 |
private static final long serialVersionUID = -942309688045973491L; |
74 |
private static final Logger logger = LoggerFactory.getLogger(AbstractPolygon.class); |
|
64 | 75 |
|
65 | 76 |
protected ArrayListCoordinateSequence coordinates; |
77 |
protected ArrayList<Ring> interiorRings; |
|
66 | 78 |
protected PointJTS vertex; |
67 | 79 |
|
68 | 80 |
/** |
... | ... | |
78 | 90 |
public AbstractPolygon(int subtype, Coordinate[] coordinates, PointJTS aVertex) { |
79 | 91 |
this(subtype); |
80 | 92 |
this.coordinates = new ArrayListCoordinateSequence(new ReadOnlyCoordinates(coordinates)); |
93 |
this.interiorRings = new ArrayList<Ring>(); |
|
81 | 94 |
vertex = aVertex; |
82 | 95 |
} |
83 | 96 |
|
... | ... | |
102 | 115 |
* @see org.gvsig.fmap.geom.primitive.Surface#getNumInteriorRings() |
103 | 116 |
*/ |
104 | 117 |
public int getNumInteriorRings() { |
105 |
// TODO Auto-generated method stub |
|
106 |
return 0; |
|
118 |
return interiorRings.size(); |
|
107 | 119 |
} |
108 | 120 |
|
109 | 121 |
/* (non-Javadoc) |
110 | 122 |
* @see org.gvsig.fmap.geom.primitive.Surface#getInteriorRing(int) |
111 | 123 |
*/ |
112 | 124 |
public Ring getInteriorRing(int index) { |
113 |
// TODO Auto-generated method stub |
|
114 |
return null; |
|
125 |
return interiorRings.get(index); |
|
115 | 126 |
} |
116 | 127 |
|
117 | 128 |
/* (non-Javadoc) |
118 | 129 |
* @see org.gvsig.fmap.geom.primitive.Surface#addInteriorRing(org.gvsig.fmap.geom.primitive.Ring) |
119 | 130 |
*/ |
120 | 131 |
public void addInteriorRing(Ring ring) { |
121 |
// TODO Auto-generated method stub
|
|
132 |
interiorRings.add(ring);
|
|
122 | 133 |
|
123 | 134 |
} |
124 | 135 |
|
... | ... | |
126 | 137 |
* @see org.gvsig.fmap.geom.primitive.Surface#removeInteriorRing(int) |
127 | 138 |
*/ |
128 | 139 |
public void removeInteriorRing(int index) { |
129 |
// TODO Auto-generated method stub |
|
130 |
|
|
140 |
interiorRings.remove(index); |
|
131 | 141 |
} |
132 | 142 |
|
133 | 143 |
/* (non-Javadoc) |
... | ... | |
200 | 210 |
* @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#setGeneralPath(org.gvsig.fmap.geom.primitive.GeneralPathX) |
201 | 211 |
*/ |
202 | 212 |
public void setGeneralPath(GeneralPathX generalPathX) { |
203 |
throw new UnsupportedOperationException(); |
|
213 |
PathIterator it = generalPathX.getPathIterator(null); |
|
214 |
double[] segment = new double[6]; |
|
215 |
int i = 0; |
|
216 |
while(!it.isDone()){ |
|
217 |
int type = it.currentSegment(segment); |
|
218 |
if(i==0){ |
|
219 |
switch (type) { |
|
220 |
case IGeneralPathX.SEG_MOVETO: |
|
221 |
Point p = new Point2D(segment[0], segment[1]); |
|
222 |
p = fixPoint(p); |
|
223 |
coordinates.add(((PointJTS)p).getJTSCoordinate()); |
|
224 |
break; |
|
225 |
default: |
|
226 |
String message = StringUtils.replace("Type of segment %(segment)s isn't SEG_MOVETO.","%(segment)s",String.valueOf(i)); |
|
227 |
logger.warn(message); |
|
228 |
throw new RuntimeException(message); |
|
229 |
} |
|
230 |
} else { |
|
231 |
//Dudo de que los casos SEG_QUADTO y SEG_CUBICTO est?n bien pero se hac?a lo mismo en la librer?a de geometr?as vieja. |
|
232 |
Point p; |
|
233 |
switch (type) { |
|
234 |
case IGeneralPathX.SEG_LINETO: |
|
235 |
p = new Point2D(segment[0], segment[1]); |
|
236 |
p = fixPoint(p); |
|
237 |
coordinates.add(((PointJTS)p).getJTSCoordinate()); |
|
238 |
break; |
|
239 |
case IGeneralPathX.SEG_QUADTO: |
|
240 |
for (int j = 0; j <= 1; j++) { |
|
241 |
p = new Point2D(segment[i], segment[i+1]); |
|
242 |
p = fixPoint(p); |
|
243 |
coordinates.add(((PointJTS) p).getJTSCoordinate()); |
|
244 |
} |
|
245 |
break; |
|
246 |
case IGeneralPathX.SEG_CUBICTO: |
|
247 |
for (int j = 0; j <= 2; j++) { |
|
248 |
p = new Point2D(segment[i], segment[i+1]); |
|
249 |
p = fixPoint(p); |
|
250 |
coordinates.add(((PointJTS) p).getJTSCoordinate()); |
|
251 |
} |
|
252 |
break; |
|
253 |
case IGeneralPathX.SEG_CLOSE: |
|
254 |
coordinates.add(coordinates.get(0)); |
|
255 |
break; |
|
256 |
default: |
|
257 |
String message = StringUtils.replace("The general path has a gap in segment %(segment)s.","%(segment)s",String.valueOf(i)); |
|
258 |
logger.warn(message); |
|
259 |
throw new RuntimeException(message); |
|
260 |
} |
|
261 |
} |
|
262 |
it.next(); |
|
263 |
i++; |
|
264 |
} |
|
204 | 265 |
} |
205 | 266 |
|
206 | 267 |
/* (non-Javadoc) |
... | ... | |
328 | 389 |
return null; |
329 | 390 |
} |
330 | 391 |
|
392 |
|
|
393 |
public class PoligonIterator extends GeneralPathXIterator { |
|
394 |
|
|
395 |
/** Transform applied on the coordinates during iteration */ |
|
396 |
private AffineTransform at; |
|
397 |
|
|
398 |
/** True when the point has been read once */ |
|
399 |
private boolean done; |
|
400 |
private int index = 0; |
|
401 |
|
|
402 |
/** |
|
403 |
* Creates a new PointIterator object. |
|
404 |
* |
|
405 |
* @param p |
|
406 |
* The polygon |
|
407 |
* @param at |
|
408 |
* The affine transform applied to coordinates during |
|
409 |
* iteration |
|
410 |
*/ |
|
411 |
public PoligonIterator(AffineTransform at) { |
|
412 |
super(new GeneralPathX()); |
|
413 |
if (at == null) { |
|
414 |
at = new AffineTransform(); |
|
415 |
} |
|
416 |
|
|
417 |
this.at = at; |
|
418 |
done = false; |
|
419 |
} |
|
420 |
|
|
421 |
/** |
|
422 |
* Return the winding rule for determining the interior of the path. |
|
423 |
* |
|
424 |
* @return <code>WIND_EVEN_ODD</code> by default. |
|
425 |
*/ |
|
426 |
public int getWindingRule() { |
|
427 |
return PathIterator.WIND_EVEN_ODD; |
|
428 |
} |
|
429 |
|
|
430 |
/** |
|
431 |
* @see java.awt.geom.PathIterator#next() |
|
432 |
*/ |
|
433 |
public void next() { |
|
434 |
|
|
435 |
int numVertices = coordinates.size(); |
|
436 |
for (int i = 0; i < interiorRings.size(); i++) { |
|
437 |
numVertices += interiorRings.get(i).getNumVertices(); |
|
438 |
} |
|
439 |
done = (numVertices == index++); |
|
440 |
} |
|
441 |
|
|
442 |
/** |
|
443 |
* @see java.awt.geom.PathIterator#isDone() |
|
444 |
*/ |
|
445 |
public boolean isDone() { |
|
446 |
return done; |
|
447 |
} |
|
448 |
|
|
449 |
/** |
|
450 |
* @see java.awt.geom.PathIterator#currentSegment(double[]) |
|
451 |
*/ |
|
452 |
public int currentSegment(double[] coords) { |
|
453 |
if (index<coordinates.size()){ |
|
454 |
coords[0] = coordinates.getX(index); |
|
455 |
coords[1] = coordinates.getY(index); |
|
456 |
at.transform(coords, 0, coords, 0, 1); |
|
457 |
if (index == 0) { |
|
458 |
return PathIterator.SEG_MOVETO; |
|
459 |
} else { |
|
460 |
return PathIterator.SEG_LINETO; |
|
461 |
} |
|
462 |
} else { |
|
463 |
int previousRingsSize = 0; |
|
464 |
for(int r=0; r<interiorRings.size(); r++){ |
|
465 |
Ring ring = interiorRings.get(r); |
|
466 |
if (index < coordinates.size()+previousRingsSize+ring.getNumVertices()){ |
|
467 |
int ringIndex = index-(coordinates.size()+previousRingsSize); |
|
468 |
coords[0] = ring.getVertex(ringIndex).getX(); |
|
469 |
coords[1] = ring.getVertex(ringIndex).getY(); |
|
470 |
at.transform(coords, 0, coords, 0, 1); |
|
471 |
if (ringIndex == 0) { |
|
472 |
return PathIterator.SEG_MOVETO; |
|
473 |
} else { |
|
474 |
return PathIterator.SEG_LINETO; |
|
475 |
} |
|
476 |
} else { |
|
477 |
previousRingsSize += ring.getNumVertices(); |
|
478 |
} |
|
479 |
} |
|
480 |
return PathIterator.SEG_CLOSE; //FIXME: ?????? |
|
481 |
} |
|
482 |
} |
|
483 |
|
|
484 |
/* |
|
485 |
* (non-Javadoc) |
|
486 |
* |
|
487 |
* @see java.awt.geom.PathIterator#currentSegment(float[]) |
|
488 |
*/ |
|
489 |
public int currentSegment(float[] coords) { |
|
490 |
if (index<coordinates.size()){ |
|
491 |
coords[0] = (float)coordinates.getX(index); |
|
492 |
coords[1] = (float)coordinates.getY(index); |
|
493 |
at.transform(coords, 0, coords, 0, 1); |
|
494 |
if (index == 0) { |
|
495 |
return PathIterator.SEG_MOVETO; |
|
496 |
} else { |
|
497 |
return PathIterator.SEG_LINETO; |
|
498 |
} |
|
499 |
} else { |
|
500 |
int previousRingsSize = 0; |
|
501 |
for(int r=0; r<interiorRings.size(); r++){ |
|
502 |
Ring ring = interiorRings.get(r); |
|
503 |
if (index < coordinates.size()+previousRingsSize+ring.getNumVertices()){ |
|
504 |
int ringIndex = index-(coordinates.size()+previousRingsSize); |
|
505 |
coords[0] = (float)ring.getVertex(ringIndex).getX(); |
|
506 |
coords[1] = (float)ring.getVertex(ringIndex).getY(); |
|
507 |
at.transform(coords, 0, coords, 0, 1); |
|
508 |
if (ringIndex == 0) { |
|
509 |
return PathIterator.SEG_MOVETO; |
|
510 |
} else { |
|
511 |
return PathIterator.SEG_LINETO; |
|
512 |
} |
|
513 |
} else { |
|
514 |
previousRingsSize += ring.getNumVertices(); |
|
515 |
} |
|
516 |
} |
|
517 |
return PathIterator.SEG_CLOSE; //FIXME: ?????? |
|
518 |
} |
|
519 |
} |
|
520 |
} |
|
521 |
|
|
522 |
|
|
523 |
|
|
524 |
|
|
525 |
|
|
331 | 526 |
/* (non-Javadoc) |
332 | 527 |
* @see org.gvsig.fmap.geom.primitive.Polygon#toPoints() |
333 | 528 |
*/ |
Also available in: Unified diff