Statistics
| Revision:

root / trunk / libraries / libFMap_geometries / src / org / gvsig / fmap / geom / util / Converter.java @ 20860

History | View | Annotate | Download (31.9 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 org.gvsig.fmap.geom.util;
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 org.gvsig.fmap.geom.Geometry;
60
import org.gvsig.fmap.geom.GeometryFactory;
61
import org.gvsig.fmap.geom.primitive.FShape;
62
import org.gvsig.fmap.geom.primitive.GeneralPathX;
63
import org.gvsig.fmap.geom.primitive.Surface2D;
64
import org.gvsig.fmap.geom.primitive.Curve2D;
65

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

    
80

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

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

    
103

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

    
110
                numpoints = Array.getLength(pointList);
111

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

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

    
122
                return false;
123
        }
124

    
125
        /**
126
         * Receives a JTS Geometry and returns a fmap IGeometry
127
         * @param jtsGeometry jts Geometry
128
         * @return IGeometry of FMap
129
         * @author azabala
130
         */
131
        public static Geometry jts_to_igeometry(com.vividsolutions.jts.geom.Geometry jtsGeometry){
132
                FShape shape = Converter.jts_to_java2d(jtsGeometry);
133
                return GeometryFactory.createGeometry(shape);
134
        }
135

    
136
        /**
137
         * Convierte un FShape a una Geometry del JTS. Para ello, utilizamos un
138
         * "flattened PathIterator". El flattened indica que las curvas las pasa a
139
         * segmentos de l�nea recta AUTOMATICAMENTE!!!.
140
         *
141
         * @param shp FShape que se quiere convertir.
142
         *
143
         * @return Geometry de JTS.
144
         */
