Statistics
| Revision:

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

History | View | Annotate | Download (31.4 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
                                                        // A?adimos el primer punto para cerrar.
226
                                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
227
                                                        arrayCoords.add(new Coordinate(firstCoord.x,
228
                                                                        firstCoord.y));
229

    
230
                                                        break;
231
                                        } //end switch
232

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

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

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

    
251
                                break;
252

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

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

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

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

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

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

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

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

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

    
314
                                                                        return null;
315
                                                                }
316

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

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

    
335
                                                        break;
336

    
337
                                                case PathIterator.SEG_LINETO:
338

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

    
343
                                                        break;
344

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

    
348
                                                        break;
349

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

    
353
                                                        break;
354

    
355
                                                case PathIterator.SEG_CLOSE:
356

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

    
362
                                                        break;
363
                                        } //end switch
364

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

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

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

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

    
403
                                        return null;
404
                                }
405

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

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

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

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

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

    
429
                                                Envelope tryEnv = tryRing.getEnvelopeInternal();
430

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

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

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

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

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

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

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

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

    
489
                                // FIN CAMBIO
490

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

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

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

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

    
514
                return geoJTS;
515
        }
516

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

    
527
                try {
528
                        if (geo instanceof Point) {
529
                                shpNew = new FPoint2D(((Point) geo).getX(), ((Point) geo).getY());
530
                        }
531

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

    
536
                        if (geo instanceof Polygon) {
537
                                shpNew = new FPolygon2D(toShape((Polygon) geo));
538
                        }
539

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

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

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

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

    
563
                return null;
564
        }
565

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

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

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

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

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

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

    
601
                return resul;
602
        }
603

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

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

622
                return viewCoordinates;
623
        } */
624

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

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

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

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

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

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

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

    
686
                return viewPoint;
687
        }
688

    
689
        private static GeneralPathX toShape(MultiPolygon mp)
690
        throws NoninvertibleTransformException {
691
        GeneralPathX path = new GeneralPathX();
692

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

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

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

    
729
                if (geometry instanceof Polygon) {
730
                        return toShape((Polygon) geometry);
731
                }
732

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

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

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

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

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

    
753

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

    
765
        theIterator = gp.getPathIterator(null); //, flatness);
766

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

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

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

    
797
                    break;
798

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

    
802
                    break;
803

    
804
                case PathIterator.SEG_CLOSE:
805
                    newGp.closePath();
806

    
807
                    break;
808
            } //end switch
809

    
810
            theIterator.next();
811
        } //end while loop
812

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

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

    
825
        Point2D ptDst = new Point2D.Double();
826
        Point2D ptSrc = new Point2D.Double();
827
        boolean bFirst = true;
828
        int xInt, yInt, antX = -1, antY = -1;
829

    
830

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

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

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

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

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

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

    
880
                    break;
881
            } //end switch
882

    
883
            theIterator.next();
884
        } //end while loop
885

    
886
        FShape shp = null;
887
        switch (gp.getGeometryType())
888
        {
889
            case FShape.POINT: //Tipo punto
890
            case FShape.POINT + FShape.Z:
891
                shp = new FPoint2D(ptDst.getX(), ptDst.getY());
892
                break;
893

    
894
            case FShape.LINE:
895
            case FShape.LINE + FShape.Z:
896
            case FShape.ARC:
897
                    shp = new FPolyline2D(newGp);
898
                break;
899

    
900
            case FShape.POLYGON:
901
            case FShape.POLYGON + FShape.Z:
902
            case FShape.CIRCLE:
903
            case FShape.ELLIPSE:
904

    
905
                shp = new FPolygon2D(newGp);
906
                break;
907
        }
908
        return shp;
909
    }
910

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

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

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

    
943
        try {
944
                        return ShapeFactory.createPolygon2D(toShape(ring));
945
                } catch (NoninvertibleTransformException e) {
946
                        e.printStackTrace();
947
                }
948
                return null;
949
    }
950

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

    
958
        return CGAlgorithms.isCCW(vs);
959
    }
960

    
961
    public static boolean isCCW(FPolygon2D pol)
962
    {
963
            Geometry jtsGeom = FConverter.java2d_to_jts(pol);
964
            if (jtsGeom.getNumGeometries() == 1)
965
            {
966
                    Coordinate[] coords = jtsGeom.getCoordinates();
967
                    return CGAlgorithms.isCCW(coords);
968
            }
969
            return false;
970

    
971
    }
972

    
973

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

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

    
993
        try {
994
                        return ShapeFactory.createPolygon2D(toShape(ring));
995
                } catch (NoninvertibleTransformException e) {
996
                        e.printStackTrace();
997
                }
998
                return null;
999
    }
1000

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

    
1006

    
1007

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

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

    
1025
                                ArrayList shells = new ArrayList();
1026
                                ArrayList holes = new ArrayList();
1027
                                Coordinate[] points = null;
1028

    
1029
                                theIterator = pol.getPathIterator(null, FLATNESS);
1030

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

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

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

    
1048
                                                                try {
1049
                                                                        LinearRing ring = geomFactory.createLinearRing(points);
1050

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

    
1060
                                                                        return null;
1061
                                                                }
1062

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

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

    
1081
                                                        break;
1082

    
1083
                                                case PathIterator.SEG_LINETO:
1084

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

    
1089
                                                        break;
1090

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

    
1094
                                                        break;
1095

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

    
1099
                                                        break;
1100

    
1101
                                                case PathIterator.SEG_CLOSE:
1102

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

    
1108
                                                        break;
1109
                                        } //end switch
1110

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

    
1115
                                arrayCoords.add(arrayCoords.get(0));
1116
                                coords = CoordinateArrays.toCoordinateArray(arrayCoords);
1117

    
1118

    
1119
                if (numParts == 1)
1120
                {
1121
                        return getExteriorPolygon(coords);
1122
                }
1123
                return ShapeFactory.createGeometry(pol);
1124

    
1125
        }
1126

    
1127

    
1128
    /* public static GeometryCollection convertFGeometryCollection(FGeometryCollection fGeomC)
1129
    {
1130

1131
        geomFactory.createGeometryCollection(theGeoms);
1132
    } */
1133
}