Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_geometries / src / org / gvsig / fmap / geom / util / Converter.java @ 21093

History | View | Annotate | Download (34.8 KB)

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

    
43
import java.awt.Shape;
44
import java.awt.geom.AffineTransform;
45
import java.awt.geom.Area;
46
import java.awt.geom.NoninvertibleTransformException;
47
import java.awt.geom.PathIterator;
48
import java.awt.geom.Rectangle2D;
49
import java.lang.reflect.Array;
50
import java.util.ArrayList;
51

    
52
import org.apache.log4j.Logger;
53
import org.gvsig.fmap.geom.Geometry;
54
import org.gvsig.fmap.geom.GeometryFactory;
55
import org.gvsig.fmap.geom.GeometryManager;
56
import org.gvsig.fmap.geom.aggregate.BaseMultiPrimitive;
57
import org.gvsig.fmap.geom.aggregate.MultiCurve2D;
58
import org.gvsig.fmap.geom.aggregate.MultiPoint2D;
59
import org.gvsig.fmap.geom.aggregate.MultiSurface2D;
60
import org.gvsig.fmap.geom.primitive.Curve2D;
61
import org.gvsig.fmap.geom.primitive.FShape;
62
import org.gvsig.fmap.geom.primitive.GeneralPathX;
63
import org.gvsig.fmap.geom.primitive.Point2D;
64
import org.gvsig.fmap.geom.primitive.Surface2D;
65

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

    
79

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

    
99
        /**
100
         * Es la m�xima distancia que permitimos que el trazo aproximado
101
         * difiera del trazo real.
102
         */
103
        public static double FLATNESS =0.8;// Por ejemplo. Cuanto m�s peque�o, m�s segmentos necesitar� la curva
104
        
105
        private static GeometryFactory factory = GeometryManager.getInstance().getGeometryFactory();
106

    
107

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

    
114
                numpoints = Array.getLength(pointList);
115

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

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

    
126
                return false;
127
        }
128

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

    
140
        /**
141
         * Convierte un MultiPoint2D a un MultiPoint de JTS
142
         * @param geom
143
         * @return
144
         */        
145
        public com.vividsolutions.jts.geom.Geometry geometryToJts(MultiPoint2D geom) {
146
                Coordinate[] theGeoms = new Coordinate[geom.getPrimitivesNumber()];
147
                for (int i = 0; i < theGeoms.length; i++) {
148
                        java.awt.geom.Point2D p = (java.awt.geom.Point2D) geom.getPrimitiveAt(i)
149
                                        .getHandlers(Geometry.SELECTHANDLER)[0].getPoint();
150
                        Coordinate c = new Coordinate(p.getX(), p.getY());
151
                        theGeoms[i] = c;
152
                }
153
                com.vividsolutions.jts.geom.MultiPoint geomCol = new com.vividsolutions.jts.geom.GeometryFactory()
154
                                .createMultiPoint(theGeoms);
155
                return geomCol;
156
        }
157
        
158
        /**
159
         * Convierte una MultiCurve2D en una MultiLineString de JTS
160
         * @param geom
161
         * @return
162
         */
163
        public static com.vividsolutions.jts.geom.Geometry geometryToJts(MultiCurve2D geom) {
164
                LineString[] lines = new LineString[geom.getPrimitivesNumber()];
165
        for (int i = 0; i < lines.length; i++){
166
                lines[i] = (LineString) geometryToJts(((Curve2D) geom.getPrimitiveAt(i)));
167
        }
168
        return new com.vividsolutions.jts.geom.GeometryFactory().createMultiLineString(lines);                
169
        }        
170
        
171
        /**
172
         * Convierte una MultiSurface2D en un MultiPolygon de JTS
173
         * @return
174
         */
175
        public com.vividsolutions.jts.geom.Geometry geometryToJts(MultiSurface2D geom) {
176
                Polygon[] polygons = new Polygon[geom.getPrimitivesNumber()];
177
        for (int i = 0; i < polygons.length; i++){
178
                polygons[i] = (Polygon) geometryToJts(((Surface2D)geom.getPrimitiveAt(i)));
179
        }
180
        return new com.vividsolutions.jts.geom.GeometryFactory().createMultiPolygon(polygons);                
181
        }        
182

    
183
        /**
184
         * Convierte una BaseMultiPrimitive en una GeometryCollection de JTS
185
         * @return
186
         */
187
        public com.vividsolutions.jts.geom.Geometry geometryToJts(BaseMultiPrimitive geom) {
188
                com.vividsolutions.jts.geom.Geometry[] geometriesAux = new LineString[geom.getPrimitivesNumber()];
189
                for (int i = 0; i < geometriesAux.length; i++) {
190
                        geometriesAux[i] = geometryToJts(((Geometry) geom.getPrimitiveAt(i)));
191
                }
192
                return new com.vividsolutions.jts.geom.GeometryFactory().createGeometryCollection(geometriesAux);
193
        }
194
        
195
        
196
        public static com.vividsolutions.jts.geom.Geometry geometryToJts(Geometry geom) {
197
                logger.debug(geom.getClass());
198
                logger.debug(new Integer(geom.getShapeType()));
199
         return java2d_to_jts((Shape)geom, geom.getShapeType());
200
        }
201
        