145
        public static com.vividsolutions.jts.geom.Geometry java2d_to_jts(FShape shp) {
146

    
147

    
148
                com.vividsolutions.jts.geom.Geometry geoJTS = null;
149
                Coordinate coord;
150
                //Coordinate[] coords;
151
                ArrayList arrayCoords = null;
152
                ArrayList arrayLines;
153
                LineString lin;
154
                //LinearRing linRing;
155
                //LinearRing linRingExt = null;
156
                int theType;
157
                int numParts = 0;
158

    
159
                //                 Use this array to store segment coordinate data
160
                double[] theData = new double[6];
161
                PathIterator theIterator;
162

    
163
                switch (shp.getShapeType()) {
164
                        case FShape.POINT:
165
            case FShape.POINT + FShape.Z:
166
                                Point2D p = (Point2D) shp;
167
                                coord = new Coordinate(p.getX(), p.getY());
168
                                geoJTS = geomFactory.createPoint(coord);
169

    
170
                                break;
171

    
172
                        case FShape.LINE:
173
                        case FShape.ARC:
174
            case FShape.LINE + FShape.Z:
175
                                arrayLines = new ArrayList();
176
                                theIterator = shp.getPathIterator(null, FLATNESS);
177

    
178
                                while (!theIterator.isDone()) {
179
                                        //while not done
180
                                        theType = theIterator.currentSegment(theData);
181

    
182
                                        //Populate a segment of the new
183
                                        // GeneralPathX object.
184
                                        //Process the current segment to populate a new
185
                                        // segment of the new GeneralPathX object.
186
                                        switch (theType) {
187
                                                case PathIterator.SEG_MOVETO:
188

    
189
                                                        // System.out.println("SEG_MOVETO");
190
                                                        if (arrayCoords == null) {
191
                                                                arrayCoords = new ArrayList();
192
                                                        } else {
193
                                                                lin = geomFactory.createLineString(CoordinateArrays.toCoordinateArray(
194
                                                                                        arrayCoords));
195
                                                                arrayLines.add(lin);
196
                                                                arrayCoords = new ArrayList();
197
                                                        }
198

    
199
                                                        numParts++;
200
                                                        arrayCoords.add(new Coordinate(theData[0],
201
                                                                        theData[1]));
202

    
203
                                                        break;
204

    
205
                                                case PathIterator.SEG_LINETO:
206

    
207
                                                        // System.out.println("SEG_LINETO");
208
                                                        arrayCoords.add(new Coordinate(theData[0],
209
                                                                        theData[1]));
210

    
211
                                                        break;
212

    
213
                                                case PathIterator.SEG_QUADTO:
214
                                                        System.out.println("Not supported here");
215

    
216
                                                        break;
217

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

    
221
                                                        break;
222

    
223
                                                case PathIterator.SEG_CLOSE:
224
                                                        // A�adimos el primer punto para cerrar.
225
                                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
226
                                                        arrayCoords.add(new Coordinate(firstCoord.x,
227
                                                                        firstCoord.y));
228

    
229
                                                        break;
230
                                        } //end switch
231

    
232
                                        theIterator.next();
233
                                } //end while loop
234

    
235
                                lin = new GeometryFactory().createLineString(CoordinateArrays.toCoordinateArray(
236
                                                        arrayCoords));
237

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

    
250
                                break;
251

    
252
                        case FShape.POLYGON:
253
                        case FShape.CIRCLE:
254
                        case FShape.ELLIPSE:
255
            case FShape.POLYGON + FShape.Z:
256
                                arrayLines = new ArrayList();
257

    
258
                                ArrayList shells = new ArrayList();
259
                                ArrayList holes = new ArrayList();
260
                                Coordinate[] points = null;
261

    
262
                                theIterator = shp.getPathIterator(null, FLATNESS);
263

    
264
                                while (!theIterator.isDone()) {
265
                                        //while not done
266
                                        theType = theIterator.currentSegment(theData);
267

    
268
                                        //Populate a segment of the new
269
                                        // GeneralPathX object.
270
                                        //Process the current segment to populate a new
271
                                        // segment of the new GeneralPathX object.
272
                                        switch (theType) {
273
                                                case PathIterator.SEG_MOVETO:
274

    
275
                                                        // System.out.println("SEG_MOVETO");
276
                                                        if (arrayCoords == null) {
277
                                                                arrayCoords = new ArrayList();
278
                                                        } else {
279
                                                                points = CoordinateArrays.toCoordinateArray(arrayCoords);
280

    
281
                                                                try {
282
                                                                        LinearRing ring = geomFactory.createLinearRing(points);
283

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

    
310
                                                                        System.err.println(
311
                                                                                "Caught Topology exception in GMLLinearRingHandler");
312

    
313
                                                                        return null;
314
                                                                }
315

    
316
                                                                /* if (numParts == 1)
317
                                                                   {
318
                                                                           linRingExt = new GeometryFactory().createLinearRing(
319
                                                                                  CoordinateArrays.toCoordinateArray(arrayCoords));
320
                                                                   }
321
                                                                   else
322
                                                                   {
323
                                                                           linRing = new GeometryFactory().createLinearRing(
324
                                                                                          CoordinateArrays.toCoordinateArray(arrayCoords));
325
                                                                           arrayLines.add(linRing);
326
                                                                   } */
327
                                                                arrayCoords = new ArrayList();
328
                                                        }
329

    
330
                                                        numParts++;
331
                                                        arrayCoords.add(new Coordinate(theData[0],
332
                                                                        theData[1]));
333

    
334
                                                        break;
335

    
336
                                                case PathIterator.SEG_LINETO:
337

    
338
                                                        // System.out.println("SEG_LINETO");
339
                                                        arrayCoords.add(new Coordinate(theData[0],
340
                                                                        theData[1]));
341

    
342
                                                        break;
343

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

    
347
                                                        break;
348

    
349
                                                case PathIterator.SEG_CUBICTO:
350
                                                        System.out.println("SEG_CUBICTO Not supported here");
351

    
352
                                                        break;
353

    
354
                                                case PathIterator.SEG_CLOSE:
355

    
356
                                                        // A�adimos el primer punto para cerrar.
357
                                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
358
                                                        arrayCoords.add(new Coordinate(firstCoord.x,
359
                                                                        firstCoord.y));
360

    
361
                                                        break;
362
                                        } //end switch
363

    
364
                                        // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
365
                                        theIterator.next();
366
                                } //end while loop
367

    
368
                                arrayCoords.add(arrayCoords.get(0));
369
                                points = CoordinateArrays.toCoordinateArray(arrayCoords);
370

    
371
                                try {
372
                                        LinearRing ring = geomFactory.createLinearRing(points);
373

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

    
402
                                        return null;
403
                                }
404

    
405
                                /* linRing = new GeometryFactory().createLinearRing(
406
                                   CoordinateArrays.toCoordinateArray(arrayCoords)); */
407

    
408
                                // System.out.println("NumParts = " + numParts);
409
                                //now we have a list of all shells and all holes
410
                                ArrayList holesForShells = new ArrayList(shells.size());
411

    
412
                                for (int i = 0; i < shells.size(); i++) {
413
                                        holesForShells.add(new ArrayList());
414
                                }
415

    
416
                                //find homes
417
                                for (int i = 0; i < holes.size(); i++) {
418
                                        LinearRing testRing = (LinearRing) holes.get(i);
419
                                        LinearRing minShell = null;
420
                                        Envelope minEnv = null;
421
                                        Envelope testEnv = testRing.getEnvelopeInternal();
422
                                        Coordinate testPt = testRing.getCoordinateN(0);
423
                                        LinearRing tryRing = null;
424

    
425
                                        for (int j = 0; j < shells.size(); j++) {
426
                                                tryRing = (LinearRing) shells.get(j);
427

    
428
                                                Envelope tryEnv = tryRing.getEnvelopeInternal();
429

    
430
                                                if (minShell != null) {
431
                                                        minEnv = minShell.getEnvelopeInternal();
432
                                                }
433

    
434
                                                boolean isContained = false;
435
                                                Coordinate[] coordList = tryRing.getCoordinates();
436

    
437
                                                if (tryEnv.contains(testEnv) &&
438
                                                                (CGAlgorithms.isPointInRing(testPt, coordList) ||
439
                                                                (pointInList(testPt, coordList)))) {
440
                                                        isContained = true;
441
                                                }
442

    
443
                                                // check if this new containing ring is smaller than the current minimum ring
444
                                                if (isContained) {
445
                                                        if ((minShell == null) || minEnv.contains(tryEnv)) {
446
                                                                minShell = tryRing;
447
                                                        }
448
                                                }
449
                                        }
450

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

    
471
                                Polygon[] polygons = new Polygon[shells.size()];
472

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

    
484
                                /* if (polygons.length == 1) {
485
                                        return polygons[0];
486
                                } */
487

    
488
                                // FIN CAMBIO
489

    
490
                                holesForShells = null;
491
                                shells = null;
492
                                holes = null;
493

    
494
                                //its a multi part
495
                                geoJTS = geomFactory.createMultiPolygon(polygons);
496

    
497
                                /* if (numParts > 1) // Generamos un Polygon con agujeros
498
                                   {
499
                                    arrayLines.add(linRing);
500
                                           // geoJTS = new GeometryFactory().createPolygon(linRingExt,
501
                                                           // GeometryFactory.toLinearRingArray(arrayLines));
502
                                    geoJTS = new GeometryFactory().buildGeometry(arrayLines);
503

504
                                    // geoJTS = Polygonizer.class.
505
                                   }
506
                                   else
507
                                   {
508
                                           geoJTS = new GeometryFactory().createPolygon(linRing,null);
509
                                   } */
510
                                break;
511
                }
512

    
513
                return geoJTS;
514
        }
515

    
516
        /**
517
         * Converts JTS Geometry objects into Java 2D Shape objects
518
         *
519
         * @param geo Geometry de JTS.
520
         *
521
         * @return FShape.
522
         */
523
        public static FShape jts_to_java2d(com.vividsolutions.jts.geom.Geometry geo) {
524
                FShape shpNew = null;
525

    
526
                try {
527
                        if (geo instanceof Point) {
528
                                shpNew = new org.gvsig.fmap.geom.primitive.Point2D(null, null, ((Point) geo).getX(), ((Point) geo).getY());
529
                        }
530

    
531
                        if (geo.isEmpty()) {
532
                                shpNew = null;
533
                        }
534

    
535
                        if (geo instanceof Polygon) {
536
                                shpNew = new Surface2D(null, null, toShape((Polygon) geo));
537
                        }
538

    
539
                        if (geo instanceof MultiPolygon) {
540
                                shpNew = new Surface2D(null, null, toShape((MultiPolygon) geo));
541
                        }
542

    
543
                        if (geo instanceof LineString) {
544
                                shpNew = new Curve2D(null, null, toShape((LineString) geo));
545
                        }
546

    
547
                        if (geo instanceof MultiLineString) {
548
                                shpNew = new Curve2D(null, null, toShape((MultiLineString) geo));
549
                        }
550

    
551
                        /* OJO: CON ALGO COMO FSHAPE NO S� C�MO PODEMOS IMPLEMENTAR UN GeometryCollection
552
                         * No sabremos si queremos una l�nea o un pol�gono.....
553
                         *  if (geometry instanceof GeometryCollection) {
554
                                  return toShape((GeometryCollection) geometry);
555
                           } */
556
                        return shpNew;
557
                } catch (NoninvertibleTransformException e) {
558
                        // TODO Auto-generated catch block
559
                        e.printStackTrace();
560
                }
561

    
562
                return null;
563
        }
564

    
565
        /**
566
         * DOCUMENT ME!
567
         *
568
         * @param p DOCUMENT ME!
569
         *
570
         * @return DOCUMENT ME!
571
         */
572
        private static GeneralPathX toShape(Polygon p) {
573
                GeneralPathX resul = new GeneralPathX();
574
                Coordinate coord;
575

    
576
                for (int i = 0; i < p.getExteriorRing().getNumPoints(); i++) {
577
                        coord = p.getExteriorRing().getCoordinateN(i);
578

    
579
                        if (i == 0) {
580
                                resul.moveTo(coord.x,coord.y);
581
                        } else {
582
                                resul.lineTo(coord.x,coord.y);
583
                        }
584
                }
585

    
586
                for (int j = 0; j < p.getNumInteriorRing(); j++) {
587
                        LineString hole = p.getInteriorRingN(j);
588

    
589
                        for (int k = 0; k < hole.getNumPoints(); k++) {
590
                                coord = hole.getCoordinateN(k);
591

    
592
                                if (k == 0) {
593
                                        resul.moveTo(coord.x, coord.y);
594
                                } else {
595
                                        resul.lineTo(coord.x, coord.y);
596
                                }
597
                        }
598
                }
599

    
600
                return resul;
601
        }
602

    
603
        /**
604
         * DOCUMENT ME!
605
         *
606
         * @param modelCoordinates DOCUMENT ME!
607
         *
608
         * @return DOCUMENT ME!
609
         *
610
         * @throws NoninvertibleTransformException DOCUMENT ME!
611
         *
612
        private Coordinate[] toViewCoordinates(Coordinate[] modelCoordinates)
613
                throws NoninvertibleTransformException {
614
                Coordinate[] viewCoordinates = new Coordinate[modelCoordinates.length];
615

616
                for (int i = 0; i < modelCoordinates.length; i++) {
617
                        FPoint2D point2D = coordinate2FPoint2D(modelCoordinates[i]);
618
                        viewCoordinates[i] = new Coordinate(point2D.getX(), point2D.getY());
619
                }
620

621
                return viewCoordinates;
622
        } */
623

    
624
        /* private Shape toShape(GeometryCollection gc)
625
           throws NoninvertibleTransformException {
626
           GeometryCollectionShape shape = new GeometryCollectionShape();
627
           for (int i = 0; i < gc.getNumGeometries(); i++) {
628
                   Geometry g = (Geometry) gc.getGeometryN(i);
629
                   shape.add(toShape(g));
630
           }
631
           return shape;
632
           } */
633
        private static GeneralPathX toShape(MultiLineString mls)
634
                throws NoninvertibleTransformException {
635
                GeneralPathX path = new GeneralPathX();
636

    
637
                for (int i = 0; i < mls.getNumGeometries(); i++) {
638
                        LineString lineString = (LineString) mls.getGeometryN(i);
639
                        path.append(toShape(lineString), false);
640
                }
641

    
642
                //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
643
                //converted to GeneralPathXs. [Jon Aquino]
644
                return path;
645
        }
646

    
647
        /**
648
         * DOCUMENT ME!
649
         *
650
         * @param lineString DOCUMENT ME!
651
         *
652
         * @return DOCUMENT ME!
653
         *
654
         * @throws NoninvertibleTransformException DOCUMENT ME!
655
         */
656
        private static GeneralPathX toShape(LineString lineString)
657
                throws NoninvertibleTransformException {
658
                GeneralPathX shape = new GeneralPathX();
659
                org.gvsig.fmap.geom.primitive.Point2D viewPoint = coordinate2FPoint2D(lineString.getCoordinateN(0));
660
                shape.moveTo(viewPoint.getX(), viewPoint.getY());
661

    
662
                for (int i = 1; i < lineString.getNumPoints(); i++) {
663
                        viewPoint = coordinate2FPoint2D(lineString.getCoordinateN(i));
664
                        shape.lineTo(viewPoint.getX(), viewPoint.getY());
665
                }
666

    
667
                //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
668
                //converted to GeneralPathXs. [Jon Aquino]
669
                return shape;
670
        }
671

    
672
        /* TODO No se usa
673
         * DOCUMENT ME!
674
         *
675
         * @param point DOCUMENT ME!
676
         *
677
         * @return DOCUMENT ME!
678
         *
679
         * @throws NoninvertibleTransformException DOCUMENT ME!
680
         *
681
        private static Point2D toShape(Point point)
682
                throws NoninvertibleTransformException {
683
                Point2D viewPoint = coordinate2FPoint2D(point.getCoordinate());
684

685
                return viewPoint;
686
        }
687
*/
688
        
689
        /**
690
         * 
691
         */
692
        private static GeneralPathX toShape(MultiPolygon mp)
693
        throws NoninvertibleTransformException {
694
        GeneralPathX path = new GeneralPathX();
695

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

    
701
        //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
702
        //converted to GeneralPathXs. [Jon Aquino]
703
        return path;
704
}
705
        /**
706
         * DOCUMENT ME!
707
         *
708
         * @param coord DOCUMENT ME!
709
         *
710
         * @return DOCUMENT ME!
711
         */
712
        public static org.gvsig.fmap.geom.primitive.Point2D coordinate2FPoint2D(Coordinate coord) {
713
                return new org.gvsig.fmap.geom.primitive.Point2D(null, null, coord.x, coord.y); //,coord.z);
714
        }
715

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

    
732
                if (geometry instanceof Polygon) {
733
                        return toShape((Polygon) geometry);
734
                }
735

    
736
                if (geometry instanceof MultiPolygon) {
737
                        return toShape((MultiPolygon) geometry);
738
                }
739

    
740
                if (geometry instanceof LineString) {
741
                        return toShape((LineString) geometry);
742
                }
743

    
744
                if (geometry instanceof MultiLineString) {
745
                        return toShape((MultiLineString) geometry);
746
                }
747

    
748
                if (geometry instanceof GeometryCollection) {
749
                        return toShape((GeometryCollection) geometry);
750
                }
751

    
752
                throw new IllegalArgumentException("Unrecognized Geometry class: " +
753
                        geometry.getClass());
754
        }
