Statistics
| Revision:

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

History | View | Annotate | Download (32 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.LineString;
73
import com.vividsolutions.jts.geom.LinearRing;
74
import com.vividsolutions.jts.geom.MultiLineString;
75
import com.vividsolutions.jts.geom.MultiPolygon;
76
import com.vividsolutions.jts.geom.Point;
77
import com.vividsolutions.jts.geom.Polygon;
78

    
79

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

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

    
102

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

    
109
                numpoints = Array.getLength(pointList);
110

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

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

    
121
                return false;
122
        }
123

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

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

    
146

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

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

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

    
169
                                break;
170

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

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

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

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

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

    
202
                                                        break;
203

    
204
                                                case PathIterator.SEG_LINETO:
205

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

    
210
                                                        break;
211

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

    
215
                                                        break;
216

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

    
220
                                                        break;
221

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

    
228
                                                        break;
229
                                        } //end switch
230

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

    
234
                                lin = new com.vividsolutions.jts.geom.GeometryFactory().createLineString(CoordinateArrays.toCoordinateArray(
235
                                                        arrayCoords));
236

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

    
249
                                break;
250

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

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

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

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

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

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

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

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

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

    
312
                                                                        return null;
313
                                                                }
314

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

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

    
333
                                                        break;
334

    
335
                                                case PathIterator.SEG_LINETO:
336

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

    
341
                                                        break;
342

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

    
346
                                                        break;
347

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

    
351
                                                        break;
352

    
353
                                                case PathIterator.SEG_CLOSE:
354

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

    
360
                                                        break;
361
                                        } //end switch
362

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

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

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

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

    
401
                                        return null;
402
                                }
403

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

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

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

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

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

    
427
                                                Envelope tryEnv = tryRing.getEnvelopeInternal();
428

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

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

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

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

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

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

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

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

    
487
                                // FIN CAMBIO
488

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

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

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

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

    
512
                return geoJTS;
513
        }
514

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

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

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

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

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

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

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

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

    
561
                return null;
562
        }
563

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

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

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

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

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

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

    
599
                return resul;
600
        }
601

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

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

620
                return viewCoordinates;
621
        } */
622

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
755

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

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

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

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

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

    
799
                    break;
800

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

    
804
                    break;
805

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

    
809
                    break;
810
            } //end switch
811

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

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

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

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

    
832

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

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

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

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

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

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

    
882
                    break;
883
            } //end switch
884

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

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

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

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

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

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

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

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

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

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

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

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

    
973
    }
974

    
975

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

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

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

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

    
1008

    
1009

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

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

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

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

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

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

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

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

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

    
1062
                                                                        return null;
1063
                                                                }
1064

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

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

    
1083
                                                        break;
1084

    
1085
                                                case PathIterator.SEG_LINETO:
1086

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

    
1091
                                                        break;
1092

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

    
1096
                                                        break;
1097

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

    
1101
                                                        break;
1102

    
1103
                                                case PathIterator.SEG_CLOSE:
1104

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

    
1110
                                                        break;
1111
                                        } //end switch
1112

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

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

    
1120

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

    
1127
        }
1128

    
1129

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

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