202
        public static com.vividsolutions.jts.geom.Geometry java2d_to_jts(FShape shp) {
203
                return java2d_to_jts(shp, shp.getShapeType());
204
        }        
205
        /**
206
         * Convierte un FShape a una Geometry del JTS. Para ello, utilizamos un
207
         * "flattened PathIterator". El flattened indica que las curvas las pasa a
208
         * segmentos de l�nea recta AUTOMATICAMENTE!!!.
209
         *
210
         * @param shp FShape que se quiere convertir.
211
         *
212
         * @return Geometry de JTS.
213
         */
214
        private static com.vividsolutions.jts.geom.Geometry java2d_to_jts(Shape shp, int shapeType) {
215

    
216

    
217
                com.vividsolutions.jts.geom.Geometry geoJTS = null;
218
                Coordinate coord;
219
                //Coordinate[] coords;
220
                ArrayList arrayCoords = null;
221
                ArrayList arrayLines;
222
                LineString lin;
223
                //LinearRing linRing;
224
                //LinearRing linRingExt = null;
225
                int theType;
226
                int numParts = 0;
227

    
228
                //                 Use this array to store segment coordinate data
229
                double[] theData = new double[6];
230
                PathIterator theIterator;
231

    
232
                logger.debug(shp.toString());
233
                
234
                switch (shapeType) {
235
                        case FShape.POINT:
236
            case FShape.POINT + FShape.Z:
237
                                org.gvsig.fmap.geom.primitive.Point2D p = (org.gvsig.fmap.geom.primitive.Point2D) shp;
238
                                coord = new Coordinate(p.getX(), p.getY());
239
                                geoJTS = geomFactory.createPoint(coord);
240

    
241
                                break;
242

    
243
                        case FShape.LINE:
244
                        case FShape.ARC:
245
            case FShape.LINE + FShape.Z:
246
                                arrayLines = new ArrayList();
247
                                theIterator = shp.getPathIterator(null, FLATNESS);
248

    
249
                                while (!theIterator.isDone()) {
250
                                        //while not done
251
                                        theType = theIterator.currentSegment(theData);
252

    
253
                                        //Populate a segment of the new
254
                                        // GeneralPathX object.
255
                                        //Process the current segment to populate a new
256
                                        // segment of the new GeneralPathX object.
257
                                        switch (theType) {
258
                                                case PathIterator.SEG_MOVETO:
259

    
260
                                                        // System.out.println("SEG_MOVETO");
261
                                                        if (arrayCoords == null) {
262
                                                                arrayCoords = new ArrayList();
263
                                                        } else {
264
                                                                lin = geomFactory.createLineString(CoordinateArrays.toCoordinateArray(
265
                                                                                        arrayCoords));
266
                                                                arrayLines.add(lin);
267
                                                                arrayCoords = new ArrayList();
268
                                                        }
269

    
270
                                                        numParts++;
271
                                                        arrayCoords.add(new Coordinate(theData[0],
272
                                                                        theData[1]));
273

    
274
                                                        break;
275

    
276
                                                case PathIterator.SEG_LINETO:
277

    
278
                                                        // System.out.println("SEG_LINETO");
279
                                                        arrayCoords.add(new Coordinate(theData[0],
280
                                                                        theData[1]));
281

    
282
                                                        break;
283

    
284
                                                case PathIterator.SEG_QUADTO:
285
                                                        System.out.println("Not supported here");
286

    
287
                                                        break;
288

    
289
                                                case PathIterator.SEG_CUBICTO:
290
                                                        System.out.println("Not supported here");
291

    
292
                                                        break;
293

    
294
                                                case PathIterator.SEG_CLOSE:
295
                                                        // A�adimos el primer punto para cerrar.
296
                                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
297
                                                        arrayCoords.add(new Coordinate(firstCoord.x,
298
                                                                        firstCoord.y));
299

    
300
                                                        break;
301
                                        } //end switch
302

    
303
                                        theIterator.next();
304
                                } //end while loop
305

    
306
                                lin = new com.vividsolutions.jts.geom.GeometryFactory().createLineString(CoordinateArrays.toCoordinateArray(
307
                                                        arrayCoords));
308

    
309
                                // CAMBIO: ENTREGAMOS SIEMPRE MULTILINESTRING, QUE ES
310
                                // LO QUE HACE TODO EL MUNDO CUANDO ESCRIBE EN POSTGIS
311
                                // O CON GEOTOOLS
312
                                // if (numParts > 1) // Generamos una MultiLineString
313
                                //  {
314
                                        arrayLines.add(lin);
315
                                        geoJTS = geomFactory.createMultiLineString(com.vividsolutions.jts.geom.GeometryFactory.toLineStringArray(
316
                                                                arrayLines));
317
                                /* } else {
318
                                        geoJTS = lin;
319
                                } */
320

    
321
                                break;
322

    
323
                        case FShape.POLYGON:
324
                        case FShape.CIRCLE:
325
                        case FShape.ELLIPSE:
326
            case FShape.POLYGON + FShape.Z:
327
                                arrayLines = new ArrayList();
328

    
329
                                ArrayList shells = new ArrayList();
330
                                ArrayList holes = new ArrayList();
331
                                Coordinate[] points = null;
332

    
333
                                theIterator = shp.getPathIterator(null, FLATNESS);
334

    
335
                                while (!theIterator.isDone()) {
336
                                        //while not done
337
                                        theType = theIterator.currentSegment(theData);
338

    
339
                                        //Populate a segment of the new
340
                                        // GeneralPathX object.
341
                                        //Process the current segment to populate a new
342
                                        // segment of the new GeneralPathX object.
343
                                        switch (theType) {
344
                                                case PathIterator.SEG_MOVETO:
345

    
346
                                                        // System.out.println("SEG_MOVETO");
347
                                                        if (arrayCoords == null) {
348
                                                                arrayCoords = new ArrayList();
349
                                                        } else {
350
                                                                points = CoordinateArrays.toCoordinateArray(arrayCoords);
351

    
352
                                                                try {
353
                                                                        LinearRing ring = geomFactory.createLinearRing(points);
354

    
355
                                                                        if (CGAlgorithms.isCCW(points)) {
356
                                                                                holes.add(ring);
357
                                                                        } else {
358
                                                                                shells.add(ring);
359
                                                                        }
360
                                                                } catch (Exception e) {
361
                                                                        /* (jaume) caso cuando todos los puntos son iguales
362
                                                                         * devuelvo el propio punto
363
                                                                         */
364
                                                                        boolean same = true;
365
                                                                        for (int i = 0; i < points.length-1 && same; i++) {
366
                                                                                if (points[i].x != points[i+1].x ||
367
                                                                                                points[i].y != points[i+1].y /*||
368
                                                                                                points[i].z != points[i+1].z*/
369
                                                                                                ) same = false;
370
                                                                        }
371
                                                                        if (same)
372
                                                                                return geomFactory.createPoint(points[0]);
373
                                                                        /*
374
                                                                         * caso cuando es una l�nea de 3 puntos, no creo un LinearRing, sino
375
                                                                         * una linea
376
                                                                         */
377
                                                                        if (points.length>1 && points.length<=3)
378
                                                                                // return geomFactory.createLineString(points);
379
                                                                                return geomFactory.createMultiLineString(new LineString[] {geomFactory.createLineString(points)});
380

    
381
                                                                        System.err.println(
382
                                                                                "Caught Topology exception in GMLLinearRingHandler");
383

    
384
                                                                        return null;
385
                                                                }
386

    
387
                                                                /* if (numParts == 1)
388
                                                                   {
389
                                                                           linRingExt = new GeometryFactory().createLinearRing(
390
                                                                                  CoordinateArrays.toCoordinateArray(arrayCoords));
391
                                                                   }
392
                                                                   else
393
                                                                   {
394
                                                                           linRing = new GeometryFactory().createLinearRing(
395
                                                                                          CoordinateArrays.toCoordinateArray(arrayCoords));
396
                                                                           arrayLines.add(linRing);
397
                                                                   } */
398
                                                                arrayCoords = new ArrayList();
399
                                                        }
400

    
401
                                                        numParts++;
402
                                                        arrayCoords.add(new Coordinate(theData[0],
403
                                                                        theData[1]));
404

    
405
                                                        break;
406

    
407
                                                case PathIterator.SEG_LINETO:
408

    
409
                                                        // System.out.println("SEG_LINETO");
410
                                                        arrayCoords.add(new Coordinate(theData[0],
411
                                                                        theData[1]));
412

    
413
                                                        break;
414

    
415
                                                case PathIterator.SEG_QUADTO:
416
                                                        System.out.println("SEG_QUADTO Not supported here");
417

    
418
                                                        break;
419

    
420
                                                case PathIterator.SEG_CUBICTO:
421
                                                        System.out.println("SEG_CUBICTO Not supported here");
422

    
423
                                                        break;
424

    
425
                                                case PathIterator.SEG_CLOSE:
426

    
427
                                                        // A�adimos el primer punto para cerrar.
428
                                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
429
                                                        arrayCoords.add(new Coordinate(firstCoord.x,
430
                                                                        firstCoord.y));
431

    
432
                                                        break;
433
                                        } //end switch
434

    
435
                                        // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
436
                                        theIterator.next();
437
                                } //end while loop
438

    
439
                                arrayCoords.add(arrayCoords.get(0));
440
                                points = CoordinateArrays.toCoordinateArray(arrayCoords);
441

    
442
                                try {
443
                                        LinearRing ring = geomFactory.createLinearRing(points);
444

    
445
                                        if (CGAlgorithms.isCCW(points)) {
446
                                                holes.add(ring);
447
                                        } else {
448
                                                shells.add(ring);
449
                                        }
450
                                } catch (Exception e) {
451
                                        /* (jaume) caso cuando todos los puntos son iguales
452
                                         * devuelvo el propio punto
453
                                         */
454
                                        boolean same = true;
455
                                        for (int i = 0; i < points.length-1 && same; i++) {
456
                                                if (points[i].x != points[i+1].x ||
457
                                                                points[i].y != points[i+1].y /*||
458
                                                                points[i].z != points[i+1].z*/
459
                                                                ) same = false;
460
                                        }
461
                                        if (same)
462
                                                return geomFactory.createPoint(points[0]);
463
                                        /*
464
                                         * caso cuando es una l�nea de 3 puntos, no creo un LinearRing, sino
465
                                         * una linea
466
                                         */
467
                                        if (points.length>1 && points.length<=3)
468
                                                // return geomFactory.createLineString(points);
469
                                                return geomFactory.createMultiLineString(new LineString[] {geomFactory.createLineString(points)});
470
                                        System.err.println(
471
                                                "Caught Topology exception in GMLLinearRingHandler");
472

    
473
                                        return null;
474
                                }
475

    
476
                                /* linRing = new GeometryFactory().createLinearRing(
477
                                   CoordinateArrays.toCoordinateArray(arrayCoords)); */
478

    
479
                                // System.out.println("NumParts = " + numParts);
480
                                //now we have a list of all shells and all holes
481
                                ArrayList holesForShells = new ArrayList(shells.size());
482

    
483
                                for (int i = 0; i < shells.size(); i++) {
484
                                        holesForShells.add(new ArrayList());
485
                                }
486

    
487
                                //find homes
488
                                for (int i = 0; i < holes.size(); i++) {
489
                                        LinearRing testRing = (LinearRing) holes.get(i);
490
                                        LinearRing minShell = null;
491
                                        Envelope minEnv = null;
492
                                        Envelope testEnv = testRing.getEnvelopeInternal();
493
                                        Coordinate testPt = testRing.getCoordinateN(0);
494
                                        LinearRing tryRing = null;
495

    
496
                                        for (int j = 0; j < shells.size(); j++) {
497
                                                tryRing = (LinearRing) shells.get(j);
498

    
499
                                                Envelope tryEnv = tryRing.getEnvelopeInternal();
500

    
501
                                                if (minShell != null) {
502
                                                        minEnv = minShell.getEnvelopeInternal();
503
                                                }
504

    
505
                                                boolean isContained = false;
506
                                                Coordinate[] coordList = tryRing.getCoordinates();
507

    
508
                                                if (tryEnv.contains(testEnv) &&
509
                                                                (CGAlgorithms.isPointInRing(testPt, coordList) ||
510
                                                                (pointInList(testPt, coordList)))) {
511
                                                        isContained = true;
512
                                                }
513

    
514
                                                // check if this new containing ring is smaller than the current minimum ring
515
                                                if (isContained) {
516
                                                        if ((minShell == null) || minEnv.contains(tryEnv)) {
517
                                                                minShell = tryRing;
518
                                                        }
519
                                                }
520
                                        }
521

    
522
                                        if (minShell == null) {
523
//                                                System.out.println(
524
//                                                        "polygon found with a hole thats not inside a shell");
525
//azabala: we do the assumption that this hole is really a shell (polygon)
526
//whose point werent digitized in the right order
527
Coordinate[] cs = testRing.getCoordinates();
528
Coordinate[] reversed = new Coordinate[cs.length];
529
int pointIndex = 0;
530
for(int z = cs.length-1; z >= 0; z--){
531
        reversed[pointIndex] = cs[z];
532
        pointIndex++;
533
}
534
LinearRing newRing = geomFactory.createLinearRing(reversed);
535
shells.add(newRing);
536
holesForShells.add(new ArrayList());
537
                                        } else {
538
                                                ((ArrayList) holesForShells.get(shells.indexOf(minShell))).add(testRing);
539
                                        }
540
                                }
541

    
542
                                Polygon[] polygons = new Polygon[shells.size()];
543

    
544
                                for (int i = 0; i < shells.size(); i++) {
545
                                        polygons[i] = geomFactory.createPolygon((LinearRing) shells.get(
546
                                                                i),
547
                                                        (LinearRing[]) ((ArrayList) holesForShells.get(i)).toArray(
548
                                                                new LinearRing[0]));
549
                                }
550
                                // CAMBIO: ENTREGAMOS SIEMPRE MULTILINESTRING, QUE ES
551
                                // LO QUE HACE TODO EL MUNDO CUANDO ESCRIBE EN POSTGIS
552
                                // O CON GEOTOOLS
553
                                // if (numParts > 1) // Generamos una MultiLineString
554

    
555
                                /* if (polygons.length == 1) {
556
                                        return polygons[0];
557
                                } */
558

    
559
                                // FIN CAMBIO
560

    
561
                                holesForShells = null;
562
                                shells = null;
563
                                holes = null;
564

    
565
                                //its a multi part
566
                                geoJTS = geomFactory.createMultiPolygon(polygons);
567

    
568
                                /* if (numParts > 1) // Generamos un Polygon con agujeros
569
                                   {
570
                                    arrayLines.add(linRing);
571
                                           // geoJTS = new GeometryFactory().createPolygon(linRingExt,
572
                                                           // GeometryFactory.toLinearRingArray(arrayLines));
573
                                    geoJTS = new GeometryFactory().buildGeometry(arrayLines);
574

575
                                    // geoJTS = Polygonizer.class.
576
                                   }
577
                                   else
578
                                   {
579
                                           geoJTS = new GeometryFactory().createPolygon(linRing,null);
580
                                   } */
581
                                break;
582
                }
583

    
584
                return geoJTS;
585
        }
