Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_geometries / src / org / gvsig / fmap / geom / util / Converter.java @ 38388

History | View | Annotate | Download (37.9 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package org.gvsig.fmap.geom.util;
42

    
43
import java.awt.Shape;
44
import java.awt.geom.AffineTransform;
45
import java.awt.geom.Area;
46
import java.awt.geom.NoninvertibleTransformException;
47
import java.awt.geom.PathIterator;
48
import java.awt.geom.Rectangle2D;
49
import java.lang.reflect.Array;
50
import java.util.ArrayList;
51

    
52
import org.gvsig.fmap.geom.Geometry;
53
import org.gvsig.fmap.geom.GeometryLocator;
54
import org.gvsig.fmap.geom.GeometryManager;
55
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
56
import org.gvsig.fmap.geom.Geometry.TYPES;
57
import org.gvsig.fmap.geom.aggregate.MultiCurve;
58
import org.gvsig.fmap.geom.aggregate.MultiPoint;
59
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
60
import org.gvsig.fmap.geom.aggregate.MultiSurface;
61
import org.gvsig.fmap.geom.exception.CreateGeometryException;
62
import org.gvsig.fmap.geom.primitive.GeneralPathX;
63
import org.gvsig.fmap.geom.primitive.Surface;
64
import org.slf4j.Logger;
65
import org.slf4j.LoggerFactory;
66

    
67
import com.vividsolutions.jts.algorithm.CGAlgorithms;
68
import com.vividsolutions.jts.algorithm.RobustCGAlgorithms;
69
import com.vividsolutions.jts.geom.Coordinate;
70
import com.vividsolutions.jts.geom.CoordinateArrays;
71
import com.vividsolutions.jts.geom.Envelope;
72
import com.vividsolutions.jts.geom.GeometryCollection;
73
import com.vividsolutions.jts.geom.LineString;
74
import com.vividsolutions.jts.geom.LinearRing;
75
import com.vividsolutions.jts.geom.MultiLineString;
76
import com.vividsolutions.jts.geom.MultiPolygon;
77
import com.vividsolutions.jts.geom.Point;
78
import com.vividsolutions.jts.geom.Polygon;
79

    
80
/**
81
 * Clase con varios m?todos est?ticos utilizados para pasar de java2d a jts
82
 * y viceversa.
83
 * 
84
 * @author fjp
85
 * @deprecated to be removed or moved from API to implementation in gvSIG 2.1.0
86
 */
87
public class Converter {
88
        private static final GeometryManager geomManager = GeometryLocator
89
                        .getGeometryManager();
90
        private static final Logger logger = LoggerFactory
91
                        .getLogger(Converter.class);
92

    
93
        // private static Logger logger = Logger.getLogger(Converter.class);
94

    
95
        /**
96
         * ?QU? PODEMOS HACER CON LOS MULTIPOINT??? => DEBER?AMOS TRABAJAR CON
97
         * UN ARRAY DE PUNTOS EN FShape.....Pensarlo bien.
98
         */
99
        public final static com.vividsolutions.jts.geom.GeometryFactory geomFactory = new com.vividsolutions.jts.geom.GeometryFactory();
100
        public static CGAlgorithms cga = new RobustCGAlgorithms();
101
        // private final static AffineTransform at = new AffineTransform();
102
        // private static double POINT_MARKER_SIZE = 3.0;
103

    
104
        private static GeometryManager manager = GeometryLocator
105
                        .getGeometryManager();
106

    
107
        // returns true if testPoint is a point in the pointList list.
108
        static boolean pointInList(Coordinate testPoint, Coordinate[] pointList) {
109
                int t;
110
                int numpoints;
111
                Coordinate p;
112

    
113
                numpoints = Array.getLength(pointList);
114

    
115
                for (t = 0; t < numpoints; t++) {
116
                        p = pointList[t];
117

    
118
                        if ((testPoint.x == p.x)
119
                                        && (testPoint.y == p.y)
120
                                        && ((testPoint.z == p.z) || (!(testPoint.z == testPoint.z))) // nan
121
                                                                                                                                                                        // test;
122
                                                                                                                                                                        // x!=x
123
                                                                                                                                                                        // iff
124
                                                                                                                                                                        // x
125
                                                                                                                                                                        // is
126
                                                                                                                                                                        // nan
127
                        ) {
128
                                return true;
129
                        }
130
                }
131

    
132
                return false;
133
        }
134

    
135
        /**
136
         * Receives a JTS Geometry and returns a fmap IGeometry
137
         * 
138
         * @param jtsGeometry
139
         *            jts Geometry
140
         * @return IGeometry of FMap
141
         * @author azabala
142
         * @throws CreateGeometryException
143
         */
144
        public static Geometry jtsToGeometry(
145
                        com.vividsolutions.jts.geom.Geometry geo)
146
                        throws CreateGeometryException {
147
                Geometry shpNew = null;
148

    
149
                try {
150
                        if (geo instanceof Point) {
151
                                shpNew = geomManager.createPoint(((Point) geo).getX(),
152
                                                ((Point) geo).getY(), SUBTYPES.GEOM2D);
153
                        }
154
                        
155
                        if (geo instanceof com.vividsolutions.jts.geom.MultiPoint) {
156
                                shpNew = (MultiPoint)geomManager.create(TYPES.MULTIPOINT, SUBTYPES.GEOM2D);
157
                                Coordinate[] coord = ((com.vividsolutions.jts.geom.MultiPoint)geo).getCoordinates();
158
                                for (int i = 0; i < coord.length; i++) {
159
                                        ((MultiPoint)shpNew).addPoint(geomManager.createPoint(coord[i].x, coord[i].y, SUBTYPES.GEOM2D));
160
                                }
161
                        }
162

    
163
                        if (geo.isEmpty()) {
164
                                shpNew = null;
165
                        }
166

    
167
                        try {
168
                                if (geo instanceof Polygon) {
169
                                        shpNew = geomManager.createSurface(toShape((Polygon) geo),
170
                                                        SUBTYPES.GEOM2D);
171
                                }
172

    
173
                                if (geo instanceof MultiPolygon) {
174
                                        shpNew = geomManager.createSurface(
175
                                                        toShape((MultiPolygon) geo), SUBTYPES.GEOM2D);
176
                                }
177

    
178
                                if (geo instanceof LineString) {
179
                                        shpNew = geomManager.createCurve(toShape((LineString) geo),
180
                                                        SUBTYPES.GEOM2D);
181
                                }
182

    
183
                                if (geo instanceof MultiLineString) {
184
                                        shpNew = geomManager.createCurve(
185
                                                        toShape((MultiLineString) geo), SUBTYPES.GEOM2D);
186
                                }
187
                        } catch (CreateGeometryException e) {
188
                                logger.error("Error creating a geometry", e);
189
                        }
190

    
191
                        /*
192
                         * OJO: CON ALGO COMO FSHAPE NO S? C?MO PODEMOS IMPLEMENTAR UN
193
                         * GeometryCollection No sabremos si queremos una l?nea o un
194
                         * pol?gono..... if (geometry instanceof GeometryCollection) {
195
                         * return toShape((GeometryCollection) geometry); }
196
                         */
197
                        return shpNew;
198
                } catch (NoninvertibleTransformException e) {
199
                        // TODO Auto-generated catch block
200
                        e.printStackTrace();
201
                }
202

    
203
                return null;
204

    
205
                //
206
                // FShape shape = Converter.jts_to_java2d(jtsGeometry);
207
                // return factory.createGeometry(shape);
208
        }
209

    
210
        /**
211
         * Convierte un MultiPoint2D a un MultiPoint de JTS
212
         * 
213
         * @param geom
214
         * @return
215
         */
216
        public com.vividsolutions.jts.geom.Geometry geometryToJts(MultiPoint geom) {
217
                Coordinate[] theGeoms = new Coordinate[geom.getPrimitivesNumber()];
218
                for (int i = 0; i < theGeoms.length; i++) {
219
                        java.awt.geom.Point2D p = geom.getPrimitiveAt(i).getHandlers(
220
                                        Geometry.SELECTHANDLER)[0].getPoint();
221
                        Coordinate c = new Coordinate(p.getX(), p.getY());
222
                        theGeoms[i] = c;
223
                }
224
                com.vividsolutions.jts.geom.MultiPoint geomCol = new com.vividsolutions.jts.geom.GeometryFactory()
225
                                .createMultiPoint(theGeoms);
226
                return geomCol;
227
        }
228

    
229
        /**
230
         * Convierte una MultiCurve2D en una MultiLineString de JTS
231
         * 
232
         * @param geom
233
         * @return
234
         */
235
        public static com.vividsolutions.jts.geom.Geometry geometryToJts(
236
                        MultiCurve geom) {
237
                LineString[] lines = new LineString[geom.getPrimitivesNumber()];
238
                for (int i = 0; i < lines.length; i++) {
239
                        lines[i] = (LineString) geometryToJts((geom.getPrimitiveAt(i)));
240
                }
241
                return new com.vividsolutions.jts.geom.GeometryFactory()
242
                                .createMultiLineString(lines);
243
        }
244

    
245
        /**
246
         * Convierte una MultiSurface2D en un MultiPolygon de JTS
247
         * 
248
         * @return
249
         */
250
        public com.vividsolutions.jts.geom.Geometry geometryToJts(MultiSurface geom) {
251
                Polygon[] polygons = new Polygon[geom.getPrimitivesNumber()];
252
                for (int i = 0; i < polygons.length; i++) {
253
                        polygons[i] = (Polygon) geometryToJts((geom.getPrimitiveAt(i)));
254
                }
255
                return new com.vividsolutions.jts.geom.GeometryFactory()
256
                                .createMultiPolygon(polygons);
257
        }
258

    
259
        /**
260
         * Convierte una BaseMultiPrimitive en una GeometryCollection de JTS
261
         * 
262
         * @return
263
         */
264
        public com.vividsolutions.jts.geom.Geometry geometryToJts(
265
                        MultiPrimitive geom) {
266
                com.vividsolutions.jts.geom.Geometry[] geometriesAux = new LineString[geom
267
                                .getPrimitivesNumber()];
268
                for (int i = 0; i < geometriesAux.length; i++) {
269
                        geometriesAux[i] = geometryToJts((geom.getPrimitiveAt(i)));
270
                }
271
                return new com.vividsolutions.jts.geom.GeometryFactory()
272
                                .createGeometryCollection(geometriesAux);
273
        }
274

    
275
        public static com.vividsolutions.jts.geom.Geometry geometryToJtsWithSRID(
276
                        Geometry geom, int srid) {
277
                // logger.debug(geom.getClass());
278
                // logger.debug(new Integer(geom.getShapeType()));
279
                return geometryToJts(geom, geom.getType(), srid);
280
        }
281

    
282
        public static com.vividsolutions.jts.geom.Geometry geometryToJts(
283
                        Geometry geom) {
284
                // logger.debug(geom.getClass());
285
                // logger.debug(new Integer(geom.getShapeType()));
286
                return geometryToJts(geom, geom.getType(), -1);
287
        }
288

    
289
        // public static com.vividsolutions.jts.geom.Geometry java2d_to_jts(FShape
290
        // shp) {
291
        // return java2d_to_jts(shp, shp.getShapeType());
292
        // }
293

    
294
        private static boolean isClosed(Coordinate firstCoordinate,
295
                        Coordinate lastCoordinate) {
296
                double diff = Math.abs(lastCoordinate.x - firstCoordinate.x);
297
                if (diff > 0.000001) {
298
                        return false;
299
                }
300
                diff = Math.abs(lastCoordinate.y - firstCoordinate.y);
301
                if (diff > 0.000001) {
302
                        return false;
303
                }
304
                return true;
305
        }
306

    
307
        /**
308
         * Convierte un FShape a una Geometry del JTS. Para ello, utilizamos un
309
         * "flattened PathIterator". El flattened indica que las curvas las pasa a
310
         * segmentos de l?nea recta AUTOMATICAMENTE!!!.
311
         * 
312
         * @param shp
313
         *            FShape que se quiere convertir.
314
         * 
315
         * @return Geometry de JTS.
316
         */
317
        private static com.vividsolutions.jts.geom.Geometry geometryToJts(
318
                        Geometry shp, int shapeType, int srid) {
319

    
320
                com.vividsolutions.jts.geom.Geometry geoJTS = null;
321
                Coordinate coord;
322
                // Coordinate[] coords;
323
                ArrayList arrayCoords = null;
324
                ArrayList arrayLines;
325
                LineString lin;
326
                // LinearRing linRing;
327
                // LinearRing linRingExt = null;
328
                int theType;
329
                int numParts = 0;
330

    
331
                // Use this array to store segment coordinate data
332
                double[] theData = new double[6];
333
                PathIterator theIterator;
334

    
335
                // logger.debug(shp.toString());
336

    
337
                switch (shapeType) {
338
                case Geometry.TYPES.POINT:
339
                        org.gvsig.fmap.geom.primitive.impl.Point2D p = (org.gvsig.fmap.geom.primitive.impl.Point2D) shp;
340
                        coord = new Coordinate(p.getX(), p.getY());
341
                        geoJTS = geomFactory.createPoint(coord);
342
                        geoJTS.setSRID(srid);
343

    
344
                        break;
345

    
346
                case Geometry.TYPES.MULTIPOINT:
347
                        org.gvsig.fmap.geom.aggregate.impl.MultiPoint2D mp = (org.gvsig.fmap.geom.aggregate.impl.MultiPoint2D) shp;
348
                        int numPoints = mp.getPrimitivesNumber();
349
                        Coordinate[] coordinates = new Coordinate[numPoints];
350
                        for (int i = 0; i < numPoints; i++) {
351
                                p = mp.getPoint(i);
352
                                coordinates[i] = new Coordinate(p.getX(), p.getY());
353
                        }
354
                        geoJTS = geomFactory.createMultiPoint(coordinates);
355
                        geoJTS.setSRID(srid);
356

    
357
                        break;
358

    
359
                case Geometry.TYPES.CURVE:
360
                case Geometry.TYPES.ARC:
361
                case Geometry.TYPES.SPLINE:
362
                        arrayLines = new ArrayList();
363
                        theIterator = shp.getPathIterator(null, manager.getFlatness());
364

    
365
                        while (!theIterator.isDone()) {
366
                                // while not done
367
                                theType = theIterator.currentSegment(theData);
368

    
369
                                // Populate a segment of the new
370
                                // GeneralPathX object.
371
                                // Process the current segment to populate a new
372
                                // segment of the new GeneralPathX object.
373
                                switch (theType) {
374
                                case PathIterator.SEG_MOVETO:
375

    
376
                                        // System.out.println("SEG_MOVETO");
377
                                        if (arrayCoords == null) {
378
                                                arrayCoords = new ArrayList();
379
                                        } else {
380
                                                lin = geomFactory.createLineString(CoordinateArrays
381
                                                                .toCoordinateArray(arrayCoords));
382
                                                lin.setSRID(srid);
383
                                                arrayLines.add(lin);
384
                                                arrayCoords = new ArrayList();
385
                                        }
386

    
387
                                        numParts++;
388
                                        coord = new Coordinate(theData[0], theData[1]);
389

    
390
                                        arrayCoords.add(coord);
391

    
392
                                        break;
393

    
394
                                case PathIterator.SEG_LINETO:
395

    
396
                                        // System.out.println("SEG_LINETO");
397
                                        arrayCoords.add(new Coordinate(theData[0], theData[1]));
398

    
399
                                        break;
400

    
401
                                case PathIterator.SEG_QUADTO:
402
                                        System.out.println("Not supported here");
403

    
404
                                        break;
405

    
406
                                case PathIterator.SEG_CUBICTO:
407
                                        System.out.println("Not supported here");
408

    
409
                                        break;
410

    
411
                                case PathIterator.SEG_CLOSE:
412
                                        // A?adimos el primer punto para cerrar.
413
                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
414
                                        // Solo anyadimos cuando no esta ya cerrado
415
                                        arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y));
416

    
417
                                        break;
418
                                } // end switch
419

    
420
                                theIterator.next();
421
                        } // end while loop
422

    
423
                        if (arrayCoords.size() < 2) {
424
                                break;
425
                        }
426
                        lin = new com.vividsolutions.jts.geom.GeometryFactory()
427
                                        .createLineString(CoordinateArrays
428
                                                        .toCoordinateArray(arrayCoords));
429

    
430
                        lin.setSRID(srid);
431
                        // CAMBIO: ENTREGAMOS SIEMPRE MULTILINESTRING, QUE ES
432
                        // LO QUE HACE TODO EL MUNDO CUANDO ESCRIBE EN POSTGIS
433
                        // O CON GEOTOOLS
434
                        // if (numParts > 1) // Generamos una MultiLineString
435
                        // {
436
                        arrayLines.add(lin);
437
                        geoJTS = geomFactory
438
                                        .createMultiLineString(com.vividsolutions.jts.geom.GeometryFactory
439
                                                        .toLineStringArray(arrayLines));
440
                        geoJTS.setSRID(srid);
441
                        /*
442
                         * } else { geoJTS = lin; }
443
                         */
444

    
445
                        break;
446

    
447
                case Geometry.TYPES.SURFACE:
448
                case Geometry.TYPES.CIRCLE:
449
                case Geometry.TYPES.ELLIPSE:
450
                        arrayLines = new ArrayList();
451

    
452
                        ArrayList shells = new ArrayList();
453
                        ArrayList holes = new ArrayList();
454
                        Coordinate[] points = null;
455

    
456
                        theIterator = shp.getPathIterator(null, manager.getFlatness());
457

    
458
                        while (!theIterator.isDone()) {
459
                                // while not done
460
                                theType = theIterator.currentSegment(theData);
461

    
462
                                // Populate a segment of the new
463
                                // GeneralPathX object.
464
                                // Process the current segment to populate a new
465
                                // segment of the new GeneralPathX object.
466
                                switch (theType) {
467
                                case PathIterator.SEG_MOVETO:
468

    
469
                                        // System.out.println("SEG_MOVETO");
470
                                        if (arrayCoords == null) {
471
                                                arrayCoords = new ArrayList();
472
                                        } else {
473
                                                points = CoordinateArrays
474
                                                                .toCoordinateArray(arrayCoords);
475

    
476
                                                try {
477
                                                        LinearRing ring = geomFactory
478
                                                                        .createLinearRing(points);
479

    
480
                                                        if (CGAlgorithms.isCCW(points)) {
481
                                                                holes.add(ring);
482
                                                        } else {
483
                                                                shells.add(ring);
484
                                                        }
485
                                                } catch (Exception e) {
486
                                                        /*
487
                                                         * (jaume) caso cuando todos los puntos son iguales
488
                                                         * devuelvo el propio punto
489
                                                         */
490
                                                        boolean same = true;
491
                                                        for (int i = 0; i < points.length - 1 && same; i++) {
492
                                                                if (points[i].x != points[i + 1].x
493
                                                                                || points[i].y != points[i + 1].y /*
494
                                                                                                                                                 * ||
495
                                                                                                                                                 * points
496
                                                                                                                                                 * [i].z
497
                                                                                                                                                 * !=
498
                                                                                                                                                 * points
499
                                                                                                                                                 * [
500
                                                                                                                                                 * i+1].
501
                                                                                                                                                 * z
502
                                                                                                                                                 */
503
                                                                ) {
504
                                                                        same = false;
505
                                                                }
506
                                                        }
507
                                                        if (same) {
508
                                                                return geomFactory.createPoint(points[0]);
509
                                                        }
510
                                                        /*
511
                                                         * caso cuando es una l?nea de 3 puntos, no creo
512
                                                         * un LinearRing, sino una linea
513
                                                         */
514
                                                        if (points.length > 1 && points.length <= 3) {
515
                                                                // return geomFactory.createLineString(points);
516
                                                                return geomFactory
517
                                                                                .createMultiLineString(new LineString[] { geomFactory
518
                                                                                                .createLineString(points) });
519
                                                        }
520

    
521
                                                        System.err
522
                                                                        .println("Caught Topology exception in GMLLinearRingHandler");
523

    
524
                                                        return null;
525
                                                }
526

    
527
                                                /*
528
                                                 * if (numParts == 1) { linRingExt = new
529
                                                 * GeometryFactory().createLinearRing(
530
                                                 * CoordinateArrays.toCoordinateArray(arrayCoords)); }
531
                                                 * else { linRing = new
532
                                                 * GeometryFactory().createLinearRing(
533
                                                 * CoordinateArrays.toCoordinateArray(arrayCoords));
534
                                                 * arrayLines.add(linRing); }
535
                                                 */
536
                                                arrayCoords = new ArrayList();
537
                                        }
538

    
539
                                        numParts++;
540
                                        arrayCoords.add(new Coordinate(theData[0], theData[1]));
541

    
542
                                        break;
543

    
544
                                case PathIterator.SEG_LINETO:
545

    
546
                                        // System.out.println("SEG_LINETO");
547
                                        arrayCoords.add(new Coordinate(theData[0], theData[1]));
548

    
549
                                        break;
550

    
551
                                case PathIterator.SEG_QUADTO:
552
                                        System.out.println("SEG_QUADTO Not supported here");
553

    
554
                                        break;
555

    
556
                                case PathIterator.SEG_CUBICTO:
557
                                        System.out.println("SEG_CUBICTO Not supported here");
558

    
559
                                        break;
560

    
561
                                case PathIterator.SEG_CLOSE:
562

    
563
                                        // A?adimos el primer punto para cerrar.
564
                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
565
                                        arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y));
566

    
567
                                        break;
568
                                } // end switch
569

    
570
                                // System.out.println("theData[0] = " + theData[0] +
571
                                // " theData[1]=" + theData[1]);
572
                                theIterator.next();
573
                        } // end while loop
