Statistics
| Revision:

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

History | View | Annotate | Download (45.8 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 DAL Geometry
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
                                    /*
152
                                     * A loop is not needed here because manager 
153
                                     * correctly creates and appends a primitive (surface)
154
                                     * each time there is a move_to in the GeneralPathX
155
                                     */
156
                                        shpNew = geomManager.createMultiSurface(toShape((MultiPolygon) geo), SUBTYPES.GEOM2D);
157
                                }
158

    
159
                                if (geo instanceof LineString) {
160
                                        shpNew = geomManager.createCurve(toShape((LineString) geo), SUBTYPES.GEOM2D);
161
                                }
162

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

    
175
                        return shpNew;
176
                } catch (NoninvertibleTransformException e) {
177
                        e.printStackTrace();
178
                }
179

    
180
                return null;
181

    
182
                //
183
                //                FShape shape = Converter.jts_to_java2d(jtsGeometry);
184
                //                return factory.createGeometry(shape);
185
        }
186

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

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

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

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

    
242
        public static com.vividsolutions.jts.geom.Geometry geometryToJtsWithSRID(
243
                        Geometry geom, int srid) {
244
                // logger.debug(geom.getClass());
245
                // logger.debug(new Integer(geom.getShapeType()));
246
                return geometryToJts(geom, geom.getType(), srid);
247
        }
248

    
249

    
250
        public static com.vividsolutions.jts.geom.Geometry geometryToJts(Geometry geom) {
251
                //logger.debug(geom.getClass());
252
                //logger.debug(new Integer(geom.getShapeType()));
253
                return geometryToJts(geom, geom.getType(), -1);
254
        }
255

    
256
        //        public static com.vividsolutions.jts.geom.Geometry java2d_to_jts(FShape shp) {
257
        //                return java2d_to_jts(shp, shp.getShapeType());
258
        //        }
259

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

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

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

    
282
                ArrayList arrayLines;
283
                LineString lin = null;
284
                PathIterator theIterator;
285
                int theType;
286
                int numParts = 0;
287
                double[] theData = new double[6];
288
                ArrayList arrayCoords = null;
289
                Coordinate coord;
290
                int subType = shp.getGeometryType().getSubType();
291
                boolean is3D = subType == 1 || subType == 3;
292

    
293
                arrayLines = new ArrayList();
294
                //El pathIterator no tiene en cuenta coordenadas 3D
295
                //theIterator = pol.getPathIterator(null, manager.getFlatness());
296
                GeneralPathX gp = shp.getGeneralPath();
297

    
298
                //while (!theIterator.isDone()) {
299
                int numCoords = gp.getNumCoords();
300
                if(gp.isClosed())
301
                        numCoords ++;
302
                for (int nPoint = 0; nPoint < numCoords; nPoint++) {
303
                        if(nPoint < gp.getNumCoords()) {
304
                                theData = gp.getCoordinatesAt(nPoint);
305
                        } 
306
                        theType = gp.getTypeAt(nPoint);
307

    
308
                        //Populate a segment of the new
309
                        // GeneralPathX object.
310
                        //Process the current segment to populate a new
311
                        // segment of the new GeneralPathX object.
312
                        switch (theType) {
313
                        case PathIterator.SEG_MOVETO:
314
                                if (arrayCoords == null) {
315
                                        arrayCoords = new ArrayList();
316
                                } else {
317
                                        lin = geomFactory.createLineString(
318
                                                        CoordinateArrays.toCoordinateArray(arrayCoords));
319
                                        lin.setSRID(srid);
320
                                        arrayLines.add(lin);
321
                                        arrayCoords = new ArrayList();
322
                                }
323

    
324
                                numParts++;
325
                                if(is3D)
326
                                        coord = new Coordinate(theData[0], theData[1], theData[2]);
327
                                else
328
                                        coord = new Coordinate(theData[0], theData[1]);
329

    
330
                                arrayCoords.add(coord);
331
                                break;
332

    
333
                        case PathIterator.SEG_LINETO:
334
                                if(is3D)
335
                                        arrayCoords.add(new Coordinate(theData[0], theData[1], theData[2]));
336
                                else
337
                                        arrayCoords.add(new Coordinate(theData[0], theData[1]));
338
                                break;
339

    
340
                        case PathIterator.SEG_QUADTO:
341
                                System.out.println("Not supported here");
342
                                break;
343

    
344
                        case PathIterator.SEG_CUBICTO:
345
                                System.out.println("Not supported here");
346
                                break;
347

    
348
                        case PathIterator.SEG_CLOSE:
349
                                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
350
                                if(is3D)
351
                                        arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y, firstCoord.z));
352
                                else
353
                                        arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y));
354
                                break;
355
                        } //end switch
356

    
357
                        //theIterator.next();
358
                } //end while loop
359

    
360
                if (arrayCoords.size() < 2) {
361

    
362
                } else {
363
                        lin = new com.vividsolutions.jts.geom.GeometryFactory().createLineString(
364
                                        CoordinateArrays.toCoordinateArray(arrayCoords));
365
                        lin.setSRID(srid);
366
                }
367

    
368
                return lin;
369
        }
370

    
371
        /**
372
         * Convierte un Geometry de DAL a una Geometry del JTS. Para ello, utilizamos un
373
         * flattened PathIterator. El flattened indica que las curvas las pasa a
374
         * segmentos de linea recta AUTOMATICAMENTE!!!.
375
         *
376
         * @param shp FShape que se quiere convertir.
377
         *
378
         * @return Geometry de JTS.
379
         */
