Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / core / v02 / FConverter.java @ 32872

History | View | Annotate | Download (32.2 KB)

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

    
49
import java.awt.Shape;
50
import java.awt.geom.AffineTransform;
51
import java.awt.geom.Area;
52
import java.awt.geom.NoninvertibleTransformException;
53
import java.awt.geom.PathIterator;
54
import java.awt.geom.Point2D;
55
import java.awt.geom.Rectangle2D;
56
import java.lang.reflect.Array;
57
import java.util.ArrayList;
58

    
59
import com.iver.cit.gvsig.fmap.core.FNullGeometry;
60
import com.iver.cit.gvsig.fmap.core.FPoint2D;
61
import com.iver.cit.gvsig.fmap.core.FPolygon2D;
62
import com.iver.cit.gvsig.fmap.core.FPolyline2D;
63
import com.iver.cit.gvsig.fmap.core.FShape;
64
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
65
import com.iver.cit.gvsig.fmap.core.IGeometry;
66
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
67
import com.vividsolutions.jts.algorithm.CGAlgorithms;
68
import com.vividsolutions.jts.algorithm.RobustCGAlgorithms;
69
import com.vividsolutions.jts.geom.Coordinate;
70
import com.vividsolutions.jts.geom.CoordinateArrays;
71
import com.vividsolutions.jts.geom.Envelope;
72
import com.vividsolutions.jts.geom.Geometry;
73
import com.vividsolutions.jts.geom.GeometryCollection;
74
import com.vividsolutions.jts.geom.GeometryFactory;
75
import com.vividsolutions.jts.geom.LineString;
76
import com.vividsolutions.jts.geom.LinearRing;
77
import com.vividsolutions.jts.geom.MultiLineString;
78
import com.vividsolutions.jts.geom.MultiPolygon;
79
import com.vividsolutions.jts.geom.Point;
80
import com.vividsolutions.jts.geom.Polygon;
81

    
82

    
83
/**
84
 * Clase con varios m?todos est?ticos utilizados para pasar de java2d a jts y
85
 * viceversa.
86
 *
87
 * @author fjp
88
 */
89
public class FConverter {
90
        /**
91
         * ?QU? PODEMOS HACER CON LOS MULTIPOINT??? => DEBER?AMOS TRABAJAR CON UN
92
         * ARRAY DE PUNTOS EN FShape.....Pensarlo bien.
93
         */
94
        public final static GeometryFactory geomFactory = new GeometryFactory();
95
        public static CGAlgorithms cga = new RobustCGAlgorithms();
96
        // private final static AffineTransform at = new AffineTransform();
97
        private static double POINT_MARKER_SIZE = 3.0;
98

    
99
        /**
100
         * Es la m?xima distancia que permitimos que el trazo aproximado
101
         * difiera del trazo real.
102
         */
103
        public static double FLATNESS =0.8;// Por ejemplo. Cuanto m?s peque?o, m?s segmentos necesitar? la curva
104

    
105

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

    
112
                numpoints = Array.getLength(pointList);
113

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

    
117
                        if ((testPoint.x == p.x) && (testPoint.y == p.y) &&
118
                                        ((testPoint.z == p.z) || (!(testPoint.z == testPoint.z))) //nan test; x!=x iff x is nan
119
                        ) {
120
                                return true;
121
                        }
122
                }
123

    
124
                return false;
125
        }
126

    
127
        /**
128
         * Receives a JTS Geometry and returns a fmap IGeometry
129
         * @param jtsGeometry jts Geometry
130
         * @return IGeometry of FMap
131
         * @author azabala
132
         */
133
        public static IGeometry jts_to_igeometry(Geometry jtsGeometry){
134
                FShape shape = FConverter.jts_to_java2d(jtsGeometry);
135
                if (shape == null)
136
                        return new FNullGeometry();
137
                return ShapeFactory.createGeometry(shape);
138
        }
139

    
140
        /**
141
         * Convierte un FShape a una Geometry del JTS. Para ello, utilizamos un
142
         * "flattened PathIterator". El flattened indica que las curvas las pasa a
143
         * segmentos de l?nea recta AUTOMATICAMENTE!!!.
144
         *
145
         * @param shp FShape que se quiere convertir.
146
         *
147
         * @return Geometry de JTS.
148
         */