574

    
575
                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
576
                        Coordinate lastCoord = (Coordinate) arrayCoords.get(arrayCoords
577
                                        .size() - 1);
578
                        if (!isClosed(firstCoord, lastCoord)) {
579
                                arrayCoords.add(firstCoord);
580
                        }
581
                        points = CoordinateArrays.toCoordinateArray(arrayCoords);
582

    
583
                        try {
584
                                LinearRing ring = geomFactory.createLinearRing(points);
585

    
586
                                if (CGAlgorithms.isCCW(points)) {
587
                                        holes.add(ring);
588
                                } else {
589
                                        shells.add(ring);
590
                                }
591
                                ring.setSRID(srid);
592
                        } catch (Exception e) {
593
                                /*
594
                                 * (jaume) caso cuando todos los puntos son iguales devuelvo el
595
                                 * propio punto
596
                                 */
597
                                boolean same = true;
598
                                for (int i = 0; i < points.length - 1 && same; i++) {
599
                                        if (points[i].x != points[i + 1].x
600
                                                        || points[i].y != points[i + 1].y /*
601
                                                                                                                         * || points[i].z !=
602
                                                                                                                         * points[i+1].z
603
                                                                                                                         */
604
                                        ) {
605
                                                same = false;
606
                                        }
607
                                }
608
                                if (same) {
609
                                        geoJTS = geomFactory.createPoint(points[0]);
610
                                        geoJTS.setSRID(srid);
611
                                        return geoJTS;
612
                                }
613
                                /*
614
                                 * caso cuando es una l?nea de 3 puntos, no creo un
615
                                 * LinearRing, sino una linea
616
                                 */
617
                                if (points.length > 1 && points.length <= 3) {
618
                                        // return geomFactory.createLineString(points);
619
                                        geoJTS = geomFactory
620
                                                        .createMultiLineString(new LineString[] { geomFactory
621
                                                                        .createLineString(points) });
622
                                        geoJTS.setSRID(srid);
623
                                        return geoJTS;
624
                                }
625
                                System.err
626
                                                .println("Caught Topology exception in GMLLinearRingHandler");
627

    
628
                                return null;
629
                        }
