Statistics
| Revision:

root / branches / piloto3d / libraries / libFMap / src / com / iver / cit / gvsig / fmap / core / v02 / FConverter.java @ 9524

History | View | Annotate | Download (30 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.FPoint2D;
60
import com.iver.cit.gvsig.fmap.core.FPolygon2D;
61
import com.iver.cit.gvsig.fmap.core.FPolyline2D;
62
import com.iver.cit.gvsig.fmap.core.FShape;
63
import com.iver.cit.gvsig.fmap.core.GeneralPathX;
64
import com.iver.cit.gvsig.fmap.core.IGeometry;
65
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
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.Geometry;
72
import com.vividsolutions.jts.geom.GeometryCollection;
73
import com.vividsolutions.jts.geom.GeometryFactory;
74
import com.vividsolutions.jts.geom.LineString;
75
import com.vividsolutions.jts.geom.LinearRing;
76
import com.vividsolutions.jts.geom.MultiLineString;
77
import com.vividsolutions.jts.geom.MultiPolygon;
78
import com.vividsolutions.jts.geom.Point;
79
import com.vividsolutions.jts.geom.Polygon;
80

    
81

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

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

    
104

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

    
111
                numpoints = Array.getLength(pointList);
112

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

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

    
123
                return false;
124
        }
125

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

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

    
148

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

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

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

    
171
                                break;
172

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

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

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

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

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

    
204
                                                        break;
205

    
206
                                                case PathIterator.SEG_LINETO:
207

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

    
212
                                                        break;
213

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

    
217
                                                        break;
218

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

    
222
                                                        break;
223

    
224
                                                case PathIterator.SEG_CLOSE:
225
                                                        System.out.println("SEG_CLOSE");
226

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

    
232
                                                        break;
233
                                        } //end switch
234

    
235
                                        theIterator.next();
236
                                } //end while loop
237

    
238
                                lin = new GeometryFactory().createLineString(CoordinateArrays.toCoordinateArray(
239
                                                        arrayCoords));
240

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

    
253
                                break;
254

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

    
261
                                ArrayList shells = new ArrayList();
262
                                ArrayList holes = new ArrayList();
263
                                Coordinate[] points = null;
264

    
265
                                theIterator = shp.getPathIterator(null, FLATNESS);
266

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

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

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

    
284
                                                                try {
285
                                                                        LinearRing ring = geomFactory.createLinearRing(points);
286

    
287
                                                                        if (CGAlgorithms.isCCW(points)) {
288
                                                                                holes.add(ring);
289
                                                                        } else {
290
                                                                                shells.add(ring);
291
                                                                        }
292
                                                                } catch (Exception e) {
293
                                                                        System.err.println(
294
                                                                                "Caught Topology exception in GMLLinearRingHandler");
295

    
296
                                                                        return null;
297
                                                                }
298

    
299
                                                                /* if (numParts == 1)
300
                                                                   {
301
                                                                           linRingExt = new GeometryFactory().createLinearRing(
302
                                                                                  CoordinateArrays.toCoordinateArray(arrayCoords));
303
                                                                   }
304
                                                                   else
305
                                                                   {
306
                                                                           linRing = new GeometryFactory().createLinearRing(
307
                                                                                          CoordinateArrays.toCoordinateArray(arrayCoords));
308
                                                                           arrayLines.add(linRing);
309
                                                                   } */
310
                                                                arrayCoords = new ArrayList();
311
                                                        }
312

    
313
                                                        numParts++;
314
                                                        arrayCoords.add(new Coordinate(theData[0],
315
                                                                        theData[1]));
316

    
317
                                                        break;
318

    
319
                                                case PathIterator.SEG_LINETO:
320

    
321
                                                        // System.out.println("SEG_LINETO");
322
                                                        arrayCoords.add(new Coordinate(theData[0],
323
                                                                        theData[1]));
324

    
325
                                                        break;
326

    
327
                                                case PathIterator.SEG_QUADTO:
328
                                                        System.out.println("SEG_QUADTO Not supported here");