149
        public static Geometry java2d_to_jts(FShape shp) {
150

    
151

    
152
                Geometry geoJTS = null;
153
                Coordinate coord;
154
                Coordinate[] coords;
155
                ArrayList arrayCoords = null;
156
                ArrayList arrayLines;
157
                LineString lin;
158
                LinearRing linRing;
159
                LinearRing linRingExt = null;
160
                int theType;
161
                int numParts = 0;
162

    
163
                //                 Use this array to store segment coordinate data
164
                double[] theData = new double[6];
165
                PathIterator theIterator;
166

    
167
                switch (shp.getShapeType()) {
168
                        case FShape.POINT:
169
            case FShape.POINT + FShape.Z:
170
                                FPoint2D p = (FPoint2D) shp;
171
                                coord = new Coordinate(p.getX(), p.getY());
172
                                geoJTS = geomFactory.createPoint(coord);
173

    
174
                                break;
175

    
176
                        case FShape.LINE:
177
                        case FShape.ARC:
178
            case FShape.LINE + FShape.Z:
179
            case FShape.LINE | FShape.M:
180
                                arrayLines = new ArrayList();
181
                                theIterator = shp.getPathIterator(null, FLATNESS);
182

    
183
                                while (!theIterator.isDone()) {
184
                                        //while not done
185
                                        theType = theIterator.currentSegment(theData);
186

    
187
                                        //Populate a segment of the new
188
                                        // GeneralPathX object.
189
                                        //Process the current segment to populate a new
190
                                        // segment of the new GeneralPathX object.
191
                                        switch (theType) {
192
                                                case PathIterator.SEG_MOVETO:
193

    
194
                                                        // System.out.println("SEG_MOVETO");
195
                                                        if (arrayCoords == null) {
196
                                                                arrayCoords = new ArrayList();
197
                                                        } else {
198
                                                                lin = geomFactory.createLineString(CoordinateArrays.toCoordinateArray(
199
                                                                                        arrayCoords));
200
                                                                arrayLines.add(lin);
201
                                                                arrayCoords = new ArrayList();
202
                                                        }
203

    
204
                                                        numParts++;
205
                                                        arrayCoords.add(new Coordinate(theData[0],
206
                                                                        theData[1]));
207

    
208
                                                        break;
209

    
210
                                                case PathIterator.SEG_LINETO:
211

    
212
                                                        // System.out.println("SEG_LINETO");
213
                                                        arrayCoords.add(new Coordinate(theData[0],
214
                                                                        theData[1]));
215

    
216
                                                        break;
217

    
218
                                                case PathIterator.SEG_QUADTO:
219
                                                        System.out.println("Not supported here");
220

    
221
                                                        break;
222

    
223
                                                case PathIterator.SEG_CUBICTO:
224
                                                        System.out.println("Not supported here");
225

    
226
                                                        break;
227

    
228
                                                case PathIterator.SEG_CLOSE:
229
                                                        // A?adimos el primer punto para cerrar.
230
                                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
231
                                                        arrayCoords.add(new Coordinate(firstCoord.x,
232
                                                                        firstCoord.y));
233

    
234
                                                        break;
235
                                        } //end switch
236

    
237
                                        theIterator.next();
238
                                } //end while loop
239

    
240
                                lin = new GeometryFactory().createLineString(CoordinateArrays.toCoordinateArray(
241
                                                        arrayCoords));
242

    
243
                                // CAMBIO: ENTREGAMOS SIEMPRE MULTILINESTRING, QUE ES
244
                                // LO QUE HACE TODO EL MUNDO CUANDO ESCRIBE EN POSTGIS
245
                                // O CON GEOTOOLS
246
                                // if (numParts > 1) // Generamos una MultiLineString
247
                                //  {
248
                                        arrayLines.add(lin);
249
                                        geoJTS = geomFactory.createMultiLineString(GeometryFactory.toLineStringArray(
250
                                                                arrayLines));
251
                                /* } else {
252
                                        geoJTS = lin;
253
                                } */
254

    
255
                                break;
256

    
257
                        case FShape.POLYGON:
258
                        case FShape.CIRCLE:
259
                        case FShape.ELLIPSE:
260
                        case FShape.POLYGON | FShape.M:
261
            case FShape.POLYGON + FShape.Z:
262
                    
263
                                arrayLines = new ArrayList();
264

    
265
                                ArrayList shells = new ArrayList();
266
                                ArrayList holes = new ArrayList();
267
                                Coordinate[] points = null;
268

    
269
                                theIterator = shp.getPathIterator(null, FLATNESS);
270

    
271
                                while (!theIterator.isDone()) {
272
                                        //while not done
273
                                        theType = theIterator.currentSegment(theData);
274

    
275
                                        //Populate a segment of the new
276
                                        // GeneralPathX object.
277
                                        //Process the current segment to populate a new
278
                                        // segment of the new GeneralPathX object.
279
                                        switch (theType) {
280
                                                case PathIterator.SEG_MOVETO:
281

    
282
                                                        // System.out.println("SEG_MOVETO");
283
                                                        if (arrayCoords == null) {
284
                                                                arrayCoords = new ArrayList();
285
                                                        } else {
286
                                                                points = CoordinateArrays.toCoordinateArray(arrayCoords);
287

    
288
                                                                try {
289
                                                                        LinearRing ring = geomFactory.createLinearRing(points);
290

    
291
                                                                        if (CGAlgorithms.isCCW(points)) {
292
                                                                                holes.add(ring);
293
                                                                        } else {
294
                                                                                shells.add(ring);
295
                                                                        }
296
                                                                } catch (Exception e) {
297
                                                                        /* (jaume) caso cuando todos los puntos son iguales
298
                                                                         * devuelvo el propio punto
299
                                                                         */
300
                                                                        boolean same = true;
301
                                                                        for (int i = 0; i < points.length-1 && same; i++) {
302
                                                                                if (points[i].x != points[i+1].x ||
303
                                                                                                points[i].y != points[i+1].y /*||
304
                                                                                                points[i].z != points[i+1].z*/
305
                                                                                                ) same = false;
306
                                                                        }
307
                                                                        if (same)
308
                                                                                return geomFactory.createPoint(points[0]);
309
                                                                        /*
310
                                                                         * caso cuando es una l?nea de 3 puntos, no creo un LinearRing, sino
311
                                                                         * una linea
312
                                                                         */
313
                                                                        if (points.length>1 && points.length<=3)
314
                                                                                // return geomFactory.createLineString(points);
315
                                                                                return geomFactory.createMultiLineString(new LineString[] {geomFactory.createLineString(points)});
316

    
317
                                                                        System.err.println(
318
                                                                                "Caught Topology exception in GMLLinearRingHandler");
319

    
320
                                                                        return null;
321
                                                                }
322

    
323
                                                                /* if (numParts == 1)
324
                                                                   {
325
                                                                           linRingExt = new GeometryFactory().createLinearRing(
326
                                                                                  CoordinateArrays.toCoordinateArray(arrayCoords));
327
                                                                   }
328
                                                                   else
329
                                                                   {
330
                                                                           linRing = new GeometryFactory().createLinearRing(
331
                                                                                          CoordinateArrays.toCoordinateArray(arrayCoords));
332
                                                                           arrayLines.add(linRing);
333
                                                                   } */
334
                                                                arrayCoords = new ArrayList();
335
                                                        }
336

    
337
                                                        numParts++;
338
                                                        arrayCoords.add(new Coordinate(theData[0],
339
                                                                        theData[1]));
340

    
341
                                                        break;
342

    
343
                                                case PathIterator.SEG_LINETO:
344

    
345
                                                        // System.out.println("SEG_LINETO");
346
                                                        arrayCoords.add(new Coordinate(theData[0],
347
                                                                        theData[1]));
348

    
349
                                                        break;
350

    
351
                                                case PathIterator.SEG_QUADTO:
352
                                                        System.out.println("SEG_QUADTO Not supported here");
353

    
354
                                                        break;
355

    
356
                                                case PathIterator.SEG_CUBICTO:
357
                                                        System.out.println("SEG_CUBICTO Not supported here");
358

    
359
                                                        break;
360

    
361
                                                case PathIterator.SEG_CLOSE:
362

    
363
                                                        // A?adimos el primer punto para cerrar.
364
                                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
365
                                                        arrayCoords.add(new Coordinate(firstCoord.x,
366
                                                                        firstCoord.y));
367

    
368
                                                        break;
369
                                        } //end switch
370

    
371
                                        // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
372
                                        theIterator.next();
373
                                } //end while loop
374

    
375
                                arrayCoords.add(arrayCoords.get(0));
376
                                points = CoordinateArrays.toCoordinateArray(arrayCoords);
377

    
378
                                try {
379
                                        LinearRing ring = geomFactory.createLinearRing(points);
380

    
381
                                        if (CGAlgorithms.isCCW(points)) {
382
                                                holes.add(ring);
383
                                        } else {
384
                                                shells.add(ring);
385
                                        }
386
                                } catch (Exception e) {
387
                                        /* (jaume) caso cuando todos los puntos son iguales
388
                                         * devuelvo el propio punto
389
                                         */
390
                                        boolean same = true;
391
                                        for (int i = 0; i < points.length-1 && same; i++) {
392
                                                if (points[i].x != points[i+1].x ||
393
                                                                points[i].y != points[i+1].y /*||
394
                                                                points[i].z != points[i+1].z*/
395
                                                                ) same = false;
396
                                        }
397
                                        if (same)
398
                                                return geomFactory.createPoint(points[0]);
399
                                        /*
400
                                         * caso cuando es una l?nea de 3 puntos, no creo un LinearRing, sino
401
                                         * una linea
402
                                         */
403
                                        if (points.length>1 && points.length<=3)
404
                                                // return geomFactory.createLineString(points);
405
                                                return geomFactory.createMultiLineString(new LineString[] {geomFactory.createLineString(points)});
406
                                        System.err.println(
407
                                                "Caught Topology exception in GMLLinearRingHandler");
408

    
409
                                        return null;
410
                                }
411

    
412
                                /* linRing = new GeometryFactory().createLinearRing(
413
                                   CoordinateArrays.toCoordinateArray(arrayCoords)); */
414

    
415
                                // System.out.println("NumParts = " + numParts);
416
                                //now we have a list of all shells and all holes
417
                                ArrayList holesForShells = new ArrayList(shells.size());
418

    
419
                                for (int i = 0; i < shells.size(); i++) {
420
                                        holesForShells.add(new ArrayList());
421
                                }
422

    
423
                                //find homes
424
                                for (int i = 0; i < holes.size(); i++) {
425
                                        LinearRing testRing = (LinearRing) holes.get(i);
426
                                        LinearRing minShell = null;
427
                                        Envelope minEnv = null;
428
                                        Envelope testEnv = testRing.getEnvelopeInternal();
429
                                        Coordinate testPt = testRing.getCoordinateN(0);
430
                                        LinearRing tryRing = null;
431

    
432
                                        for (int j = 0; j < shells.size(); j++) {
433
                                                tryRing = (LinearRing) shells.get(j);
434

    
435
                                                Envelope tryEnv = tryRing.getEnvelopeInternal();
436

    
437
                                                if (minShell != null) {
438
                                                        minEnv = minShell.getEnvelopeInternal();
439
                                                }
440

    
441
                                                boolean isContained = false;
442
                                                Coordinate[] coordList = tryRing.getCoordinates();
443

    
444
                                                if (tryEnv.contains(testEnv) &&
445
                                                                (CGAlgorithms.isPointInRing(testPt, coordList) ||
446
                                                                (pointInList(testPt, coordList)))) {
447
                                                        isContained = true;
448
                                                }
449

    
450
                                                // check if this new containing ring is smaller than the current minimum ring
451
                                                if (isContained) {
452
                                                        if ((minShell == null) || minEnv.contains(tryEnv)) {
453
                                                                minShell = tryRing;
454
                                                        }
455
                                                }
456
                                        }
457

    
458
                                        if (minShell == null) {
459
//                                                System.out.println(
460
//                                                        "polygon found with a hole thats not inside a shell");
461
//azabala: we do the assumption that this hole is really a shell (polygon)
462
//whose point werent digitized in the right order
463
Coordinate[] cs = testRing.getCoordinates();
464
Coordinate[] reversed = new Coordinate[cs.length];
465
int pointIndex = 0;
466
for(int z = cs.length-1; z >= 0; z--){
467
        reversed[pointIndex] = cs[z];
468
        pointIndex++;
469
}
470
LinearRing newRing = geomFactory.createLinearRing(reversed);
471
shells.add(newRing);
472
holesForShells.add(new ArrayList());
473
                                        } else {
474
                                                ((ArrayList) holesForShells.get(shells.indexOf(minShell))).add(testRing);
475
                                        }
476
                                }
477

    
478
                                Polygon[] polygons = new Polygon[shells.size()];
479

    
480
                                for (int i = 0; i < shells.size(); i++) {
481
                                        polygons[i] = geomFactory.createPolygon((LinearRing) shells.get(
482
                                                                i),
483
                                                        (LinearRing[]) ((ArrayList) holesForShells.get(i)).toArray(
484
                                                                new LinearRing[0]));
485
                                }
486
                                // CAMBIO: ENTREGAMOS SIEMPRE MULTILINESTRING, QUE ES
487
                                // LO QUE HACE TODO EL MUNDO CUANDO ESCRIBE EN POSTGIS
488
                                // O CON GEOTOOLS
489
                                // if (numParts > 1) // Generamos una MultiLineString
490

    
491
                                /* if (polygons.length == 1) {
492
                                        return polygons[0];
493
                                } */
494

    
495
                                // FIN CAMBIO
496

    
497
                                holesForShells = null;
498
                                shells = null;
499
                                holes = null;
500

    
501
                                //its a multi part
502
                                geoJTS = geomFactory.createMultiPolygon(polygons);
503

    
504
                                /* if (numParts > 1) // Generamos un Polygon con agujeros
505
                                   {
506
                                    arrayLines.add(linRing);
507
                                           // geoJTS = new GeometryFactory().createPolygon(linRingExt,
508
                                                           // GeometryFactory.toLinearRingArray(arrayLines));
509
                                    geoJTS = new GeometryFactory().buildGeometry(arrayLines);
510

511
                                    // geoJTS = Polygonizer.class.
512
                                   }
513
                                   else
514
                                   {
515
                                           geoJTS = new GeometryFactory().createPolygon(linRing,null);
516
                                   } */
517
                                break;
518
                }
519

    
520
                return geoJTS;
521
        }