586

    
587
        /**
588
         * Converts JTS Geometry objects into Java 2D Shape objects
589
         *
590
         * @param geo Geometry de JTS.
591
         *
592
         * @return FShape.
593
         */
594
        public static FShape jts_to_java2d(com.vividsolutions.jts.geom.Geometry geo) {
595
                FShape shpNew = null;
596

    
597
                try {
598
                        if (geo instanceof Point) {
599
                                shpNew = new org.gvsig.fmap.geom.primitive.Point2D(null, null, ((Point) geo).getX(), ((Point) geo).getY());
600
                        }
601

    
602
                        if (geo.isEmpty()) {
603
                                shpNew = null;
604
                        }
605

    
606
                        if (geo instanceof Polygon) {
607
                                shpNew = new Surface2D(null, null, toShape((Polygon) geo));
608
                        }
609

    
610
                        if (geo instanceof MultiPolygon) {
611
                                shpNew = new Surface2D(null, null, toShape((MultiPolygon) geo));
612
                        }
613

    
614
                        if (geo instanceof LineString) {
615
                                shpNew = new Curve2D(null, null, toShape((LineString) geo));
616
                        }
617

    
618
                        if (geo instanceof MultiLineString) {
619
                                shpNew = new Curve2D(null, null, toShape((MultiLineString) geo));
620
                        }
621

    
622
                        /* OJO: CON ALGO COMO FSHAPE NO S� C�MO PODEMOS IMPLEMENTAR UN GeometryCollection
623
                         * No sabremos si queremos una l�nea o un pol�gono.....
624
                         *  if (geometry instanceof GeometryCollection) {
625
                                  return toShape((GeometryCollection) geometry);
626
                           } */
627
                        return shpNew;
628
                } catch (NoninvertibleTransformException e) {
629
                        // TODO Auto-generated catch block
630
                        e.printStackTrace();
631
                }
632

    
633
                return null;
634
        }