329

    
330
                                                        break;
331

    
332
                                                case PathIterator.SEG_CUBICTO:
333
                                                        System.out.println("SEG_CUBICTO Not supported here");
334

    
335
                                                        break;
336

    
337
                                                case PathIterator.SEG_CLOSE:
338

    
339
                                                        // A?adimos el primer punto para cerrar.
340
                                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
341
                                                        arrayCoords.add(new Coordinate(firstCoord.x,
342
                                                                        firstCoord.y));
343

    
344
                                                        break;
345
                                        } //end switch
346

    
347
                                        // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
348
                                        theIterator.next();
349
                                } //end while loop
350

    
351
                                arrayCoords.add(arrayCoords.get(0));
352
                                points = CoordinateArrays.toCoordinateArray(arrayCoords);
353

    
354
                                try {
355
                                        LinearRing ring = geomFactory.createLinearRing(points);
356

    
357
                                        if (CGAlgorithms.isCCW(points)) {
358
                                                holes.add(ring);
359
                                        } else {
360
                                                shells.add(ring);
361
                                        }
362
                                } catch (Exception e) {
363
                                        System.err.println(
364
                                                "Caught Topology exception in GMLLinearRingHandler");
365

    
366
                                        return null;
367
                                }
368

    
369
                                /* linRing = new GeometryFactory().createLinearRing(
370
                                   CoordinateArrays.toCoordinateArray(arrayCoords)); */
371

    
372
                                // System.out.println("NumParts = " + numParts);
373
                                //now we have a list of all shells and all holes
374
                                ArrayList holesForShells = new ArrayList(shells.size());
375

    
376
                                for (int i = 0; i < shells.size(); i++) {
377
                                        holesForShells.add(new ArrayList());
378
                                }
379

    
380
                                //find homes
381
                                for (int i = 0; i < holes.size(); i++) {
382
                                        LinearRing testRing = (LinearRing) holes.get(i);
383
                                        LinearRing minShell = null;
384
                                        Envelope minEnv = null;
385
                                        Envelope testEnv = testRing.getEnvelopeInternal();
386
                                        Coordinate testPt = testRing.getCoordinateN(0);
387
                                        LinearRing tryRing = null;
388

    
389
                                        for (int j = 0; j < shells.size(); j++) {
390
                                                tryRing = (LinearRing) shells.get(j);
391

    
392
                                                Envelope tryEnv = tryRing.getEnvelopeInternal();
393

    
394
                                                if (minShell != null) {
395
                                                        minEnv = minShell.getEnvelopeInternal();
396
                                                }
397

    
398
                                                boolean isContained = false;
399
                                                Coordinate[] coordList = tryRing.getCoordinates();
400

    
401
                                                if (tryEnv.contains(testEnv) &&
402
                                                                (CGAlgorithms.isPointInRing(testPt, coordList) ||
403
                                                                (pointInList(testPt, coordList)))) {
404
                                                        isContained = true;
405
                                                }
406

    
407
                                                // check if this new containing ring is smaller than the current minimum ring
408
                                                if (isContained) {
409
                                                        if ((minShell == null) || minEnv.contains(tryEnv)) {
410
                                                                minShell = tryRing;
411
                                                        }
412
                                                }
413
                                        }
414

    
415
                                        if (minShell == null) {
416
                                                System.out.println(
417
                                                        "polygon found with a hole thats not inside a shell");
418
//azabala: we do the assumption that this hole is really a shell (polygon)
419
//whose point werent digitized in the right order
420
Coordinate[] cs = testRing.getCoordinates();
421
Coordinate[] reversed = new Coordinate[cs.length];
422
int pointIndex = 0;
423
for(int z = cs.length-1; z >= 0; z--){
424
        reversed[pointIndex] = cs[z];
425
        pointIndex++;
426
}
427
LinearRing newRing = geomFactory.createLinearRing(reversed);
428
shells.add(newRing);
429
holesForShells.add(new ArrayList());
430
                                        } else {
431
                                                ((ArrayList) holesForShells.get(shells.indexOf(minShell))).add(testRing);
432
                                        }
433
                                }