380
        private static com.vividsolutions.jts.geom.Geometry geometryToJts(
381
                        Geometry shp, int shapeType, int srid) {
382

    
383

    
384
                com.vividsolutions.jts.geom.Geometry geoJTS = null;
385
                Coordinate coord;
386
                ArrayList arrayCoords = null;
387
                ArrayList arrayLines;
388
                LineString lin;
389
                int theType;
390
                int numParts = 0;
391
                int subType = shp.getGeometryType().getSubType();
392
                boolean is3D = subType == 1 || subType == 3;
393

    
394
                //Use this array to store segment coordinate data
395
                double[] theData = new double[6];
396
                PathIterator theIterator;
397

    
398

    
399
                switch (shapeType) {
400
                case Geometry.TYPES.POINT:
401
                        if(is3D) {
402
                                org.gvsig.fmap.geom.primitive.impl.Point2DZ p = (org.gvsig.fmap.geom.primitive.impl.Point2DZ) shp;
403
                                coord = new Coordinate(p.getX(), p.getY(), p.getCoordinateAt(Geometry.DIMENSIONS.Z));
404
                        } else {
405
                                org.gvsig.fmap.geom.primitive.impl.Point2D p = (org.gvsig.fmap.geom.primitive.impl.Point2D) shp;
406
                                coord = new Coordinate(p.getX(), p.getY());
407
                        }
408
                        geoJTS = geomFactory.createPoint(coord);
409
                        geoJTS.setSRID(srid);
410
                        break;
411

    
412
                        /*case Geometry.TYPES.MULTIPOINT:
413
                    org.gvsig.fmap.geom.aggregate.impl.MultiPoint2D mp = (org.gvsig.fmap.geom.aggregate.impl.MultiPoint2D) shp;
414
                    int numPoints = mp.getPrimitivesNumber();
415
                    Coordinate[] coordinates = new Coordinate[numPoints];
416
                    for(int i=0; i<numPoints; i++){
417
                        p = mp.getPoint(i);
418
                        coordinates[i]=new Coordinate(p.getX(), p.getY());
419
                    }
420
                    geoJTS = geomFactory.createMultiPoint(coordinates);
421
                    geoJTS.setSRID(srid);
422

423
                    break;*/
424

    
425
                case Geometry.TYPES.CURVE:
426
                case Geometry.TYPES.ARC:
427
        case Geometry.TYPES.SPLINE:
428
                        arrayLines = new ArrayList();
429
                        //El pathIterator no tiene en cuenta coordenadas 3D
430
                        //theIterator = pol.getPathIterator(null, manager.getFlatness());
431
                        GeneralPathX gp = shp.getGeneralPath();
432

    
433
                        //while (!theIterator.isDone()) {
434
                        int numCoords = gp.getNumCoords();
435
                        for (int nPoint = 0; nPoint < numCoords; nPoint++) {
436
                                theData = gp.getCoordinatesAt(nPoint);
437
                                theType = gp.getTypeAt(nPoint);
438

    
439
                                //Populate a segment of the new
440
                                // GeneralPathX object.
441
                                //Process the current segment to populate a new
442
                                // segment of the new GeneralPathX object.
443
                                switch (theType) {
444
                                case PathIterator.SEG_MOVETO:
445
                                        if (arrayCoords == null) {
446
                                                arrayCoords = new ArrayList();
447
                                        } else {
448
                                                lin = geomFactory.createLineString(CoordinateArrays.toCoordinateArray(arrayCoords));
449
                                                lin.setSRID(srid);
450
                                                arrayLines.add(lin);
451
                                                arrayCoords = new ArrayList();
452
                                        }
453

    
454
                                        numParts++;
455
                                        if(is3D)
456
                                                coord = new Coordinate(theData[0], theData[1], theData[2]);
457
                                        else
458
                                                coord = new Coordinate(theData[0], theData[1]);
459
                                        
460
                                        arrayCoords.add(coord);
461
                                        break;
462

    
463
                                case PathIterator.SEG_LINETO:
464
                                        if(is3D)
465
                                                arrayCoords.add(new Coordinate(theData[0], theData[1], theData[2]));
466
                                        else
467
                                                arrayCoords.add(new Coordinate(theData[0], theData[1]));
468
                                        break;
469

    
470
                                case PathIterator.SEG_QUADTO:
471
                                        System.out.println("Not supported here");
472
                                        break;
473

    
474
                                case PathIterator.SEG_CUBICTO:
475
                                        System.out.println("Not supported here");
476
                                        break;
477

    
478
                                case PathIterator.SEG_CLOSE:
479
                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
480
                                        if(is3D)
481
                                                arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y, firstCoord.z));
482
                                        else
483
                                                arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y));
484
                                        break;
485
                                } //end switch
486

    
487
                                //theIterator.next();
488
                        } //end while loop
489

    
490
                        if (arrayCoords.size() < 2) {
491
                                break;
492
                        }
493
                        lin = new com.vividsolutions.jts.geom.GeometryFactory().createLineString(
494
                                        CoordinateArrays.toCoordinateArray(arrayCoords));
495

    
496
                        lin.setSRID(srid);
497
                        // CAMBIO: ENTREGAMOS SIEMPRE MULTILINESTRING, QUE ES
498
                        // LO QUE HACE TO_DO EL MUNDO CUANDO ESCRIBE EN POSTGIS
499
                        // O CON GEOTOOLS
500
                        // if (numParts > 1) // Generamos una MultiLineString
501
                        //  {
502
                        arrayLines.add(lin);
503
                        geoJTS = geomFactory.createMultiLineString(
504
                                        com.vividsolutions.jts.geom.GeometryFactory.toLineStringArray(arrayLines));
505
                        geoJTS.setSRID(srid);
506
                        break;
507

    
508
                case Geometry.TYPES.SURFACE:
509
                case Geometry.TYPES.CIRCLE:
510
                case Geometry.TYPES.ELLIPSE:
511
                        arrayLines = new ArrayList();
512

    
513
                        ArrayList shells = new ArrayList();
514
                        ArrayList holes = new ArrayList();
515
                        Coordinate[] points = null;
516

    
517
                        //El pathIterator no tiene en cuenta coordenadas 3D
518
                        //theIterator = pol.getPathIterator(null, manager.getFlatness());
519
                        GeneralPathX gp1 = shp.getGeneralPath();
520

    
521
                        //while (!theIterator.isDone()) {
522
                        for (int nPoint = 0; nPoint < gp1.getNumCoords(); nPoint++) {
523
                                theData = gp1.getCoordinatesAt(nPoint);
524
                                theType = gp1.getTypeAt(nPoint);
525

    
526
                                //Populate a segment of the new
527
                                // GeneralPathX object.
528
                                //Process the current segment to populate a new
529
                                // segment of the new GeneralPathX object.
530
                                switch (theType) {
531
                                case PathIterator.SEG_MOVETO:
532
                                        if (arrayCoords == null) {
533
                                                arrayCoords = new ArrayList();
534
                                        } else {
535
                                                points = CoordinateArrays.toCoordinateArray(arrayCoords);
536

    
537
                                                try {
538
                                                        LinearRing ring = geomFactory.createLinearRing(points);
539

    
540
                                                        if (CGAlgorithms.isCCW(points)) {
541
                                                                holes.add(ring);
542
                                                        } else {
543
                                                                shells.add(ring);
544
                                                        }
545
                                                } catch (Exception e) {
546
                                                        boolean same = true;
547
                                                        for (int i = 0; i < points.length-1 && same; i++) {
548
                                                                if (points[i].x != points[i+1].x ||
549
                                                                                points[i].y != points[i+1].y /*||
550
                                                                                points[i].z != points[i+1].z*/
551
                                                                ) {
552
                                                                        same = false;
553
                                                                }
554
                                                        }
555
                                                        if (same) {
556
                                                                return geomFactory.createPoint(points[0]);
557
                                                        }
558
                                                        if (points.length>1 && points.length <= 3) {
559
                                                                // return geomFactory.createLineString(points);
560
                                                                return geomFactory.createMultiLineString(new LineString[] {geomFactory.createLineString(points)});
561
                                                        }
562

    
563
                                                        System.err.println(
564
                                                        "Caught Topology exception in GMLLinearRingHandler");
565

    
566
                                                        return null;
567
                                                }
568

    
569
                                                /* if (numParts == 1)
570
                                                 {
571
                                                 linRingExt = new GeometryFactory().createLinearRing(
572
                                                 CoordinateArrays.toCoordinateArray(arrayCoords));
573
                                                 }
574
                                                 else
575
                                                 {
576
                                                 linRing = new GeometryFactory().createLinearRing(
577
                                                 CoordinateArrays.toCoordinateArray(arrayCoords));
578
                                                 arrayLines.add(linRing);
579
                                                 } */
580
                                                arrayCoords = new ArrayList();
581
                                        }
582

    
583
                                        numParts++;
584
                                        if(is3D)
585
                                                arrayCoords.add(new Coordinate(theData[0], theData[1], theData[2]));
586
                                        else
587
                                                arrayCoords.add(new Coordinate(theData[0], theData[1]));
588
                                        break;
589

    
590
                                case PathIterator.SEG_LINETO:
591
                                        if(is3D)
592
                                                arrayCoords.add(new Coordinate(theData[0], theData[1], theData[2]));
593
                                        else
594
                                                arrayCoords.add(new Coordinate(theData[0], theData[1]));
595
                                        break;
596

    
597
                                case PathIterator.SEG_QUADTO:
598
                                        System.out.println("SEG_QUADTO Not supported here");
599

    
600
                                        break;
601

    
602
                                case PathIterator.SEG_CUBICTO:
603
                                        System.out.println("SEG_CUBICTO Not supported here");
604
                                        break;
605

    
606
                                case PathIterator.SEG_CLOSE:
607
                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
608
                                        if(is3D)
609
                                                arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y, firstCoord.z));
