Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.geometry / org.gvsig.fmap.geometry.impl / src / main / java / org / gvsig / fmap / geom / util / Converter.java @ 41216

History | View | Annotate | Download (54.5 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.geom.util;
25

    
26
import java.awt.Shape;
27
import java.awt.geom.AffineTransform;
28
import java.awt.geom.Area;
29
import java.awt.geom.NoninvertibleTransformException;
30
import java.awt.geom.PathIterator;
31
import java.awt.geom.Rectangle2D;
32
import java.lang.reflect.Array;
33
import java.util.ArrayList;
34
import java.util.List;
35

    
36
import org.gvsig.fmap.geom.Geometry;
37
import org.gvsig.fmap.geom.GeometryLocator;
38
import org.gvsig.fmap.geom.GeometryManager;
39
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
40
import org.gvsig.fmap.geom.Geometry.TYPES;
41
import org.gvsig.fmap.geom.aggregate.MultiCurve;
42
import org.gvsig.fmap.geom.aggregate.MultiPoint;
43
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
44
import org.gvsig.fmap.geom.aggregate.MultiSurface;
45
import org.gvsig.fmap.geom.exception.CreateGeometryException;
46
import org.gvsig.fmap.geom.primitive.Curve;
47
import org.gvsig.fmap.geom.primitive.GeneralPathX;
48
import org.gvsig.fmap.geom.primitive.Primitive;
49
import org.gvsig.fmap.geom.primitive.Surface;
50
import org.slf4j.Logger;
51
import org.slf4j.LoggerFactory;
52

    
53
import com.vividsolutions.jts.algorithm.CGAlgorithms;
54
import com.vividsolutions.jts.algorithm.RobustCGAlgorithms;
55
import com.vividsolutions.jts.geom.Coordinate;
56
import com.vividsolutions.jts.geom.CoordinateArrays;
57
import com.vividsolutions.jts.geom.Envelope;
58
import com.vividsolutions.jts.geom.GeometryCollection;
59
import com.vividsolutions.jts.geom.LineString;
60
import com.vividsolutions.jts.geom.LinearRing;
61
import com.vividsolutions.jts.geom.MultiLineString;
62
import com.vividsolutions.jts.geom.MultiPolygon;
63
import com.vividsolutions.jts.geom.Point;
64
import com.vividsolutions.jts.geom.Polygon;
65

    
66
/**
67
 * Clase con varios metodos estaticos utilizados para pasar de java2d a jts
68
 * y viceversa.
69
 * 
70
 * @author fjp
71
 * @deprecated to be removed or moved from API to implementation in gvSIG 2.1.0
72
 */
73
public class Converter {
74
        private static final GeometryManager geomManager = GeometryLocator.getGeometryManager();
75
        private static final Logger logger = LoggerFactory.getLogger(Converter.class);
76
        public final static com.vividsolutions.jts.geom.GeometryFactory geomFactory = new com.vividsolutions.jts.geom.GeometryFactory();
77
        public static CGAlgorithms cga = new RobustCGAlgorithms();
78

    
79
        private static GeometryManager manager = GeometryLocator.getGeometryManager();
80

    
81
        //returns true if testPoint is a point in the pointList list.
82
        static boolean pointInList(Coordinate testPoint, Coordinate[] pointList) {
83
                int t;
84
                int numpoints;
85
                Coordinate p;
86

    
87
                numpoints = Array.getLength(pointList);
88

    
89
                for (t = 0; t < numpoints; t++) {
90
                        p = pointList[t];
91

    
92
                        if ((testPoint.x == p.x) && (testPoint.y == p.y) &&
93
                                        ((testPoint.z == p.z) || (!(testPoint.z == testPoint.z))) //nan test; x!=x iff x is nan
94
                        ) {
95
                                return true;
96
                        }
97
                }
98

    
99
                return false;
100
        }
101

    
102
        /**
103
         * Receives a JTS Geometry and returns a DAL Geometry
104
         * @param jtsGeometry jts Geometry
105
         * @return IGeometry of FMap
106
         * @author azabala
107
         * @throws CreateGeometryException 
108
         */
109
        public static Geometry jtsToGeometry(com.vividsolutions.jts.geom.Geometry geo) throws CreateGeometryException{
110
                Geometry shpNew = null;
111

    
112
                try {
113
                        if (geo instanceof Point) {
114
                                shpNew = geomManager.createPoint(((Point) geo).getX(),((Point) geo).getY(), SUBTYPES.GEOM2D);
115
                        }
116

    
117
                        if (geo.isEmpty()) {
118
                                shpNew = null;
119
                        }
120

    
121
                        try{
122
                                if (geo instanceof com.vividsolutions.jts.geom.MultiPoint) {
123
                                        shpNew = geomManager.create(TYPES.MULTIPOINT, SUBTYPES.GEOM2D);
124
                                        for (int i = 0; i < geo.getNumGeometries(); i++) {
125
                                                Point point = (Point) geo.getGeometryN(i);
126
                                                ((MultiPoint)shpNew).addPoint((org.gvsig.fmap.geom.primitive.Point) jtsToGeometry(point));
127
                                        }
128
                                        
129
                                }
130
                                
131
                                if (geo instanceof Polygon) {
132
                                        shpNew = geomManager.createSurface(toShape((Polygon) geo), SUBTYPES.GEOM2D);
133
                                }
134

    
135
                                if (geo instanceof MultiPolygon) {
136
                                    /*
137
                                     * We need a loop because a global path would not
138
                                     * differentiate between move-to inside a polygon (holes)
139
                                     * and move-to from one polygon to another
140
                                     */
141
                                    MultiSurface msu = geomManager.createMultiSurface(SUBTYPES.GEOM2D);
142
                                    MultiPolygon mpo = (MultiPolygon) geo;
143
                                    Surface itemsu = null;
144
                                    int npo = mpo.getNumGeometries();
145
                                    for (int i=0; i<npo; i++) {
146
                                        itemsu = geomManager.createSurface(
147
                                            toShape((Polygon) mpo.getGeometryN(i)), SUBTYPES.GEOM2D);
148
                                        msu.addPrimitive(itemsu);
149
                                    }
150
                                        shpNew = msu;
151
                                }
152

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

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

    
169
                        return shpNew;
170
                } catch (NoninvertibleTransformException e) {
171
                        e.printStackTrace();
172
                }
173

    
174
                return null;
175
        }
176

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

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

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

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

    
240
        public static com.vividsolutions.jts.geom.Geometry geometryToJtsWithSRID(Geometry geom, int srid) {
241
                return geometryToJts(geom, geom.getType(), srid);
242
        }
243
        
244
        public static com.vividsolutions.jts.geom.Geometry geometryToJtsWithSRIDForcingType(Geometry geom, int srid, int type) {
245
                return geometryToJts(geom, type, srid);
246
        }
247

    
248

    
249
        public static com.vividsolutions.jts.geom.Geometry geometryToJts(Geometry geom) {
250
                return geometryToJts(geom, geom.getType(), -1);
251
        }
252

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

    
265
        private static com.vividsolutions.jts.geom.Geometry curveToJts(Geometry shp, int srid){
266
                ArrayList arrayLines;
267
                LineString lin = null;
268
                int theType;
269
                int numParts = 0;
270
                double[] dataLine = new double[3];
271
                double[] dataQuad = new double[3];
272
                double[] dataCubic = new double[3];
273
                ArrayList arrayCoords = null;
274
                Coordinate coord;
275
                int subType = shp.getGeometryType().getSubType();
276
                boolean is3D = subType == 1 || subType == 3;
277

    
278
                arrayLines = new ArrayList();
279
                
280
                //El pathIterator no tiene en cuenta coordenadas 3D, por lo que de usar este, las Z's se perder?n
281
                //Las splines vienen con todos los puntos calculados por lo que no es necesario un 
282
                //iterador que interpole. Por esto obtenemos el mismo resultado recorriendo los puntos.
283
                //Tiene su riesgo pero hasta que se soporte el 3D en el iterador funciona para todos los casos
284
                
285
                //theIterator = pol.getPathIterator(null, manager.getFlatness());
286
                GeneralPathX gp = shp.getGeneralPath();
287

    
288
                //while (!theIterator.isDone()) {
289
                int nPoint = 0;
290
                for (int nType = 0; nType < gp.getNumTypes(); nType++) {        
291
                        theType = gp.getTypeAt(nType);
292
                        switch (theType) {
293
                        case PathIterator.SEG_MOVETO:
294
                        case PathIterator.SEG_LINETO: //Se lee un punto
295
                                dataLine = gp.get3DCoordinatesAt(nPoint);
296
                                nPoint ++;
297
                                break;
298
                        case PathIterator.SEG_QUADTO: //Se leen dos puntos
299
                                dataLine = gp.get3DCoordinatesAt(nPoint);
300
                                dataQuad = gp.get3DCoordinatesAt(nPoint + 1);
301
                                nPoint += 2;
302
                                break;
303
                        case PathIterator.SEG_CUBICTO: //Se leen tres puntos
304
                                dataLine = gp.get3DCoordinatesAt(nPoint);
305
                                dataQuad = gp.get3DCoordinatesAt(nPoint + 1);
306
                                dataCubic = gp.get3DCoordinatesAt(nPoint + 2);
307
                                nPoint += 3;
308
                                break;
309
                        }
310

    
311
                        switch (theType) {
312
                        case PathIterator.SEG_MOVETO:
313
                                if (arrayCoords == null) {
314
                                        arrayCoords = new ArrayList();
315
                                } else {
316
                                        lin = geomFactory.createLineString(
317
                                                        CoordinateArrays.toCoordinateArray(arrayCoords));
318
                                        lin.setSRID(srid);
319
                                        arrayLines.add(lin);
320
                                        arrayCoords = new ArrayList();
321
                                }
322

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

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

    
332
                        case PathIterator.SEG_LINETO:
333
                                loadArrayCoordinates(arrayCoords, is3D, dataLine);
334
                                break;
335

    
336
                        case PathIterator.SEG_QUADTO:
337
                                loadArrayCoordinates(arrayCoords, is3D, dataLine);
338
                                loadArrayCoordinates(arrayCoords, is3D, dataQuad);
339
                                break;
340

    
341
                        case PathIterator.SEG_CUBICTO:
342
                                loadArrayCoordinates(arrayCoords, is3D, dataLine);
343
                                loadArrayCoordinates(arrayCoords, is3D, dataQuad);
344
                                loadArrayCoordinates(arrayCoords, is3D, dataCubic);
345
                                break;
346

    
347
                        case PathIterator.SEG_CLOSE:
348
                                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
349
                                loadArrayCoordinates(arrayCoords, is3D, new double[]{firstCoord.x, firstCoord.y, firstCoord.z});
350
                                break;
351
                        } //end switch
352

    
353
                        //theIterator.next();
354
                } //end while loop
355

    
356
                if (arrayCoords.size() < 2) {
357

    
358
                } else {
359
                        lin = new com.vividsolutions.jts.geom.GeometryFactory().createLineString(
360
                                        CoordinateArrays.toCoordinateArray(arrayCoords));
361
                        lin.setSRID(srid);
362
                }
363

    
364
                return lin;
365
        }
366
        
367
        /**
368
         * Convierte un Geometry de DAL a una Geometry del JTS. Para ello, utilizamos un
369
         * flattened PathIterator. El flattened indica que las curvas las pasa a
370
         * segmentos de linea recta AUTOMATICAMENTE!!!.
371
         *
372
         * @param shp FShape que se quiere convertir.
373
         *
374
         * @return Geometry de JTS.
375
         */
376
        private static com.vividsolutions.jts.geom.Geometry geometryToJts(
377
                        Geometry shp, int destinationType, int srid) {
378
                com.vividsolutions.jts.geom.Geometry geoJTS = null;
379
                Coordinate coord;
380
                ArrayList arrayCoords = null;
381
                ArrayList arrayLines;
382
                LineString lin;
383
                int theType;
384
                int numParts = 0;
385
                int sourceType = shp.getGeometryType().getType();
386
                int subType = shp.getGeometryType().getSubType();
387
                boolean is3D = subType == 1 || subType == 3;
388
                
389
                //Use this array to store segment coordinate data
390
                double[] dataLine = new double[3];
391
                double[] dataQuad = new double[3];
392
                double[] dataCubic = new double[3];
393

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

    
407
                case Geometry.TYPES.CURVE:
408
                case Geometry.TYPES.ARC:
409
        case Geometry.TYPES.SPLINE:
410
        case Geometry.TYPES.ELLIPTICARC:
411

    
412
                        arrayLines = new ArrayList();
413
                        
414
                        //El pathIterator no tiene en cuenta coordenadas 3D, por lo que de usar este, las Z's se perder?n
415
                        //Las splines vienen con todos los puntos calculados por lo que no es necesario un 
416
                        //iterador que interpole. Por esto obtenemos el mismo resultado recorriendo los puntos.
417
                        //Tiene su riesgo pero hasta que se soporte el 3D en el iterador funciona para todos los casos
418
                        
419
                        //theIterator = pol.getPathIterator(null, manager.getFlatness());
420
                        GeneralPathX gp = shp.getGeneralPath();
421

    
422
                        //while (!theIterator.isDone()) {
423
                        int nPoint = 0;
424
                        for (int nType = 0; nType < gp.getNumTypes(); nType++) {        
425
                                theType = gp.getTypeAt(nType);
426
                                switch (theType) {
427
                                case PathIterator.SEG_MOVETO:
428
                                case PathIterator.SEG_LINETO: //Se lee un punto
429
                                        dataLine = gp.get3DCoordinatesAt(nPoint);
430
                                        nPoint ++;
431
                                        break;
432
                                case PathIterator.SEG_QUADTO: //Se leen dos puntos
433
                                        dataLine = gp.get3DCoordinatesAt(nPoint);
434
                                        dataQuad = gp.get3DCoordinatesAt(nPoint + 1);
435
                                        nPoint += 2;
436
                                        break;
437
                                case PathIterator.SEG_CUBICTO: //Se leen tres puntos
438
                                        dataLine = gp.get3DCoordinatesAt(nPoint);
439
                                        dataQuad = gp.get3DCoordinatesAt(nPoint + 1);
440
                                        dataCubic = gp.get3DCoordinatesAt(nPoint + 2);
441
                                        nPoint += 3;
442
                                        break;
443
                                }
444

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

    
460
                                        numParts++;
461
                                        if(is3D)
462
                                                coord = new Coordinate(dataLine[0], dataLine[1], dataLine[2]);
463
                                        else
464
                                                coord = new Coordinate(dataLine[0], dataLine[1]);
465
                                        
466
                                        arrayCoords.add(coord);
467
                                        break;
468

    
469
                                case PathIterator.SEG_LINETO:
470
                                        loadArrayCoordinates(arrayCoords, is3D, dataLine);
471
                                        break;
472

    
473
                                case PathIterator.SEG_QUADTO:
474
                                        loadArrayCoordinates(arrayCoords, is3D, dataLine);
475
                                        loadArrayCoordinates(arrayCoords, is3D, dataQuad);
476
                                        break;
477

    
478
                                case PathIterator.SEG_CUBICTO:
479
                                        loadArrayCoordinates(arrayCoords, is3D, dataLine);
480
                                        loadArrayCoordinates(arrayCoords, is3D, dataQuad);
481
                                        loadArrayCoordinates(arrayCoords, is3D, dataCubic);
482
                                        break;
483

    
484
                                case PathIterator.SEG_CLOSE:
485
                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
486
                                        loadArrayCoordinates(arrayCoords, is3D, new double[]{firstCoord.x, firstCoord.y, firstCoord.z});
487
                                        break;
488
                                } //end switch
489

    
490
                                //theIterator.next();
491
                        } //end while loop
492

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

    
499
                        lin.setSRID(srid);
500
                        geoJTS = lin;
501
                        
502
                        /*
503
                         * We were creating always a multilinestring here, but
504
                         * we have decided that we should return the correct type
505
                         * (linestring) and other parts of the application will have
506
                         * to solve the problem, it there is a problem with this.
507
                         * 
508
                        arrayLines.add(lin);
509
                        geoJTS = geomFactory.createMultiLineString(
510
                                        com.vividsolutions.jts.geom.GeometryFactory.toLineStringArray(arrayLines));
511
                        geoJTS.setSRID(srid);
512
                        */
513
                        break;
514

    
515
                case Geometry.TYPES.SURFACE:
516
                case Geometry.TYPES.CIRCLE:
517
                case Geometry.TYPES.ELLIPSE:
518
                        arrayLines = new ArrayList();
519

    
520
                        ArrayList shells = new ArrayList();
521
                        ArrayList holes = new ArrayList();
522
                        Coordinate[] points = null;
523

    
524
                        //El pathIterator no tiene en cuenta coordenadas 3D, pero para la creaci?n de elipses y circulos
525
                        //es necesario el iterador que interpole puntos. El resultado es que en la creaci?n de geometr?as de este
526
                        //tipo no se puede asignar la Z porque se perder?a, pero gvSIG tampoco dispone de esta funci?n, as? que
527
                        //no se nota. Una vez creadas las geometr?a de tipo Elipse y circulo cuando las editamos ya tendr?n todos
528
                        //los puntos calculados y se toman como l?neas por lo que ya se podr?a asignar la Z.
529
                        
530
                        PathIterator theIterator = shp.getPathIterator(null, manager.getFlatness());
531
                        while (!theIterator.isDone()) {
532
                                theType = theIterator.currentSegment(dataLine);
533
                                
534
                                switch (theType) {
535
                                case PathIterator.SEG_MOVETO:
536
                                        if (arrayCoords == null) {
537
                                                arrayCoords = new ArrayList();
538
                                        } else {
539
                                                points = CoordinateArrays.toCoordinateArray(arrayCoords);
540

    
541
                                                try {
542
                                                        LinearRing ring = geomFactory.createLinearRing(points);
543

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

    
567
                                                        System.err.println(
568
                                                        "Caught Topology exception in GMLLinearRingHandler");
569

    
570
                                                        return null;
571
                                                }
572
                                                arrayCoords = new ArrayList();
573
                                        }
574

    
575
                                        numParts++;
576
                                        loadArrayCoordinates(arrayCoords, is3D, dataLine);
577
                                        break;
578

    
579
                                case PathIterator.SEG_LINETO:
580
                                        loadArrayCoordinates(arrayCoords, is3D, dataLine);
581
                                        break;
582

    
583
                                case PathIterator.SEG_QUADTO:
584
                                        break;
585

    
586
                                case PathIterator.SEG_CUBICTO:
587
                                        break;
588

    
589
                                case PathIterator.SEG_CLOSE:
590
                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
591
                                        loadArrayCoordinates(arrayCoords, is3D, new double[]{firstCoord.x, firstCoord.y, firstCoord.z});
592
                                        break;
593
                                } //end switch
594

    
595
                                theIterator.next();
596
                        } //end while loop
597

    
598

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

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

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

    
642
                                return null;
643
                        }
644

    
645
                        /* linRing = new GeometryFactory().createLinearRing(
646
                         CoordinateArrays.toCoordinateArray(arrayCoords)); */
647

    
648
                        // System.out.println("NumParts = " + numParts);
649
                        //now we have a list of all shells and all holes
650
                        ArrayList holesForShells = new ArrayList(shells.size());
651

    
652
                        for (int i = 0; i < shells.size(); i++) {
653
                                holesForShells.add(new ArrayList());
654
                        }
655

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

    
665
                                for (int j = 0; j < shells.size(); j++) {
666
                                        tryRing = (LinearRing) shells.get(j);
667

    
668
                                        Envelope tryEnv = tryRing.getEnvelopeInternal();
669

    
670
                                        if (minShell != null) {
671
                                                minEnv = minShell.getEnvelopeInternal();
672
                                        }
673

    
674
                                        boolean isContained = false;
675
                                        Coordinate[] coordList = tryRing.getCoordinates();
676

    
677
                                        if (tryEnv.contains(testEnv) &&
678
                                                        (CGAlgorithms.isPointInRing(testPt, coordList) ||
679
                                                                        (pointInList(testPt, coordList)))) {
680
                                                isContained = true;
681
                                        }
682

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

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

    
711
                        Polygon[] polygons = new Polygon[shells.size()];
712

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

    
724
                        /* if (polygons.length == 1) {
725
                         return polygons[0];
726
                         } */
727

    
728
                        // FIN CAMBIO
729

    
730
                        holesForShells = null;
731
                        shells = null;
732
                        holes = null;
733

    
734
                        if (polygons.length == 1) {
735
                                geoJTS = polygons[0];
736
                        } else {
737
                                // its a multi part
738
                                geoJTS = geomFactory.createMultiPolygon(polygons);
739
                        }
740
                        geoJTS.setSRID(srid);
741
                        //its a multi part
742
                        //geoJTS = geomFactory.createMultiPolygon(polygons);
743
                        //geoJTS.setSRID(srid);
744

    
745
                        break;
746

    
747
                case Geometry.TYPES.MULTICURVE:
748
                        geoJTS = multiCurveToJts((MultiCurve)shp, srid);
749
                        geoJTS.setSRID(srid);
750
                        break;
751

    
752
                case Geometry.TYPES.MULTIPOINT:
753
                        geoJTS = geometryToJts((MultiPoint)shp);
754
                        geoJTS.setSRID(srid);
755
                        break;
756

    
757
                case Geometry.TYPES.MULTISURFACE:
758
                        geoJTS = multiSurfaceToJts((MultiSurface)shp, srid);
759
                        geoJTS.setSRID(srid);
760
                        break;
761
                }
762

    
763
                if(destinationType != sourceType)
764
                        geoJTS = convertTypes(geoJTS, sourceType, destinationType);
765
                
766
                geoJTS.setSRID(srid);
767
                return geoJTS;
768
        }
769
        
770
        /**
771
         * This function is called when the we need force types, that is the destination 
772
         * type does not match with the input geometry type
773
         * @param g
774
         * @param sourceType
775
         * @param destinationType
776
         * @return
777
         */
778
        private static com.vividsolutions.jts.geom.Geometry convertTypes(
779
                        com.vividsolutions.jts.geom.Geometry g,
780
                        int sourceType,
781
                        int destinationType) {
782
                if((sourceType == Geometry.TYPES.CURVE || 
783
                        sourceType == Geometry.TYPES.SPLINE || 
784
                        sourceType == Geometry.TYPES.ARC ||
785
                        sourceType == Geometry.TYPES.ELLIPTICARC) 
786
                        && destinationType == Geometry.TYPES.MULTISURFACE) {
787
                        if(g instanceof MultiLineString) {
788
                                Polygon[] poly = new Polygon[((MultiLineString)g).getNumGeometries()];
789
                                for (int i = 0; i < ((MultiLineString)g).getNumGeometries(); i++) {
790
                                        com.vividsolutions.jts.geom.Geometry lineString = ((MultiLineString)g).getGeometryN(i);
791
                                        poly[i] = convertLineStringToPolygon((LineString)lineString);
792
                                }
793
                                return geomFactory.createMultiPolygon(poly);
794
                        } else
795
                                return convertLineStringToPolygon((LineString)g);
796
                }
797
                
798
                if((sourceType == Geometry.TYPES.CIRCLE || 
799
                        sourceType == Geometry.TYPES.ELLIPSE) && 
800
                        destinationType == Geometry.TYPES.MULTICURVE) {
801
                        if(g instanceof Polygon) {
802
                                Polygon poly = (Polygon)g; 
803
                                LineString lineString = geomFactory.createLinearRing(poly.getCoordinates());
804
                                return geomFactory.createMultiLineString(new LineString[]{lineString});
805
                        }
806
                }
807
                return g;
808
        }
809

    
810
        private static com.vividsolutions.jts.geom.Polygon convertLineStringToPolygon(LineString line) {
811
                Coordinate[] coordinates = line.getCoordinates();
812
                LinearRing shell = geomFactory.createLinearRing(coordinates);
813
                Polygon pol = geomFactory.createPolygon(shell, null);
814
                return pol;
815
        }
816
        
817
        /**
818
         * DOCUMENT ME!
819
         *
820
         * @param p DOCUMENT ME!
821
         *
822
         * @return DOCUMENT ME!
823
         */
824
        private static GeneralPathX toShape(Polygon p) {
825
                GeneralPathX resul = new GeneralPathX();
826
                Coordinate coord;
827

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

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

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

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

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

    
852
                return resul;
853
        }
854

    
855

    
856
        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
        case Geometry.TYPES.ELLIPTICARC:
1110
                        try {
1111
                                shp = geomManager.createCurve(newGp, SUBTYPES.GEOM2D);
1112
                        } catch (CreateGeometryException e1) {
1113
                                logger.error("Error creating a curve", e1);
1114
                        }
1115
                        break;
1116

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1299
                                break;
1300

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

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

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

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

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

    
1367

    
1368
                ArrayList shells = new ArrayList();
1369
                ArrayList holes = new ArrayList();
1370
                Coordinate[] points = null;
1371
                
1372
                //El pathIterator no tiene en cuenta coordenadas 3D. En este caso no 
1373
                //necesitamos un iterador que interpole porque las SURFACE vienen con todos
1374
                //los puntos calculados, as? que hacemos un recorrido en vez de usar el 
1375
                //iterador para poder obtener la Z y no perderla.
1376
                
1377
                //theIterator = shp.getPathIterator(null, manager.getFlatness());
1378
                GeneralPathX gp = shp.getGeneralPath();
1379

    
1380
                //while (!theIterator.isDone()) {
1381
                int nPoint = 0;
1382
                for (int nType = 0; nType < gp.getNumTypes(); nType++) {        
1383
                        theType = gp.getTypeAt(nType);
1384
                        switch (theType) {
1385
                        case PathIterator.SEG_MOVETO:
1386
                        case PathIterator.SEG_LINETO: //Se lee un punto
1387
                                dataLine = gp.get3DCoordinatesAt(nPoint);
1388
                                nPoint ++;
1389
                                break;
1390
                        case PathIterator.SEG_QUADTO: //Se leen dos puntos
1391
                                dataLine = gp.get3DCoordinatesAt(nPoint);
1392
                                dataQuad = gp.get3DCoordinatesAt(nPoint + 1);
1393
                                nPoint += 2;
1394
                                break;
1395
                        case PathIterator.SEG_CUBICTO: //Se leen tres puntos
1396
                                dataLine = gp.get3DCoordinatesAt(nPoint);
1397
                                dataQuad = gp.get3DCoordinatesAt(nPoint + 1);
1398
                                dataCubic = gp.get3DCoordinatesAt(nPoint + 2);
1399
                                nPoint += 3;
1400
                                break;
1401
                        }
1402
                        //theType = theIterator.currentSegment(theData);
1403

    
1404
                        switch (theType) {
1405
                        case PathIterator.SEG_MOVETO:
1406

    
1407
                                // System.out.println("SEG_MOVETO");
1408
                                if (arrayCoords == null) {
1409
                                        arrayCoords = new ArrayList();
1410
                                } else {
1411
                                        points = CoordinateArrays.toCoordinateArray(arrayCoords);
1412

    
1413
                                        try {
1414
                                                LinearRing ring = geomFactory.createLinearRing(points);
1415

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

    
1435
                                                if (points.length > 1 && points.length <= 3) {
1436
                                                        // return geomFactory.createLineString(points);
1437
                                                        return geomFactory.createMultiLineString(new LineString[] {geomFactory.createLineString(points)});
1438
                                                }
1439

    
1440
                                                System.err.println(
1441
                                                "Caught Topology exception in GMLLinearRingHandler");
1442

    
1443
                                                return null;
1444
                                        }
1445

    
1446
                                        arrayCoords = new ArrayList();
1447
                                }
1448

    
1449
                                numParts++;
1450
                                loadArrayCoordinates(arrayCoords, is3D, dataLine);
1451
                                break;
1452

    
1453
                        case PathIterator.SEG_LINETO:
1454
                                loadArrayCoordinates(arrayCoords, is3D, dataLine);
1455
                                break;
1456

    
1457
                        case PathIterator.SEG_QUADTO:
1458
                                loadArrayCoordinates(arrayCoords, is3D, dataLine);
1459
                                loadArrayCoordinates(arrayCoords, is3D, dataQuad);
1460
                                break;
1461

    
1462
                        case PathIterator.SEG_CUBICTO:
1463
                                loadArrayCoordinates(arrayCoords, is3D, dataLine);
1464
                                loadArrayCoordinates(arrayCoords, is3D, dataQuad);
1465
                                loadArrayCoordinates(arrayCoords, is3D, dataCubic);
1466
                                break;
1467

    
1468
                        case PathIterator.SEG_CLOSE:
1469
                                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
1470
                                loadArrayCoordinates(arrayCoords, is3D, new double[]{firstCoord.x, firstCoord.y, firstCoord.z});
1471
                                break;
1472
                        } //end switch
1473

    
1474
                        //theIterator.next();
1475
                } //end while loop
1476

    
1477

    
1478
                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
1479
                Coordinate lastCoord = (Coordinate) arrayCoords.get(arrayCoords.size() - 1);
1480
                
1481
                if (!isClosed(firstCoord, lastCoord)) {
1482
                        arrayCoords.add(firstCoord);
1483
                }
1484
                points = CoordinateArrays.toCoordinateArray(arrayCoords);
1485

    
1486
                try {
1487
                        LinearRing ring = geomFactory.createLinearRing(points);
1488

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

    
1521
                        return null;
1522
                }
1523

    
1524
                /* linRing = new GeometryFactory().createLinearRing(
1525
                 CoordinateArrays.toCoordinateArray(arrayCoords)); */
1526

    
1527
                // System.out.println("NumParts = " + numParts);
1528
                //now we have a list of all shells and all holes
1529
                ArrayList holesForShells = new ArrayList(shells.size());
1530

    
1531
                for (int i = 0; i < shells.size(); i++) {
1532
                        holesForShells.add(new ArrayList());
1533
                }
1534

    
1535
                //find homes
1536
                for (int i = 0; i < holes.size(); i++) {
1537
                        LinearRing testRing = (LinearRing) holes.get(i);
1538
                        LinearRing minShell = null;
1539
                        Envelope minEnv = null;
1540
                        Envelope testEnv = testRing.getEnvelopeInternal();
1541
                        Coordinate testPt = testRing.getCoordinateN(0);
1542
                        LinearRing tryRing = null;
1543

    
1544
                        for (int j = 0; j < shells.size(); j++) {
1545
                                tryRing = (LinearRing) shells.get(j);
1546

    
1547
                                Envelope tryEnv = tryRing.getEnvelopeInternal();
1548

    
1549
                                if (minShell != null) {
1550
                                        minEnv = minShell.getEnvelopeInternal();
1551
                                }
1552

    
1553
                                boolean isContained = false;
1554
                                Coordinate[] coordList = tryRing.getCoordinates();
1555

    
1556
                                if (tryEnv.contains(testEnv) &&
1557
                                                (CGAlgorithms.isPointInRing(testPt, coordList) ||
1558
                                                                (pointInList(testPt, coordList)))) {
1559
                                        isContained = true;
1560
                                }
1561

    
1562
                                // check if this new containing ring is smaller than the current minimum ring
1563
                                if (isContained) {
1564
                                        if ((minShell == null) || minEnv.contains(tryEnv)) {
1565
                                                minShell = tryRing;
1566
                                        }
1567
                                }
1568
                        }
1569

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

    
1590
                Polygon[] polygons = new Polygon[shells.size()];
1591

    
1592
                for (int i = 0; i < shells.size(); i++) {
1593
                        polygons[i] = geomFactory.createPolygon(
1594
                                        (LinearRing) shells.get(i),
1595
                                        (LinearRing[]) ((ArrayList) holesForShells.get(i)).toArray(new LinearRing[0]));
1596
                        polygons[i].setSRID(srid);
1597
                }
1598
                
1599

    
1600
                holesForShells = null;
1601
                shells = null;
1602
                holes = null;
1603

    
1604
                geoJTS = geomFactory.createMultiPolygon(polygons);
1605
                geoJTS.setSRID(srid);
1606
                
1607
                return geoJTS;
1608
        }
1609
        
1610
        private static com.vividsolutions.jts.geom.Geometry ellipseToJts(Geometry shp, int srid) {
1611
                com.vividsolutions.jts.geom.Geometry geoJTS = null;
1612
                int theType;
1613
                int numParts = 0;
1614
                ArrayList arrayCoords = null;
1615
                int subType = shp.getGeometryType().getSubType();
1616
                boolean is3D = subType == 1 || subType == 3;
1617
                double[] dataLine = new double[3];
1618

    
1619

    
1620
                ArrayList shells = new ArrayList();
1621
                ArrayList holes = new ArrayList();
1622
                Coordinate[] points = null;
1623
                
1624
                //El pathIterator no tiene en cuenta coordenadas 3D, pero para la creaci?n de elipses y circulos
1625
                //es necesario el iterador que interpole puntos. El resultado es que en la creaci?n de geometr?as de este
1626
                //tipo no se puede asignar la Z porque se perder?a, pero gvSIG tampoco dispone de esta funci?n, as? que
1627
                //no se nota. Una vez creadas las geometr?a de tipo Elipse y circulo cuando las editamos ya tendr?n todos
1628
                //los puntos calculados y se toman como l?neas por lo que ya se podr?a asignar la Z.
1629
                
1630
                PathIterator theIterator = shp.getPathIterator(null, manager.getFlatness());
1631
                while (!theIterator.isDone()) {
1632
                        theType = theIterator.currentSegment(dataLine);
1633

    
1634
                        switch (theType) {
1635
                        case PathIterator.SEG_MOVETO:
1636
                                if (arrayCoords == null) {
1637
                                        arrayCoords = new ArrayList();
1638
                                } else {
1639
                                        points = CoordinateArrays.toCoordinateArray(arrayCoords);
1640

    
1641
                                        try {
1642
                                                LinearRing ring = geomFactory.createLinearRing(points);
1643

    
1644
                                                if (CGAlgorithms.isCCW(points)) {
1645
                                                        holes.add(ring);
1646
                                                } else {
1647
                                                        shells.add(ring);
1648
                                                }
1649
                                        } catch (Exception e) {
1650
                                                boolean same = true;
1651
                                                for (int i = 0; i < points.length-1 && same; i++) {
1652
                                                        if (points[i].x != points[i+1].x ||
1653
                                                                        points[i].y != points[i+1].y /*||
1654
                                                                        points[i].z != points[i+1].z*/
1655
                                                        ) {
1656
                                                                same = false;
1657
                                                        }
1658
                                                }
1659
                                                if (same) {
1660
                                                        return geomFactory.createPoint(points[0]);
1661
                                                }
1662

    
1663
                                                if (points.length > 1 && points.length <= 3) {
1664
                                                        // return geomFactory.createLineString(points);
1665
                                                        return geomFactory.createMultiLineString(new LineString[] {geomFactory.createLineString(points)});
1666
                                                }
1667

    
1668
                                                System.err.println(
1669
                                                "Caught Topology exception in GMLLinearRingHandler");
1670

    
1671
                                                return null;
1672
                                        }
1673

    
1674
                                        arrayCoords = new ArrayList();
1675
                                }
1676

    
1677
                                numParts++;
1678
                                loadArrayCoordinates(arrayCoords, is3D, dataLine);
1679
                                break;
1680

    
1681
                        case PathIterator.SEG_LINETO:
1682
                                loadArrayCoordinates(arrayCoords, is3D, dataLine);
1683
                                break;
1684

    
1685
                        case PathIterator.SEG_QUADTO:
1686
                                break;
1687

    
1688
                        case PathIterator.SEG_CUBICTO:
1689
                                break;
1690

    
1691
                        case PathIterator.SEG_CLOSE:
1692
                                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
1693
                                loadArrayCoordinates(arrayCoords, is3D, new double[]{firstCoord.x, firstCoord.y, firstCoord.z});
1694
                                break;
1695
                        } //end switch
1696

    
1697
                        theIterator.next();
1698
                } //end while loop
1699

    
1700

    
1701
                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
1702
                Coordinate lastCoord = (Coordinate) arrayCoords.get(arrayCoords.size() - 1);
1703
                
1704
                if (!isClosed(firstCoord, lastCoord)) {
1705
                        arrayCoords.add(firstCoord);
1706
                }
1707
                points = CoordinateArrays.toCoordinateArray(arrayCoords);
1708

    
1709
                try {
1710
                        LinearRing ring = geomFactory.createLinearRing(points);
1711

    
1712
                        if (CGAlgorithms.isCCW(points)) {
1713
                                holes.add(ring);
1714
                        } else {
1715
                                shells.add(ring);
1716
                        }
1717
                        ring.setSRID(srid);
1718
                } catch (Exception e) {
1719
                        boolean same = true;
1720
                        for (int i = 0; i < points.length-1 && same; i++) {
1721
                                if (points[i].x != points[i+1].x ||
1722
                                                points[i].y != points[i+1].y /*||
1723
                                                points[i].z != points[i+1].z*/
1724
                                ) {
1725
                                        same = false;
1726
                                }
1727
                        }
1728
                        if (same) {
1729
                                geoJTS = geomFactory.createPoint(points[0]);
1730
                                geoJTS.setSRID(srid);
1731
                                return geoJTS;
1732
                        }
1733
                        if (points.length > 1 && points.length <= 3) {
1734
                                // return geomFactory.createLineString(points);
1735
                                geoJTS = geomFactory
1736
                                .createMultiLineString(new LineString[] { geomFactory
1737
                                                .createLineString(points) });
1738
                                geoJTS.setSRID(srid);
1739
                                return geoJTS;
1740
                        }
1741
                        System.err.println(
1742
                        "Caught Topology exception in GMLLinearRingHandler");
1743

    
1744
                        return null;
1745
                }
1746

    
1747
                /* linRing = new GeometryFactory().createLinearRing(
1748
                 CoordinateArrays.toCoordinateArray(arrayCoords)); */
1749

    
1750
                // System.out.println("NumParts = " + numParts);
1751
                //now we have a list of all shells and all holes
1752
                ArrayList holesForShells = new ArrayList(shells.size());
1753

    
1754
                for (int i = 0; i < shells.size(); i++) {
1755
                        holesForShells.add(new ArrayList());
1756
                }
1757

    
1758
                //find homes
1759
                for (int i = 0; i < holes.size(); i++) {
1760
                        LinearRing testRing = (LinearRing) holes.get(i);
1761
                        LinearRing minShell = null;
1762
                        Envelope minEnv = null;
1763
                        Envelope testEnv = testRing.getEnvelopeInternal();
1764
                        Coordinate testPt = testRing.getCoordinateN(0);
1765
                        LinearRing tryRing = null;
1766

    
1767
                        for (int j = 0; j < shells.size(); j++) {
1768
                                tryRing = (LinearRing) shells.get(j);
1769

    
1770
                                Envelope tryEnv = tryRing.getEnvelopeInternal();
1771

    
1772
                                if (minShell != null) {
1773
                                        minEnv = minShell.getEnvelopeInternal();
1774
                                }
1775

    
1776
                                boolean isContained = false;
1777
                                Coordinate[] coordList = tryRing.getCoordinates();
1778

    
1779
                                if (tryEnv.contains(testEnv) &&
1780
                                                (CGAlgorithms.isPointInRing(testPt, coordList) ||
1781
                                                                (pointInList(testPt, coordList)))) {
1782
                                        isContained = true;
1783
                                }
1784

    
1785
                                // check if this new containing ring is smaller than the current minimum ring
1786
                                if (isContained) {
1787
                                        if ((minShell == null) || minEnv.contains(tryEnv)) {
1788
                                                minShell = tryRing;
1789
                                        }
1790
                                }
1791
                        }
1792

    
1793
                        if (minShell == null) {
1794
                                //                                        System.out.println(
1795
                                //                                        polygon found with a hole thats not inside a shell);
1796
                                //                                        azabala: we do the assumption that this hole is really a shell (polygon)
1797
                                //                                        whose point werent digitized in the right order
1798
                                Coordinate[] cs = testRing.getCoordinates();
1799
                                Coordinate[] reversed = new Coordinate[cs.length];
1800
                                int pointIndex = 0;
1801
                                for(int z = cs.length-1; z >= 0; z--){
1802
                                        reversed[pointIndex] = cs[z];
1803
                                        pointIndex++;
1804
                                }
1805
                                LinearRing newRing = geomFactory.createLinearRing(reversed);
1806
                                shells.add(newRing);
1807
                                holesForShells.add(new ArrayList());
1808
                        } else {
1809
                                ((ArrayList) holesForShells.get(shells.indexOf(minShell))).add(testRing);
1810
                        }
1811
                }
1812

    
1813
                Polygon[] polygons = new Polygon[shells.size()];
1814

    
1815
                for (int i = 0; i < shells.size(); i++) {
1816
                        polygons[i] = geomFactory.createPolygon(
1817
                                        (LinearRing) shells.get(i),
1818
                                        (LinearRing[]) ((ArrayList) holesForShells.get(i)).toArray(new LinearRing[0]));
1819
                        polygons[i].setSRID(srid);
1820
                }
1821
                
1822

    
1823
                holesForShells = null;
1824
                shells = null;
1825
                holes = null;
1826

    
1827
                geoJTS = geomFactory.createMultiPolygon(polygons);
1828
                geoJTS.setSRID(srid);
1829
                
1830
                return geoJTS;
1831
        }
1832
        
1833
        /**
1834
         * Loads one element in the <code>List</code> of coordinates with the 
1835
         * data contained in the array of doubles 
1836
         * @param arrayCoords
1837
         * @param is3D
1838
         * @param data
1839
         */
1840
        private static void loadArrayCoordinates(List arrayCoords, boolean is3D, double[] data) {
1841
                if(is3D)
1842
                        arrayCoords.add(new Coordinate(data[0], data[1], data[2]));
1843
                else
1844
                        arrayCoords.add(new Coordinate(data[0], data[1]));
1845
        }
1846

    
1847
}