522

    
523
        /**
524
         * Converts JTS Geometry objects into Java 2D Shape objects
525
         *
526
         * @param geo Geometry de JTS.
527
         *
528
         * @return FShape.
529
         */
530
        public static FShape jts_to_java2d(Geometry geo) {
531
                FShape shpNew = null;
532

    
533
                try {
534
                        if (geo instanceof Point) {
535
                                shpNew = new FPoint2D(((Point) geo).getX(), ((Point) geo).getY());
536
                        }
537

    
538
                        if (geo.isEmpty()) {
539
                                shpNew = null;
540
                        }
541

    
542
                        if (geo instanceof Polygon) {
543
                                shpNew = new FPolygon2D(toShape((Polygon) geo));
544
                        }
545

    
546
                        if (geo instanceof MultiPolygon) {
547
                                shpNew = new FPolygon2D(toShape((MultiPolygon) geo));
548
                        }
549

    
550
                        if (geo instanceof LineString) {
551
                                shpNew = new FPolyline2D(toShape((LineString) geo));
552
                        }
553

    
554
                        if (geo instanceof MultiLineString) {
555
                                shpNew = new FPolyline2D(toShape((MultiLineString) geo));
556
                        }
557

    
558
                        /* OJO: CON ALGO COMO FSHAPE NO S? C?MO PODEMOS IMPLEMENTAR UN GeometryCollection
559
                         * No sabremos si queremos una l?nea o un pol?gono.....
560
                         *  if (geometry instanceof GeometryCollection) {
561
                                  return toShape((GeometryCollection) geometry);
562
                           } */
563
                        return shpNew;
564
                } catch (NoninvertibleTransformException e) {
565
                        // TODO Auto-generated catch block
566
                        e.printStackTrace();
567
                }
568

    
569
                return null;
570
        }