755

    
756

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

    
768
        theIterator = gp.getPathIterator(null); //, flatness);
769

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

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

    
797
                case PathIterator.SEG_QUADTO:
798
                    System.out.println("Not supported here");
799

    
800
                    break;
801

    
802
                case PathIterator.SEG_CUBICTO:
803
                    System.out.println("Not supported here");
804

    
805
                    break;
806

    
807
                case PathIterator.SEG_CLOSE:
808
                    newGp.closePath();
809

    
810
                    break;
811
            } //end switch
812

    
813
            theIterator.next();
814
        } //end while loop
815

    
816
        return newGp;
817
    }
818
    public static FShape transformToInts(Geometry gp, AffineTransform at) {
819
        GeneralPathX newGp = new GeneralPathX();
820
        double[] theData = new double[6];
821
        double[] aux = new double[6];
822

    
823
        // newGp.reset();
824
        PathIterator theIterator;
825
        int theType;
826
        int numParts = 0;
827

    
828
        java.awt.geom.Point2D ptDst = new java.awt.geom.Point2D.Double();
829
        java.awt.geom.Point2D ptSrc = new java.awt.geom.Point2D.Double();
830
        boolean bFirst = true;
831
        int xInt, yInt, antX = -1, antY = -1;
832

    
833

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

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

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

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

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

    
878
                case PathIterator.SEG_CLOSE:
879
                    if (numSegmentsAdded < 3)
880
                        newGp.lineTo(antX, antY);
881
                    newGp.closePath();
882

    
883
                    break;
884
            } //end switch