630

    
631
                        /*
632
                         * linRing = new GeometryFactory().createLinearRing(
633
                         * CoordinateArrays.toCoordinateArray(arrayCoords));
634
                         */
635

    
636
                        // System.out.println("NumParts = " + numParts);
637
                        // now we have a list of all shells and all holes
638
                        ArrayList holesForShells = new ArrayList(shells.size());
639

    
640
                        for (int i = 0; i < shells.size(); i++) {
641
                                holesForShells.add(new ArrayList());
642
                        }
643

    
644
                        // find homes
645
                        for (int i = 0; i < holes.size(); i++) {
646
                                LinearRing testRing = (LinearRing) holes.get(i);
647
                                LinearRing minShell = null;
648
                                Envelope minEnv = null;
649
                                Envelope testEnv = testRing.getEnvelopeInternal();
650
                                Coordinate testPt = testRing.getCoordinateN(0);
651
                                LinearRing tryRing = null;
652

    
653
                                for (int j = 0; j < shells.size(); j++) {
654
                                        tryRing = (LinearRing) shells.get(j);
655

    
656
                                        Envelope tryEnv = tryRing.getEnvelopeInternal();
657

    
658
                                        if (minShell != null) {
659
                                                minEnv = minShell.getEnvelopeInternal();
660
                                        }
661

    
662
                                        boolean isContained = false;
663
                                        Coordinate[] coordList = tryRing.getCoordinates();
664

    
665
                                        if (tryEnv.contains(testEnv)
666
                                                        && (CGAlgorithms.isPointInRing(testPt, coordList) || (pointInList(
667
                                                                        testPt, coordList)))) {
668
                                                isContained = true;
669
                                        }
670

    
671
                                        // check if this new containing ring is smaller than the
672
                                        // current minimum ring
673
                                        if (isContained) {
674
                                                if ((minShell == null) || minEnv.contains(tryEnv)) {
675
                                                        minShell = tryRing;
676
                                                }
677
                                        }
678
                                }
679

    
680
                                if (minShell == null) {
681
                                        // System.out.println(
682
                                        // "polygon found with a hole thats not inside a shell");
683
                                        // azabala: we do the assumption that this hole is really a
684
                                        // shell (polygon)
685
                                        // whose point werent digitized in the right order
686
                                        Coordinate[] cs = testRing.getCoordinates();
687
                                        Coordinate[] reversed = new Coordinate[cs.length];
688
                                        int pointIndex = 0;
689
                                        for (int z = cs.length - 1; z >= 0; z--) {
690
                                                reversed[pointIndex] = cs[z];
691
                                                pointIndex++;
692
                                        }
693
                                        LinearRing newRing = geomFactory.createLinearRing(reversed);
694
                                        shells.add(newRing);
695
                                        holesForShells.add(new ArrayList());
696
                                } else {
697
                                        ((ArrayList) holesForShells.get(shells.indexOf(minShell)))
698
                                                        .add(testRing);
699
                                }
700
                        }
