Statistics
| Revision:

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

History | View | Annotate | Download (32.1 KB)

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

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

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

    
82

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

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

    
105

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

    
112
                numpoints = Array.getLength(pointList);
113

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

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

    
124
                return false;
125
        }
126

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

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

    
151

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

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

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

    
174
                                break;
175

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

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

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

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

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

    
208
                                                        break;
209

    
210
                                                case PathIterator.SEG_LINETO:
211

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

    
216
                                                        break;
217

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

    
221
                                                        break;
222

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

    
226
                                                        break;
227

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

    
234
                                                        break;
235
                                        } //end switch
236

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

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

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

    
255
                                break;
256

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

    
263
                                ArrayList shells = new ArrayList();
264
                                ArrayList holes = new ArrayList();
265
                                Coordinate[] points = null;
266

    
267
                                theIterator = shp.getPathIterator(null, FLATNESS);
268

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

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

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

    
286
                                                                try {
287
                                                                        LinearRing ring = geomFactory.createLinearRing(points);
288

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

    
315
                                                                        System.err.println(
316
                                                                                "Caught Topology exception in GMLLinearRingHandler");
317

    
318
                                                                        return null;
319
                                                                }
320

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

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

    
339
                                                        break;
340

    
341
                                                case PathIterator.SEG_LINETO:
342

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

    
347
                                                        break;
348

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

    
352
                                                        break;
353

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

    
357
                                                        break;
358

    
359
                                                case PathIterator.SEG_CLOSE:
360

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

    
366
                                                        break;
367
                                        } //end switch
368

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

    
373
                                arrayCoords.add(arrayCoords.get(0));
374
                                points = CoordinateArrays.toCoordinateArray(arrayCoords);
375

    
376
                                try {
377
                                        LinearRing ring = geomFactory.createLinearRing(points);
378

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

    
407
                                        return null;
408
                                }
409

    
410
                                /* linRing = new GeometryFactory().createLinearRing(
411
                                   CoordinateArrays.toCoordinateArray(arrayCoords)); */
412

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

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

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

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

    
433
                                                Envelope tryEnv = tryRing.getEnvelopeInternal();
434

    
435
                                                if (minShell != null) {
436
                                                        minEnv = minShell.getEnvelopeInternal();
437
                                                }
438

    
439
                                                boolean isContained = false;
440
                                                Coordinate[] coordList = tryRing.getCoordinates();
441

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

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

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

    
476
                                Polygon[] polygons = new Polygon[shells.size()];
477

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

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

    
493
                                // FIN CAMBIO
494

    
495
                                holesForShells = null;
496
                                shells = null;
497
                                holes = null;
498

    
499
                                //its a multi part
500
                                geoJTS = geomFactory.createMultiPolygon(polygons);
501

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

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

    
518
                return geoJTS;
519
        }
520

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

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

    
536
                        if (geo.isEmpty()) {
537
                                shpNew = null;
538
                        }
539

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

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

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

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

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

    
567
                return null;
568
        }
569

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

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

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

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

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

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

    
605
                return resul;
606
        }
607

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

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

626
                return viewCoordinates;
627
        } */
628

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

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

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

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

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

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

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

    
690
                return viewPoint;
691
        }
692

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

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

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

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

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

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

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

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

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

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

    
757

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

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

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

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

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

    
801
                    break;
802

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

    
806
                    break;
807

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

    
811
                    break;
812
            } //end switch
813

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

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

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

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

    
834

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

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

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

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

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

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

    
884
                    break;
885
            } //end switch
886

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

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

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

    
905
            case FShape.POLYGON:
906
            case FShape.POLYGON + FShape.Z:
907
            case FShape.CIRCLE:
908
            case FShape.ELLIPSE:
909

    
910
                shp = new FPolygon2D(newGp);
911
                break;
912
        }
913
        return shp;
914
    }
915

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

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

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

    
948
        try {
949
                        return ShapeFactory.createPolygon2D(toShape(ring));
950
                } catch (NoninvertibleTransformException e) {
951
                        e.printStackTrace();
952
                }
953
                return null;
954
    }
955

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

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

    
985
    }
986

    
987

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

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

    
1007
        try {
1008
                        return ShapeFactory.createPolygon2D(toShape(ring));
1009
                } catch (NoninvertibleTransformException e) {
1010
                        e.printStackTrace();
1011
                }
1012
                return null;
1013
    }
1014

    
1015
        public static Shape getExteriorPolygon(GeneralPathX gp) {
1016
                Area area = new Area(gp);
1017
                area.isSingular();
1018
                return area;
1019

    
1020

    
1021

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

    
1035
                //                 Use this array to store segment coordinate data
1036
                double[] theData = new double[6];
1037
                PathIterator theIterator;
1038

    
1039
                                ArrayList shells = new ArrayList();
1040
                                ArrayList holes = new ArrayList();
1041
                                Coordinate[] points = null;
1042

    
1043
                                theIterator = pol.getPathIterator(null, FLATNESS);
1044

    
1045
                                while (!theIterator.isDone()) {
1046
                                        //while not done
1047
                                        theType = theIterator.currentSegment(theData);
1048

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

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

    
1062
                                                                try {
1063
                                                                        LinearRing ring = geomFactory.createLinearRing(points);
1064

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

    
1074
                                                                        return null;
1075
                                                                }
1076

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

    
1091
                                                        numParts++;
1092
                                                        arrayCoords.add(new Coordinate(theData[0],
1093
                                                                        theData[1]));
1094

    
1095
                                                        break;
1096

    
1097
                                                case PathIterator.SEG_LINETO:
1098

    
1099
                                                        // System.out.println("SEG_LINETO");
1100
                                                        arrayCoords.add(new Coordinate(theData[0],
1101
                                                                        theData[1]));
1102

    
1103
                                                        break;
1104

    
1105
                                                case PathIterator.SEG_QUADTO:
1106
                                                        System.out.println("SEG_QUADTO Not supported here");
1107

    
1108
                                                        break;
1109

    
1110
                                                case PathIterator.SEG_CUBICTO:
1111
                                                        System.out.println("SEG_CUBICTO Not supported here");
1112

    
1113
                                                        break;
1114

    
1115
                                                case PathIterator.SEG_CLOSE:
1116

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

    
1122
                                                        break;
1123
                                        } //end switch
1124

    
1125
                                        // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
1126
                                        theIterator.next();
1127
                                } //end while loop
1128

    
1129
                                arrayCoords.add(arrayCoords.get(0));
1130
                                coords = CoordinateArrays.toCoordinateArray(arrayCoords);
1131

    
1132

    
1133
                if (numParts == 1)
1134
                {
1135
                        return getExteriorPolygon(coords);
1136
                }
1137
                return ShapeFactory.createGeometry(pol);
1138

    
1139
        }
1140

    
1141

    
1142
    /* public static GeometryCollection convertFGeometryCollection(FGeometryCollection fGeomC)
1143
    {
1144

1145
        geomFactory.createGeometryCollection(theGeoms);
1146
    } */
1147
}