434

    
435
                                Polygon[] polygons = new Polygon[shells.size()];
436

    
437
                                for (int i = 0; i < shells.size(); i++) {
438
                                        polygons[i] = geomFactory.createPolygon((LinearRing) shells.get(
439
                                                                i),
440
                                                        (LinearRing[]) ((ArrayList) holesForShells.get(i)).toArray(
441
                                                                new LinearRing[0]));
442
                                }
443
                                // CAMBIO: ENTREGAMOS SIEMPRE MULTILINESTRING, QUE ES
444
                                // LO QUE HACE TODO EL MUNDO CUANDO ESCRIBE EN POSTGIS
445
                                // O CON GEOTOOLS
446
                                // if (numParts > 1) // Generamos una MultiLineString
447

    
448
                                /* if (polygons.length == 1) {
449
                                        return polygons[0];
450
                                } */
451

    
452
                                // FIN CAMBIO
453

    
454
                                holesForShells = null;
455
                                shells = null;
456
                                holes = null;
457

    
458
                                //its a multi part
459
                                geoJTS = geomFactory.createMultiPolygon(polygons);
460

    
461
                                /* if (numParts > 1) // Generamos un Polygon con agujeros
462
                                   {
463
                                    arrayLines.add(linRing);
464
                                           // geoJTS = new GeometryFactory().createPolygon(linRingExt,
465
                                                           // GeometryFactory.toLinearRingArray(arrayLines));
466
                                    geoJTS = new GeometryFactory().buildGeometry(arrayLines);
467

468
                                    // geoJTS = Polygonizer.class.
469
                                   }
470
                                   else
471
                                   {
472
                                           geoJTS = new GeometryFactory().createPolygon(linRing,null);
473
                                   } */
474
                                break;
475
                }
476

    
477
                return geoJTS;
478
        }
479

    
480
        /**
481
         * Converts JTS Geometry objects into Java 2D Shape objects
482
         *
483
         * @param geo Geometry de JTS.
484
         *
485
         * @return FShape.
486
         */
487
        public static FShape jts_to_java2d(Geometry geo) {
488
                FShape shpNew = null;
489

    
490
                try {
491
                        if (geo instanceof Point) {
492
                                shpNew = new FPoint2D(((Point) geo).getX(), ((Point) geo).getY());
493
                        }
494

    
495
                        if (geo.isEmpty()) {
496
                                shpNew = null;
497
                        }
498

    
499
                        if (geo instanceof Polygon) {
500
                                shpNew = new FPolygon2D(toShape((Polygon) geo));
501
                        }
502

    
503
                        if (geo instanceof MultiPolygon) {
504
                                shpNew = new FPolygon2D(toShape((MultiPolygon) geo));
505
                        }
506

    
507
                        if (geo instanceof LineString) {
508
                                shpNew = new FPolyline2D(toShape((LineString) geo));
509
                        }
510

    
511
                        if (geo instanceof MultiLineString) {
512
                                shpNew = new FPolyline2D(toShape((MultiLineString) geo));
513
                        }
514

    
515
                        /* OJO: CON ALGO COMO FSHAPE NO S? C?MO PODEMOS IMPLEMENTAR UN GeometryCollection
516
                         * No sabremos si queremos una l?nea o un pol?gono.....
517
                         *  if (geometry instanceof GeometryCollection) {
518
                                  return toShape((GeometryCollection) geometry);
519
                           } */
520
                        return shpNew;
521
                } catch (NoninvertibleTransformException e) {
522
                        // TODO Auto-generated catch block
523
                        e.printStackTrace();
524
                }
525

    
526
                return null;
527
        }
528

    
529
        /**
530
         * DOCUMENT ME!
531
         *
532
         * @param p DOCUMENT ME!
533
         *
534
         * @return DOCUMENT ME!
535
         */