610
                                        else
611
                                                arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y));
612
                                        break;
613
                                } //end switch
614

    
615
                                //theIterator.next();
616
                        } //end while loop
617

    
618

    
619
                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
620
                        Coordinate lastCoord = (Coordinate) arrayCoords.get(arrayCoords.size() - 1);
621
                        if (!isClosed(firstCoord, lastCoord)) {
622
                                arrayCoords.add(firstCoord);
623
                        }
624
                        points = CoordinateArrays.toCoordinateArray(arrayCoords);
625

    
626
                        try {
627
                                LinearRing ring = geomFactory.createLinearRing(points);
628

    
629
                                if (CGAlgorithms.isCCW(points)) {
630
                                        holes.add(ring);
631
                                } else {
632
                                        shells.add(ring);
633
                                }
634
                                ring.setSRID(srid);
635
                        } catch (Exception e) {
636
                                boolean same = true;
637
                                for (int i = 0; i < points.length-1 && same; i++) {
638
                                        if (points[i].x != points[i+1].x ||
639
                                                        points[i].y != points[i+1].y /*||
640
                                                        points[i].z != points[i+1].z*/
641
                                        ) {
642
                                                same = false;
643
                                        }
644
                                }
645
                                if (same) {
646
                                        geoJTS = geomFactory.createPoint(points[0]);
647
                                        geoJTS.setSRID(srid);
648
                                        return geoJTS;
649
                                }
650
                                /*
651
                                 * caso cuando es una linea de 3 puntos, no creo un LinearRing, sino
652
                                 * una linea
653
                                 */
654
                                if (points.length > 1 && points.length <= 3) {
655
                                        // return geomFactory.createLineString(points);
656
                                        geoJTS = geomFactory.createMultiLineString(new LineString[] { geomFactory.createLineString(points) });
657
                                        geoJTS.setSRID(srid);
658
                                        return geoJTS;
659
                                }
660
                                System.err.println("Caught Topology exception in GMLLinearRingHandler");
661

    
662
                                return null;
663
                        }
664

    
665
                        /* linRing = new GeometryFactory().createLinearRing(
666
                         CoordinateArrays.toCoordinateArray(arrayCoords)); */
667

    
668
                        // System.out.println("NumParts = " + numParts);
669
                        //now we have a list of all shells and all holes
670
                        ArrayList holesForShells = new ArrayList(shells.size());
671

    
672
                        for (int i = 0; i < shells.size(); i++) {
673
                                holesForShells.add(new ArrayList());
674
                        }
675

    
676
                        //find homes
677
                        for (int i = 0; i < holes.size(); i++) {
678
                                LinearRing testRing = (LinearRing) holes.get(i);
679
                                LinearRing minShell = null;
680
                                Envelope minEnv = null;
681
                                Envelope testEnv = testRing.getEnvelopeInternal();
682
                                Coordinate testPt = testRing.getCoordinateN(0);
683
                                LinearRing tryRing = null;
684

    
685
                                for (int j = 0; j < shells.size(); j++) {
686
                                        tryRing = (LinearRing) shells.get(j);
687

    
688
                                        Envelope tryEnv = tryRing.getEnvelopeInternal();
689

    
690
                                        if (minShell != null) {
691
                                                minEnv = minShell.getEnvelopeInternal();
692
                                        }
693

    
694
                                        boolean isContained = false;
695
                                        Coordinate[] coordList = tryRing.getCoordinates();
696

    
697
                                        if (tryEnv.contains(testEnv) &&
698
                                                        (CGAlgorithms.isPointInRing(testPt, coordList) ||
699
                                                                        (pointInList(testPt, coordList)))) {
700
                                                isContained = true;
701
                                        }
702

    
703
                                        // check if this new containing ring is smaller than the current minimum ring
704
                                        if (isContained) {
705
                                                if ((minShell == null) || minEnv.contains(tryEnv)) {
706
                                                        minShell = tryRing;
707
                                                }
708
                                        }
709
                                }
710

    
711
                                if (minShell == null) {
712
                                        //                                        System.out.println(
713
                                        //                                        polygon found with a hole thats not inside a shell);
714
                                        //                                        azabala: we do the assumption that this hole is really a shell (polygon)
715
                                        //                                        whose point werent digitized in the right order
716
                                        Coordinate[] cs = testRing.getCoordinates();
717
                                        Coordinate[] reversed = new Coordinate[cs.length];
718
                                        int pointIndex = 0;
719
                                        for(int z = cs.length-1; z >= 0; z--){
720
                                                reversed[pointIndex] = cs[z];
721
                                                pointIndex++;
722
                                        }
723
                                        LinearRing newRing = geomFactory.createLinearRing(reversed);
724
                                        shells.add(newRing);
725
                                        holesForShells.add(new ArrayList());
726
                                } else {
727
                                        ((ArrayList) holesForShells.get(shells.indexOf(minShell))).add(testRing);
728
                                }
729
                        }
730

    
731
                        Polygon[] polygons = new Polygon[shells.size()];
732

    
733
                        for (int i = 0; i < shells.size(); i++) {
734
                                polygons[i] = geomFactory.createPolygon(
735
                                                (LinearRing) shells.get(i),
736
                                                (LinearRing[]) ((ArrayList) holesForShells.get(i)).toArray(new LinearRing[0]));
737
                                polygons[i].setSRID(srid);
738
                        }