635

    
636
        /**
637
         * DOCUMENT ME!
638
         *
639
         * @param p DOCUMENT ME!
640
         *
641
         * @return DOCUMENT ME!
642
         */
643
        private static GeneralPathX toShape(Polygon p) {
644
                GeneralPathX resul = new GeneralPathX();
645
                Coordinate coord;
646

    
647
                for (int i = 0; i < p.getExteriorRing().getNumPoints(); i++) {
648
                        coord = p.getExteriorRing().getCoordinateN(i);
649

    
650
                        if (i == 0) {
651
                                resul.moveTo(coord.x,coord.y);
652
                        } else {
653
                                resul.lineTo(coord.x,coord.y);
654
                        }
655
                }
656

    
657
                for (int j = 0; j < p.getNumInteriorRing(); j++) {
658
                        LineString hole = p.getInteriorRingN(j);
659

    
660
                        for (int k = 0; k < hole.getNumPoints(); k++) {
661
                                coord = hole.getCoordinateN(k);
662

    
663
                                if (k == 0) {
664
                                        resul.moveTo(coord.x, coord.y);
665
                                } else {
666
                                        resul.lineTo(coord.x, coord.y);
667
                                }
668
                        }
669
                }
670

    
671
                return resul;
672
        }
673

    
674
        /**
675
         * DOCUMENT ME!
676
         *
677
         * @param modelCoordinates DOCUMENT ME!
678
         *
679
         * @return DOCUMENT ME!
680
         *
681
         * @throws NoninvertibleTransformException DOCUMENT ME!
682
         *
683
        private Coordinate[] toViewCoordinates(Coordinate[] modelCoordinates)
684
                throws NoninvertibleTransformException {
685
                Coordinate[] viewCoordinates = new Coordinate[modelCoordinates.length];
686

687
                for (int i = 0; i < modelCoordinates.length; i++) {
688
                        FPoint2D point2D = coordinate2FPoint2D(modelCoordinates[i]);
689
                        viewCoordinates[i] = new Coordinate(point2D.getX(), point2D.getY());
690
                }
691

692
                return viewCoordinates;
693
        } */