885

    
886
            theIterator.next();
887
        } //end while loop
888

    
889
        FShape shp = null;
890
        switch (gp.getShapeType())
891
        {
892
            case FShape.POINT: //Tipo punto
893
            case FShape.POINT + FShape.Z:
894
                shp = new org.gvsig.fmap.geom.primitive.Point2D(null, null, ptDst.getX(), ptDst.getY());
895
                break;
896

    
897
            case FShape.LINE:
898
            case FShape.LINE + FShape.Z:
899
            case FShape.ARC:
900
                    shp = new Curve2D(null, null, newGp);
901
                break;
902

    
903
            case FShape.POLYGON:
904
            case FShape.POLYGON + FShape.Z:
905
            case FShape.CIRCLE:
906
            case FShape.ELLIPSE:
907

    
908
                shp = new Surface2D(null, null, newGp);
909
                break;
910
        }
911
        return shp;
912
    }
913

    
914
    public static Rectangle2D convertEnvelopeToRectangle2D(Envelope jtsR)
915
    {
916
        Rectangle2D.Double r = new Rectangle2D.Double(jtsR.getMinX(),
917
                jtsR.getMinY(), jtsR.getWidth(), jtsR.getHeight());
918
        return r;
919
    }
920

    
921
    public static Envelope convertRectangle2DtoEnvelope(Rectangle2D r)