701

    
702
                        Polygon[] polygons = new Polygon[shells.size()];
703

    
704
                        for (int i = 0; i < shells.size(); i++) {
705
                                polygons[i] = geomFactory.createPolygon((LinearRing) shells
706
                                                .get(i), (LinearRing[]) ((ArrayList) holesForShells
707
                                                .get(i)).toArray(new LinearRing[0]));
708
                                polygons[i].setSRID(srid);
709
                        }
710
                        // CAMBIO: ENTREGAMOS SIEMPRE MULTILINESTRING, QUE ES
711
                        // LO QUE HACE TODO EL MUNDO CUANDO ESCRIBE EN POSTGIS
712
                        // O CON GEOTOOLS
713
                        // if (numParts > 1) // Generamos una MultiLineString
714

    
715
                        /*
716
                         * if (polygons.length == 1) { return polygons[0]; }
717
                         */
718

    
719
                        // FIN CAMBIO
720

    
721
                        holesForShells = null;
722
                        shells = null;
723
                        holes = null;
724

    
725
                        if (polygons.length == 1) {
726
                                geoJTS = polygons[0];
727
                        } else {
728
                                // its a multi part
729
                                geoJTS = geomFactory.createMultiPolygon(polygons);
730
                        }
731
                        geoJTS.setSRID(srid);