694

    
695
        /* private Shape toShape(GeometryCollection gc)
696
           throws NoninvertibleTransformException {
697
           GeometryCollectionShape shape = new GeometryCollectionShape();
698
           for (int i = 0; i < gc.getNumGeometries(); i++) {
699
                   Geometry g = (Geometry) gc.getGeometryN(i);
700
                   shape.add(toShape(g));
701
           }
702
           return shape;
703
           } */
704
        private static GeneralPathX toShape(MultiLineString mls)
705
                throws NoninvertibleTransformException {
706
                GeneralPathX path = new GeneralPathX();
707

    
708
                for (int i = 0; i < mls.getNumGeometries(); i++) {
709
                        LineString lineString = (LineString) mls.getGeometryN(i);
710
                        path.append(toShape(lineString), false);
711
                }
712

    
713
                //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
714
                //converted to GeneralPathXs. [Jon Aquino]
715
                return path;
716
        }
717

    
718
        /**
719
         * DOCUMENT ME!
720
         *
721
         * @param lineString DOCUMENT ME!
722
         *
723
         * @return DOCUMENT ME!
724
         *
725
         * @throws NoninvertibleTransformException DOCUMENT ME!
726
         */
727
        private static GeneralPathX toShape(LineString lineString)
728
                throws NoninvertibleTransformException {
729
                GeneralPathX shape = new GeneralPathX();
730
                org.gvsig.fmap.geom.primitive.Point2D viewPoint = coordinate2FPoint2D(lineString.getCoordinateN(0));
731
                shape.moveTo(viewPoint.getX(), viewPoint.getY());
732

    
733
                for (int i = 1; i < lineString.getNumPoints(); i++) {
734
                        viewPoint = coordinate2FPoint2D(lineString.getCoordinateN(i));
735
                        shape.lineTo(viewPoint.getX(), viewPoint.getY());
736
                }
737

    
738
                //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
739
                //converted to GeneralPathXs. [Jon Aquino]
740
                return shape;
741
        }