922
    {
923
            Envelope e = new Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(),
924
                        r.getY() + r.getHeight());
925
            return e;
926
    }
927

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

    
946
        try {
947
                        return GeometryFactory.createPolygon2D(toShape(ring));
948
                } catch (NoninvertibleTransformException e) {
949
                        e.printStackTrace();
950
                }
951
                return null;
952
    }
953

    
954
    public static boolean isCCW(Point2D[] points)
955
    {
956
            Coordinate[] vs=new Coordinate[points.length];
957
            for (int i=points.length-1;i>=0;i--){
958
                    vs[i] = new Coordinate(points[i].getX(), points[i].getY());
959
            }
960

    
961
        return CGAlgorithms.isCCW(vs);
962
    }
963

    
964
    public static boolean isCCW(Surface2D pol)
965
    {
966
            com.vividsolutions.jts.geom.Geometry jtsGeom = Converter.java2d_to_jts(pol);
967
            if (jtsGeom.getNumGeometries() == 1)
968
            {
969
                    Coordinate[] coords = jtsGeom.getCoordinates();
970
                    return CGAlgorithms.isCCW(coords);
971
            }
972
            return false;
973

    
974
    }
975

    
976

    
977
    /**
978
     * Return a hole (CCW ordered points)
979
     * @param coordinates
980
     * @return
981
     */