739
                        // CAMBIO: ENTREGAMOS SIEMPRE MULTILINESTRING, QUE ES
740
                        // LO QUE HACE TO_DO EL MUNDO CUANDO ESCRIBE EN POSTGIS
741
                        // O CON GEOTOOLS
742
                        // if (numParts > 1) // Generamos una MultiLineString
743

    
744
                        /* if (polygons.length == 1) {
745
                         return polygons[0];
746
                         } */
747

    
748
                        // FIN CAMBIO
749

    
750
                        holesForShells = null;
751
                        shells = null;
752
                        holes = null;
753

    
754
                        if (polygons.length == 1) {
755
                                geoJTS = polygons[0];
756
                        } else {
757
                                // its a multi part
758
                                geoJTS = geomFactory.createMultiPolygon(polygons);
759
                        }
760
                        geoJTS.setSRID(srid);
761
                        //its a multi part
762
                        //geoJTS = geomFactory.createMultiPolygon(polygons);
763
                        //geoJTS.setSRID(srid);
764

    
765
                        break;
766

    
767
                case Geometry.TYPES.MULTICURVE:
768
                        geoJTS = multiCurveToJts((MultiCurve)shp, srid);
769
                        geoJTS.setSRID(srid);
770
                        break;
771

    
772
                case Geometry.TYPES.MULTIPOINT:
773
                        geoJTS = geometryToJts((MultiPoint)shp);
774
                        geoJTS.setSRID(srid);
775
                        break;
776

    
777
                case Geometry.TYPES.MULTISURFACE:
778
                        geoJTS = multiSurfaceToJts((MultiSurface)shp, srid);
779
                        geoJTS.setSRID(srid);
780
                        break;
781
                }
782

    
783
                geoJTS.setSRID(srid);
784
                return geoJTS;
785
        }
786

    
787
        /**
788
         * DOCUMENT ME!
789
         *
790
         * @param p DOCUMENT ME!
791
         *
792
         * @return DOCUMENT ME!
793
         */
794
        private static GeneralPathX toShape(Polygon p) {
795
                GeneralPathX resul = new GeneralPathX();
796
                Coordinate coord;
797

    
798
                for (int i = 0; i < p.getExteriorRing().getNumPoints(); i++) {
799
                        coord = p.getExteriorRing().getCoordinateN(i);
800

    
801
                        if (i == 0) {
802
                                resul.moveTo(coord.x, coord.y);
803
                        } else {
804
                                resul.lineTo(coord.x, coord.y);
805
                        }
806
                }
807

    
808
                for (int j = 0; j < p.getNumInteriorRing(); j++) {
809
                        LineString hole = p.getInteriorRingN(j);
810

    
811
                        for (int k = 0; k < hole.getNumPoints(); k++) {
812
                                coord = hole.getCoordinateN(k);
813

    
814
                                if (k == 0) {
815
                                        resul.moveTo(coord.x, coord.y);
816
                                } else {
817
                                        resul.lineTo(coord.x, coord.y);
818
                                }
819
                        }
820
                }
821

    
822
                return resul;
823
        }
824

    
825
        /**
826
         * DOCUMENT ME!
827
         *
828
         * @param modelCoordinates DOCUMENT ME!
829
         *
830
         * @return DOCUMENT ME!
831
         *
832
         * @throws NoninvertibleTransformException DOCUMENT ME!
833
         *
834
        private Coordinate[] toViewCoordinates(Coordinate[] modelCoordinates)
835
                throws NoninvertibleTransformException {
836
                Coordinate[] viewCoordinates = new Coordinate[modelCoordinates.length];
837

838
                for (int i = 0; i < modelCoordinates.length; i++) {
839
                        FPoint2D point2D = coordinate2FPoint2D(modelCoordinates[i]);
840
                        viewCoordinates[i] = new Coordinate(point2D.getX(), point2D.getY());
841
                }
842

843
                return viewCoordinates;
844
        } 
845
         * @throws CreateGeometryException */
846

    
847
        /* private Shape toShape(GeometryCollection gc)
848
           throws NoninvertibleTransformException {
849
           GeometryCollectionShape shape = new GeometryCollectionShape();
850
           for (int i = 0; i < gc.getNumGeometries(); i++) {
851
                   Geometry g = (Geometry) gc.getGeometryN(i);
852
                   shape.add(toShape(g));
853
           }
854
           return shape;
855
           } */
856
        private static GeneralPathX toShape(MultiLineString mls)
857
        throws NoninvertibleTransformException, CreateGeometryException {
858
                GeneralPathX path = new GeneralPathX();
859

    
860
                for (int i = 0; i < mls.getNumGeometries(); i++) {
861
                        LineString lineString = (LineString) mls.getGeometryN(i);
862
                        path.append(toShape(lineString).getPathIterator(null), false);
863
                }
864

    
865
                //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
866
                //converted to GeneralPathXs. [Jon Aquino]
867
                return path;
868
        }
869

    
870
        /**
871
         * DOCUMENT ME!
872
         *
873
         * @param lineString DOCUMENT ME!
874
         *
875
         * @return DOCUMENT ME!
876
         *
877
         * @throws NoninvertibleTransformException DOCUMENT ME!
878
         * @throws CreateGeometryException 
879
         */
880
        private static GeneralPathX toShape(LineString lineString)
881
        throws NoninvertibleTransformException, CreateGeometryException {
882
                GeneralPathX shape = new GeneralPathX();
883
                org.gvsig.fmap.geom.primitive.Point viewPoint = coordinate2FPoint2D(lineString.getCoordinateN(0));
884
                shape.moveTo(viewPoint.getX(), viewPoint.getY());
885

    
886
                for (int i = 1; i < lineString.getNumPoints(); i++) {
887
                        viewPoint = coordinate2FPoint2D(lineString.getCoordinateN(i));
888
                        shape.lineTo(viewPoint.getX(), viewPoint.getY());
889
                }
890

    
891
                //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
892
                //converted to GeneralPathXs. [Jon Aquino]
893
                return shape;
894
        }
895

    
896

    
897
        /**
898
         *
899
         */
900
        private static GeneralPathX toShape(MultiPolygon mp)
901
        throws NoninvertibleTransformException {
902
                GeneralPathX path = new GeneralPathX();
903

    
904
                for (int i = 0; i < mp.getNumGeometries(); i++) {
905
                        Polygon polygon = (Polygon) mp.getGeometryN(i);
906
                        path.append(toShape(polygon).getPathIterator(null), false);
907
                }
908

    
909
                //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
910
                //converted to GeneralPathXs. [Jon Aquino]
911
                return path;
912
        }
913
        /**
914
         * DOCUMENT ME!
915
         *
916
         * @param coord DOCUMENT ME!
917
         *
918
         * @return DOCUMENT ME!
919
         * @throws CreateGeometryException 
920
         */
921
        public static org.gvsig.fmap.geom.primitive.Point coordinate2FPoint2D(Coordinate coord) throws CreateGeometryException {
922
                return geomManager.createPoint(coord.x, coord.y, SUBTYPES.GEOM2D); //,coord.z);
923
        }