536
        private static GeneralPathX toShape(Polygon p) {
537
                GeneralPathX resul = new GeneralPathX();
538
                Coordinate coord;
539

    
540
                for (int i = 0; i < p.getExteriorRing().getNumPoints(); i++) {
541
                        coord = p.getExteriorRing().getCoordinateN(i);
542

    
543
                        if (i == 0) {
544
                                resul.moveTo(coord.x,coord.y);
545
                        } else {
546
                                resul.lineTo(coord.x,coord.y);
547
                        }
548
                }
549

    
550
                for (int j = 0; j < p.getNumInteriorRing(); j++) {
551
                        LineString hole = p.getInteriorRingN(j);
552

    
553
                        for (int k = 0; k < hole.getNumPoints(); k++) {
554
                                coord = hole.getCoordinateN(k);
555

    
556
                                if (k == 0) {
557
                                        resul.moveTo(coord.x, coord.y);
558
                                } else {
559
                                        resul.lineTo(coord.x, coord.y);
560
                                }
561
                        }
562
                }
563

    
564
                return resul;
565
        }
566

    
567
        /**
568
         * DOCUMENT ME!
569
         *
570
         * @param modelCoordinates DOCUMENT ME!
571
         *
572
         * @return DOCUMENT ME!
573
         *
574
         * @throws NoninvertibleTransformException DOCUMENT ME!
575
         *
576
        private Coordinate[] toViewCoordinates(Coordinate[] modelCoordinates)
577
                throws NoninvertibleTransformException {
578
                Coordinate[] viewCoordinates = new Coordinate[modelCoordinates.length];
579

580
                for (int i = 0; i < modelCoordinates.length; i++) {
581
                        FPoint2D point2D = coordinate2FPoint2D(modelCoordinates[i]);
582
                        viewCoordinates[i] = new Coordinate(point2D.getX(), point2D.getY());
583
                }
584

585
                return viewCoordinates;
586
        } */
587

    
588
        /* private Shape toShape(GeometryCollection gc)
589
           throws NoninvertibleTransformException {
590
           GeometryCollectionShape shape = new GeometryCollectionShape();
591
           for (int i = 0; i < gc.getNumGeometries(); i++) {
592
                   Geometry g = (Geometry) gc.getGeometryN(i);
593
                   shape.add(toShape(g));
594
           }
595
           return shape;
596
           } */
597
        private static GeneralPathX toShape(MultiLineString mls)
598
                throws NoninvertibleTransformException {
599
                GeneralPathX path = new GeneralPathX();
600

    
601
                for (int i = 0; i < mls.getNumGeometries(); i++) {
602
                        LineString lineString = (LineString) mls.getGeometryN(i);
603
                        path.append(toShape(lineString), false);
604
                }
605

    
606
                //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
607
                //converted to GeneralPathXs. [Jon Aquino]
608
                return path;
609
        }
610

    
611
        /**
612
         * DOCUMENT ME!
613
         *
614
         * @param lineString DOCUMENT ME!
615
         *
616
         * @return DOCUMENT ME!
617
         *
618
         * @throws NoninvertibleTransformException DOCUMENT ME!
619
         */
620
        private static GeneralPathX toShape(LineString lineString)
621
                throws NoninvertibleTransformException {
622
                GeneralPathX shape = new GeneralPathX();
623
                FPoint2D viewPoint = coordinate2FPoint2D(lineString.getCoordinateN(0));
624
                shape.moveTo(viewPoint.getX(), viewPoint.getY());
625

    
626
                for (int i = 1; i < lineString.getNumPoints(); i++) {
627
                        viewPoint = coordinate2FPoint2D(lineString.getCoordinateN(i));
628
                        shape.lineTo(viewPoint.getX(), viewPoint.getY());
629
                }
630

    
631
                //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
632
                //converted to GeneralPathXs. [Jon Aquino]
633
                return shape;
634
        }
635

    
636
        /**
637
         * DOCUMENT ME!
638
         *
639
         * @param point DOCUMENT ME!
640
         *
641
         * @return DOCUMENT ME!
642
         *
643
         * @throws NoninvertibleTransformException DOCUMENT ME!
644
         */