732

    
733
                        /*
734
                         * if (numParts > 1) // Generamos un Polygon con agujeros {
735
                         * arrayLines.add(linRing); // geoJTS = new
736
                         * GeometryFactory().createPolygon(linRingExt, //
737
                         * GeometryFactory.toLinearRingArray(arrayLines)); geoJTS = new
738
                         * GeometryFactory().buildGeometry(arrayLines);
739
                         * 
740
                         * // geoJTS = Polygonizer.class. } else { geoJTS = new
741
                         * GeometryFactory().createPolygon(linRing,null); }
742
                         */
743
                        break;
744
                }
745

    
746
                geoJTS.setSRID(srid);
747
                return geoJTS;
748
        }
749

    
750
        /**
751
         * Converts JTS Geometry objects into Java 2D Shape objects
752
         * 
753
         * @param geo
754
         *            Geometry de JTS.
755
         * 
756
         * @return FShape.
757
         */
758
        // public static FShape jts_to_java2d(com.vividsolutions.jts.geom.Geometry
759
        // geo) {
760
        // FShape shpNew = null;
761
        //
762
        // try {
763
        // if (geo instanceof Point) {
764
        // shpNew = new org.gvsig.fmap.geom.primitive.Point2D(null, null, ((Point)
765
        // geo).getX(), ((Point) geo).getY());
766
        // }
767
        //
768
        // if (geo.isEmpty()) {
769
        // shpNew = null;
770
        // }
771
        //
772
        // if (geo instanceof Polygon) {
773
        // shpNew = new Surface2D(null, null, toShape((Polygon) geo));
774
        // }
775
        //
776
        // if (geo instanceof MultiPolygon) {
777
        // shpNew = new Surface2D(null, null, toShape((MultiPolygon) geo));
778
        // }
779
        //
780
        // if (geo instanceof LineString) {
781
        // shpNew = new Curve2D(null, null, toShape((LineString) geo));
782
        // }
783
        //
784
        // if (geo instanceof MultiLineString) {
785
        // shpNew = new Curve2D(null, null, toShape((MultiLineString) geo));
786
        // }
787
        //
788
        // /* OJO: CON ALGO COMO FSHAPE NO S? C?MO PODEMOS IMPLEMENTAR UN
789
        // GeometryCollection
790
        // * No sabremos si queremos una l?nea o un pol?gono.....
791
        // * if (geometry instanceof GeometryCollection) {
792
        // return toShape((GeometryCollection) geometry);
793
        // } */
794
        // return shpNew;
795
        // } catch (NoninvertibleTransformException e) {
796
        // // TODO Auto-generated catch block
797
        // e.printStackTrace();
798
        // }
799
        //
800
        // return null;
801
        // }
802

    
803
        /**
804
         * DOCUMENT ME!
805
         * 
806
         * @param p
807
         *            DOCUMENT ME!
808
         * 
809
         * @return DOCUMENT ME!
810
         */
811
        private static GeneralPathX toShape(Polygon p) {
812
                GeneralPathX resul = new GeneralPathX();
813
                Coordinate coord;
814

    
815
                for (int i = 0; i < p.getExteriorRing().getNumPoints(); i++) {
816
                        coord = p.getExteriorRing().getCoordinateN(i);
817

    
818
                        if (i == 0) {
819
                                resul.moveTo(coord.x, coord.y);
820
                        } else {
821
                                resul.lineTo(coord.x, coord.y);
822
                        }
823
                }
824

    
825
                for (int j = 0; j < p.getNumInteriorRing(); j++) {
826
                        LineString hole = p.getInteriorRingN(j);
827

    
828
                        for (int k = 0; k < hole.getNumPoints(); k++) {
829
                                coord = hole.getCoordinateN(k);
830

    
831
                                if (k == 0) {
832
                                        resul.moveTo(coord.x, coord.y);
833
                                } else {
834
                                        resul.lineTo(coord.x, coord.y);
835
                                }
836
                        }
837
                }
838

    
839
                return resul;
840
        }
841

    
842
        /**
843
         * DOCUMENT ME!
844
         * 
845
         * @param modelCoordinates
846
         *            DOCUMENT ME!
847
         * 
848
         * @return DOCUMENT ME!
849
         * 
850
         * @throws NoninvertibleTransformException
851
         *             DOCUMENT ME!
852
         * 
853
         *             private Coordinate[] toViewCoordinates(Coordinate[]
854
         *             modelCoordinates) throws NoninvertibleTransformException {
855
         *             Coordinate[] viewCoordinates = new
856
         *             Coordinate[modelCoordinates.length];
857
         * 
858
         *             for (int i = 0; i < modelCoordinates.length; i++) { FPoint2D
859
         *             point2D = coordinate2FPoint2D(modelCoordinates[i]);
860
         *             viewCoordinates[i] = new Coordinate(point2D.getX(),
861
         *             point2D.getY()); }
862
         * 
863
         *             return viewCoordinates; }
864
         * @throws CreateGeometryException
865
         */
866

    
867
        /*
868
         * private Shape toShape(GeometryCollection gc) throws
869
         * NoninvertibleTransformException { GeometryCollectionShape shape = new
870
         * GeometryCollectionShape(); for (int i = 0; i < gc.getNumGeometries();
871
         * i++) { Geometry g = (Geometry) gc.getGeometryN(i); shape.add(toShape(g));
872
         * } return shape; }
873
         */
874
        private static GeneralPathX toShape(MultiLineString mls)