742

    
743
        /* TODO No se usa
744
         * DOCUMENT ME!
745
         *
746
         * @param point DOCUMENT ME!
747
         *
748
         * @return DOCUMENT ME!
749
         *
750
         * @throws NoninvertibleTransformException DOCUMENT ME!
751
         *
752
        private static Point2D toShape(Point point)
753
                throws NoninvertibleTransformException {
754
                Point2D viewPoint = coordinate2FPoint2D(point.getCoordinate());
755

756
                return viewPoint;
757
        }
758
*/
759
        
760
        /**
761
         * 
762
         */
763
        private static GeneralPathX toShape(MultiPolygon mp)
764
        throws NoninvertibleTransformException {
765
        GeneralPathX path = new GeneralPathX();
766

    
767
        for (int i = 0; i < mp.getNumGeometries(); i++) {
768
                Polygon polygon = (Polygon) mp.getGeometryN(i);
769
                path.append(toShape(polygon), false);
770
        }
771

    
772
        //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be
773
        //converted to GeneralPathXs. [Jon Aquino]
774
        return path;
775
}
776
        /**
777
         * DOCUMENT ME!
778
         *
779
         * @param coord DOCUMENT ME!
780
         *
781
         * @return DOCUMENT ME!
782
         */
783
        public static org.gvsig.fmap.geom.primitive.Point2D coordinate2FPoint2D(Coordinate coord) {
784
                return new org.gvsig.fmap.geom.primitive.Point2D(null, null, coord.x, coord.y); //,coord.z);
785
        }
786

    
787
        /**
788
         * Convierte una Geometry de JTS a GeneralPathX.
789
         *
790
         * @param geometry Geometry a convertir.
791
         *
792
         * @return GeneralPathX.
793
         *
794
         * @throws NoninvertibleTransformException
795
         * @throws IllegalArgumentException
796
         */
797
        public static GeneralPathX toShape(com.vividsolutions.jts.geom.Geometry geometry)
798
                throws NoninvertibleTransformException {
799
                if (geometry.isEmpty()) {
800
                        return new GeneralPathX();
801
                }
802

    
803
                if (geometry instanceof Polygon) {
804
                        return toShape((Polygon) geometry);
805
                }
806

    
807
                if (geometry instanceof MultiPolygon) {
808
                        return toShape((MultiPolygon) geometry);
809
                }
810

    
811
                if (geometry instanceof LineString) {
812
                        return toShape((LineString) geometry);
813
                }
814

    
815
                if (geometry instanceof MultiLineString) {
816
                        return toShape((MultiLineString) geometry);
817
                }
818

    
819
                if (geometry instanceof GeometryCollection) {
820
                        return toShape((GeometryCollection) geometry);
821
                }
822

    
823
                throw new IllegalArgumentException("Unrecognized Geometry class: " +
824
                        geometry.getClass());
825
        }
826

    
827

    
828
    public static GeneralPathX transformToInts(GeneralPathX gp, AffineTransform at) {
829
        GeneralPathX newGp = new GeneralPathX();
830
        PathIterator theIterator;
831
        int theType;
832
        int numParts = 0;
833
        double[] theData = new double[6];
834
        java.awt.geom.Point2D ptDst = new java.awt.geom.Point2D.Double();
835
        java.awt.geom.Point2D ptSrc = new java.awt.geom.Point2D.Double();
836
        boolean bFirst = true;
837
        int xInt, yInt, antX = -1, antY = -1;
838

    
839
        theIterator = gp.getPathIterator(null); //, flatness);
840

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

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

    
868
                case PathIterator.SEG_QUADTO:
869
                    System.out.println("Not supported here");
870

    
871
                    break;
872

    
873
                case PathIterator.SEG_CUBICTO:
874
                    System.out.println("Not supported here");
875

    
876
                    break;
877

    
878
                case PathIterator.SEG_CLOSE:
879
                    newGp.closePath();
880

    
881
                    break;
882
            } //end switch
883

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

    
887
        return newGp;
888
    }