571

    
572
        /**
573
         * DOCUMENT ME!
574
         *
575
         * @param p DOCUMENT ME!
576
         *
577
         * @return DOCUMENT ME!
578
         */
579
        private static GeneralPathX toShape(Polygon p) {
580
                GeneralPathX resul = new GeneralPathX();
581
                Coordinate coord;
582

    
583
                for (int i = 0; i < p.getExteriorRing().getNumPoints(); i++) {
584
                        coord = p.getExteriorRing().getCoordinateN(i);
585

    
586
                        if (i == 0) {
587
                                resul.moveTo(coord.x,coord.y);
588
                        } else {
589
                                resul.lineTo(coord.x,coord.y);
590
                        }
591
                }
592

    
593
                for (int j = 0; j < p.getNumInteriorRing(); j++) {
594
                        LineString hole = p.getInteriorRingN(j);
595

    
596
                        for (int k = 0; k < hole.getNumPoints(); k++) {
597
                                coord = hole.getCoordinateN(k);
598

    
599
                                if (k == 0) {
600
                                        resul.moveTo(coord.x, coord.y);
601
                                } else {
602
                                        resul.lineTo(coord.x, coord.y);
603
                                }
604
                        }
605
                }
606

    
607
                return resul;
608
        }
609

    
610
        /**
611
         * DOCUMENT ME!
612
         *
613
         * @param modelCoordinates DOCUMENT ME!
614
         *
615
         * @return DOCUMENT ME!
616
         *
617
         * @throws NoninvertibleTransformException DOCUMENT ME!
618
         *
619
        private Coordinate[] toViewCoordinates(Coordinate[] modelCoordinates)
620
                throws NoninvertibleTransformException {
621
                Coordinate[] viewCoordinates = new Coordinate[modelCoordinates.length];
622

623
                for (int i = 0; i < modelCoordinates.length; i++) {
624
                        FPoint2D point2D = coordinate2FPoint2D(modelCoordinates[i]);
625
                        viewCoordinates[i] = new Coordinate(point2D.getX(), point2D.getY());
626
                }
627

628
                return viewCoordinates;
629
        } */