924

    
925
        /**
926
         * Convierte una Geometry de JTS a GeneralPathX.
927
         *
928
         * @param geometry Geometry a convertir.
929
         *
930
         * @return GeneralPathX.
931
         *
932
         * @throws NoninvertibleTransformException
933
         * @throws CreateGeometryException 
934
         * @throws IllegalArgumentException
935
         */
936
        public static GeneralPathX toShape(com.vividsolutions.jts.geom.Geometry geometry)
937
        throws NoninvertibleTransformException, CreateGeometryException {
938
                if (geometry.isEmpty()) {
939
                        return new GeneralPathX();
940
                }
941

    
942
                if (geometry instanceof Polygon) {
943
                        return toShape((Polygon) geometry);
944
                }
945

    
946
                if (geometry instanceof MultiPolygon) {
947
                        return toShape((MultiPolygon) geometry);
948
                }
949

    
950
                if (geometry instanceof LineString) {
951
                        return toShape((LineString) geometry);
952
                }
953

    
954
                if (geometry instanceof MultiLineString) {
955
                        return toShape((MultiLineString) geometry);
956
                }
957

    
958
                if (geometry instanceof GeometryCollection) {
959
                        return toShape(geometry);
960
                }
961

    
962
                throw new IllegalArgumentException("Unrecognized Geometry class: " +
963
                                geometry.getClass());
964
        }
965

    
966

    
967
        public static GeneralPathX transformToInts(GeneralPathX gp, AffineTransform at) {
968
                GeneralPathX newGp = new GeneralPathX();
969
                PathIterator theIterator;
970
                int theType;
971
                int numParts = 0;
972
                double[] theData = new double[6];
973
                java.awt.geom.Point2D ptDst = new java.awt.geom.Point2D.Double();
974
                java.awt.geom.Point2D ptSrc = new java.awt.geom.Point2D.Double();
975
                boolean bFirst = true;
976
                int xInt, yInt, antX = -1, antY = -1;
977

    
978
                theIterator = gp.getPathIterator(null); //, flatness);
979

    
980
                while (!theIterator.isDone()) {
981
                        theType = theIterator.currentSegment(theData);
982
                        switch (theType) {
983
                        case PathIterator.SEG_MOVETO:
984
                                numParts++;
985
                                ptSrc.setLocation(theData[0], theData[1]);
986
                                at.transform(ptSrc, ptDst);
987
                                antX = (int) ptDst.getX();
988
                                antY = (int) ptDst.getY();
989
                                newGp.moveTo(antX, antY);
990
                                bFirst = true;
991
                                break;
992

    
993
                        case PathIterator.SEG_LINETO:
994
                                ptSrc.setLocation(theData[0], theData[1]);
995
                                at.transform(ptSrc, ptDst);
996
                                xInt = (int) ptDst.getX();
997
                                yInt = (int) ptDst.getY();
998
                                if ((bFirst) || ((xInt != antX) || (yInt != antY)))
999
                                {
1000
                                        newGp.lineTo(xInt, yInt);
1001
                                        antX = xInt;
1002
                                        antY = yInt;
1003
                                        bFirst = false;
1004
                                }
1005
                                break;
1006

    
1007
                        case PathIterator.SEG_QUADTO:
1008
                                System.out.println("Not supported here");
1009

    
1010
                                break;
1011

    
1012
                        case PathIterator.SEG_CUBICTO:
1013
                                System.out.println("Not supported here");
1014

    
1015
                                break;
1016

    
1017
                        case PathIterator.SEG_CLOSE:
1018
                                newGp.closePath();
1019

    
1020
                                break;
1021
                        } //end switch
1022

    
1023
                        theIterator.next();
1024
                } //end while loop
1025

    
1026
                return newGp;
1027
        }
1028
        public static Geometry transformToInts(Geometry gp, AffineTransform at) throws CreateGeometryException {
1029
                GeneralPathX newGp = new GeneralPathX();
1030
                double[] theData = new double[6];
1031
                double[] aux = new double[6];
1032

    
1033
                // newGp.reset();
1034
                PathIterator theIterator;
1035
                int theType;
1036
                int numParts = 0;
1037

    
1038
                java.awt.geom.Point2D ptDst = new java.awt.geom.Point2D.Double();
1039
                java.awt.geom.Point2D ptSrc = new java.awt.geom.Point2D.Double();
1040
                boolean bFirst = true;
1041
                int xInt, yInt, antX = -1, antY = -1;
1042

    
1043

    
1044
                theIterator = gp.getPathIterator(null); //, flatness);
1045
                int numSegmentsAdded = 0;
1046
                while (!theIterator.isDone()) {
1047
                        theType = theIterator.currentSegment(theData);
1048

    
1049
                        switch (theType) {
1050
                        case PathIterator.SEG_MOVETO:
1051
                                numParts++;
1052
                                ptSrc.setLocation(theData[0], theData[1]);
1053
                                at.transform(ptSrc, ptDst);
1054
                                antX = (int) ptDst.getX();
1055
                                antY = (int) ptDst.getY();
1056
                                newGp.moveTo(antX, antY);
1057
                                numSegmentsAdded++;
1058
                                bFirst = true;
1059
                                break;
1060

    
1061
                        case PathIterator.SEG_LINETO:
1062
                                ptSrc.setLocation(theData[0], theData[1]);
1063
                                at.transform(ptSrc, ptDst);
1064
                                xInt = (int) ptDst.getX();
1065
                                yInt = (int) ptDst.getY();
1066
                                if ((bFirst) || ((xInt != antX) || (yInt != antY)))
1067
                                {
1068
                                        newGp.lineTo(xInt, yInt);
1069
                                        antX = xInt;
1070
                                        antY = yInt;
1071
                                        bFirst = false;
1072
                                        numSegmentsAdded++;
1073
                                }
1074
                                break;
1075

    
1076
                        case PathIterator.SEG_QUADTO:
1077
                                at.transform(theData,0,aux,0,2);
1078
                                newGp.quadTo(aux[0], aux[1], aux[2], aux[3]);
1079
                                numSegmentsAdded++;
1080
                                break;
1081

    
1082
                        case PathIterator.SEG_CUBICTO:
1083
                                at.transform(theData,0,aux,0,3);
1084
                                newGp.curveTo(aux[0], aux[1], aux[2], aux[3], aux[4], aux[5]);
1085
                                numSegmentsAdded++;
1086
                                break;
1087

    
1088
                        case PathIterator.SEG_CLOSE:
1089
                                if (numSegmentsAdded < 3) {
1090
                                        newGp.lineTo(antX, antY);
1091
                                }
1092
                                newGp.closePath();
1093

    
1094
                                break;
1095
                        } //end switch
1096

    
1097
                        theIterator.next();
1098
                } //end while loop
1099

    
1100
                Geometry shp = null;
1101
                switch (gp.getType())
1102
                {
1103
                case Geometry.TYPES.POINT:
1104
                        shp = geomManager.createPoint(ptDst.getX(), ptDst.getY(), SUBTYPES.GEOM2D); 
1105
                        break;
1106

    
1107
                case Geometry.TYPES.CURVE:
1108
                case Geometry.TYPES.ARC:
1109
                        try {
1110
                                shp = geomManager.createCurve(newGp, SUBTYPES.GEOM2D);
1111
                        } catch (CreateGeometryException e1) {
1112
                                logger.error("Error creating a curve", e1);
1113
                        }
1114
                        break;
1115

    
1116
                case Geometry.TYPES.SURFACE:
1117
                case Geometry.TYPES.CIRCLE:
1118
                case Geometry.TYPES.ELLIPSE:
1119

    
1120
                        try {
1121
                                shp = geomManager.createSurface(newGp, SUBTYPES.GEOM2D);
1122
                        } catch (CreateGeometryException e) {
1123
                                logger.error("Error creating a surface", e);
1124
                        }
1125
                        break;
1126
                }
1127
                return shp;
1128
        }
