Statistics
| Revision:

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

History | View | Annotate | Download (44.4 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.Curve;
63
import org.gvsig.fmap.geom.primitive.GeneralPathX;
64
import org.gvsig.fmap.geom.primitive.Surface;
65
import org.slf4j.Logger;
66
import org.slf4j.LoggerFactory;
67

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

    
81
/**
82
 * Clase con varios metodos estaticos utilizados para pasar de java2d a jts
83
 * y viceversa.
84
 * 
85
 * @author fjp
86
 * @deprecated to be removed or moved from API to implementation in gvSIG 2.1.0
87
 */
88
public class Converter {
89
        private static final GeometryManager geomManager = GeometryLocator.getGeometryManager();
90
        private static final Logger logger = LoggerFactory.getLogger(Converter.class);
91
        public final static com.vividsolutions.jts.geom.GeometryFactory geomFactory = new com.vividsolutions.jts.geom.GeometryFactory();
92
        public static CGAlgorithms cga = new RobustCGAlgorithms();
93

    
94
        private static GeometryManager manager = GeometryLocator.getGeometryManager();
95

    
96
        //returns true if testPoint is a point in the pointList list.
97
        static boolean pointInList(Coordinate testPoint, Coordinate[] pointList) {
98
                int t;
99
                int numpoints;
100
                Coordinate p;
101

    
102
                numpoints = Array.getLength(pointList);
103

    
104
                for (t = 0; t < numpoints; t++) {
105
                        p = pointList[t];
106

    
107
                        if ((testPoint.x == p.x) && (testPoint.y == p.y) &&
108
                                        ((testPoint.z == p.z) || (!(testPoint.z == testPoint.z))) //nan test; x!=x iff x is nan
109
                        ) {
110
                                return true;
111
                        }
112
                }
113

    
114
                return false;
115
        }
116

    
117
        /**
118
         * Receives a JTS Geometry and returns a fmap IGeometry
119
         * @param jtsGeometry jts Geometry
120
         * @return IGeometry of FMap
121
         * @author azabala
122
         * @throws CreateGeometryException 
123
         */
124
        public static Geometry jtsToGeometry(com.vividsolutions.jts.geom.Geometry geo) throws CreateGeometryException{
125
                Geometry shpNew = null;
126

    
127
                try {
128
                        if (geo instanceof Point) {
129
                                shpNew = geomManager.createPoint(((Point) geo).getX(),((Point) geo).getY(), SUBTYPES.GEOM2D);
130
                        }
131

    
132
                        if (geo.isEmpty()) {
133
                                shpNew = null;
134
                        }
135

    
136
                        try{
137
                                if (geo instanceof com.vividsolutions.jts.geom.MultiPoint) {
138
                                        shpNew = geomManager.create(TYPES.MULTIPOINT, SUBTYPES.GEOM2D);
139
                                        for (int i = 0; i < geo.getNumGeometries(); i++) {
140
                                                Point point = (Point) geo.getGeometryN(i);
141
                                                ((MultiPoint)shpNew).addPoint((org.gvsig.fmap.geom.primitive.Point) jtsToGeometry(point));
142
                                        }
143
                                        
144
                                }
145
                                
146
                                if (geo instanceof Polygon) {
147
                                        shpNew = geomManager.createSurface(toShape((Polygon) geo), SUBTYPES.GEOM2D);
148
                                }
149

    
150
                                if (geo instanceof MultiPolygon) {
151
                                        shpNew = geomManager.createSurface(toShape((MultiPolygon) geo), SUBTYPES.GEOM2D);
152
                                }
153

    
154
                                if (geo instanceof LineString) {
155
                                        shpNew = geomManager.createCurve(toShape((LineString) geo), SUBTYPES.GEOM2D);
156
                                }
157

    
158
                                if (geo instanceof MultiLineString) {
159
                                        shpNew = geomManager.create(TYPES.MULTICURVE, SUBTYPES.GEOM2D);
160
                                        for (int i = 0; i < ((MultiLineString)geo).getNumGeometries(); i++) {
161
                                                com.vividsolutions.jts.geom.Geometry g = ((MultiLineString)geo).getGeometryN(i);
162
                                                Curve c = geomManager.createCurve(toShape((LineString) g), SUBTYPES.GEOM2D);
163
                                                ((MultiCurve)shpNew).addCurve(c);
164
                                        }
165
                                }
166
                        }catch(CreateGeometryException e){
167
                                logger.error("Error creating a geometry", e);
168
                        }
169

    
170
                        return shpNew;
171
                } catch (NoninvertibleTransformException e) {
172
                        // TODO Auto-generated catch block
173
                        e.printStackTrace();
174
                }
175

    
176
                return null;
177

    
178
                //
179
                //                FShape shape = Converter.jts_to_java2d(jtsGeometry);
180
                //                return factory.createGeometry(shape);
181
        }
182

    
183
        /**
184
         * Convierte un MultiPoint2D a un MultiPoint de JTS
185
         * @param geom
186
         * @return
187
         */
188
        public static com.vividsolutions.jts.geom.Geometry geometryToJts(MultiPoint geom) {
189
                Coordinate[] theGeoms = new Coordinate[geom.getPrimitivesNumber()];
190
                for (int i = 0; i < theGeoms.length; i++) {
191
                        java.awt.geom.Point2D p = geom.getPrimitiveAt(i)
192
                        .getHandlers(Geometry.SELECTHANDLER)[0].getPoint();
193
                        Coordinate c = new Coordinate(p.getX(), p.getY());
194
                        theGeoms[i] = c;
195
                }
196
                com.vividsolutions.jts.geom.MultiPoint geomCol = new com.vividsolutions.jts.geom.GeometryFactory()
197
                .createMultiPoint(theGeoms);
198
                return geomCol;
199
        }
200

    
201
        /**
202
         * Convierte una MultiCurve2D en una MultiLineString de JTS
203
         * @param geom
204
         * @return
205
         */
206
        public static com.vividsolutions.jts.geom.Geometry geometryToJts(MultiCurve geom) {
207
                LineString[] lines = new LineString[geom.getPrimitivesNumber()];
208
                for (int i = 0; i < lines.length; i++){
209
                        lines[i] = (LineString) geometryToJts((geom.getPrimitiveAt(i)));
210
                }
211
                return new com.vividsolutions.jts.geom.GeometryFactory().createMultiLineString(lines);
212
        }
213

    
214
        /**
215
         * Convierte una MultiSurface2D en un MultiPolygon de JTS
216
         * @return
217
         */
218
        public static com.vividsolutions.jts.geom.Geometry geometryToJts(MultiSurface geom) {
219
                Polygon[] polygons = new Polygon[geom.getPrimitivesNumber()];
220
                for (int i = 0; i < polygons.length; i++){
221
                        polygons[i] = (Polygon) geometryToJts((geom.getPrimitiveAt(i)));
222
                }
223
                return new com.vividsolutions.jts.geom.GeometryFactory().createMultiPolygon(polygons);
224
        }
225

    
226
        /**
227
         * Convierte una BaseMultiPrimitive en una GeometryCollection de JTS
228
         * @return
229
         */
230
        public com.vividsolutions.jts.geom.Geometry geometryToJts(MultiPrimitive geom) {
231
                com.vividsolutions.jts.geom.Geometry[] geometriesAux = new LineString[geom.getPrimitivesNumber()];
232
                for (int i = 0; i < geometriesAux.length; i++) {
233
                        geometriesAux[i] = geometryToJts((geom.getPrimitiveAt(i)));
234
                }
235
                return new com.vividsolutions.jts.geom.GeometryFactory().createGeometryCollection(geometriesAux);
236
        }
237

    
238
        public static com.vividsolutions.jts.geom.Geometry geometryToJtsWithSRID(
239
                        Geometry geom, int srid) {
240
                // logger.debug(geom.getClass());
241
                // logger.debug(new Integer(geom.getShapeType()));
242
                return geometryToJts(geom, geom.getType(), srid);
243
        }
244

    
245

    
246
        public static com.vividsolutions.jts.geom.Geometry geometryToJts(Geometry geom) {
247
                //logger.debug(geom.getClass());
248
                //logger.debug(new Integer(geom.getShapeType()));
249
                return geometryToJts(geom, geom.getType(), -1);
250
        }
251

    
252
        //        public static com.vividsolutions.jts.geom.Geometry java2d_to_jts(FShape shp) {
253
        //                return java2d_to_jts(shp, shp.getShapeType());
254
        //        }
255

    
256
        private static boolean isClosed(Coordinate firstCoordinate, Coordinate lastCoordinate){
257
                double diff = Math.abs(lastCoordinate.x - firstCoordinate.x);
258
                if (diff > 0.000001) {
259
                        return false;
260
                }
261
                diff = Math.abs(lastCoordinate.y - firstCoordinate.y);
262
                if (diff > 0.000001) {
263
                        return false;
264
                }
265
                return true;
266
        }
267

    
268
        public static com.vividsolutions.jts.geom.Geometry multiCurveToJts(MultiCurve geom, int srid) {
269
                LineString[] lines = new LineString[geom.getPrimitivesNumber()];
270
                for (int i = 0; i < lines.length; i++){
271
                        lines[i] = (LineString) curveToJts((geom.getPrimitiveAt(i)), srid);
272
                }
273
                return new com.vividsolutions.jts.geom.GeometryFactory().createMultiLineString(lines);
274
        }
275

    
276
        private static com.vividsolutions.jts.geom.Geometry curveToJts(Geometry shp, int srid){
277

    
278
                ArrayList arrayLines;
279
                LineString lin = null;
280
                PathIterator theIterator;
281
                int theType;
282
                int numParts = 0;
283
                double[] theData = new double[6];
284
                ArrayList arrayCoords = null;
285
                Coordinate coord;
286

    
287
                arrayLines = new ArrayList();
288
                theIterator = shp.getPathIterator(null, manager.getFlatness());
289

    
290
                while (!theIterator.isDone()) {
291
                        //while not done
292
                        theType = theIterator.currentSegment(theData);
293

    
294
                        //Populate a segment of the new
295
                        // GeneralPathX object.
296
                        //Process the current segment to populate a new
297
                        // segment of the new GeneralPathX object.
298
                        switch (theType) {
299
                        case PathIterator.SEG_MOVETO:
300
                                if (arrayCoords == null) {
301
                                        arrayCoords = new ArrayList();
302
                                } else {
303
                                        lin = geomFactory.createLineString(CoordinateArrays.toCoordinateArray(
304
                                                        arrayCoords));
305
                                        lin.setSRID(srid);
306
                                        arrayLines.add(lin);
307
                                        arrayCoords = new ArrayList();
308
                                }
309

    
310
                                numParts++;
311
                                coord = new Coordinate(theData[0], theData[1]);
312

    
313
                                arrayCoords.add(coord);
314

    
315
                                break;
316

    
317
                        case PathIterator.SEG_LINETO:
318
                                arrayCoords.add(new Coordinate(theData[0],
319
                                                theData[1]));
320

    
321
                                break;
322

    
323
                        case PathIterator.SEG_QUADTO:
324
                                System.out.println("Not supported here");
325

    
326
                                break;
327

    
328
                        case PathIterator.SEG_CUBICTO:
329
                                System.out.println("Not supported here");
330

    
331
                                break;
332

    
333
                        case PathIterator.SEG_CLOSE:
334
                                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
335
                                arrayCoords.add(new Coordinate(firstCoord.x,
336
                                                firstCoord.y));
337

    
338
                                break;
339
                        } //end switch
340

    
341
                        theIterator.next();
342
                } //end while loop
343

    
344
                if (arrayCoords.size()<2) {
345

    
346
                }else{
347

    
348
                        lin = new com.vividsolutions.jts.geom.GeometryFactory().createLineString(CoordinateArrays.toCoordinateArray(
349
                                        arrayCoords));
350

    
351
                        lin.setSRID(srid);
352

    
353
                }
354

    
355
                return lin;
356
        }
357

    
358
        /**
359
         * Convierte un FShape a una Geometry del JTS. Para ello, utilizamos un
360
         * flattened PathIterator. El flattened indica que las curvas las pasa a
361
         * segmentos de linea recta AUTOMATICAMENTE!!!.
362
         *
363
         * @param shp FShape que se quiere convertir.
364
         *
365
         * @return Geometry de JTS.
366
         */
367
        private static com.vividsolutions.jts.geom.Geometry geometryToJts(
368
                        Geometry shp, int shapeType, int srid) {
369

    
370

    
371
                com.vividsolutions.jts.geom.Geometry geoJTS = null;
372
                Coordinate coord;
373
                //Coordinate[] coords;
374
                ArrayList arrayCoords = null;
375
                ArrayList arrayLines;
376
                LineString lin;
377
                //LinearRing linRing;
378
                //LinearRing linRingExt = null;
379
                int theType;
380
                int numParts = 0;
381

    
382
                //                 Use this array to store segment coordinate data
383
                double[] theData = new double[6];
384
                PathIterator theIterator;
385

    
386
                //logger.debug(shp.toString());
387

    
388

    
389
                switch (shapeType) {
390
                case Geometry.TYPES.POINT:
391
                        org.gvsig.fmap.geom.primitive.impl.Point2D p = (org.gvsig.fmap.geom.primitive.impl.Point2D) shp;
392
                        coord = new Coordinate(p.getX(), p.getY());
393
                        geoJTS = geomFactory.createPoint(coord);
394
                        geoJTS.setSRID(srid);
395

    
396
                        break;
397

    
398
                        /*case Geometry.TYPES.MULTIPOINT:
399
                    org.gvsig.fmap.geom.aggregate.impl.MultiPoint2D mp = (org.gvsig.fmap.geom.aggregate.impl.MultiPoint2D) shp;
400
                    int numPoints = mp.getPrimitivesNumber();
401
                    Coordinate[] coordinates = new Coordinate[numPoints];
402
                    for(int i=0; i<numPoints; i++){
403
                        p = mp.getPoint(i);
404
                        coordinates[i]=new Coordinate(p.getX(), p.getY());
405
                    }
406
                    geoJTS = geomFactory.createMultiPoint(coordinates);
407
                    geoJTS.setSRID(srid);
408

409
                    break;*/
410

    
411
                case Geometry.TYPES.CURVE:
412
                case Geometry.TYPES.ARC:
413
                        arrayLines = new ArrayList();
414
                        theIterator = shp.getPathIterator(null, manager.getFlatness());
415

    
416
                        while (!theIterator.isDone()) {
417
                                //while not done
418
                                theType = theIterator.currentSegment(theData);
419

    
420
                                //Populate a segment of the new
421
                                // GeneralPathX object.
422
                                //Process the current segment to populate a new
423
                                // segment of the new GeneralPathX object.
424
                                switch (theType) {
425
                                case PathIterator.SEG_MOVETO:
426
                                        if (arrayCoords == null) {
427
                                                arrayCoords = new ArrayList();
428
                                        } else {
429
                                                lin = geomFactory.createLineString(CoordinateArrays.toCoordinateArray(
430
                                                                arrayCoords));
431
                                                lin.setSRID(srid);
432
                                                arrayLines.add(lin);
433
                                                arrayCoords = new ArrayList();
434
                                        }
435

    
436
                                        numParts++;
437
                                        coord = new Coordinate(theData[0], theData[1]);
438

    
439
                                        arrayCoords.add(coord);
440

    
441
                                        break;
442

    
443
                                case PathIterator.SEG_LINETO:
444
                                        arrayCoords.add(new Coordinate(theData[0],
445
                                                        theData[1]));
446

    
447
                                        break;
448

    
449
                                case PathIterator.SEG_QUADTO:
450
                                        System.out.println("Not supported here");
451

    
452
                                        break;
453

    
454
                                case PathIterator.SEG_CUBICTO:
455
                                        System.out.println("Not supported here");
456

    
457
                                        break;
458

    
459
                                case PathIterator.SEG_CLOSE:
460
                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
461
                                        arrayCoords.add(new Coordinate(firstCoord.x,
462
                                                        firstCoord.y));
463

    
464
                                        break;
465
                                } //end switch
466

    
467
                                theIterator.next();
468
                        } //end while loop
469

    
470
                        if (arrayCoords.size()<2) {
471
                                break;
472
                        }
473
                        lin = new com.vividsolutions.jts.geom.GeometryFactory().createLineString(CoordinateArrays.toCoordinateArray(
474
                                        arrayCoords));
475

    
476
                        lin.setSRID(srid);
477
                        // CAMBIO: ENTREGAMOS SIEMPRE MULTILINESTRING, QUE ES
478
                        // LO QUE HACE TODO EL MUNDO CUANDO ESCRIBE EN POSTGIS
479
                        // O CON GEOTOOLS
480
                        // if (numParts > 1) // Generamos una MultiLineString
481
                        //  {
482
                        arrayLines.add(lin);
483
                        geoJTS = geomFactory.createMultiLineString(com.vividsolutions.jts.geom.GeometryFactory.toLineStringArray(
484
                                        arrayLines));
485
                        geoJTS.setSRID(srid);
486
                        /* } else {
487
                         geoJTS = lin;
488
                         } */
489

    
490
                        break;
491

    
492
                case Geometry.TYPES.SURFACE:
493
                case Geometry.TYPES.CIRCLE:
494
                case Geometry.TYPES.ELLIPSE:
495
                        arrayLines = new ArrayList();
496

    
497
                        ArrayList shells = new ArrayList();
498
                        ArrayList holes = new ArrayList();
499
                        Coordinate[] points = null;
500

    
501
                        theIterator = shp.getPathIterator(null, manager.getFlatness());
502

    
503
                        while (!theIterator.isDone()) {
504
                                //while not done
505
                                theType = theIterator.currentSegment(theData);
506

    
507
                                //Populate a segment of the new
508
                                // GeneralPathX object.
509
                                //Process the current segment to populate a new
510
                                // segment of the new GeneralPathX object.
511
                                switch (theType) {
512
                                case PathIterator.SEG_MOVETO:
513
                                        if (arrayCoords == null) {
514
                                                arrayCoords = new ArrayList();
515
                                        } else {
516
                                                points = CoordinateArrays.toCoordinateArray(arrayCoords);
517

    
518
                                                try {
519
                                                        LinearRing ring = geomFactory.createLinearRing(points);
520

    
521
                                                        if (CGAlgorithms.isCCW(points)) {
522
                                                                holes.add(ring);
523
                                                        } else {
524
                                                                shells.add(ring);
525
                                                        }
526
                                                } catch (Exception e) {
527
                                                        boolean same = true;
528
                                                        for (int i = 0; i < points.length-1 && same; i++) {
529
                                                                if (points[i].x != points[i+1].x ||
530
                                                                                points[i].y != points[i+1].y /*||
531
                                                                                points[i].z != points[i+1].z*/
532
                                                                ) {
533
                                                                        same = false;
534
                                                                }
535
                                                        }
536
                                                        if (same) {
537
                                                                return geomFactory.createPoint(points[0]);
538
                                                        }
539
                                                        if (points.length>1 && points.length<=3) {
540
                                                                // return geomFactory.createLineString(points);
541
                                                                return geomFactory.createMultiLineString(new LineString[] {geomFactory.createLineString(points)});
542
                                                        }
543

    
544
                                                        System.err.println(
545
                                                        "Caught Topology exception in GMLLinearRingHandler");
546

    
547
                                                        return null;
548
                                                }
549

    
550
                                                /* if (numParts == 1)
551
                                                 {
552
                                                 linRingExt = new GeometryFactory().createLinearRing(
553
                                                 CoordinateArrays.toCoordinateArray(arrayCoords));
554
                                                 }
555
                                                 else
556
                                                 {
557
                                                 linRing = new GeometryFactory().createLinearRing(
558
                                                 CoordinateArrays.toCoordinateArray(arrayCoords));
559
                                                 arrayLines.add(linRing);
560
                                                 } */
561
                                                arrayCoords = new ArrayList();
562
                                        }
563

    
564
                                        numParts++;
565
                                        arrayCoords.add(new Coordinate(theData[0],
566
                                                        theData[1]));
567

    
568
                                        break;
569

    
570
                                case PathIterator.SEG_LINETO:
571
                                        arrayCoords.add(new Coordinate(theData[0],
572
                                                        theData[1]));
573

    
574
                                        break;
575

    
576
                                case PathIterator.SEG_QUADTO:
577
                                        System.out.println("SEG_QUADTO Not supported here");
578

    
579
                                        break;
580

    
581
                                case PathIterator.SEG_CUBICTO:
582
                                        System.out.println("SEG_CUBICTO Not supported here");
583

    
584
                                        break;
585

    
586
                                case PathIterator.SEG_CLOSE:
587
                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
588
                                        arrayCoords.add(new Coordinate(firstCoord.x,
589
                                                        firstCoord.y));
590

    
591
                                        break;
592
                                } //end switch
593

    
594
                                // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
595
                                theIterator.next();
596
                        } //end while loop
597

    
598

    
599
                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
600
                        Coordinate lastCoord = (Coordinate) arrayCoords.get(arrayCoords
601
                                        .size() - 1);
602
                        if (!isClosed(firstCoord, lastCoord)) {
603
                                arrayCoords.add(firstCoord);
604
                        }
605
                        points = CoordinateArrays.toCoordinateArray(arrayCoords);
606

    
607
                        try {
608
                                LinearRing ring = geomFactory.createLinearRing(points);
609

    
610
                                if (CGAlgorithms.isCCW(points)) {
611
                                        holes.add(ring);
612
                                } else {
613
                                        shells.add(ring);
614
                                }
615
                                ring.setSRID(srid);
616
                        } catch (Exception e) {
617
                                boolean same = true;
618
                                for (int i = 0; i < points.length-1 && same; i++) {
619
                                        if (points[i].x != points[i+1].x ||
620
                                                        points[i].y != points[i+1].y /*||
621
                                                        points[i].z != points[i+1].z*/
622
                                        ) {
623
                                                same = false;
624
                                        }
625
                                }
626
                                if (same) {
627
                                        geoJTS = geomFactory.createPoint(points[0]);
628
                                        geoJTS.setSRID(srid);
629
                                        return geoJTS;
630
                                }
631
                                /*
632
                                 * caso cuando es una linea de 3 puntos, no creo un LinearRing, sino
633
                                 * una linea
634
                                 */
635
                                if (points.length>1 && points.length<=3) {
636
                                        // return geomFactory.createLineString(points);
637
                                        geoJTS = geomFactory
638
                                        .createMultiLineString(new LineString[] { geomFactory
639
                                                        .createLineString(points) });
640
                                        geoJTS.setSRID(srid);
641
                                        return geoJTS;
642
                                }
643
                                System.err.println(
644
                                "Caught Topology exception in GMLLinearRingHandler");
645

    
646
                                return null;
647
                        }
648

    
649
                        /* linRing = new GeometryFactory().createLinearRing(
650
                         CoordinateArrays.toCoordinateArray(arrayCoords)); */
651

    
652
                        // System.out.println("NumParts = " + numParts);
653
                        //now we have a list of all shells and all holes
654
                        ArrayList holesForShells = new ArrayList(shells.size());
655

    
656
                        for (int i = 0; i < shells.size(); i++) {
657
                                holesForShells.add(new ArrayList());
658
                        }
659

    
660
                        //find homes
661
                        for (int i = 0; i < holes.size(); i++) {
662
                                LinearRing testRing = (LinearRing) holes.get(i);
663
                                LinearRing minShell = null;
664
                                Envelope minEnv = null;
665
                                Envelope testEnv = testRing.getEnvelopeInternal();
666
                                Coordinate testPt = testRing.getCoordinateN(0);
667
                                LinearRing tryRing = null;
668

    
669
                                for (int j = 0; j < shells.size(); j++) {
670
                                        tryRing = (LinearRing) shells.get(j);
671

    
672
                                        Envelope tryEnv = tryRing.getEnvelopeInternal();
673

    
674
                                        if (minShell != null) {
675
                                                minEnv = minShell.getEnvelopeInternal();
676
                                        }
677

    
678
                                        boolean isContained = false;
679
                                        Coordinate[] coordList = tryRing.getCoordinates();
680

    
681
                                        if (tryEnv.contains(testEnv) &&
682
                                                        (CGAlgorithms.isPointInRing(testPt, coordList) ||
683
                                                                        (pointInList(testPt, coordList)))) {
684
                                                isContained = true;
685
                                        }
686

    
687
                                        // check if this new containing ring is smaller than the current minimum ring
688
                                        if (isContained) {
689
                                                if ((minShell == null) || minEnv.contains(tryEnv)) {
690
                                                        minShell = tryRing;
691
                                                }
692
                                        }
693
                                }
694

    
695
                                if (minShell == null) {
696
                                        //                                        System.out.println(
697
                                        //                                        polygon found with a hole thats not inside a shell);
698
                                        //                                        azabala: we do the assumption that this hole is really a shell (polygon)
699
                                        //                                        whose point werent digitized in the right order
700
                                        Coordinate[] cs = testRing.getCoordinates();
701
                                        Coordinate[] reversed = new Coordinate[cs.length];
702
                                        int pointIndex = 0;
703
                                        for(int z = cs.length-1; z >= 0; z--){
704
                                                reversed[pointIndex] = cs[z];
705
                                                pointIndex++;
706
                                        }
707
                                        LinearRing newRing = geomFactory.createLinearRing(reversed);
708
                                        shells.add(newRing);
709
                                        holesForShells.add(new ArrayList());
710
                                } else {
711
                                        ((ArrayList) holesForShells.get(shells.indexOf(minShell))).add(testRing);
712
                                }
713
                        }
714

    
715
                        Polygon[] polygons = new Polygon[shells.size()];
716

    
717
                        for (int i = 0; i < shells.size(); i++) {
718
                                polygons[i] = geomFactory.createPolygon((LinearRing) shells.get(
719
                                                i),
720
                                                (LinearRing[]) ((ArrayList) holesForShells.get(i)).toArray(
721
                                                                new LinearRing[0]));
722
                                polygons[i].setSRID(srid);
723
                        }
724
                        // CAMBIO: ENTREGAMOS SIEMPRE MULTILINESTRING, QUE ES
725
                        // LO QUE HACE TODO EL MUNDO CUANDO ESCRIBE EN POSTGIS
726
                        // O CON GEOTOOLS
727
                        // if (numParts > 1) // Generamos una MultiLineString
728

    
729
                        /* if (polygons.length == 1) {
730
                         return polygons[0];
731
                         } */
732

    
733
                        // FIN CAMBIO
734

    
735
                        holesForShells = null;
736
                        shells = null;
737
                        holes = null;
738

    
739
                        if (polygons.length == 1) {
740
                                geoJTS = polygons[0];
741
                        } else {
742
                                // its a multi part
743
                                geoJTS = geomFactory.createMultiPolygon(polygons);
744
                        }
745
                        geoJTS.setSRID(srid);
746
                        //its a multi part
747
                        //geoJTS = geomFactory.createMultiPolygon(polygons);
748
                        //geoJTS.setSRID(srid);
749

    
750
                        break;
751

    
752
                case Geometry.TYPES.MULTICURVE:
753
                        geoJTS = multiCurveToJts((MultiCurve)shp, srid);
754
                        geoJTS.setSRID(srid);
755
                        break;
756

    
757
                case Geometry.TYPES.MULTIPOINT:
758
                        geoJTS = geometryToJts((MultiPoint)shp);
759
                        geoJTS.setSRID(srid);
760
                        break;
761

    
762
                case Geometry.TYPES.MULTISURFACE:
763
                        geoJTS = multiSurfaceToJts((MultiSurface)shp, srid);
764
                        geoJTS.setSRID(srid);
765
                        break;
766

    
767
                }
768

    
769
                geoJTS.setSRID(srid);
770
                return geoJTS;
771
        }
772

    
773
        /**
774
         * Converts JTS Geometry objects into Java 2D Shape objects
775
         *
776
         * @param geo Geometry de JTS.
777
         *
778
         * @return FShape.
779
         */
780
        //        public static FShape jts_to_java2d(com.vividsolutions.jts.geom.Geometry geo) {
781
        //                FShape shpNew = null;
782
        //
783
        //                try {
784
        //                        if (geo instanceof Point) {
785
        //                                shpNew = new org.gvsig.fmap.geom.primitive.Point2D(null, null, ((Point) geo).getX(), ((Point) geo).getY());
786
        //                        }
787
        //
788
        //                        if (geo.isEmpty()) {
789
        //                                shpNew = null;
790
        //                        }
791
        //
792
        //                        if (geo instanceof Polygon) {
793
        //                                shpNew = new Surface2D(null, null, toShape((Polygon) geo));
794
        //                        }
795
        //
796
        //                        if (geo instanceof MultiPolygon) {
797
        //                                shpNew = new Surface2D(null, null, toShape((MultiPolygon) geo));
798
        //                        }
799
        //
800
        //                        if (geo instanceof LineString) {
801
        //                                shpNew = new Curve2D(null, null, toShape((LineString) geo));
802
        //                        }
803
        //
804
        //                        if (geo instanceof MultiLineString) {
805
        //                                shpNew = new Curve2D(null, null, toShape((MultiLineString) geo));
806
        //                        }
807
        //
808
        //                        return shpNew;
809
        //                } catch (NoninvertibleTransformException e) {
810
        //                        // TODO Auto-generated catch block
811
        //                        e.printStackTrace();
812
        //                }
813
        //
814
        //                return null;
815
        //        }
816

    
817
        /**
818
         * DOCUMENT ME!
819
         *
820
         * @param p DOCUMENT ME!
821
         *
822
         * @return DOCUMENT ME!
823
         */
824
        private static GeneralPathX toShape(Polygon p) {
825
                GeneralPathX resul = new GeneralPathX();
826
                Coordinate coord;
827

    
828
                for (int i = 0; i < p.getExteriorRing().getNumPoints(); i++) {
829
                        coord = p.getExteriorRing().getCoordinateN(i);
830

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

    
838
                for (int j = 0; j < p.getNumInteriorRing(); j++) {
839
                        LineString hole = p.getInteriorRingN(j);
840

    
841
                        for (int k = 0; k < hole.getNumPoints(); k++) {
842
                                coord = hole.getCoordinateN(k);
843

    
844
                                if (k == 0) {
845
                                        resul.moveTo(coord.x, coord.y);
846
                                } else {
847
                                        resul.lineTo(coord.x, coord.y);
848
                                }
849
                        }
850
                }
851

    
852
                return resul;
853
        }
854

    
855
        /**
856
         * DOCUMENT ME!
857
         *
858
         * @param modelCoordinates DOCUMENT ME!
859
         *
860
         * @return DOCUMENT ME!
861
         *
862
         * @throws NoninvertibleTransformException DOCUMENT ME!
863
         *
864
        private Coordinate[] toViewCoordinates(Coordinate[] modelCoordinates)
865
                throws NoninvertibleTransformException {
866
                Coordinate[] viewCoordinates = new Coordinate[modelCoordinates.length];
867

868
                for (int i = 0; i < modelCoordinates.length; i++) {
869
                        FPoint2D point2D = coordinate2FPoint2D(modelCoordinates[i]);
870
                        viewCoordinates[i] = new Coordinate(point2D.getX(), point2D.getY());
871
                }
872

873
                return viewCoordinates;
874
        } 
875
         * @throws CreateGeometryException */
876

    
877
        /* private Shape toShape(GeometryCollection gc)
878
           throws NoninvertibleTransformException {
879
           GeometryCollectionShape shape = new GeometryCollectionShape();
880
           for (int i = 0; i < gc.getNumGeometries(); i++) {
881
                   Geometry g = (Geometry) gc.getGeometryN(i);
882
                   shape.add(toShape(g));
883
           }
884
           return shape;
885
           } */
886
        private static GeneralPathX toShape(MultiLineString mls)
887
        throws NoninvertibleTransformException, CreateGeometryException {
888
                GeneralPathX path = new GeneralPathX();
889

    
890
                for (int i = 0; i < mls.getNumGeometries(); i++) {
891
                        LineString lineString = (LineString) mls.getGeometryN(i);
892
                        path.append(toShape(lineString).getPathIterator(null), false);
893
                }
894

    
895
                //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
896
                //converted to GeneralPathXs. [Jon Aquino]
897
                return path;
898
        }
899

    
900
        /**
901
         * DOCUMENT ME!
902
         *
903
         * @param lineString DOCUMENT ME!
904
         *
905
         * @return DOCUMENT ME!
906
         *
907
         * @throws NoninvertibleTransformException DOCUMENT ME!
908
         * @throws CreateGeometryException 
909
         */
910
        private static GeneralPathX toShape(LineString lineString)
911
        throws NoninvertibleTransformException, CreateGeometryException {
912
                GeneralPathX shape = new GeneralPathX();
913
                org.gvsig.fmap.geom.primitive.Point viewPoint = coordinate2FPoint2D(lineString.getCoordinateN(0));
914
                shape.moveTo(viewPoint.getX(), viewPoint.getY());
915

    
916
                for (int i = 1; i < lineString.getNumPoints(); i++) {
917
                        viewPoint = coordinate2FPoint2D(lineString.getCoordinateN(i));
918
                        shape.lineTo(viewPoint.getX(), viewPoint.getY());
919
                }
920

    
921
                //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
922
                //converted to GeneralPathXs. [Jon Aquino]
923
                return shape;
924
        }
925

    
926

    
927
        /**
928
         *
929
         */
930
        private static GeneralPathX toShape(MultiPolygon mp)
931
        throws NoninvertibleTransformException {
932
                GeneralPathX path = new GeneralPathX();
933

    
934
                for (int i = 0; i < mp.getNumGeometries(); i++) {
935
                        Polygon polygon = (Polygon) mp.getGeometryN(i);
936
                        path.append(toShape(polygon).getPathIterator(null), false);
937
                }
938

    
939
                //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
940
                //converted to GeneralPathXs. [Jon Aquino]
941
                return path;
942
        }
943
        /**
944
         * DOCUMENT ME!
945
         *
946
         * @param coord DOCUMENT ME!
947
         *
948
         * @return DOCUMENT ME!
949
         * @throws CreateGeometryException 
950
         */
951
        public static org.gvsig.fmap.geom.primitive.Point coordinate2FPoint2D(Coordinate coord) throws CreateGeometryException {
952
                return geomManager.createPoint(coord.x, coord.y, SUBTYPES.GEOM2D); //,coord.z);
953
        }
954

    
955
        /**
956
         * Convierte una Geometry de JTS a GeneralPathX.
957
         *
958
         * @param geometry Geometry a convertir.
959
         *
960
         * @return GeneralPathX.
961
         *
962
         * @throws NoninvertibleTransformException
963
         * @throws CreateGeometryException 
964
         * @throws IllegalArgumentException
965
         */
966
        public static GeneralPathX toShape(com.vividsolutions.jts.geom.Geometry geometry)
967
        throws NoninvertibleTransformException, CreateGeometryException {
968
                if (geometry.isEmpty()) {
969
                        return new GeneralPathX();
970
                }
971

    
972
                if (geometry instanceof Polygon) {
973
                        return toShape((Polygon) geometry);
974
                }
975

    
976
                if (geometry instanceof MultiPolygon) {
977
                        return toShape((MultiPolygon) geometry);
978
                }
979

    
980
                if (geometry instanceof LineString) {
981
                        return toShape((LineString) geometry);
982
                }
983

    
984
                if (geometry instanceof MultiLineString) {
985
                        return toShape((MultiLineString) geometry);
986
                }
987

    
988
                if (geometry instanceof GeometryCollection) {
989
                        return toShape(geometry);
990
                }
991

    
992
                throw new IllegalArgumentException("Unrecognized Geometry class: " +
993
                                geometry.getClass());
994
        }
995

    
996

    
997
        public static GeneralPathX transformToInts(GeneralPathX gp, AffineTransform at) {
998
                GeneralPathX newGp = new GeneralPathX();
999
                PathIterator theIterator;
1000
                int theType;
1001
                int numParts = 0;
1002
                double[] theData = new double[6];
1003
                java.awt.geom.Point2D ptDst = new java.awt.geom.Point2D.Double();
1004
                java.awt.geom.Point2D ptSrc = new java.awt.geom.Point2D.Double();
1005
                boolean bFirst = true;
1006
                int xInt, yInt, antX = -1, antY = -1;
1007

    
1008
                theIterator = gp.getPathIterator(null); //, flatness);
1009

    
1010
                while (!theIterator.isDone()) {
1011
                        theType = theIterator.currentSegment(theData);
1012
                        switch (theType) {
1013
                        case PathIterator.SEG_MOVETO:
1014
                                numParts++;
1015
                                ptSrc.setLocation(theData[0], theData[1]);
1016
                                at.transform(ptSrc, ptDst);
1017
                                antX = (int) ptDst.getX();
1018
                                antY = (int) ptDst.getY();
1019
                                newGp.moveTo(antX, antY);
1020
                                bFirst = true;
1021
                                break;
1022

    
1023
                        case PathIterator.SEG_LINETO:
1024
                                ptSrc.setLocation(theData[0], theData[1]);
1025
                                at.transform(ptSrc, ptDst);
1026
                                xInt = (int) ptDst.getX();
1027
                                yInt = (int) ptDst.getY();
1028
                                if ((bFirst) || ((xInt != antX) || (yInt != antY)))
1029
                                {
1030
                                        newGp.lineTo(xInt, yInt);
1031
                                        antX = xInt;
1032
                                        antY = yInt;
1033
                                        bFirst = false;
1034
                                }
1035
                                break;
1036

    
1037
                        case PathIterator.SEG_QUADTO:
1038
                                System.out.println("Not supported here");
1039

    
1040
                                break;
1041

    
1042
                        case PathIterator.SEG_CUBICTO:
1043
                                System.out.println("Not supported here");
1044

    
1045
                                break;
1046

    
1047
                        case PathIterator.SEG_CLOSE:
1048
                                newGp.closePath();
1049

    
1050
                                break;
1051
                        } //end switch
1052

    
1053
                        theIterator.next();
1054
                } //end while loop
1055

    
1056
                return newGp;
1057
        }
1058
        public static Geometry transformToInts(Geometry gp, AffineTransform at) throws CreateGeometryException {
1059
                GeneralPathX newGp = new GeneralPathX();
1060
                double[] theData = new double[6];
1061
                double[] aux = new double[6];
1062

    
1063
                // newGp.reset();
1064
                PathIterator theIterator;
1065
                int theType;
1066
                int numParts = 0;
1067

    
1068
                java.awt.geom.Point2D ptDst = new java.awt.geom.Point2D.Double();
1069
                java.awt.geom.Point2D ptSrc = new java.awt.geom.Point2D.Double();
1070
                boolean bFirst = true;
1071
                int xInt, yInt, antX = -1, antY = -1;
1072

    
1073

    
1074
                theIterator = gp.getPathIterator(null); //, flatness);
1075
                int numSegmentsAdded = 0;
1076
                while (!theIterator.isDone()) {
1077
                        theType = theIterator.currentSegment(theData);
1078

    
1079
                        switch (theType) {
1080
                        case PathIterator.SEG_MOVETO:
1081
                                numParts++;
1082
                                ptSrc.setLocation(theData[0], theData[1]);
1083
                                at.transform(ptSrc, ptDst);
1084
                                antX = (int) ptDst.getX();
1085
                                antY = (int) ptDst.getY();
1086
                                newGp.moveTo(antX, antY);
1087
                                numSegmentsAdded++;
1088
                                bFirst = true;
1089
                                break;
1090

    
1091
                        case PathIterator.SEG_LINETO:
1092
                                ptSrc.setLocation(theData[0], theData[1]);
1093
                                at.transform(ptSrc, ptDst);
1094
                                xInt = (int) ptDst.getX();
1095
                                yInt = (int) ptDst.getY();
1096
                                if ((bFirst) || ((xInt != antX) || (yInt != antY)))
1097
                                {
1098
                                        newGp.lineTo(xInt, yInt);
1099
                                        antX = xInt;
1100
                                        antY = yInt;
1101
                                        bFirst = false;
1102
                                        numSegmentsAdded++;
1103
                                }
1104
                                break;
1105

    
1106
                        case PathIterator.SEG_QUADTO:
1107
                                at.transform(theData,0,aux,0,2);
1108
                                newGp.quadTo(aux[0], aux[1], aux[2], aux[3]);
1109
                                numSegmentsAdded++;
1110
                                break;
1111

    
1112
                        case PathIterator.SEG_CUBICTO:
1113
                                at.transform(theData,0,aux,0,3);
1114
                                newGp.curveTo(aux[0], aux[1], aux[2], aux[3], aux[4], aux[5]);
1115
                                numSegmentsAdded++;
1116
                                break;
1117

    
1118
                        case PathIterator.SEG_CLOSE:
1119
                                if (numSegmentsAdded < 3) {
1120
                                        newGp.lineTo(antX, antY);
1121
                                }
1122
                                newGp.closePath();
1123

    
1124
                                break;
1125
                        } //end switch
1126

    
1127
                        theIterator.next();
1128
                } //end while loop
1129

    
1130
                Geometry shp = null;
1131
                switch (gp.getType())
1132
                {
1133
                case Geometry.TYPES.POINT:
1134
                        shp = geomManager.createPoint(ptDst.getX(), ptDst.getY(), SUBTYPES.GEOM2D); 
1135
                        break;
1136

    
1137
                case Geometry.TYPES.CURVE:
1138
                case Geometry.TYPES.ARC:
1139
                        try {
1140
                                shp = geomManager.createCurve(newGp, SUBTYPES.GEOM2D);
1141
                        } catch (CreateGeometryException e1) {
1142
                                logger.error("Error creating a curve", e1);
1143
                        }
1144
                        break;
1145

    
1146
                case Geometry.TYPES.SURFACE:
1147
                case Geometry.TYPES.CIRCLE:
1148
                case Geometry.TYPES.ELLIPSE:
1149

    
1150
                        try {
1151
                                shp = geomManager.createSurface(newGp, SUBTYPES.GEOM2D);
1152
                        } catch (CreateGeometryException e) {
1153
                                logger.error("Error creating a surface", e);
1154
                        }
1155
                        break;
1156
                }
1157
                return shp;
1158
        }
1159

    
1160
        public static Rectangle2D convertEnvelopeToRectangle2D(Envelope jtsR) {
1161
                Rectangle2D.Double r = new Rectangle2D.Double(jtsR.getMinX(),
1162
                                jtsR.getMinY(), jtsR.getWidth(), jtsR.getHeight());
1163
                return r;
1164
        }
1165

    
1166
        public static Envelope convertEnvelopeToJTS(org.gvsig.fmap.geom.primitive.Envelope r) {
1167
                Envelope e = new Envelope(r.getMinimum(0), r.getMaximum(0), r.getMinimum(1),
1168
                                r.getMaximum(1));
1169
                return e;
1170
        }
1171

    
1172
        /**
1173
         * Return a correct polygon (no hole)
1174
         * @param coordinates
1175
         * @return
1176
         */
1177
        public static Geometry getExteriorPolygon(Coordinate[] coordinates) {
1178
                // isCCW = true => it's a hole
1179
                Coordinate[] vs = new Coordinate[coordinates.length];
1180
                if (CGAlgorithms.isCCW(coordinates)) {
1181
                        for (int i = vs.length-1;i >= 0; i--){
1182
                                vs[i] = coordinates[i];
1183
                        }
1184
                } else {
1185
                        vs = coordinates;
1186
                }
1187
                LinearRing ring = geomFactory.createLinearRing(vs);
1188

    
1189
                try {
1190
                        Surface surface = (Surface)manager.create(TYPES.SURFACE, SUBTYPES.GEOM2D);
1191
                        surface.setGeneralPath(toShape(ring));
1192
                        return surface;
1193
                } catch (NoninvertibleTransformException e) {
1194
                        e.printStackTrace();
1195
                } catch (CreateGeometryException e) {
1196
                        e.printStackTrace();
1197
                }
1198
                return null;
1199
        }
1200

    
1201
        public static boolean isCCW(Point[] points) {
1202
                int length = points.length;
1203
                Coordinate[] vs;
1204

    
1205
                if (points[0].getX() != points[length-1].getX() || points[0].getY() != points[length-1].getY()) {
1206
                        vs=new Coordinate[length+1];
1207
                        vs[points.length] = new Coordinate(points[0].getX(), points[0].getY());
1208
                } else {
1209
                        vs=new Coordinate[length];
1210
                }
1211
                for (int i = 0; i < length; i++) {
1212
                        vs[i] = new Coordinate(points[i].getX(), points[i].getY());
1213
                }
1214

    
1215
                return CGAlgorithms.isCCW(vs);
1216
        }
1217

    
1218
        public static boolean isCCW(Surface pol) {
1219
                com.vividsolutions.jts.geom.Geometry jtsGeom = Converter.geometryToJts(pol);
1220
                if (jtsGeom.getNumGeometries() == 1) {
1221
                        Coordinate[] coords = jtsGeom.getCoordinates();
1222
                        return CGAlgorithms.isCCW(coords);
1223
                }
1224
                return false;
1225
        }
1226

    
1227
        /**
1228
         * Return a hole (CCW ordered points)
1229
         * @param coordinates
1230
         * @return
1231
         */
1232
        public static Geometry getHole(Coordinate[] coordinates) {
1233
                Coordinate[] vs = new Coordinate[coordinates.length];
1234
                if (CGAlgorithms.isCCW(coordinates)) {
1235
                        vs=coordinates;
1236

    
1237
                }else{
1238
                        for (int i = vs.length-1; i >= 0; i--) {
1239
                                vs[i] = coordinates[i];
1240
                        }
1241
                }
1242
                LinearRing ring = geomFactory.createLinearRing(vs);
1243

    
1244
                try {
1245
                        Surface surface = (Surface)manager.create(TYPES.SURFACE, SUBTYPES.GEOM2D);
1246
                        surface.setGeneralPath(toShape(ring));
1247
                        return surface;
1248
                } catch (NoninvertibleTransformException e) {
1249
                        e.printStackTrace();
1250
                } catch (CreateGeometryException e) {
1251
                        e.printStackTrace();
1252
                }
1253
                return null;
1254
        }
1255

    
1256
        public static Shape getExteriorPolygon(GeneralPathX gp) {
1257
                Area area = new Area(gp);
1258
                area.isSingular();
1259
                return area;
1260
        }
1261
        
1262
        /**
1263
         * Use it ONLY for NOT multipart polygons.
1264
         * @param pol
1265
         * @return
1266
         */
1267
        public static Geometry getNotHolePolygon(Surface pol) {
1268
                // isCCW == true => hole
1269
                Coordinate[] coords;
1270
                ArrayList arrayCoords = null;
1271
                int theType;
1272
                int numParts = 0;
1273

    
1274
                //                 Use this array to store segment coordinate data
1275
                double[] theData = new double[6];
1276
                PathIterator theIterator;
1277

    
1278
                ArrayList shells = new ArrayList();
1279
                ArrayList holes = new ArrayList();
1280
                Coordinate[] points = null;
1281

    
1282
                theIterator = pol.getPathIterator(null, manager.getFlatness());
1283

    
1284
                while (!theIterator.isDone()) {
1285
                        //while not done
1286
                        theType = theIterator.currentSegment(theData);
1287

    
1288
                        //Populate a segment of the new
1289
                        // GeneralPathX object.
1290
                        //Process the current segment to populate a new
1291
                        // segment of the new GeneralPathX object.
1292
                        switch (theType) {
1293
                        case PathIterator.SEG_MOVETO:
1294

    
1295
                                // System.out.println("SEG_MOVETO");
1296
                                if (arrayCoords == null) {
1297
                                        arrayCoords = new ArrayList();
1298
                                } else {
1299
                                        points = CoordinateArrays.toCoordinateArray(arrayCoords);
1300

    
1301
                                        try {
1302
                                                LinearRing ring = geomFactory.createLinearRing(points);
1303

    
1304
                                                if (CGAlgorithms.isCCW(points)) {
1305
                                                        holes.add(ring);
1306
                                                } else {
1307
                                                        shells.add(ring);
1308
                                                }
1309
                                        } catch (Exception e) {
1310
                                                System.err.println(
1311
                                                                "Caught Topology exception in GMLLinearRingHandler");
1312

    
1313
                                                return null;
1314
                                        }
1315
                                        arrayCoords = new ArrayList();
1316
                                }
1317

    
1318
                                numParts++;
1319
                                arrayCoords.add(new Coordinate(theData[0],
1320
                                                theData[1]));
1321

    
1322
                                break;
1323

    
1324
                        case PathIterator.SEG_LINETO:
1325
                                arrayCoords.add(new Coordinate(theData[0],
1326
                                                theData[1]));
1327
                                break;
1328
                        case PathIterator.SEG_QUADTO:
1329
                                System.out.println("SEG_QUADTO Not supported here");
1330
                                break;
1331
                        case PathIterator.SEG_CUBICTO:
1332
                                System.out.println("SEG_CUBICTO Not supported here");
1333
                                break;
1334
                        case PathIterator.SEG_CLOSE:
1335
                                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
1336
                                arrayCoords.add(new Coordinate(firstCoord.x,
1337
                                                firstCoord.y));
1338
                                break;
1339
                        } //end switch
1340

    
1341
                        // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
1342
                        theIterator.next();
1343
                } //end while loop
1344

    
1345
                arrayCoords.add(arrayCoords.get(0));
1346
                coords = CoordinateArrays.toCoordinateArray(arrayCoords);
1347

    
1348
                if (numParts == 1) {
1349
                        return getExteriorPolygon(coords);
1350
                }
1351
                return pol;
1352
        }
1353

    
1354
        /**
1355
         * Metodo creado para construir un MultiSurface formado por varias surface
1356
         * 
1357
         * @author Leticia Riestra
1358
         * @param geom
1359
         * @return
1360
         */
1361
        public static com.vividsolutions.jts.geom.Geometry multiSurfaceToJts(MultiSurface geom, int srid) {
1362
                Polygon[] polygons = new Polygon[geom.getPrimitivesNumber()];
1363
                for (int i = 0; i < polygons.length; i++){
1364
                        MultiPolygon polygon = (MultiPolygon)surfaceToJts((geom.getPrimitiveAt(i)), srid);
1365
                        
1366
                        polygons[i] = (Polygon)polygon.getGeometryN(0);//(Polygon) surfaceToJts((geom.getPrimitiveAt(i)), srid);
1367
                }
1368
                return new com.vividsolutions.jts.geom.GeometryFactory().createMultiPolygon(polygons);
1369
        }
1370
        
1371
        private static com.vividsolutions.jts.geom.Geometry surfaceToJts(Geometry shp, int srid) {
1372
                com.vividsolutions.jts.geom.Geometry geoJTS = null;
1373
                ArrayList arrayLines;
1374
                LineString lin = null;
1375
                PathIterator theIterator;
1376
                int theType;
1377
                int numParts = 0;
1378
                double[] theData = new double[6];
1379
                ArrayList arrayCoords = null;
1380
                Coordinate coord;
1381

    
1382
                arrayLines = new ArrayList();
1383

    
1384
                ArrayList shells = new ArrayList();
1385
                ArrayList holes = new ArrayList();
1386
                Coordinate[] points = null;
1387

    
1388
                theIterator = shp.getPathIterator(null, manager.getFlatness());
1389

    
1390
                while (!theIterator.isDone()) {
1391
                        //while not done
1392
                        theType = theIterator.currentSegment(theData);
1393

    
1394
                        //Populate a segment of the new
1395
                        // GeneralPathX object.
1396
                        //Process the current segment to populate a new
1397
                        // segment of the new GeneralPathX object.
1398
                        switch (theType) {
1399
                        case PathIterator.SEG_MOVETO:
1400

    
1401
                                // System.out.println("SEG_MOVETO");
1402
                                if (arrayCoords == null) {
1403
                                        arrayCoords = new ArrayList();
1404
                                } else {
1405
                                        points = CoordinateArrays.toCoordinateArray(arrayCoords);
1406

    
1407
                                        try {
1408
                                                LinearRing ring = geomFactory.createLinearRing(points);
1409

    
1410
                                                if (CGAlgorithms.isCCW(points)) {
1411
                                                        holes.add(ring);
1412
                                                } else {
1413
                                                        shells.add(ring);
1414
                                                }
1415
                                        } catch (Exception e) {
1416
                                                boolean same = true;
1417
                                                for (int i = 0; i < points.length-1 && same; i++) {
1418
                                                        if (points[i].x != points[i+1].x ||
1419
                                                                        points[i].y != points[i+1].y /*||
1420
                                                                        points[i].z != points[i+1].z*/
1421
                                                        ) {
1422
                                                                same = false;
1423
                                                        }
1424
                                                }
1425
                                                if (same) {
1426
                                                        return geomFactory.createPoint(points[0]);
1427
                                                }
1428

    
1429
                                                if (points.length>1 && points.length<=3) {
1430
                                                        // return geomFactory.createLineString(points);
1431
                                                        return geomFactory.createMultiLineString(new LineString[] {geomFactory.createLineString(points)});
1432
                                                }
1433

    
1434
                                                System.err.println(
1435
                                                "Caught Topology exception in GMLLinearRingHandler");
1436

    
1437
                                                return null;
1438
                                        }
1439

    
1440
                                        /* if (numParts == 1)
1441
                                         {
1442
                                         linRingExt = new GeometryFactory().createLinearRing(
1443
                                         CoordinateArrays.toCoordinateArray(arrayCoords));
1444
                                         }
1445
                                         else
1446
                                         {
1447
                                         linRing = new GeometryFactory().createLinearRing(
1448
                                         CoordinateArrays.toCoordinateArray(arrayCoords));
1449
                                         arrayLines.add(linRing);
1450
                                         } */
1451
                                        arrayCoords = new ArrayList();
1452
                                }
1453

    
1454
                                numParts++;
1455
                                arrayCoords.add(new Coordinate(theData[0],
1456
                                                theData[1]));
1457

    
1458
                                break;
1459

    
1460
                        case PathIterator.SEG_LINETO:
1461

    
1462
                                arrayCoords.add(new Coordinate(theData[0],
1463
                                                theData[1]));
1464

    
1465
                                break;
1466

    
1467
                        case PathIterator.SEG_QUADTO:
1468
                                System.out.println("SEG_QUADTO Not supported here");
1469

    
1470
                                break;
1471

    
1472
                        case PathIterator.SEG_CUBICTO:
1473
                                System.out.println("SEG_CUBICTO Not supported here");
1474

    
1475
                                break;
1476

    
1477
                        case PathIterator.SEG_CLOSE:
1478
                                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
1479
                                arrayCoords.add(new Coordinate(firstCoord.x,
1480
                                                firstCoord.y));
1481

    
1482
                                break;
1483
                        } //end switch
1484

    
1485
                        // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
1486
                        theIterator.next();
1487
                } //end while loop
1488

    
1489

    
1490
                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
1491
                Coordinate lastCoord = (Coordinate) arrayCoords.get(arrayCoords
1492
                                .size() - 1);
1493
                if (!isClosed(firstCoord, lastCoord)) {
1494
                        arrayCoords.add(firstCoord);
1495
                }
1496
                points = CoordinateArrays.toCoordinateArray(arrayCoords);
1497

    
1498
                try {
1499
                        LinearRing ring = geomFactory.createLinearRing(points);
1500

    
1501
                        if (CGAlgorithms.isCCW(points)) {
1502
                                holes.add(ring);
1503
                        } else {
1504
                                shells.add(ring);
1505
                        }
1506
                        ring.setSRID(srid);
1507
                } catch (Exception e) {
1508
                        boolean same = true;
1509
                        for (int i = 0; i < points.length-1 && same; i++) {
1510
                                if (points[i].x != points[i+1].x ||
1511
                                                points[i].y != points[i+1].y /*||
1512
                                                points[i].z != points[i+1].z*/
1513
                                ) {
1514
                                        same = false;
1515
                                }
1516
                        }
1517
                        if (same) {
1518
                                geoJTS = geomFactory.createPoint(points[0]);
1519
                                geoJTS.setSRID(srid);
1520
                                return geoJTS;
1521
                        }
1522
                        if (points.length>1 && points.length<=3) {
1523
                                // return geomFactory.createLineString(points);
1524
                                geoJTS = geomFactory
1525
                                .createMultiLineString(new LineString[] { geomFactory
1526
                                                .createLineString(points) });
1527
                                geoJTS.setSRID(srid);
1528
                                return geoJTS;
1529
                        }
1530
                        System.err.println(
1531
                        "Caught Topology exception in GMLLinearRingHandler");
1532

    
1533
                        return null;
1534
                }
1535

    
1536
                /* linRing = new GeometryFactory().createLinearRing(
1537
                 CoordinateArrays.toCoordinateArray(arrayCoords)); */
1538

    
1539
                // System.out.println("NumParts = " + numParts);
1540
                //now we have a list of all shells and all holes
1541
                ArrayList holesForShells = new ArrayList(shells.size());
1542

    
1543
                for (int i = 0; i < shells.size(); i++) {
1544
                        holesForShells.add(new ArrayList());
1545
                }
1546

    
1547
                //find homes
1548
                for (int i = 0; i < holes.size(); i++) {
1549
                        LinearRing testRing = (LinearRing) holes.get(i);
1550
                        LinearRing minShell = null;
1551
                        Envelope minEnv = null;
1552
                        Envelope testEnv = testRing.getEnvelopeInternal();
1553
                        Coordinate testPt = testRing.getCoordinateN(0);
1554
                        LinearRing tryRing = null;
1555

    
1556
                        for (int j = 0; j < shells.size(); j++) {
1557
                                tryRing = (LinearRing) shells.get(j);
1558

    
1559
                                Envelope tryEnv = tryRing.getEnvelopeInternal();
1560

    
1561
                                if (minShell != null) {
1562
                                        minEnv = minShell.getEnvelopeInternal();
1563
                                }
1564

    
1565
                                boolean isContained = false;
1566
                                Coordinate[] coordList = tryRing.getCoordinates();
1567

    
1568
                                if (tryEnv.contains(testEnv) &&
1569
                                                (CGAlgorithms.isPointInRing(testPt, coordList) ||
1570
                                                                (pointInList(testPt, coordList)))) {
1571
                                        isContained = true;
1572
                                }
1573

    
1574
                                // check if this new containing ring is smaller than the current minimum ring
1575
                                if (isContained) {
1576
                                        if ((minShell == null) || minEnv.contains(tryEnv)) {
1577
                                                minShell = tryRing;
1578
                                        }
1579
                                }
1580
                        }
1581

    
1582
                        if (minShell == null) {
1583
                                //                                        System.out.println(
1584
                                //                                        polygon found with a hole thats not inside a shell);
1585
                                //                                        azabala: we do the assumption that this hole is really a shell (polygon)
1586
                                //                                        whose point werent digitized in the right order
1587
                                Coordinate[] cs = testRing.getCoordinates();
1588
                                Coordinate[] reversed = new Coordinate[cs.length];
1589
                                int pointIndex = 0;
1590
                                for(int z = cs.length-1; z >= 0; z--){
1591
                                        reversed[pointIndex] = cs[z];
1592
                                        pointIndex++;
1593
                                }
1594
                                LinearRing newRing = geomFactory.createLinearRing(reversed);
1595
                                shells.add(newRing);
1596
                                holesForShells.add(new ArrayList());
1597
                        } else {
1598
                                ((ArrayList) holesForShells.get(shells.indexOf(minShell))).add(testRing);
1599
                        }
1600
                }
1601

    
1602
                Polygon[] polygons = new Polygon[shells.size()];
1603

    
1604
                for (int i = 0; i < shells.size(); i++) {
1605
                        polygons[i] = geomFactory.createPolygon((LinearRing) shells.get(
1606
                                        i),
1607
                                        (LinearRing[]) ((ArrayList) holesForShells.get(i)).toArray(
1608
                                                        new LinearRing[0]));
1609
                        polygons[i].setSRID(srid);
1610
                }
1611
                
1612

    
1613
                holesForShells = null;
1614
                shells = null;
1615
                holes = null;
1616

    
1617
                geoJTS = geomFactory.createMultiPolygon(polygons);
1618
                geoJTS.setSRID(srid);
1619
                
1620
                return geoJTS;
1621
        }
1622

    
1623
        /* public static GeometryCollection convertFGeometryCollection(FGeometryCollection fGeomC)
1624
    {
1625

1626
        geomFactory.createGeometryCollection(theGeoms);
1627
    } */
1628
}