645
        private static FPoint2D toShape(Point point)
646
                throws NoninvertibleTransformException {
647
                FPoint2D viewPoint = coordinate2FPoint2D(point.getCoordinate());
648

    
649
                return viewPoint;
650
        }
651

    
652
        private static GeneralPathX toShape(MultiPolygon mp)
653
        throws NoninvertibleTransformException {
654
        GeneralPathX path = new GeneralPathX();
655

    
656
        for (int i = 0; i < mp.getNumGeometries(); i++) {
657
                Polygon polygon = (Polygon) mp.getGeometryN(i);
658
                path.append(toShape(polygon), false);
659
        }
660

    
661
        //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
662
        //converted to GeneralPathXs. [Jon Aquino]
663
        return path;
664
}
665
        /**
666
         * DOCUMENT ME!
667
         *
668
         * @param coord DOCUMENT ME!
669
         *
670
         * @return DOCUMENT ME!
671
         */
672
        public static FPoint2D coordinate2FPoint2D(Coordinate coord) {
673
                return new FPoint2D(coord.x, coord.y); //,coord.z);
674
        }
675

    
676
        /**
677
         * Convierte una Geometry de JTS a GeneralPathX.
678
         *
679
         * @param geometry Geometry a convertir.
680
         *
681
         * @return GeneralPathX.
682
         *
683
         * @throws NoninvertibleTransformException
684
         * @throws IllegalArgumentException
685
         */
686
        public static GeneralPathX toShape(Geometry geometry)
687
                throws NoninvertibleTransformException {
688
                if (geometry.isEmpty()) {
689
                        return new GeneralPathX();
690
                }
691

    
692
                if (geometry instanceof Polygon) {
693
                        return toShape((Polygon) geometry);
694
                }
695

    
696
                if (geometry instanceof MultiPolygon) {
697
                        return toShape((MultiPolygon) geometry);
698
                }
699

    
700
                if (geometry instanceof LineString) {
701
                        return toShape((LineString) geometry);
702
                }
703

    
704
                if (geometry instanceof MultiLineString) {
705
                        return toShape((MultiLineString) geometry);
706
                }
707

    
708
                if (geometry instanceof GeometryCollection) {
709
                        return toShape((GeometryCollection) geometry);
710
                }
711

    
712
                throw new IllegalArgumentException("Unrecognized Geometry class: " +
713
                        geometry.getClass());
714
        }
715

    
716

    
717
    public static GeneralPathX transformToInts(GeneralPathX gp, AffineTransform at) {
718
        GeneralPathX newGp = new GeneralPathX();
719
        PathIterator theIterator;
720
        int theType;
721
        int numParts = 0;
722
        double[] theData = new double[6];
723
        Point2D ptDst = new Point2D.Double();
724
        Point2D ptSrc = new Point2D.Double();
725
        boolean bFirst = true;
726
        int xInt, yInt, antX = -1, antY = -1;
727

    
728
        theIterator = gp.getPathIterator(null); //, flatness);
729

    
730
        while (!theIterator.isDone()) {
731
            theType = theIterator.currentSegment(theData);
732
            switch (theType) {
733
                case PathIterator.SEG_MOVETO:
734
                    numParts++;
735
                    ptSrc.setLocation(theData[0], theData[1]);
736
                    at.transform(ptSrc, ptDst);
737
                    antX = (int) ptDst.getX();
738
                    antY = (int) ptDst.getY();
739
                    newGp.moveTo(antX, antY);
740
                    bFirst = true;
741
                    break;
742

    
743
                case PathIterator.SEG_LINETO:
744
                    ptSrc.setLocation(theData[0], theData[1]);
745
                    at.transform(ptSrc, ptDst);
746
                    xInt = (int) ptDst.getX();
747
                    yInt = (int) ptDst.getY();
748
                    if ((bFirst) || ((xInt != antX) || (yInt != antY)))
749
                    {
750
                        newGp.lineTo(xInt, yInt);
751
                        antX = xInt;
752
                        antY = yInt;
753
                        bFirst = false;
754
                    }
755
                    break;
756

    
757
                case PathIterator.SEG_QUADTO:
758
                    System.out.println("Not supported here");
759

    
760
                    break;
761

    
762
                case PathIterator.SEG_CUBICTO:
763
                    System.out.println("Not supported here");
764

    
765
                    break;
766

    
767
                case PathIterator.SEG_CLOSE:
768
                    newGp.closePath();
769

    
770
                    break;
771
            } //end switch
772

    
773
            theIterator.next();
774
        } //end while loop
775

    
776
        return newGp;
777
    }
