Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.geometry / org.gvsig.fmap.geometry.operation / src / main / java / org / gvsig / fmap / geom / operation / tojts / Surface2DToJTS.java @ 40559

History | View | Annotate | Download (10.3 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
/* gvSIG. Geographic Information System of the Valencian Government
25
*
26
* Copyright (C) 2007-2008 Infrastructures and Transports Department
27
* of the Valencian Government (CIT)
28
* 
29
* This program is free software; you can redistribute it and/or
30
* modify it under the terms of the GNU General Public License
31
* as published by the Free Software Foundation; either version 2
32
* of the License, or (at your option) any later version.
33
* 
34
* This program is distributed in the hope that it will be useful,
35
* but WITHOUT ANY WARRANTY; without even the implied warranty of
36
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37
* GNU General Public License for more details.
38
* 
39
* You should have received a copy of the GNU General Public License
40
* along with this program; if not, write to the Free Software
41
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
42
* MA  02110-1301, USA.
43
* 
44
*/
45

    
46
/*
47
* AUTHORS (In addition to CIT):
48
* 2009 {Iver T.I.}   {Task}
49
*/
50
 
51
package org.gvsig.fmap.geom.operation.tojts;
52

    
53
import java.awt.geom.PathIterator;
54
import java.util.ArrayList;
55

    
56
import org.gvsig.fmap.geom.Geometry;
57
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
58
import org.gvsig.fmap.geom.operation.GeometryOperationException;
59

    
60
import com.vividsolutions.jts.algorithm.CGAlgorithms;
61
import com.vividsolutions.jts.geom.Coordinate;
62
import com.vividsolutions.jts.geom.CoordinateArrays;
63
import com.vividsolutions.jts.geom.Envelope;
64
import com.vividsolutions.jts.geom.LineString;
65
import com.vividsolutions.jts.geom.LinearRing;
66
import com.vividsolutions.jts.geom.Polygon;
67

    
68
/**
69
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
70
 */
71
public class Surface2DToJTS extends ToJTS{
72
        /*
73
         * (non-Javadoc)
74
         * @see org.gvsig.fmap.geom.operation.tojts.ToJTS#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.geom.operation.GeometryOperationContext)
75
         */
76
        public Object invoke(Geometry geom, GeometryOperationContext ctx) throws GeometryOperationException {
77
                int srid = -1;
78
                if (ctx != null){
79
                        srid = ((JTSGeometryOperationContext)ctx).getSrid();
80
                }
81
                ArrayList arrayLines = new ArrayList();
82
                PathIterator theIterator = geom.getPathIterator(null, geomManager.getFlatness());
83
                int theType;
84
                double[] theData = new double[6];
85
                ArrayList arrayCoords = null;
86
                LineString lin;
87
                int numParts = 0;
88
                Coordinate coord;
89

    
90
                ArrayList shells = new ArrayList();
91
                ArrayList holes = new ArrayList();
92
                Coordinate[] points = null;
93

    
94
                while (!theIterator.isDone()) {
95
                        //while not done
96
                        theType = theIterator.currentSegment(theData);
97

    
98
                        //Populate a segment of the new
99
                        // GeneralPathX object.
100
                        //Process the current segment to populate a new
101
                        // segment of the new GeneralPathX object.
102
                        switch (theType) {
103
                        case PathIterator.SEG_MOVETO:
104

    
105
                                // System.out.println("SEG_MOVETO");
106
                                if (arrayCoords == null) {
107
                                        arrayCoords = new ArrayList();
108
                                } else {
109
                                        points = CoordinateArrays.toCoordinateArray(arrayCoords);
110

    
111
                                        try {
112
                                                LinearRing ring = geomFactory.createLinearRing(points);
113

    
114
                                                if (CGAlgorithms.isCCW(points)) {
115
                                                        holes.add(ring);
116
                                                } else {
117
                                                        shells.add(ring);
118
                                                }
119
                                        } catch (Exception e) {
120
                                                /* (jaume) caso cuando todos los puntos son iguales
121
                                                 * devuelvo el propio punto
122
                                                 */
123
                                                boolean same = true;
124
                                                for (int i = 0; i < points.length-1 && same; i++) {
125
                                                        if (points[i].x != points[i+1].x ||
126
                                                                        points[i].y != points[i+1].y /*||
127
                                                                        points[i].z != points[i+1].z*/
128
                                                        ) {
129
                                                                same = false;
130
                                                        }
131
                                                }
132
                                                if (same) {
133
                                                        return geomFactory.createPoint(points[0]);
134
                                                }
135
                                                /*
136
                                                 * caso cuando es una l�nea de 3 puntos, no creo un LinearRing, sino
137
                                                 * una linea
138
                                                 */
139
                                                if (points.length>1 && points.length<=3) {
140
                                                        // return geomFactory.createLineString(points);
141
                                                        return geomFactory.createMultiLineString(new LineString[] {geomFactory.createLineString(points)});
142
                                                }
143

    
144
                                                System.err.println(
145
                                                "Caught Topology exception in GMLLinearRingHandler");
146

    
147
                                                return null;
148
                                        }
149

    
150
                                        /* if (numParts == 1)
151
                                         {
152
                                         linRingExt = new GeometryFactory().createLinearRing(
153
                                         CoordinateArrays.toCoordinateArray(arrayCoords));
154
                                         }
155
                                         else
156
                                         {
157
                                         linRing = new GeometryFactory().createLinearRing(
158
                                         CoordinateArrays.toCoordinateArray(arrayCoords));
159
                                         arrayLines.add(linRing);
160
                                         } */
161
                                        arrayCoords = new ArrayList();
162
                                }
163

    
164
                                numParts++;
165
                                arrayCoords.add(new Coordinate(theData[0],
166
                                                theData[1]));
167

    
168
                                break;
169

    
170
                        case PathIterator.SEG_LINETO:
171

    
172
                                // System.out.println("SEG_LINETO");
173
                                arrayCoords.add(new Coordinate(theData[0],
174
                                                theData[1]));
175

    
176
                                break;
177

    
178
                        case PathIterator.SEG_QUADTO:
179
                                System.out.println("SEG_QUADTO Not supported here");
180

    
181
                                break;
182

    
183
                        case PathIterator.SEG_CUBICTO:
184
                                System.out.println("SEG_CUBICTO Not supported here");
185

    
186
                                break;
187

    
188
                        case PathIterator.SEG_CLOSE:
189

    
190
                                // A�adimos el primer punto para cerrar.
191
                                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
192
                                arrayCoords.add(new Coordinate(firstCoord.x,
193
                                                firstCoord.y));
194

    
195
                                break;
196
                        } //end switch
197

    
198
                        // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
199
                        theIterator.next();
200
                } //end while loop
201

    
202

    
203
                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
204
                Coordinate lastCoord = (Coordinate) arrayCoords.get(arrayCoords
205
                                .size() - 1);
206
                if (!isClosed(firstCoord, lastCoord)) {
207
                        arrayCoords.add(firstCoord);
208
                }
209
                points = CoordinateArrays.toCoordinateArray(arrayCoords);
210

    
211
                try {
212
                        LinearRing ring = geomFactory.createLinearRing(points);
213

    
214
                        if (CGAlgorithms.isCCW(points)) {
215
                                holes.add(ring);
216
                        } else {
217
                                shells.add(ring);
218
                        }
219
                        ring.setSRID(srid);
220
                } catch (Exception e) {
221
                        /* (jaume) caso cuando todos los puntos son iguales
222
                         * devuelvo el propio punto
223
                         */
224
                        boolean same = true;
225
                        for (int i = 0; i < points.length-1 && same; i++) {
226
                                if (points[i].x != points[i+1].x ||
227
                                                points[i].y != points[i+1].y /*||
228
                                                points[i].z != points[i+1].z*/
229
                                ) {
230
                                        same = false;
231
                                }
232
                        }
233
                        if (same) {
234
                                com.vividsolutions.jts.geom.Geometry geoJTS = geomFactory.createPoint(points[0]);
235
                                geoJTS.setSRID(srid);
236
                                return geoJTS;
237
                        }
238
                        /*
239
                         * caso cuando es una l�nea de 3 puntos, no creo un LinearRing, sino
240
                         * una linea
241
                         */
242
                        if (points.length>1 && points.length<=3) {
243
                                // return geomFactory.createLineString(points);
244
                                com.vividsolutions.jts.geom.Geometry geoJTS = geomFactory
245
                                                .createMultiLineString(new LineString[] { geomFactory
246
                                                                .createLineString(points) });
247
                                geoJTS.setSRID(srid);
248
                                return geoJTS;
249
                        }
250
                        System.err.println(
251
                        "Caught Topology exception in GMLLinearRingHandler");
252

    
253
                        return null;
254
                }
255

    
256
                /* linRing = new GeometryFactory().createLinearRing(
257
                 CoordinateArrays.toCoordinateArray(arrayCoords)); */
258

    
259
                // System.out.println("NumParts = " + numParts);
260
                //now we have a list of all shells and all holes
261
                ArrayList holesForShells = new ArrayList(shells.size());
262

    
263
                for (int i = 0; i < shells.size(); i++) {
264
                        holesForShells.add(new ArrayList());
265
                }
266

    
267
                //find homes
268
                for (int i = 0; i < holes.size(); i++) {
269
                        LinearRing testRing = (LinearRing) holes.get(i);
270
                        LinearRing minShell = null;
271
                        Envelope minEnv = null;
272
                        Envelope testEnv = testRing.getEnvelopeInternal();
273
                        Coordinate testPt = testRing.getCoordinateN(0);
274
                        LinearRing tryRing = null;
275

    
276
                        for (int j = 0; j < shells.size(); j++) {
277
                                tryRing = (LinearRing) shells.get(j);
278

    
279
                                Envelope tryEnv = tryRing.getEnvelopeInternal();
280

    
281
                                if (minShell != null) {
282
                                        minEnv = minShell.getEnvelopeInternal();
283
                                }
284

    
285
                                boolean isContained = false;
286
                                Coordinate[] coordList = tryRing.getCoordinates();
287

    
288
                                if (tryEnv.contains(testEnv) &&
289
                                                (CGAlgorithms.isPointInRing(testPt, coordList) ||
290
                                                                (pointInList(testPt, coordList)))) {
291
                                        isContained = true;
292
                                }
293

    
294
                                // check if this new containing ring is smaller than the current minimum ring
295
                                if (isContained) {
296
                                        if ((minShell == null) || minEnv.contains(tryEnv)) {
297
                                                minShell = tryRing;
298
                                        }
299
                                }
300
                        }
301

    
302
                        if (minShell == null) {
303
//                                System.out.println(
304
//                                "polygon found with a hole thats not inside a shell");
305
//                                azabala: we do the assumption that this hole is really a shell (polygon)
306
//                                whose point werent digitized in the right order
307
                                Coordinate[] cs = testRing.getCoordinates();
308
                                Coordinate[] reversed = new Coordinate[cs.length];
309
                                int pointIndex = 0;
310
                                for(int z = cs.length-1; z >= 0; z--){
311
                                        reversed[pointIndex] = cs[z];
312
                                        pointIndex++;
313
                                }
314
                                LinearRing newRing = geomFactory.createLinearRing(reversed);
315
                                shells.add(newRing);
316
                                holesForShells.add(new ArrayList());
317
                        } else {
318
                                ((ArrayList) holesForShells.get(shells.indexOf(minShell))).add(testRing);
319
                        }
320
                }
321

    
322
                Polygon[] polygons = new Polygon[shells.size()];
323

    
324
                for (int i = 0; i < shells.size(); i++) {
325
                        polygons[i] = geomFactory.createPolygon((LinearRing) shells.get(
326
                                        i),
327
                                        (LinearRing[]) ((ArrayList) holesForShells.get(i)).toArray(
328
                                                        new LinearRing[0]));
329
                        polygons[i].setSRID(srid);
330
                }
331
        
332
                holesForShells = null;
333
                shells = null;
334
                holes = null;
335

    
336
                //com.vividsolutions.jts.geom.Geometry geoJTS = geomFactory.createMultiPolygon(polygons);
337
                polygons[0].setSRID(srid);
338

    
339
                com.vividsolutions.jts.geom.Geometry geoJTS;
340
        if (polygons.length == 1) {
341
            geoJTS = polygons[0];
342
        } else {
343
            // its a multi part
344
            geoJTS = geomFactory.createMultiPolygon(polygons);
345
        }
346
        geoJTS.setSRID(srid);
347
                return geoJTS;
348
        }
349
}