630

    
631
        /* private Shape toShape(GeometryCollection gc)
632
           throws NoninvertibleTransformException {
633
           GeometryCollectionShape shape = new GeometryCollectionShape();
634
           for (int i = 0; i < gc.getNumGeometries(); i++) {
635
                   Geometry g = (Geometry) gc.getGeometryN(i);
636
                   shape.add(toShape(g));
637
           }
638
           return shape;
639
           } */
640
        private static GeneralPathX toShape(MultiLineString mls)
641
                throws NoninvertibleTransformException {
642
                GeneralPathX path = new GeneralPathX();
643

    
644
                for (int i = 0; i < mls.getNumGeometries(); i++) {
645
                        LineString lineString = (LineString) mls.getGeometryN(i);
646
                        path.append(toShape(lineString), false);
647
                }
648

    
649
                //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
650
                //converted to GeneralPathXs. [Jon Aquino]
651
                return path;
652
        }
653

    
654
        /**
655
         * DOCUMENT ME!
656
         *
657
         * @param lineString DOCUMENT ME!
658
         *
659
         * @return DOCUMENT ME!
660
         *
661
         * @throws NoninvertibleTransformException DOCUMENT ME!
662
         */
663
        private static GeneralPathX toShape(LineString lineString)
664
                throws NoninvertibleTransformException {
665
                GeneralPathX shape = new GeneralPathX();
666
                FPoint2D viewPoint = coordinate2FPoint2D(lineString.getCoordinateN(0));
667
                shape.moveTo(viewPoint.getX(), viewPoint.getY());
668

    
669
                for (int i = 1; i < lineString.getNumPoints(); i++) {
670
                        viewPoint = coordinate2FPoint2D(lineString.getCoordinateN(i));
671
                        shape.lineTo(viewPoint.getX(), viewPoint.getY());
672
                }
673

    
674
                //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
675
                //converted to GeneralPathXs. [Jon Aquino]
676
                return shape;
677
        }
678

    
679
        /**
680
         * DOCUMENT ME!
681
         *
682
         * @param point DOCUMENT ME!
683
         *
684
         * @return DOCUMENT ME!
685
         *
686
         * @throws NoninvertibleTransformException DOCUMENT ME!
687
         */
688
        private static FPoint2D toShape(Point point)
689
                throws NoninvertibleTransformException {
690
                FPoint2D viewPoint = coordinate2FPoint2D(point.getCoordinate());
691

    
692
                return viewPoint;
693
        }
694

    
695
        private static GeneralPathX toShape(MultiPolygon mp)
696
        throws NoninvertibleTransformException {
697
        GeneralPathX path = new GeneralPathX();
698

    
699
        for (int i = 0; i < mp.getNumGeometries(); i++) {
700
                Polygon polygon = (Polygon) mp.getGeometryN(i);
701
                path.append(toShape(polygon), false);
702
        }
703

    
704
        //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
705
        //converted to GeneralPathXs. [Jon Aquino]
706
        return path;
707
}
708
        /**
709
         * DOCUMENT ME!
710
         *
711
         * @param coord DOCUMENT ME!
712
         *
713
         * @return DOCUMENT ME!
714
         */
715
        public static FPoint2D coordinate2FPoint2D(Coordinate coord) {
716
                return new FPoint2D(coord.x, coord.y); //,coord.z);
717
        }