778
    public static FShape transformToInts(IGeometry gp, AffineTransform at) {
779
        GeneralPathX newGp = new GeneralPathX();
780
        double[] theData = new double[6];
781
        double[] aux = new double[6];
782

    
783
        // newGp.reset();
784
        PathIterator theIterator;
785
        int theType;
786
        int numParts = 0;
787

    
788
        Point2D ptDst = new Point2D.Double();
789
        Point2D ptSrc = new Point2D.Double();
790
        boolean bFirst = true;
791
        int xInt, yInt, antX = -1, antY = -1;
792

    
793

    
794
        theIterator = gp.getPathIterator(null); //, flatness);
795
        int numSegmentsAdded = 0;
796
        while (!theIterator.isDone()) {
797
            theType = theIterator.currentSegment(theData);
798

    
799
            switch (theType) {
800
                case PathIterator.SEG_MOVETO:
801
                    numParts++;
802
                    ptSrc.setLocation(theData[0], theData[1]);
803
                    at.transform(ptSrc, ptDst);
804
                    antX = (int) ptDst.getX();
805
                    antY = (int) ptDst.getY();
806
                    newGp.moveTo(antX, antY);
807
                    numSegmentsAdded++;
808
                    bFirst = true;
809
                    break;
810

    
811
                case PathIterator.SEG_LINETO:
812
                    ptSrc.setLocation(theData[0], theData[1]);
813
                    at.transform(ptSrc, ptDst);
814
                    xInt = (int) ptDst.getX();
815
                    yInt = (int) ptDst.getY();
816
                    if ((bFirst) || ((xInt != antX) || (yInt != antY)))
817
                    {
818
                        newGp.lineTo(xInt, yInt);
819
                        antX = xInt;
820
                        antY = yInt;
821
                        bFirst = false;
822
                        numSegmentsAdded++;
823
                    }
824
                    break;
825

    
826
                case PathIterator.SEG_QUADTO:
827
                    at.transform(theData,0,aux,0,2);
828
                    newGp.quadTo(aux[0], aux[1], aux[2], aux[3]);
829
                    numSegmentsAdded++;
830
                    break;
831

    
832
                case PathIterator.SEG_CUBICTO:
833
                    at.transform(theData,0,aux,0,3);
834
                    newGp.curveTo(aux[0], aux[1], aux[2], aux[3], aux[4], aux[5]);
835
                    numSegmentsAdded++;
836
                    break;
837

    
838
                case PathIterator.SEG_CLOSE:
839
                    if (numSegmentsAdded < 3)
840
                        newGp.lineTo(antX, antY);
841
                    newGp.closePath();
842

    
843
                    break;
844
            } //end switch
845

    
846
            theIterator.next();
847
        } //end while loop
848
        FShape shp = null;
849
        switch (gp.getGeometryType())
850
        {
851
            case FShape.POINT: //Tipo punto
852
            case FShape.POINT + FShape.Z:
853
                shp = new FPoint2D(ptDst.getX(), ptDst.getY());
854
                break;
855

    
856
            case FShape.LINE:
857
            case FShape.LINE + FShape.Z:
858
            case FShape.ARC:
859
                    shp = new FPolyline2D(newGp);
860
                break;
861

    
862
            case FShape.POLYGON:
863
            case FShape.POLYGON + FShape.Z:
864
            case FShape.CIRCLE:
865
            case FShape.ELLIPSE:
866

    
867
                shp = new FPolygon2D(newGp);
868
                break;
869
        }
870
        return shp;
871
    }