982
    public static Geometry getHole(Coordinate[] coordinates)
983
    {
984
            // isCCW = true => it's a hole
985
            Coordinate[] vs=new Coordinate[coordinates.length];
986
        if (CGAlgorithms.isCCW(coordinates)){
987
                vs=coordinates;
988

    
989
        }else{
990
                for (int i=vs.length-1;i>=0;i--){
991
                        vs[i]=coordinates[i];
992
                }
993
        }
994
        LinearRing ring = geomFactory.createLinearRing(vs);
995

    
996
        try {
997
                        return GeometryFactory.createPolygon2D(toShape(ring));
998
                } catch (NoninvertibleTransformException e) {
999
                        e.printStackTrace();
1000
                }
1001
                return null;
1002
    }
1003

    
1004
        public static Shape getExteriorPolygon(GeneralPathX gp) {
1005
                Area area = new Area(gp);
1006
                area.isSingular();
1007
                return area;
1008

    
1009

    
1010

    
1011
        }
1012
        /**
1013
         * Use it ONLY for NOT multipart polygons.
1014
         * @param pol
1015
         * @return
1016
         */
1017
        public static Geometry getNotHolePolygon(Surface2D pol) {
1018
                // isCCW == true => hole
1019
                Coordinate[] coords;
1020
                ArrayList arrayCoords = null;
1021
                int theType;
1022
                int numParts = 0;
1023

    
1024
                //                 Use this array to store segment coordinate data
1025
                double[] theData = new double[6];
1026
                PathIterator theIterator;
1027

    
1028
                                ArrayList shells = new ArrayList();
1029
                                ArrayList holes = new ArrayList();
1030
                                Coordinate[] points = null;
1031

    
1032
                                theIterator = pol.getPathIterator(null, FLATNESS);
1033

    
1034
                                while (!theIterator.isDone()) {
1035
                                        //while not done
1036
                                        theType = theIterator.currentSegment(theData);
1037

    
1038
                                        //Populate a segment of the new
1039
                                        // GeneralPathX object.
1040
                                        //Process the current segment to populate a new
1041
                                        // segment of the new GeneralPathX object.
1042
                                        switch (theType) {
1043
                                                case PathIterator.SEG_MOVETO:
1044

    
1045
                                                        // System.out.println("SEG_MOVETO");
1046
                                                        if (arrayCoords == null) {
1047
                                                                arrayCoords = new ArrayList();
1048
                                                        } else {
1049
                                                                points = CoordinateArrays.toCoordinateArray(arrayCoords);
1050

    
1051
                                                                try {
1052
                                                                        LinearRing ring = geomFactory.createLinearRing(points);
1053

    
1054
                                                                        if (CGAlgorithms.isCCW(points)) {
1055
                                                                                holes.add(ring);
1056
                                                                        } else {
1057
                                                                                shells.add(ring);
1058
                                                                        }
1059
                                                                } catch (Exception e) {
1060
                                                                        System.err.println(
1061
                                                                                "Caught Topology exception in GMLLinearRingHandler");
1062

    
1063
                                                                        return null;
1064
                                                                }
1065

    
1066
                                                                /* if (numParts == 1)
1067
                                                                   {
1068
                                                                           linRingExt = new GeometryFactory().createLinearRing(
1069
                                                                                  CoordinateArrays.toCoordinateArray(arrayCoords));
1070
                                                                   }
1071
                                                                   else
1072
                                                                   {
1073
                                                                           linRing = new GeometryFactory().createLinearRing(
1074
                                                                                          CoordinateArrays.toCoordinateArray(arrayCoords));
1075
                                                                           arrayLines.add(linRing);
1076
                                                                   } */
1077
                                                                arrayCoords = new ArrayList();
1078
                                                        }
1079

    
1080
                                                        numParts++;
1081
                                                        arrayCoords.add(new Coordinate(theData[0],
1082
                                                                        theData[1]));
1083

    
1084
                                                        break;
1085

    
1086
                                                case PathIterator.SEG_LINETO:
1087

    
1088
                                                        // System.out.println("SEG_LINETO");
1089
                                                        arrayCoords.add(new Coordinate(theData[0],
1090
                                                                        theData[1]));
1091

    
1092
                                                        break;
1093

    
1094
                                                case PathIterator.SEG_QUADTO:
1095
                                                        System.out.println("SEG_QUADTO Not supported here");
1096

    
1097
                                                        break;
1098

    
1099
                                                case PathIterator.SEG_CUBICTO:
1100
                                                        System.out.println("SEG_CUBICTO Not supported here");
1101

    
1102
                                                        break;
1103

    
1104
                                                case PathIterator.SEG_CLOSE:
1105

    
1106
                                                        // A�adimos el primer punto para cerrar.
1107
                                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
1108
                                                        arrayCoords.add(new Coordinate(firstCoord.x,
1109
                                                                        firstCoord.y));
1110

    
1111
                                                        break;
1112
                                        } //end switch
1113

    
1114
                                        // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
1115
                                        theIterator.next();
1116
                                } //end while loop
1117

    
1118
                                arrayCoords.add(arrayCoords.get(0));
1119
                                coords = CoordinateArrays.toCoordinateArray(arrayCoords);
1120

    
1121

    
1122
                if (numParts == 1)
1123
                {
1124
                        return getExteriorPolygon(coords);
1125
                }
1126
                return GeometryFactory.createGeometry(pol);
1127

    
1128
        }
1129

    
1130

    
1131
    /* public static GeometryCollection convertFGeometryCollection(FGeometryCollection fGeomC)
1132
    {
1133

1134
        geomFactory.createGeometryCollection(theGeoms);
1135
    } */
1136
}