718

    
719
        /**
720
         * Convierte una Geometry de JTS a GeneralPathX.
721
         *
722
         * @param geometry Geometry a convertir.
723
         *
724
         * @return GeneralPathX.
725
         *
726
         * @throws NoninvertibleTransformException
727
         * @throws IllegalArgumentException
728
         */
729
        public static GeneralPathX toShape(Geometry geometry)
730
                throws NoninvertibleTransformException {
731
                if (geometry.isEmpty()) {
732
                        return new GeneralPathX();
733
                }
734

    
735
                if (geometry instanceof Polygon) {
736
                        return toShape((Polygon) geometry);
737
                }
738

    
739
                if (geometry instanceof MultiPolygon) {
740
                        return toShape((MultiPolygon) geometry);
741
                }
742

    
743
                if (geometry instanceof LineString) {
744
                        return toShape((LineString) geometry);
745
                }
746

    
747
                if (geometry instanceof MultiLineString) {
748
                        return toShape((MultiLineString) geometry);
749
                }
750

    
751
                if (geometry instanceof GeometryCollection) {
752
                        return toShape((GeometryCollection) geometry);
753
                }
754

    
755
                throw new IllegalArgumentException("Unrecognized Geometry class: " +
756
                        geometry.getClass());
757
        }
758

    
759

    
760
    public static GeneralPathX transformToInts(GeneralPathX gp, AffineTransform at) {
761
        GeneralPathX newGp = new GeneralPathX();
762
        PathIterator theIterator;
763
        int theType;
764
        int numParts = 0;
765
        double[] theData = new double[6];
766
        Point2D ptDst = new Point2D.Double();
767
        Point2D ptSrc = new Point2D.Double();
768
        boolean bFirst = true;
769
        int xInt, yInt, antX = -1, antY = -1;
770

    
771
        theIterator = gp.getPathIterator(null); //, flatness);
772

    
773
        while (!theIterator.isDone()) {
774
            theType = theIterator.currentSegment(theData);
775
            switch (theType) {
776
                case PathIterator.SEG_MOVETO:
777
                    numParts++;
778
                    ptSrc.setLocation(theData[0], theData[1]);
779
                    at.transform(ptSrc, ptDst);
780
                    antX = (int) ptDst.getX();
781
                    antY = (int) ptDst.getY();
782
                    newGp.moveTo(antX, antY);
783
                    bFirst = true;
784
                    break;
785

    
786
                case PathIterator.SEG_LINETO:
787
                    ptSrc.setLocation(theData[0], theData[1]);
788
                    at.transform(ptSrc, ptDst);
789
                    xInt = (int) ptDst.getX();
790
                    yInt = (int) ptDst.getY();
791
                    if ((bFirst) || ((xInt != antX) || (yInt != antY)))
792
                    {
793
                        newGp.lineTo(xInt, yInt);
794
                        antX = xInt;
795
                        antY = yInt;
796
                        bFirst = false;
797
                    }
798
                    break;
799

    
800
                case PathIterator.SEG_QUADTO:
801
                    System.out.println("Not supported here");
802

    
803
                    break;
804

    
805
                case PathIterator.SEG_CUBICTO:
806
                    System.out.println("Not supported here");
807

    
808
                    break;
809

    
810
                case PathIterator.SEG_CLOSE:
811
                    newGp.closePath();
812

    
813
                    break;
814
            } //end switch
815

    
816
            theIterator.next();
817
        } //end while loop
818

    
819
        return newGp;
820
    }