872

    
873
    public static Rectangle2D convertEnvelopeToRectangle2D(Envelope jtsR)
874
    {
875
        Rectangle2D.Double r = new Rectangle2D.Double(jtsR.getMinX(),
876
                jtsR.getMinY(), jtsR.getWidth(), jtsR.getHeight());
877
        return r;
878
    }
879

    
880
    public static Envelope convertRectangle2DtoEnvelope(Rectangle2D r)
881
    {
882
            Envelope e = new Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(),
883
                        r.getY() + r.getHeight());
884
            return e;
885
    }
886

    
887
    /**
888
     * Return a correct polygon (no hole)
889
     * @param coordinates
890
     * @return
891
     */
892
    public static IGeometry getExteriorPolygon(Coordinate[] coordinates)
893
    {
894
            // isCCW = true => it's a hole
895
            Coordinate[] vs=new Coordinate[coordinates.length];
896
        if (CGAlgorithms.isCCW(coordinates)){
897
                for (int i=vs.length-1;i>=0;i--){
898
                        vs[i]=coordinates[i];
899
                }
900
        }else{
901
                vs=coordinates;
902
        }
903
        LinearRing ring = geomFactory.createLinearRing(vs);
904

    
905
        try {
906
                        return ShapeFactory.createPolygon2D(toShape(ring));
907
                } catch (NoninvertibleTransformException e) {
908
                        e.printStackTrace();
909
                }
910
                return null;
911
    }
912

    
913
    public static boolean isCCW(Point2D[] points)
914
    {
915
            Coordinate[] vs=new Coordinate[points.length];
916
            for (int i=points.length-1;i>=0;i--){
917
                    vs[i] = new Coordinate(points[i].getX(), points[i].getY());
918
            }
919

    
920
        return CGAlgorithms.isCCW(vs);
921
    }
922

    
923
    public static boolean isCCW(FPolygon2D pol)
924
    {
925
            Geometry jtsGeom = FConverter.java2d_to_jts(pol);
926
            if (jtsGeom.getNumGeometries() == 1)
927
            {
928
                    Coordinate[] coords = jtsGeom.getCoordinates();
929
                    return CGAlgorithms.isCCW(coords);
930
            }
931
            return false;
932

    
933
    }
934

    
935

    
936
    /**
937
     * Return a hole (CCW ordered points)
938
     * @param coordinates
939
     * @return
940
     */
941
    public static IGeometry getHole(Coordinate[] coordinates)
942
    {
943
            // isCCW = true => it's a hole
944
            Coordinate[] vs=new Coordinate[coordinates.length];
945
        if (CGAlgorithms.isCCW(coordinates)){
946
                vs=coordinates;
947

    
948
        }else{
949
                for (int i=vs.length-1;i>=0;i--){
950
                        vs[i]=coordinates[i];
951
                }
952
        }
953
        LinearRing ring = geomFactory.createLinearRing(vs);
954

    
955
        try {
956
                        return ShapeFactory.createPolygon2D(toShape(ring));
957
                } catch (NoninvertibleTransformException e) {
958
                        e.printStackTrace();
959
                }
960
                return null;
961
    }
962

    
963
        public static Shape getExteriorPolygon(GeneralPathX gp) {
964
                Area area = new Area(gp);
965
                area.isSingular();
966
                return area;
967

    
968

    
969

    
970
        }
971
        /**
972
         * Use it ONLY for NOT multipart polygons.
973
         * @param pol
974
         * @return
975
         */