875
                        throws NoninvertibleTransformException, CreateGeometryException {
876
                GeneralPathX path = new GeneralPathX();
877

    
878
                for (int i = 0; i < mls.getNumGeometries(); i++) {
879
                        LineString lineString = (LineString) mls.getGeometryN(i);
880
                        path.append(toShape(lineString).getPathIterator(null), false);
881
                }
882

    
883
                // BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
884
                // converted to GeneralPathXs. [Jon Aquino]
885
                return path;
886
        }
887

    
888
        /**
889
         * DOCUMENT ME!
890
         * 
891
         * @param lineString
892
         *            DOCUMENT ME!
893
         * 
894
         * @return DOCUMENT ME!
895
         * 
896
         * @throws NoninvertibleTransformException
897
         *             DOCUMENT ME!
898
         * @throws CreateGeometryException
899
         */
900
        private static GeneralPathX toShape(LineString lineString)
901
                        throws NoninvertibleTransformException, CreateGeometryException {
902
                GeneralPathX shape = new GeneralPathX();
903
                org.gvsig.fmap.geom.primitive.Point viewPoint = coordinate2FPoint2D(lineString
904
                                .getCoordinateN(0));
905
                shape.moveTo(viewPoint.getX(), viewPoint.getY());
906

    
907
                for (int i = 1; i < lineString.getNumPoints(); i++) {
908
                        viewPoint = coordinate2FPoint2D(lineString.getCoordinateN(i));
909
                        shape.lineTo(viewPoint.getX(), viewPoint.getY());
910
                }
911

    
912
                // BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
913
                // converted to GeneralPathXs. [Jon Aquino]
914
                return shape;
915
        }
916

    
917
        /*
918
         * TODO No se usa DOCUMENT ME!
919
         * 
920
         * @param point DOCUMENT ME!
921
         * 
922
         * @return DOCUMENT ME!
923
         * 
924
         * @throws NoninvertibleTransformException DOCUMENT ME!
925
         * 
926
         * private static Point2D toShape(Point point) throws
927
         * NoninvertibleTransformException { Point2D viewPoint =
928
         * coordinate2FPoint2D(point.getCoordinate());
929
         * 
930
         * return viewPoint; }
931
         */
932

    
933
        /**
934
         *
935
         */
936
        private static GeneralPathX toShape(MultiPolygon mp)
937
                        throws NoninvertibleTransformException {
938
                GeneralPathX path = new GeneralPathX();
939

    
940
                for (int i = 0; i < mp.getNumGeometries(); i++) {
941
                        Polygon polygon = (Polygon) mp.getGeometryN(i);
942
                        path.append(toShape(polygon).getPathIterator(null), false);
943
                }
944

    
945
                // BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
946
                // converted to GeneralPathXs. [Jon Aquino]
947
                return path;
948
        }
949

    
950
        /**
951
         * DOCUMENT ME!
952
         * 
953
         * @param coord
954
         *            DOCUMENT ME!
955
         * 
956
         * @return DOCUMENT ME!
957
         * @throws CreateGeometryException
958
         */
959
        public static org.gvsig.fmap.geom.primitive.Point coordinate2FPoint2D(
960
                        Coordinate coord) throws CreateGeometryException {
961
                return geomManager.createPoint(coord.x, coord.y, SUBTYPES.GEOM2D); // ,coord.z);
962
        }
963

    
964
        /**
965
         * Convierte una Geometry de JTS a GeneralPathX.
966
         * 
967
         * @param geometry
968
         *            Geometry a convertir.
969
         * 
970
         * @return GeneralPathX.
971
         * 
972
         * @throws NoninvertibleTransformException
973
         * @throws CreateGeometryException
974
         * @throws IllegalArgumentException
975
         */
976
        public static GeneralPathX toShape(
977
                        com.vividsolutions.jts.geom.Geometry geometry)
978
                        throws NoninvertibleTransformException, CreateGeometryException {
979
                if (geometry.isEmpty()) {
980
                        return new GeneralPathX();
981
                }
982

    
983
                if (geometry instanceof Polygon) {
984
                        return toShape((Polygon) geometry);
985
                }
986

    
987
                if (geometry instanceof MultiPolygon) {
988
                        return toShape((MultiPolygon) geometry);
989
                }
990

    
991
                if (geometry instanceof LineString) {
992
                        return toShape((LineString) geometry);
993
                }
994

    
995
                if (geometry instanceof MultiLineString) {
996
                        return toShape((MultiLineString) geometry);
997
                }
998

    
999
                if (geometry instanceof GeometryCollection) {
1000
                        return toShape(geometry);
1001
                }
1002

    
1003
                throw new IllegalArgumentException("Unrecognized Geometry class: "
1004
                                + geometry.getClass());
1005
        }
1006

    
1007
        public static GeneralPathX transformToInts(GeneralPathX gp,
1008
                        AffineTransform at) {
1009
                GeneralPathX newGp = new GeneralPathX();
1010
                PathIterator theIterator;
1011
                int theType;
1012
                int numParts = 0;
1013
                double[] theData = new double[6];
1014
                java.awt.geom.Point2D ptDst = new java.awt.geom.Point2D.Double();
1015
                java.awt.geom.Point2D ptSrc = new java.awt.geom.Point2D.Double();
1016
                boolean bFirst = true;
1017
                int xInt, yInt, antX = -1, antY = -1;
1018

    
1019
                theIterator = gp.getPathIterator(null); // , flatness);
1020

    
1021
                while (!theIterator.isDone()) {
1022
                        theType = theIterator.currentSegment(theData);
1023
                        switch (theType) {
1024
                        case PathIterator.SEG_MOVETO:
1025
                                numParts++;
1026
                                ptSrc.setLocation(theData[0], theData[1]);
1027
                                at.transform(ptSrc, ptDst);
1028
                                antX = (int) ptDst.getX();
1029
                                antY = (int) ptDst.getY();
1030
                                newGp.moveTo(antX, antY);
1031
                                bFirst = true;
1032
                                break;
1033

    
1034
                        case PathIterator.SEG_LINETO:
1035
                                ptSrc.setLocation(theData[0], theData[1]);
1036
                                at.transform(ptSrc, ptDst);
1037
                                xInt = (int) ptDst.getX();
1038
                                yInt = (int) ptDst.getY();
1039
                                if ((bFirst) || ((xInt != antX) || (yInt != antY))) {
1040
                                        newGp.lineTo(xInt, yInt);
1041
                                        antX = xInt;
1042
                                        antY = yInt;
1043
                                        bFirst = false;
1044
                                }
1045
                                break;
1046

    
1047
                        case PathIterator.SEG_QUADTO:
1048
                                System.out.println("Not supported here");
1049

    
1050
                                break;
1051

    
1052
                        case PathIterator.SEG_CUBICTO:
1053
                                System.out.println("Not supported here");
1054

    
1055
                                break;
1056

    
1057
                        case PathIterator.SEG_CLOSE:
1058
                                newGp.closePath();
1059

    
1060
                                break;
1061
                        } // end switch
1062

    
1063
                        theIterator.next();
1064
                } // end while loop
1065

    
1066
                return newGp;
1067
        }