821
    public static FShape transformToInts(IGeometry gp, AffineTransform at) {
822
        GeneralPathX newGp = new GeneralPathX();
823
        double[] theData = new double[6];
824
        double[] aux = new double[6];
825

    
826
        // newGp.reset();
827
        PathIterator theIterator;
828
        int theType;
829
        int numParts = 0;
830

    
831
        Point2D ptDst = new Point2D.Double();
832
        Point2D ptSrc = new Point2D.Double();
833
        boolean bFirst = true;
834
        int xInt, yInt, antX = -1, antY = -1;
835

    
836

    
837
        theIterator = gp.getPathIterator(null); //, flatness);
838
        int numSegmentsAdded = 0;
839
        while (!theIterator.isDone()) {
840
            theType = theIterator.currentSegment(theData);
841

    
842
            switch (theType) {
843
                case PathIterator.SEG_MOVETO:
844
                    numParts++;
845
                    ptSrc.setLocation(theData[0], theData[1]);
846
                    at.transform(ptSrc, ptDst);
847
                    antX = (int) ptDst.getX();
848
                    antY = (int) ptDst.getY();
849
                    newGp.moveTo(antX, antY);
850
                    numSegmentsAdded++;
851
                    bFirst = true;
852
                    break;
853

    
854
                case PathIterator.SEG_LINETO:
855
                    ptSrc.setLocation(theData[0], theData[1]);
856
                    at.transform(ptSrc, ptDst);
857
                    xInt = (int) ptDst.getX();
858
                    yInt = (int) ptDst.getY();
859
                    if ((bFirst) || ((xInt != antX) || (yInt != antY)))
860
                    {
861
                        newGp.lineTo(xInt, yInt);
862
                        antX = xInt;
863
                        antY = yInt;
864
                        bFirst = false;
865
                        numSegmentsAdded++;
866
                    }
867
                    break;
868

    
869
                case PathIterator.SEG_QUADTO:
870
                    at.transform(theData,0,aux,0,2);
871
                    newGp.quadTo(aux[0], aux[1], aux[2], aux[3]);
872
                    numSegmentsAdded++;
873
                    break;
874

    
875
                case PathIterator.SEG_CUBICTO:
876
                    at.transform(theData,0,aux,0,3);
877
                    newGp.curveTo(aux[0], aux[1], aux[2], aux[3], aux[4], aux[5]);
878
                    numSegmentsAdded++;
879
                    break;
880

    
881
                case PathIterator.SEG_CLOSE:
882
                    if (numSegmentsAdded < 3)
883
                        newGp.lineTo(antX, antY);
884
                    newGp.closePath();
885

    
886
                    break;
887
            } //end switch
888

    
889
            theIterator.next();
890
        } //end while loop
891

    
892
        FShape shp = null;
893
        switch (gp.getGeometryType())
894
        {
895
            case FShape.POINT: //Tipo punto
896
            case FShape.POINT + FShape.Z:
897
                shp = new FPoint2D(ptDst.getX(), ptDst.getY());
898
                break;
899

    
900
            case FShape.LINE:
901
            case FShape.LINE + FShape.Z:
902
            case FShape.LINE | FShape.M:
903
            case FShape.ARC:
904
                    shp = new FPolyline2D(newGp);
905
                break;
906

    
907
            case FShape.POLYGON:
908
            case FShape.POLYGON + FShape.Z:
909
            case FShape.POLYGON | FShape.M:
910
            case FShape.CIRCLE:
911
            case FShape.ELLIPSE:
912

    
913
                shp = new FPolygon2D(newGp);
914
                break;
915
        }
916
        return shp;
917
    }
918

    
919
    public static Rectangle2D convertEnvelopeToRectangle2D(Envelope jtsR)
920
    {
921
        Rectangle2D.Double r = new Rectangle2D.Double(jtsR.getMinX(),
922
                jtsR.getMinY(), jtsR.getWidth(), jtsR.getHeight());
923
        return r;
924
    }
925

    
926
    public static Envelope convertRectangle2DtoEnvelope(Rectangle2D r)
927
    {
928
            Envelope e = new Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(),
929
                        r.getY() + r.getHeight());
930
            return e;
931
    }
932

    
933
    /**
934
     * Return a correct polygon (no hole)
935
     * @param coordinates
936
     * @return
937
     */
938
    public static IGeometry getExteriorPolygon(Coordinate[] coordinates)
939
    {
940
            // isCCW = true => it's a hole
941
            Coordinate[] vs=new Coordinate[coordinates.length];
942
        if (CGAlgorithms.isCCW(coordinates)){
943
                for (int i=vs.length-1;i>=0;i--){
944
                        vs[i]=coordinates[i];
945
                }
946
        }else{
947
                vs=coordinates;
948
        }
949
        LinearRing ring = geomFactory.createLinearRing(vs);
950

    
951
        try {
952
                        return ShapeFactory.createPolygon2D(toShape(ring));
953
                } catch (NoninvertibleTransformException e) {
954
                        e.printStackTrace();
955
                }
956
                return null;
957
    }
958

    
959
    public static boolean isCCW(Point2D[] points)
960
    {
961
            int length = points.length;
962
            Coordinate[] vs;
963
            // CGAlgorithms.isCCW asume que la lista de puntos tienen el primer
964
            // y el ultimo puntos iguales.... y que este algoritmo est? solo
965
            // garantizado con anillos v?lidos.
966
            if (points[0].getX() != points[length-1].getX() || points[0].getY() != points[length-1].getY()) {
967
                vs=new Coordinate[length+1];
968
                vs[points.length] = new Coordinate(points[0].getX(), points[0].getY());
969
            } else {
970
                vs=new Coordinate[length];
971
            }
972
               for (int i=0; i<length; i++){
973
                    vs[i] = new Coordinate(points[i].getX(), points[i].getY());
974
            }
975
        return CGAlgorithms.isCCW(vs);
976
    }
977

    
978
    public static boolean isCCW(FPolygon2D pol)
979
    {
980
            Geometry jtsGeom = FConverter.java2d_to_jts(pol);
981
            if (jtsGeom.getNumGeometries() == 1)
982
            {
983
                    Coordinate[] coords = jtsGeom.getCoordinates();
984
                    return CGAlgorithms.isCCW(coords);
985
            }
986
            return false;
987

    
988
    }
989

    
990

    
991
    /**
992
     * Return a hole (CCW ordered points)
993
     * @param coordinates
994
     * @return
995
     */
996
    public static IGeometry getHole(Coordinate[] coordinates)
997
    {
998
            // isCCW = true => it's a hole
999
            Coordinate[] vs=new Coordinate[coordinates.length];
1000
        if (CGAlgorithms.isCCW(coordinates)){
1001
                vs=coordinates;
1002

    
1003
        }else{
1004
                for (int i=vs.length-1;i>=0;i--){
1005
                        vs[i]=coordinates[i];
1006
                }
1007
        }
1008
        LinearRing ring = geomFactory.createLinearRing(vs);
1009

    
1010
        try {
1011
                        return ShapeFactory.createPolygon2D(toShape(ring));
1012
                } catch (NoninvertibleTransformException e) {
1013
                        e.printStackTrace();
1014
                }
1015
                return null;
1016
    }