1129

    
1130
        public static Rectangle2D convertEnvelopeToRectangle2D(Envelope jtsR) {
1131
                Rectangle2D.Double r = new Rectangle2D.Double(jtsR.getMinX(),
1132
                                jtsR.getMinY(), jtsR.getWidth(), jtsR.getHeight());
1133
                return r;
1134
        }
1135

    
1136
        public static Envelope convertEnvelopeToJTS(org.gvsig.fmap.geom.primitive.Envelope r) {
1137
                Envelope e = new Envelope(r.getMinimum(0), r.getMaximum(0), r.getMinimum(1),
1138
                                r.getMaximum(1));
1139
                return e;
1140
        }
1141

    
1142
        /**
1143
         * Return a correct polygon (no hole)
1144
         * @param coordinates
1145
         * @return
1146
         */
1147
        public static Geometry getExteriorPolygon(Coordinate[] coordinates) {
1148
                // isCCW = true => it's a hole
1149
                Coordinate[] vs = new Coordinate[coordinates.length];
1150
                if (CGAlgorithms.isCCW(coordinates)) {
1151
                        for (int i = vs.length-1;i >= 0; i--){
1152
                                vs[i] = coordinates[i];
1153
                        }
1154
                } else {
1155
                        vs = coordinates;
1156
                }
1157
                LinearRing ring = geomFactory.createLinearRing(vs);
1158

    
1159
                try {
1160
                        Surface surface = (Surface)manager.create(TYPES.SURFACE, SUBTYPES.GEOM2D);
1161
                        surface.setGeneralPath(toShape(ring));
1162
                        return surface;
1163
                } catch (NoninvertibleTransformException e) {
1164
                        e.printStackTrace();
1165
                } catch (CreateGeometryException e) {
1166
                        e.printStackTrace();
1167
                }
1168
                return null;
1169
        }
1170

    
1171
        public static boolean isCCW(Point[] points) {
1172
                int length = points.length;
1173
                Coordinate[] vs;
1174

    
1175
                if (points[0].getX() != points[length-1].getX() || points[0].getY() != points[length-1].getY()) {
1176
                        vs=new Coordinate[length+1];
1177
                        vs[points.length] = new Coordinate(points[0].getX(), points[0].getY());
1178
                } else {
1179
                        vs=new Coordinate[length];
1180
                }
1181
                for (int i = 0; i < length; i++) {
1182
                        vs[i] = new Coordinate(points[i].getX(), points[i].getY());
1183
                }
1184

    
1185
                return CGAlgorithms.isCCW(vs);
1186
        }
1187

    
1188
        public static boolean isCCW(Surface pol) {
1189
                com.vividsolutions.jts.geom.Geometry jtsGeom = Converter.geometryToJts(pol);
1190
                if (jtsGeom.getNumGeometries() == 1) {
1191
                        Coordinate[] coords = jtsGeom.getCoordinates();
1192
                        return CGAlgorithms.isCCW(coords);
1193
                }
1194
                return false;
1195
        }
1196

    
1197
        /**
1198
         * Return a hole (CCW ordered points)
1199
         * @param coordinates
1200
         * @return
1201
         */
1202
        public static Geometry getHole(Coordinate[] coordinates) {
1203
                Coordinate[] vs = new Coordinate[coordinates.length];
1204
                if (CGAlgorithms.isCCW(coordinates)) {
1205
                        vs=coordinates;
1206

    
1207
                }else{
1208
                        for (int i = vs.length-1; i >= 0; i--) {
1209
                                vs[i] = coordinates[i];
1210
                        }
1211
                }
1212
                LinearRing ring = geomFactory.createLinearRing(vs);
1213

    
1214
                try {
1215
                        Surface surface = (Surface)manager.create(TYPES.SURFACE, SUBTYPES.GEOM2D);
1216
                        surface.setGeneralPath(toShape(ring));
1217
                        return surface;
1218
                } catch (NoninvertibleTransformException e) {
1219
                        e.printStackTrace();
1220
                } catch (CreateGeometryException e) {
1221
                        e.printStackTrace();
1222
                }
1223
                return null;
1224
        }
1225

    
1226
        public static Shape getExteriorPolygon(GeneralPathX gp) {
1227
                Area area = new Area(gp);
1228
                area.isSingular();
1229
                return area;
1230
        }
1231
        
1232
        /**
1233
         * Use it ONLY for NOT multipart polygons.
1234
         * @param pol
1235
         * @return
1236
         */