1068

    
1069
        public static Geometry transformToInts(Geometry gp, AffineTransform at)
1070
                        throws CreateGeometryException {
1071
                GeneralPathX newGp = new GeneralPathX();
1072
                double[] theData = new double[6];
1073
                double[] aux = new double[6];
1074

    
1075
                // newGp.reset();
1076
                PathIterator theIterator;
1077
                int theType;
1078
                int numParts = 0;
1079

    
1080
                java.awt.geom.Point2D ptDst = new java.awt.geom.Point2D.Double();
1081
                java.awt.geom.Point2D ptSrc = new java.awt.geom.Point2D.Double();
1082
                boolean bFirst = true;
1083
                int xInt, yInt, antX = -1, antY = -1;
1084

    
1085
                theIterator = gp.getPathIterator(null); // , flatness);
1086
                int numSegmentsAdded = 0;
1087
                while (!theIterator.isDone()) {
1088
                        theType = theIterator.currentSegment(theData);
1089

    
1090
                        switch (theType) {
1091
                        case PathIterator.SEG_MOVETO:
1092
                                numParts++;
1093
                                ptSrc.setLocation(theData[0], theData[1]);
1094
                                at.transform(ptSrc, ptDst);
1095
                                antX = (int) ptDst.getX();
1096
                                antY = (int) ptDst.getY();
1097
                                newGp.moveTo(antX, antY);
1098
                                numSegmentsAdded++;
1099
                                bFirst = true;
1100
                                break;
1101

    
1102
                        case PathIterator.SEG_LINETO:
1103
                                ptSrc.setLocation(theData[0], theData[1]);
1104
                                at.transform(ptSrc, ptDst);
1105
                                xInt = (int) ptDst.getX();
1106
                                yInt = (int) ptDst.getY();
1107
                                if ((bFirst) || ((xInt != antX) || (yInt != antY))) {
1108
                                        newGp.lineTo(xInt, yInt);
1109
                                        antX = xInt;
1110
                                        antY = yInt;
1111
                                        bFirst = false;
1112
                                        numSegmentsAdded++;
1113
                                }
1114
                                break;
1115

    
1116
                        case PathIterator.SEG_QUADTO:
1117
                                at.transform(theData, 0, aux, 0, 2);
1118
                                newGp.quadTo(aux[0], aux[1], aux[2], aux[3]);
1119
                                numSegmentsAdded++;
1120
                                break;
1121

    
1122
                        case PathIterator.SEG_CUBICTO:
1123
                                at.transform(theData, 0, aux, 0, 3);
1124
                                newGp.curveTo(aux[0], aux[1], aux[2], aux[3], aux[4], aux[5]);
1125
                                numSegmentsAdded++;
1126
                                break;
1127

    
1128
                        case PathIterator.SEG_CLOSE:
1129
                                if (numSegmentsAdded < 3) {
1130
                                        newGp.lineTo(antX, antY);
1131
                                }
1132
                                newGp.closePath();
1133

    
1134
                                break;
1135
                        } // end switch
1136

    
1137
                        theIterator.next();
1138
                } // end while loop
1139

    
1140
                Geometry shp = null;
1141
                switch (gp.getType()) {
1142
                case Geometry.TYPES.POINT:
1143
                        shp = geomManager.createPoint(ptDst.getX(), ptDst.getY(),
1144
                                        SUBTYPES.GEOM2D);
1145
                        break;
1146

    
1147
                case Geometry.TYPES.CURVE:
1148
                case Geometry.TYPES.ARC:
1149
                        try {
1150
                                shp = geomManager.createCurve(newGp, SUBTYPES.GEOM2D);
1151
                        } catch (CreateGeometryException e1) {
1152
                                logger.error("Error creating a curve", e1);
1153
                        }
1154
                        break;
1155

    
1156
                case Geometry.TYPES.SURFACE:
1157
                case Geometry.TYPES.CIRCLE:
1158
                case Geometry.TYPES.ELLIPSE:
1159

    
1160
                        try {
1161
                                shp = geomManager.createSurface(newGp, SUBTYPES.GEOM2D);
1162
                        } catch (CreateGeometryException e) {
1163
                                logger.error("Error creating a surface", e);
1164
                        }
1165
                        break;
1166
                }
1167
                return shp;
1168
        }
1169

    
1170
        public static Rectangle2D convertEnvelopeToRectangle2D(Envelope jtsR) {
1171
                Rectangle2D.Double r = new Rectangle2D.Double(jtsR.getMinX(),
1172
                                jtsR.getMinY(), jtsR.getWidth(), jtsR.getHeight());
1173
                return r;
1174
        }
1175

    
1176
        public static Envelope convertEnvelopeToJTS(
1177
                        org.gvsig.fmap.geom.primitive.Envelope r) {
1178
                Envelope e = new Envelope(r.getMinimum(0), r.getMaximum(0),
1179
                                r.getMinimum(1), r.getMaximum(1));
1180
                return e;
1181
        }
1182

    
1183
        /**
1184
         * Return a correct polygon (no hole)
1185
         * 
1186
         * @param coordinates
1187
         * @return
1188
         */
1189
        public static Geometry getExteriorPolygon(Coordinate[] coordinates) {
1190
                // isCCW = true => it's a hole
1191
                Coordinate[] vs = new Coordinate[coordinates.length];
1192
                if (CGAlgorithms.isCCW(coordinates)) {
1193
                        for (int i = vs.length - 1; i >= 0; i--) {
1194
                                vs[i] = coordinates[i];
1195
                        }
1196
                } else {
1197
                        vs = coordinates;
1198
                }
1199
                LinearRing ring = geomFactory.createLinearRing(vs);
1200

    
1201
                try {
1202
                        Surface surface = (Surface) manager.create(TYPES.SURFACE,
1203
                                        SUBTYPES.GEOM2D);
1204
                        surface.setGeneralPath(toShape(ring));
1205
                        return surface;
1206
                } catch (NoninvertibleTransformException e) {
1207
                        e.printStackTrace();
1208
                } catch (CreateGeometryException e) {
1209
                        e.printStackTrace();
1210
                }
1211
                return null;
1212
        }