976
        public static IGeometry getNotHolePolygon(FPolygon2D pol) {
977
                // isCCW == true => hole
978
                Coordinate[] coords;
979
                ArrayList arrayCoords = null;
980
                int theType;
981
                int numParts = 0;
982

    
983
                //                 Use this array to store segment coordinate data
984
                double[] theData = new double[6];
985
                PathIterator theIterator;
986

    
987
                                ArrayList shells = new ArrayList();
988
                                ArrayList holes = new ArrayList();
989
                                Coordinate[] points = null;
990

    
991
                                theIterator = pol.getPathIterator(null, FLATNESS);
992

    
993
                                while (!theIterator.isDone()) {
994
                                        //while not done
995
                                        theType = theIterator.currentSegment(theData);
996

    
997
                                        //Populate a segment of the new
998
                                        // GeneralPathX object.
999
                                        //Process the current segment to populate a new
1000
                                        // segment of the new GeneralPathX object.
1001
                                        switch (theType) {
1002
                                                case PathIterator.SEG_MOVETO:
1003

    
1004
                                                        // System.out.println("SEG_MOVETO");
1005
                                                        if (arrayCoords == null) {
1006
                                                                arrayCoords = new ArrayList();
1007
                                                        } else {
1008
                                                                points = CoordinateArrays.toCoordinateArray(arrayCoords);
1009

    
1010
                                                                try {
1011
                                                                        LinearRing ring = geomFactory.createLinearRing(points);
1012

    
1013
                                                                        if (CGAlgorithms.isCCW(points)) {
1014
                                                                                holes.add(ring);
1015
                                                                        } else {
1016
                                                                                shells.add(ring);
1017
                                                                        }
1018
                                                                } catch (Exception e) {
1019
                                                                        System.err.println(
1020
                                                                                "Caught Topology exception in GMLLinearRingHandler");
1021

    
1022
                                                                        return null;
1023
                                                                }
1024

    
1025
                                                                /* if (numParts == 1)
1026
                                                                   {
1027
                                                                           linRingExt = new GeometryFactory().createLinearRing(
1028
                                                                                  CoordinateArrays.toCoordinateArray(arrayCoords));
1029
                                                                   }
1030
                                                                   else
1031
                                                                   {
1032
                                                                           linRing = new GeometryFactory().createLinearRing(
1033
                                                                                          CoordinateArrays.toCoordinateArray(arrayCoords));
1034
                                                                           arrayLines.add(linRing);
1035
                                                                   } */
1036
                                                                arrayCoords = new ArrayList();
1037
                                                        }
1038

    
1039
                                                        numParts++;
1040
                                                        arrayCoords.add(new Coordinate(theData[0],
1041
                                                                        theData[1]));
1042

    
1043
                                                        break;
1044

    
1045
                                                case PathIterator.SEG_LINETO:
1046

    
1047
                                                        // System.out.println("SEG_LINETO");
1048
                                                        arrayCoords.add(new Coordinate(theData[0],
1049
                                                                        theData[1]));
1050

    
1051
                                                        break;
1052

    
1053
                                                case PathIterator.SEG_QUADTO:
1054
                                                        System.out.println("SEG_QUADTO Not supported here");
1055

    
1056
                                                        break;
1057

    
1058
                                                case PathIterator.SEG_CUBICTO:
1059
                                                        System.out.println("SEG_CUBICTO Not supported here");
1060

    
1061
                                                        break;
1062

    
1063
                                                case PathIterator.SEG_CLOSE:
1064

    
1065
                                                        // A?adimos el primer punto para cerrar.
1066
                                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
1067
                                                        arrayCoords.add(new Coordinate(firstCoord.x,
1068
                                                                        firstCoord.y));
1069

    
1070
                                                        break;
1071
                                        } //end switch
1072

    
1073
                                        // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
1074
                                        theIterator.next();
1075
                                } //end while loop
1076

    
1077
                                arrayCoords.add(arrayCoords.get(0));
1078
                                coords = CoordinateArrays.toCoordinateArray(arrayCoords);
1079

    
1080

    
1081
                if (numParts == 1)
1082
                {
1083
                        return getExteriorPolygon(coords);
1084
                }
1085
                return ShapeFactory.createGeometry(pol);
1086

    
1087
        }
1088

    
1089

    
1090
    /* public static GeometryCollection convertFGeometryCollection(FGeometryCollection fGeomC)
1091
    {
1092

1093
        geomFactory.createGeometryCollection(theGeoms);
1094
    } */
1095
}