1237
        public static Geometry getNotHolePolygon(Surface pol) {
1238
                // isCCW == true => hole
1239
                Coordinate[] coords;
1240
                ArrayList arrayCoords = null;
1241
                int theType;
1242
                int numParts = 0;
1243

    
1244
                //Use this array to store segment coordinate data
1245
                double[] theData = new double[4];
1246

    
1247
                ArrayList shells = new ArrayList();
1248
                ArrayList holes = new ArrayList();
1249
                Coordinate[] points = null;
1250
                
1251
                int subType = pol.getGeometryType().getSubType();
1252
                boolean is3D = subType == 1 || subType == 3;
1253
                
1254
                //El pathIterator no tiene en cuenta coordenadas 3D
1255
                //theIterator = pol.getPathIterator(null, manager.getFlatness());
1256
                GeneralPathX gp = pol.getGeneralPath();
1257

    
1258
                //while (!theIterator.isDone()) {
1259
                for (int nPoint = 0; nPoint < gp.getNumCoords(); nPoint++) {
1260
                        theData = gp.getCoordinatesAt(nPoint);
1261
                        theType = gp.getTypeAt(nPoint);
1262

    
1263
                        //Populate a segment of the new
1264
                        // GeneralPathX object.
1265
                        //Process the current segment to populate a new
1266
                        // segment of the new GeneralPathX object.
1267
                        switch (theType) {
1268
                        case PathIterator.SEG_MOVETO:
1269

    
1270
                                // System.out.println("SEG_MOVETO");
1271
                                if (arrayCoords == null) {
1272
                                        arrayCoords = new ArrayList();
1273
                                } else {
1274
                                        points = CoordinateArrays.toCoordinateArray(arrayCoords);
1275

    
1276
                                        try {
1277
                                                LinearRing ring = geomFactory.createLinearRing(points);
1278

    
1279
                                                if (CGAlgorithms.isCCW(points)) {
1280
                                                        holes.add(ring);
1281
                                                } else {
1282
                                                        shells.add(ring);
1283
                                                }
1284
                                        } catch (Exception e) {
1285
                                                System.err.println("Caught Topology exception in GMLLinearRingHandler");
1286

    
1287
                                                return null;
1288
                                        }
1289
                                        arrayCoords = new ArrayList();
1290
                                }
1291

    
1292
                                numParts++;
1293
                                if(is3D)
1294
                                        arrayCoords.add(new Coordinate(theData[0], theData[1], theData[2]));
1295
                                else
1296
                                        arrayCoords.add(new Coordinate(theData[0], theData[1]));
1297

    
1298
                                break;
1299

    
1300
                        case PathIterator.SEG_LINETO:
1301
                                if(is3D)
1302
                                        arrayCoords.add(new Coordinate(theData[0], theData[1], theData[2]));
1303
                                else
1304
                                        arrayCoords.add(new Coordinate(theData[0], theData[1]));
1305
                                break;
1306
                        case PathIterator.SEG_QUADTO:
1307
                                System.out.println("SEG_QUADTO Not supported here");
1308
                                break;
1309
                        case PathIterator.SEG_CUBICTO:
1310
                                System.out.println("SEG_CUBICTO Not supported here");
1311
                                break;
1312
                        case PathIterator.SEG_CLOSE:
1313
                                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
1314
                                if(is3D)
1315
                                        arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y, firstCoord.z));
1316
                                else
1317
                                        arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y));
1318
                                break;
1319
                        } //end switch
1320

    
1321
                        //theIterator.next();
1322
                } //end while loop
1323

    
1324
                arrayCoords.add(arrayCoords.get(0));
1325
                coords = CoordinateArrays.toCoordinateArray(arrayCoords);
1326

    
1327
                if (numParts == 1) {
1328
                        return getExteriorPolygon(coords);
1329
                }
1330
                return pol;
1331
        }
1332

    
1333
        /**
1334
         * Metodo creado para construir un MultiSurface formado por varias surface
1335
         * 
1336
         * @author Leticia Riestra
1337
         * @param geom
1338
         * @return
1339
         */
1340
        public static com.vividsolutions.jts.geom.Geometry multiSurfaceToJts(MultiSurface geom, int srid) {
1341
                Polygon[] polygons = new Polygon[geom.getPrimitivesNumber()];
1342
                for (int i = 0; i < polygons.length; i++){
1343
                        MultiPolygon polygon = (MultiPolygon)surfaceToJts((geom.getPrimitiveAt(i)), srid);
1344
                        
1345
                        polygons[i] = (Polygon)polygon.getGeometryN(0);//(Polygon) surfaceToJts((geom.getPrimitiveAt(i)), srid);
1346
                }
1347
                return new com.vividsolutions.jts.geom.GeometryFactory().createMultiPolygon(polygons);
1348
        }
1349
        
1350
        private static com.vividsolutions.jts.geom.Geometry surfaceToJts(Geometry shp, int srid) {
1351
                com.vividsolutions.jts.geom.Geometry geoJTS = null;
1352
                PathIterator theIterator;
1353
                int theType;
1354
                int numParts = 0;
1355
                double[] theData = new double[4];
1356
                ArrayList arrayCoords = null;
1357
                int subType = shp.getGeometryType().getSubType();
1358
                boolean is3D = subType == 1 || subType == 3;
1359

    
1360

    
1361
                ArrayList shells = new ArrayList();
1362
                ArrayList holes = new ArrayList();
1363
                Coordinate[] points = null;
1364
                
1365
                //El pathIterator no tiene en cuenta coordenadas 3D
1366
                //theIterator = shp.getPathIterator(null, manager.getFlatness());
1367
                GeneralPathX gp = shp.getGeneralPath();
1368

    
1369
                //while (!theIterator.isDone()) {
1370
                for (int nPoint = 0; nPoint < gp.getNumCoords(); nPoint++) {
1371
                        theData = gp.getCoordinatesAt(nPoint);
1372
                        theType = gp.getTypeAt(nPoint);
1373
                        //theType = theIterator.currentSegment(theData);
1374

    
1375
                        //Populate a segment of the new
1376
                        // GeneralPathX object.
1377
                        //Process the current segment to populate a new
1378
                        // segment of the new GeneralPathX object.
1379
                        switch (theType) {
1380
                        case PathIterator.SEG_MOVETO:
1381

    
1382
                                // System.out.println("SEG_MOVETO");
1383
                                if (arrayCoords == null) {
1384
                                        arrayCoords = new ArrayList();
1385
                                } else {
1386
                                        points = CoordinateArrays.toCoordinateArray(arrayCoords);
1387

    
1388
                                        try {
1389
                                                LinearRing ring = geomFactory.createLinearRing(points);
1390

    
1391
                                                if (CGAlgorithms.isCCW(points)) {
1392
                                                        holes.add(ring);
1393
                                                } else {
1394
                                                        shells.add(ring);
1395
                                                }
1396
                                        } catch (Exception e) {
1397
                                                boolean same = true;
1398
                                                for (int i = 0; i < points.length-1 && same; i++) {
1399
                                                        if (points[i].x != points[i+1].x ||
1400
                                                                        points[i].y != points[i+1].y /*||
1401
                                                                        points[i].z != points[i+1].z*/
1402
                                                        ) {
1403
                                                                same = false;
1404
                                                        }
1405
                                                }
1406
                                                if (same) {
1407
                                                        return geomFactory.createPoint(points[0]);
1408
                                                }
1409

    
1410
                                                if (points.length > 1 && points.length <= 3) {
1411
                                                        // return geomFactory.createLineString(points);
1412
                                                        return geomFactory.createMultiLineString(new LineString[] {geomFactory.createLineString(points)});
1413
                                                }
1414

    
1415
                                                System.err.println(
1416
                                                "Caught Topology exception in GMLLinearRingHandler");
1417

    
1418
                                                return null;
1419
                                        }
1420

    
1421
                                        /* if (numParts == 1)
1422
                                         {
1423
                                         linRingExt = new GeometryFactory().createLinearRing(
1424
                                         CoordinateArrays.toCoordinateArray(arrayCoords));
1425
                                         }
1426
                                         else
1427
                                         {
1428
                                         linRing = new GeometryFactory().createLinearRing(
1429
                                         CoordinateArrays.toCoordinateArray(arrayCoords));
1430
                                         arrayLines.add(linRing);
1431
                                         } */
1432
                                        arrayCoords = new ArrayList();
1433
                                }
1434

    
1435
                                numParts++;
1436
                                if(is3D)
1437
                                        arrayCoords.add(new Coordinate(theData[0], theData[1], theData[2]));
1438
                                else
1439
                                        arrayCoords.add(new Coordinate(theData[0], theData[1]));
1440
                                break;
1441

    
1442
                        case PathIterator.SEG_LINETO:
1443
                                if(is3D)
1444
                                        arrayCoords.add(new Coordinate(theData[0], theData[1], theData[2]));
1445
                                else
1446
                                        arrayCoords.add(new Coordinate(theData[0], theData[1]));
1447
                                break;
1448

    
1449
                        case PathIterator.SEG_QUADTO:
1450
                                System.out.println("SEG_QUADTO Not supported here");
1451
                                break;
1452

    
1453
                        case PathIterator.SEG_CUBICTO:
1454
                                System.out.println("SEG_CUBICTO Not supported here");
1455
                                break;
1456

    
1457
                        case PathIterator.SEG_CLOSE:
1458
                                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
1459
                                if(is3D)
1460
                                        arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y, firstCoord.z));
1461
                                else
1462
                                        arrayCoords.add(new Coordinate(firstCoord.x, firstCoord.y));
1463

    
1464
                                break;
1465
                        } //end switch