1213

    
1214
        public static boolean isCCW(Point[] points) {
1215
                int length = points.length;
1216
                Coordinate[] vs;
1217
                // CGAlgorithms.isCCW asume que la lista de puntos tienen el primer
1218
                // y el ultimo puntos iguales.... y que este algoritmo est? solo
1219
                // garantizado con anillos v?lidos.
1220
                if (points[0].getX() != points[length - 1].getX()
1221
                                || points[0].getY() != points[length - 1].getY()) {
1222
                        vs = new Coordinate[length + 1];
1223
                        vs[points.length] = new Coordinate(points[0].getX(),
1224
                                        points[0].getY());
1225
                } else {
1226
                        vs = new Coordinate[length];
1227
                }
1228
                for (int i = 0; i < length; i++) {
1229
                        vs[i] = new Coordinate(points[i].getX(), points[i].getY());
1230
                }
1231

    
1232
                return CGAlgorithms.isCCW(vs);
1233
        }
1234

    
1235
        public static boolean isCCW(Surface pol) {
1236
                com.vividsolutions.jts.geom.Geometry jtsGeom = Converter
1237
                                .geometryToJts(pol);
1238
                if (jtsGeom.getNumGeometries() == 1) {
1239
                        Coordinate[] coords = jtsGeom.getCoordinates();
1240
                        return CGAlgorithms.isCCW(coords);
1241
                }
1242
                return false;
1243

    
1244
        }
1245

    
1246
        /**
1247
         * Return a hole (CCW ordered points)
1248
         * 
1249
         * @param coordinates
1250
         * @return
1251
         */
1252
        public static Geometry getHole(Coordinate[] coordinates) {
1253
                // isCCW = true => it's a hole
1254
                Coordinate[] vs = new Coordinate[coordinates.length];
1255
                if (CGAlgorithms.isCCW(coordinates)) {
1256
                        vs = coordinates;
1257

    
1258
                } else {
1259
                        for (int i = vs.length - 1; i >= 0; i--) {
1260
                                vs[i] = coordinates[i];
1261
                        }
1262
                }
1263
                LinearRing ring = geomFactory.createLinearRing(vs);
1264

    
1265
                try {
1266
                        Surface surface = (Surface) manager.create(TYPES.SURFACE,
1267
                                        SUBTYPES.GEOM2D);
1268
                        surface.setGeneralPath(toShape(ring));
1269
                        return surface;
1270
                } catch (NoninvertibleTransformException e) {
1271
                        e.printStackTrace();
1272
                } catch (CreateGeometryException e) {
1273
                        e.printStackTrace();
1274
                }
1275
                return null;
1276
        }
1277

    
1278
        public static Shape getExteriorPolygon(GeneralPathX gp) {
1279
                Area area = new Area(gp);
1280
                area.isSingular();
1281
                return area;
1282

    
1283
        }
1284

    
1285
        /**
1286
         * Use it ONLY for NOT multipart polygons.
1287
         * 
1288
         * @param pol
1289
         * @return
1290
         */
1291
        public static Geometry getNotHolePolygon(Surface pol) {
1292
                // isCCW == true => hole
1293
                Coordinate[] coords;
1294
                ArrayList arrayCoords = null;
1295
                int theType;
1296
                int numParts = 0;
1297

    
1298
                // Use this array to store segment coordinate data
1299
                double[] theData = new double[6];
1300
                PathIterator theIterator;
1301

    
1302
                ArrayList shells = new ArrayList();
1303
                ArrayList holes = new ArrayList();
1304
                Coordinate[] points = null;
1305

    
1306
                theIterator = pol.getPathIterator(null, manager.getFlatness());
1307

    
1308
                while (!theIterator.isDone()) {
1309
                        // while not done
1310
                        theType = theIterator.currentSegment(theData);
1311

    
1312
                        // Populate a segment of the new
1313
                        // GeneralPathX object.
1314
                        // Process the current segment to populate a new
1315
                        // segment of the new GeneralPathX object.
1316
                        switch (theType) {
1317
                        case PathIterator.SEG_MOVETO:
1318

    
1319
                                // System.out.println("SEG_MOVETO");
1320
                                if (arrayCoords == null) {
1321
                                        arrayCoords = new ArrayList();
1322
                                } else {
1323
                                        points = CoordinateArrays.toCoordinateArray(arrayCoords);
1324

    
1325
                                        try {
1326
                                                LinearRing ring = geomFactory.createLinearRing(points);
1327

    
1328
                                                if (CGAlgorithms.isCCW(points)) {
1329
                                                        holes.add(ring);
1330
                                                } else {
1331
                                                        shells.add(ring);
1332
                                                }
1333
                                        } catch (Exception e) {
1334
                                                System.err
1335
                                                                .println("Caught Topology exception in GMLLinearRingHandler");
1336

    
1337
                                                return null;
1338
                                        }
1339

    
1340
                                        /*
1341
                                         * if (numParts == 1) { linRingExt = new
1342
                                         * GeometryFactory().createLinearRing(
1343
                                         * CoordinateArrays.toCoordinateArray(arrayCoords)); } else
1344
                                         * { linRing = new GeometryFactory().createLinearRing(
1345
                                         * CoordinateArrays.toCoordinateArray(arrayCoords));
1346
                                         * arrayLines.add(linRing); }
1347
                                         */
1348
                                        arrayCoords = new ArrayList();
1349
                                }
1350

    
1351
                                numParts++;
1352
                                arrayCoords.add(new Coordinate(theData[0], theData[1]));
1353

    
1354
                                break;
1355

    
1356
                        case PathIterator.SEG_LINETO:
1357

    
1358
                                // System.out.println("SEG_LINETO");
1359
                                arrayCoords.add(new Coordinate(theData[0], theData[1]));
1360

    
1361
                                break;
1362

    
1363
                        case PathIterator.SEG_QUADTO:
1364
                                System.out.println("SEG_QUADTO Not supported here");
1365

    
1366
                                break;
1367

    
1368
                        case PathIterator.SEG_CUBICTO:
1369
                                System.out.println("SEG_CUBICTO Not supported here");
1370

    
1371
                                break;
1372

    
1373
                        case PathIterator.SEG_CLOSE:
1374

    
1375
                                // A?adimos el primer punto para cerrar.
1376
                                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
1377
                                arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y));
1378

    
1379
                                break;
1380
                        } // end switch
1381

    
1382
                        // System.out.println("theData[0] = " + theData[0] + " theData[1]="
1383
                        // + theData[1]);
1384
                        theIterator.next();
1385
                } // end while loop
1386

    
1387
                arrayCoords.add(arrayCoords.get(0));
1388
                coords = CoordinateArrays.toCoordinateArray(arrayCoords);
1389

    
1390
                if (numParts == 1) {
1391
                        return getExteriorPolygon(coords);
1392
                }
1393
                return pol;
1394

    
1395
        }
1396

    
1397
        /*
1398
         * public static GeometryCollection
1399
         * convertFGeometryCollection(FGeometryCollection fGeomC) {
1400
         * 
1401
         * geomFactory.createGeometryCollection(theGeoms); }
1402
         */
1403
}