889
    public static FShape transformToInts(Geometry gp, AffineTransform at) {
890
        GeneralPathX newGp = new GeneralPathX();
891
        double[] theData = new double[6];
892
        double[] aux = new double[6];
893

    
894
        // newGp.reset();
895
        PathIterator theIterator;
896
        int theType;
897
        int numParts = 0;
898

    
899
        java.awt.geom.Point2D ptDst = new java.awt.geom.Point2D.Double();
900
        java.awt.geom.Point2D ptSrc = new java.awt.geom.Point2D.Double();
901
        boolean bFirst = true;
902
        int xInt, yInt, antX = -1, antY = -1;
903

    
904

    
905
        theIterator = gp.getPathIterator(null); //, flatness);
906
        int numSegmentsAdded = 0;
907
        while (!theIterator.isDone()) {
908
            theType = theIterator.currentSegment(theData);
909

    
910
            switch (theType) {
911
                case PathIterator.SEG_MOVETO:
912
                    numParts++;
913
                    ptSrc.setLocation(theData[0], theData[1]);
914
                    at.transform(ptSrc, ptDst);
915
                    antX = (int) ptDst.getX();
916
                    antY = (int) ptDst.getY();
917
                    newGp.moveTo(antX, antY);
918
                    numSegmentsAdded++;
919
                    bFirst = true;
920
                    break;
921

    
922
                case PathIterator.SEG_LINETO:
923
                    ptSrc.setLocation(theData[0], theData[1]);
924
                    at.transform(ptSrc, ptDst);
925
                    xInt = (int) ptDst.getX();
926
                    yInt = (int) ptDst.getY();
927
                    if ((bFirst) || ((xInt != antX) || (yInt != antY)))
928
                    {
929
                        newGp.lineTo(xInt, yInt);
930
                        antX = xInt;
931
                        antY = yInt;
932
                        bFirst = false;
933
                        numSegmentsAdded++;
934
                    }
935
                    break;
936

    
937
                case PathIterator.SEG_QUADTO:
938
                    at.transform(theData,0,aux,0,2);
939
                    newGp.quadTo(aux[0], aux[1], aux[2], aux[3]);
940
                    numSegmentsAdded++;
941
                    break;
942

    
943
                case PathIterator.SEG_CUBICTO:
944
                    at.transform(theData,0,aux,0,3);
945
                    newGp.curveTo(aux[0], aux[1], aux[2], aux[3], aux[4], aux[5]);
946
                    numSegmentsAdded++;
947
                    break;
948

    
949
                case PathIterator.SEG_CLOSE:
950
                    if (numSegmentsAdded < 3)
951
                        newGp.lineTo(antX, antY);
952
                    newGp.closePath();
953

    
954
                    break;
955
            } //end switch
956

    
957
            theIterator.next();
958
        } //end while loop
959

    
960
        FShape shp = null;
961
        switch (gp.getShapeType())
962
        {
963
            case FShape.POINT: //Tipo punto
964
            case FShape.POINT + FShape.Z:
965
                shp = new org.gvsig.fmap.geom.primitive.Point2D(null, null, ptDst.getX(), ptDst.getY());
966
                break;
967

    
968
            case FShape.LINE:
969
            case FShape.LINE + FShape.Z:
970
            case FShape.ARC:
971
                    shp = new Curve2D(null, null, newGp);
972
                break;
973

    
974
            case FShape.POLYGON:
975
            case FShape.POLYGON + FShape.Z:
976
            case FShape.CIRCLE:
977
            case FShape.ELLIPSE:
978

    
979
                shp = new Surface2D(null, null, newGp);
980
                break;
981
        }
982
        return shp;
983
    }
984

    
985
    public static Rectangle2D convertEnvelopeToRectangle2D(Envelope jtsR)
986
    {
987
        Rectangle2D.Double r = new Rectangle2D.Double(jtsR.getMinX(),
988
                jtsR.getMinY(), jtsR.getWidth(), jtsR.getHeight());
989
        return r;
990
    }
991

    
992
    public static Envelope convertRectangle2DtoEnvelope(Rectangle2D r)
993
    {
994
            Envelope e = new Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(),
995
                        r.getY() + r.getHeight());
996
            return e;
997
    }
998

    
999
    /**
1000
     * Return a correct polygon (no hole)
1001
     * @param coordinates
1002
     * @return
1003
     */
1004
    public static Geometry getExteriorPolygon(Coordinate[] coordinates)
1005
    {
1006
            // isCCW = true => it's a hole
1007
            Coordinate[] vs=new Coordinate[coordinates.length];
1008
        if (CGAlgorithms.isCCW(coordinates)){
1009
                for (int i=vs.length-1;i>=0;i--){
1010
                        vs[i]=coordinates[i];
1011
                }
1012
        }else{
1013
                vs=coordinates;
1014
        }
1015
        LinearRing ring = geomFactory.createLinearRing(vs);
1016

    
1017
        try {
1018
                        return factory.createPolygon2D(toShape(ring));
1019
                } catch (NoninvertibleTransformException e) {
1020
                        e.printStackTrace();
1021
                }
1022
                return null;
1023
    }
1024

    
1025
    public static boolean isCCW(Point2D[] points)
1026
    {
1027
            Coordinate[] vs=new Coordinate[points.length];
1028
            for (int i=points.length-1;i>=0;i--){
1029
                    vs[i] = new Coordinate(points[i].getX(), points[i].getY());
1030
            }
1031

    
1032
        return CGAlgorithms.isCCW(vs);
1033
    }
1034

    
1035
    public static boolean isCCW(Surface2D pol)
1036
    {
1037
            com.vividsolutions.jts.geom.Geometry jtsGeom = Converter.java2d_to_jts(pol);
1038
            if (jtsGeom.getNumGeometries() == 1)
1039
            {
1040
                    Coordinate[] coords = jtsGeom.getCoordinates();
1041
                    return CGAlgorithms.isCCW(coords);
1042
            }
1043
            return false;
1044

    
1045
    }
1046

    
1047

    
1048
    /**
1049
     * Return a hole (CCW ordered points)
1050
     * @param coordinates
1051
     * @return
1052
     */
1053
    public static Geometry getHole(Coordinate[] coordinates)