1017

    
1018
        public static Shape getExteriorPolygon(GeneralPathX gp) {
1019
                Area area = new Area(gp);
1020
                area.isSingular();
1021
                return area;
1022

    
1023

    
1024

    
1025
        }
1026
        /**
1027
         * Use it ONLY for NOT multipart polygons.
1028
         * @param pol
1029
         * @return
1030
         */
1031
        public static IGeometry getNotHolePolygon(FPolygon2D pol) {
1032
                // isCCW == true => hole
1033
                Coordinate[] coords;
1034
                ArrayList arrayCoords = null;
1035
                int theType;
1036
                int numParts = 0;
1037

    
1038
                //                 Use this array to store segment coordinate data
1039
                double[] theData = new double[6];
1040
                PathIterator theIterator;
1041

    
1042
                                ArrayList shells = new ArrayList();
1043
                                ArrayList holes = new ArrayList();
1044
                                Coordinate[] points = null;
1045

    
1046
                                theIterator = pol.getPathIterator(null, FLATNESS);
1047

    
1048
                                while (!theIterator.isDone()) {
1049
                                        //while not done
1050
                                        theType = theIterator.currentSegment(theData);
1051

    
1052
                                        //Populate a segment of the new
1053
                                        // GeneralPathX object.
1054
                                        //Process the current segment to populate a new
1055
                                        // segment of the new GeneralPathX object.
1056
                                        switch (theType) {
1057
                                                case PathIterator.SEG_MOVETO:
1058

    
1059
                                                        // System.out.println("SEG_MOVETO");
1060
                                                        if (arrayCoords == null) {
1061
                                                                arrayCoords = new ArrayList();
1062
                                                        } else {
1063
                                                                points = CoordinateArrays.toCoordinateArray(arrayCoords);
1064

    
1065
                                                                try {
1066
                                                                        LinearRing ring = geomFactory.createLinearRing(points);
1067

    
1068
                                                                        if (CGAlgorithms.isCCW(points)) {
1069
                                                                                holes.add(ring);
1070
                                                                        } else {
1071
                                                                                shells.add(ring);
1072
                                                                        }
1073
                                                                } catch (Exception e) {
1074
                                                                        System.err.println(
1075
                                                                                "Caught Topology exception in GMLLinearRingHandler");
1076

    
1077
                                                                        return null;
1078
                                                                }
1079

    
1080
                                                                /* if (numParts == 1)
1081
                                                                   {
1082
                                                                           linRingExt = new GeometryFactory().createLinearRing(
1083
                                                                                  CoordinateArrays.toCoordinateArray(arrayCoords));
1084
                                                                   }
1085
                                                                   else
1086
                                                                   {
1087
                                                                           linRing = new GeometryFactory().createLinearRing(
1088
                                                                                          CoordinateArrays.toCoordinateArray(arrayCoords));
1089
                                                                           arrayLines.add(linRing);
1090
                                                                   } */
1091
                                                                arrayCoords = new ArrayList();
1092
                                                        }
1093

    
1094
                                                        numParts++;
1095
                                                        arrayCoords.add(new Coordinate(theData[0],
1096
                                                                        theData[1]));
1097

    
1098
                                                        break;
1099

    
1100
                                                case PathIterator.SEG_LINETO:
1101

    
1102
                                                        // System.out.println("SEG_LINETO");
1103
                                                        arrayCoords.add(new Coordinate(theData[0],
1104
                                                                        theData[1]));
1105

    
1106
                                                        break;
1107

    
1108
                                                case PathIterator.SEG_QUADTO:
1109
                                                        System.out.println("SEG_QUADTO Not supported here");
1110

    
1111
                                                        break;
1112

    
1113
                                                case PathIterator.SEG_CUBICTO:
1114
                                                        System.out.println("SEG_CUBICTO Not supported here");
1115

    
1116
                                                        break;
1117

    
1118
                                                case PathIterator.SEG_CLOSE:
1119

    
1120
                                                        // A?adimos el primer punto para cerrar.
1121
                                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
1122
                                                        arrayCoords.add(new Coordinate(firstCoord.x,
1123
                                                                        firstCoord.y));
1124

    
1125
                                                        break;
1126
                                        } //end switch
1127

    
1128
                                        // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
1129
                                        theIterator.next();
1130
                                } //end while loop
1131

    
1132
                                arrayCoords.add(arrayCoords.get(0));
1133
                                coords = CoordinateArrays.toCoordinateArray(arrayCoords);
1134

    
1135

    
1136
                if (numParts == 1)
1137
                {
1138
                        return getExteriorPolygon(coords);
1139
                }
1140
                return ShapeFactory.createGeometry(pol);
1141

    
1142
        }
1143

    
1144

    
1145
    /* public static GeometryCollection convertFGeometryCollection(FGeometryCollection fGeomC)
1146
    {
1147

1148
        geomFactory.createGeometryCollection(theGeoms);
1149
    } */
1150
}