1466

    
1467
                        // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
1468
                        //theIterator.next();
1469
                } //end while loop
1470

    
1471

    
1472
                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
1473
                Coordinate lastCoord = (Coordinate) arrayCoords.get(arrayCoords.size() - 1);
1474
                
1475
                if (!isClosed(firstCoord, lastCoord)) {
1476
                        arrayCoords.add(firstCoord);
1477
                }
1478
                points = CoordinateArrays.toCoordinateArray(arrayCoords);
1479

    
1480
                try {
1481
                        LinearRing ring = geomFactory.createLinearRing(points);
1482

    
1483
                        if (CGAlgorithms.isCCW(points)) {
1484
                                holes.add(ring);
1485
                        } else {
1486
                                shells.add(ring);
1487
                        }
1488
                        ring.setSRID(srid);
1489
                } catch (Exception e) {
1490
                        boolean same = true;
1491
                        for (int i = 0; i < points.length-1 && same; i++) {
1492
                                if (points[i].x != points[i+1].x ||
1493
                                                points[i].y != points[i+1].y /*||
1494
                                                points[i].z != points[i+1].z*/
1495
                                ) {
1496
                                        same = false;
1497
                                }
1498
                        }
1499
                        if (same) {
1500
                                geoJTS = geomFactory.createPoint(points[0]);
1501
                                geoJTS.setSRID(srid);
1502
                                return geoJTS;
1503
                        }
1504
                        if (points.length > 1 && points.length <= 3) {
1505
                                // return geomFactory.createLineString(points);
1506
                                geoJTS = geomFactory
1507
                                .createMultiLineString(new LineString[] { geomFactory
1508
                                                .createLineString(points) });
1509
                                geoJTS.setSRID(srid);
1510
                                return geoJTS;
1511
                        }
1512
                        System.err.println(
1513
                        "Caught Topology exception in GMLLinearRingHandler");
1514

    
1515
                        return null;
1516
                }
1517

    
1518
                /* linRing = new GeometryFactory().createLinearRing(
1519
                 CoordinateArrays.toCoordinateArray(arrayCoords)); */
1520

    
1521
                // System.out.println("NumParts = " + numParts);
1522
                //now we have a list of all shells and all holes
1523
                ArrayList holesForShells = new ArrayList(shells.size());
1524

    
1525
                for (int i = 0; i < shells.size(); i++) {
1526
                        holesForShells.add(new ArrayList());
1527
                }
1528

    
1529
                //find homes
1530
                for (int i = 0; i < holes.size(); i++) {
1531
                        LinearRing testRing = (LinearRing) holes.get(i);
1532
                        LinearRing minShell = null;
1533
                        Envelope minEnv = null;
1534
                        Envelope testEnv = testRing.getEnvelopeInternal();
1535
                        Coordinate testPt = testRing.getCoordinateN(0);
1536
                        LinearRing tryRing = null;
1537

    
1538
                        for (int j = 0; j < shells.size(); j++) {
1539
                                tryRing = (LinearRing) shells.get(j);
1540

    
1541
                                Envelope tryEnv = tryRing.getEnvelopeInternal();
1542

    
1543
                                if (minShell != null) {
1544
                                        minEnv = minShell.getEnvelopeInternal();
1545
                                }
1546

    
1547
                                boolean isContained = false;
1548
                                Coordinate[] coordList = tryRing.getCoordinates();
1549

    
1550
                                if (tryEnv.contains(testEnv) &&
1551
                                                (CGAlgorithms.isPointInRing(testPt, coordList) ||
1552
                                                                (pointInList(testPt, coordList)))) {
1553
                                        isContained = true;
1554
                                }
1555

    
1556
                                // check if this new containing ring is smaller than the current minimum ring
1557
                                if (isContained) {
1558
                                        if ((minShell == null) || minEnv.contains(tryEnv)) {
1559
                                                minShell = tryRing;
1560
                                        }
1561
                                }
1562
                        }
1563

    
1564
                        if (minShell == null) {
1565
                                //                                        System.out.println(
1566
                                //                                        polygon found with a hole thats not inside a shell);
1567
                                //                                        azabala: we do the assumption that this hole is really a shell (polygon)
1568
                                //                                        whose point werent digitized in the right order
1569
                                Coordinate[] cs = testRing.getCoordinates();
1570
                                Coordinate[] reversed = new Coordinate[cs.length];
1571
                                int pointIndex = 0;
1572
                                for(int z = cs.length-1; z >= 0; z--){
1573
                                        reversed[pointIndex] = cs[z];
1574
                                        pointIndex++;
1575
                                }
1576
                                LinearRing newRing = geomFactory.createLinearRing(reversed);
1577
                                shells.add(newRing);
1578
                                holesForShells.add(new ArrayList());
1579
                        } else {
1580
                                ((ArrayList) holesForShells.get(shells.indexOf(minShell))).add(testRing);
1581
                        }
1582
                }
1583

    
1584
                Polygon[] polygons = new Polygon[shells.size()];
1585

    
1586
                for (int i = 0; i < shells.size(); i++) {
1587
                        polygons[i] = geomFactory.createPolygon(
1588
                                        (LinearRing) shells.get(i),
1589
                                        (LinearRing[]) ((ArrayList) holesForShells.get(i)).toArray(new LinearRing[0]));
1590
                        polygons[i].setSRID(srid);
1591
                }
1592
                
1593

    
1594
                holesForShells = null;
1595
                shells = null;
1596
                holes = null;
1597

    
1598
                geoJTS = geomFactory.createMultiPolygon(polygons);
1599
                geoJTS.setSRID(srid);
1600
                
1601
                return geoJTS;
1602
        }
1603

    
1604
}