1054
    {
1055
            // isCCW = true => it's a hole
1056
            Coordinate[] vs=new Coordinate[coordinates.length];
1057
        if (CGAlgorithms.isCCW(coordinates)){
1058
                vs=coordinates;
1059

    
1060
        }else{
1061
                for (int i=vs.length-1;i>=0;i--){
1062
                        vs[i]=coordinates[i];
1063
                }
1064
        }
1065
        LinearRing ring = geomFactory.createLinearRing(vs);
1066

    
1067
        try {
1068
                        return factory.createPolygon2D(toShape(ring));
1069
                } catch (NoninvertibleTransformException e) {
1070
                        e.printStackTrace();
1071
                }
1072
                return null;
1073
    }
1074

    
1075
        public static Shape getExteriorPolygon(GeneralPathX gp) {
1076
                Area area = new Area(gp);
1077
                area.isSingular();
1078
                return area;
1079

    
1080

    
1081

    
1082
        }
1083
        /**
1084
         * Use it ONLY for NOT multipart polygons.
1085
         * @param pol
1086
         * @return
1087
         */
1088
        public static Geometry getNotHolePolygon(Surface2D pol) {
1089
                // isCCW == true => hole
1090
                Coordinate[] coords;
1091
                ArrayList arrayCoords = null;
1092
                int theType;
1093
                int numParts = 0;
1094

    
1095
                //                 Use this array to store segment coordinate data
1096
                double[] theData = new double[6];
1097
                PathIterator theIterator;
1098

    
1099
                                ArrayList shells = new ArrayList();
1100
                                ArrayList holes = new ArrayList();
1101
                                Coordinate[] points = null;
1102

    
1103
                                theIterator = pol.getPathIterator(null, FLATNESS);
1104

    
1105
                                while (!theIterator.isDone()) {
1106
                                        //while not done
1107
                                        theType = theIterator.currentSegment(theData);
1108

    
1109
                                        //Populate a segment of the new
1110
                                        // GeneralPathX object.
1111
                                        //Process the current segment to populate a new
1112
                                        // segment of the new GeneralPathX object.
1113
                                        switch (theType) {
1114
                                                case PathIterator.SEG_MOVETO:
1115

    
1116
                                                        // System.out.println("SEG_MOVETO");
1117
                                                        if (arrayCoords == null) {
1118
                                                                arrayCoords = new ArrayList();
1119
                                                        } else {
1120
                                                                points = CoordinateArrays.toCoordinateArray(arrayCoords);
1121

    
1122
                                                                try {
1123
                                                                        LinearRing ring = geomFactory.createLinearRing(points);
1124

    
1125
                                                                        if (CGAlgorithms.isCCW(points)) {
1126
                                                                                holes.add(ring);
1127
                                                                        } else {
1128
                                                                                shells.add(ring);
1129
                                                                        }
1130
                                                                } catch (Exception e) {
1131
                                                                        System.err.println(
1132
                                                                                "Caught Topology exception in GMLLinearRingHandler");
1133

    
1134
                                                                        return null;
1135
                                                                }
1136

    
1137
                                                                /* if (numParts == 1)
1138
                                                                   {
1139
                                                                           linRingExt = new GeometryFactory().createLinearRing(
1140
                                                                                  CoordinateArrays.toCoordinateArray(arrayCoords));
1141
                                                                   }
1142
                                                                   else
1143
                                                                   {
1144
                                                                           linRing = new GeometryFactory().createLinearRing(
1145
                                                                                          CoordinateArrays.toCoordinateArray(arrayCoords));
1146
                                                                           arrayLines.add(linRing);
1147
                                                                   } */
1148
                                                                arrayCoords = new ArrayList();
1149
                                                        }
1150

    
1151
                                                        numParts++;
1152
                                                        arrayCoords.add(new Coordinate(theData[0],
1153
                                                                        theData[1]));
1154

    
1155
                                                        break;
1156

    
1157
                                                case PathIterator.SEG_LINETO:
1158

    
1159
                                                        // System.out.println("SEG_LINETO");
1160
                                                        arrayCoords.add(new Coordinate(theData[0],
1161
                                                                        theData[1]));
1162

    
1163
                                                        break;
1164

    
1165
                                                case PathIterator.SEG_QUADTO:
1166
                                                        System.out.println("SEG_QUADTO Not supported here");
1167

    
1168
                                                        break;
1169

    
1170
                                                case PathIterator.SEG_CUBICTO:
1171
                                                        System.out.println("SEG_CUBICTO Not supported here");
1172

    
1173
                                                        break;
1174

    
1175
                                                case PathIterator.SEG_CLOSE:
1176

    
1177
                                                        // A�adimos el primer punto para cerrar.
1178
                                                        Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
1179
                                                        arrayCoords.add(new Coordinate(firstCoord.x,
1180
                                                                        firstCoord.y));
1181

    
1182
                                                        break;
1183
                                        } //end switch
1184

    
1185
                                        // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
1186
                                        theIterator.next();
1187
                                } //end while loop
1188

    
1189
                                arrayCoords.add(arrayCoords.get(0));
1190
                                coords = CoordinateArrays.toCoordinateArray(arrayCoords);
1191

    
1192

    
1193
                if (numParts == 1)
1194
                {
1195
                        return getExteriorPolygon(coords);
1196
                }
1197
                return factory.createGeometry(pol);
1198

    
1199
        }
1200

    
1201

    
1202
    /* public static GeometryCollection convertFGeometryCollection(FGeometryCollection fGeomC)
1203
    {
1204

1205
        geomFactory.createGeometryCollection(theGeoms);
1206
    } */
1207
}