Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2058 / libraries / libFMap_geometries / src / org / gvsig / fmap / geom / util / Converter.java @ 39246

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
        case Geometry.TYPES.SPLINE:
414
                        arrayLines = new ArrayList();
415
                        theIterator = shp.getPathIterator(null, manager.getFlatness());
416

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

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

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

    
440
                                        arrayCoords.add(coord);
441

    
442
                                        break;
443

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

    
448
                                        break;
449

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

    
453
                                        break;
454

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

    
458
                                        break;
459

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

    
465
                                        break;
466
                                } //end switch
467

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

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

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

    
491
                        break;
492

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

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

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

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

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

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

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

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

    
548
                                                        return null;
549
                                                }
550

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

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

    
569
                                        break;
570

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

    
575
                                        break;
576

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

    
580
                                        break;
581

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

    
585
                                        break;
586

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

    
592
                                        break;
593
                                } //end switch
594

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

    
599

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

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

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

    
647
                                return null;
648
                        }
649

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

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

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

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

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

    
673
                                        Envelope tryEnv = tryRing.getEnvelopeInternal();
674

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

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

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

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

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

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

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

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

    
734
                        // FIN CAMBIO
735

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

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

    
751
                        break;
752

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

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

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

    
768
                }
769

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

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

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

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

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

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

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

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

    
853
                return resul;
854
        }
855

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

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

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

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

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

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

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

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

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

    
927

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

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

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

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

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

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

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

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

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

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

    
997

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

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

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

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

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

    
1041
                                break;
1042

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

    
1046
                                break;
1047

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

    
1051
                                break;
1052
                        } //end switch
1053

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

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

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

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

    
1074

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

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

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

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

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

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

    
1125
                                break;
1126
                        } //end switch
1127

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1323
                                break;
1324

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

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

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

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

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

    
1383
                arrayLines = new ArrayList();
1384

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

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

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

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

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

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

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

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

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

    
1438
                                                return null;
1439
                                        }
1440

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

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

    
1459
                                break;
1460

    
1461
                        case PathIterator.SEG_LINETO:
1462

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

    
1466
                                break;
1467

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

    
1471
                                break;
1472

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

    
1476
                                break;
1477

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

    
1483
                                break;
1484
                        } //end switch
1485

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

    
1490

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

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

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

    
1534
                        return null;
1535
                }
1536

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

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

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

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

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

    
1560
                                Envelope tryEnv = tryRing.getEnvelopeInternal();
1561

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

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

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

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

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

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

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

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

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

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

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