Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_geometries / src / org / gvsig / fmap / geom / operation / tojts / Surface2DToJTS.java @ 30323

History | View | Annotate | Download (9.16 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
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 2
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
*/
22

    
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2009 {Iver T.I.}   {Task}
26
*/
27
 
28
package org.gvsig.fmap.geom.operation.tojts;
29

    
30
import java.awt.geom.PathIterator;
31
import java.util.ArrayList;
32

    
33
import org.gvsig.fmap.geom.Geometry;
34
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
35
import org.gvsig.fmap.geom.operation.GeometryOperationException;
36

    
37
import com.vividsolutions.jts.algorithm.CGAlgorithms;
38
import com.vividsolutions.jts.geom.Coordinate;
39
import com.vividsolutions.jts.geom.CoordinateArrays;
40
import com.vividsolutions.jts.geom.Envelope;
41
import com.vividsolutions.jts.geom.LineString;
42
import com.vividsolutions.jts.geom.LinearRing;
43
import com.vividsolutions.jts.geom.Polygon;
44

    
45
/**
46
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
47
 */
48
public class Surface2DToJTS extends ToJTS{
49
        /*
50
         * (non-Javadoc)
51
         * @see org.gvsig.fmap.geom.operation.tojts.ToJTS#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.geom.operation.GeometryOperationContext)
52
         */
53
        public Object invoke(Geometry geom, GeometryOperationContext ctx) throws GeometryOperationException {
54
                int srid = -1;
55
                if (ctx != null){
56
                        srid = ((JTSGeometryOperationContext)ctx).getSrid();
57
                }
58
                ArrayList arrayLines = new ArrayList();
59
                PathIterator theIterator = geom.getPathIterator(null, geomManager.getFlatness());
60
                int theType;
61
                double[] theData = new double[6];
62
                ArrayList arrayCoords = null;
63
                LineString lin;
64
                int numParts = 0;
65
                Coordinate coord;
66

    
67
                ArrayList shells = new ArrayList();
68
                ArrayList holes = new ArrayList();
69
                Coordinate[] points = null;
70

    
71
                theIterator = geom.getPathIterator(null, geomManager.getFlatness());
72

    
73
                while (!theIterator.isDone()) {
74
                        //while not done
75
                        theType = theIterator.currentSegment(theData);
76

    
77
                        //Populate a segment of the new
78
                        // GeneralPathX object.
79
                        //Process the current segment to populate a new
80
                        // segment of the new GeneralPathX object.
81
                        switch (theType) {
82
                        case PathIterator.SEG_MOVETO:
83

    
84
                                // System.out.println("SEG_MOVETO");
85
                                if (arrayCoords == null) {
86
                                        arrayCoords = new ArrayList();
87
                                } else {
88
                                        points = CoordinateArrays.toCoordinateArray(arrayCoords);
89

    
90
                                        try {
91
                                                LinearRing ring = geomFactory.createLinearRing(points);
92

    
93
                                                if (CGAlgorithms.isCCW(points)) {
94
                                                        holes.add(ring);
95
                                                } else {
96
                                                        shells.add(ring);
97
                                                }
98
                                        } catch (Exception e) {
99
                                                /* (jaume) caso cuando todos los puntos son iguales
100
                                                 * devuelvo el propio punto
101
                                                 */
102
                                                boolean same = true;
103
                                                for (int i = 0; i < points.length-1 && same; i++) {
104
                                                        if (points[i].x != points[i+1].x ||
105
                                                                        points[i].y != points[i+1].y /*||
106
                                                                        points[i].z != points[i+1].z*/
107
                                                        ) {
108
                                                                same = false;
109
                                                        }
110
                                                }
111
                                                if (same) {
112
                                                        return geomFactory.createPoint(points[0]);
113
                                                }
114
                                                /*
115
                                                 * caso cuando es una l�nea de 3 puntos, no creo un LinearRing, sino
116
                                                 * una linea
117
                                                 */
118
                                                if (points.length>1 && points.length<=3) {
119
                                                        // return geomFactory.createLineString(points);
120
                                                        return geomFactory.createMultiLineString(new LineString[] {geomFactory.createLineString(points)});
121
                                                }
122

    
123
                                                System.err.println(
124
                                                "Caught Topology exception in GMLLinearRingHandler");
125

    
126
                                                return null;
127
                                        }
128

    
129
                                        /* if (numParts == 1)
130
                                         {
131
                                         linRingExt = new GeometryFactory().createLinearRing(
132
                                         CoordinateArrays.toCoordinateArray(arrayCoords));
133
                                         }
134
                                         else
135
                                         {
136
                                         linRing = new GeometryFactory().createLinearRing(
137
                                         CoordinateArrays.toCoordinateArray(arrayCoords));
138
                                         arrayLines.add(linRing);
139
                                         } */
140
                                        arrayCoords = new ArrayList();
141
                                }
142

    
143
                                numParts++;
144
                                arrayCoords.add(new Coordinate(theData[0],
145
                                                theData[1]));
146

    
147
                                break;
148

    
149
                        case PathIterator.SEG_LINETO:
150

    
151
                                // System.out.println("SEG_LINETO");
152
                                arrayCoords.add(new Coordinate(theData[0],
153
                                                theData[1]));
154

    
155
                                break;
156

    
157
                        case PathIterator.SEG_QUADTO:
158
                                System.out.println("SEG_QUADTO Not supported here");
159

    
160
                                break;
161

    
162
                        case PathIterator.SEG_CUBICTO:
163
                                System.out.println("SEG_CUBICTO Not supported here");
164

    
165
                                break;
166

    
167
                        case PathIterator.SEG_CLOSE:
168

    
169
                                // A�adimos el primer punto para cerrar.
170
                                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
171
                                arrayCoords.add(new Coordinate(firstCoord.x,
172
                                                firstCoord.y));
173

    
174
                                break;
175
                        } //end switch
176

    
177
                        // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
178
                        theIterator.next();
179
                } //end while loop
180

    
181

    
182
                Coordinate firstCoord = (Coordinate) arrayCoords.get(0);
183
                Coordinate lastCoord = (Coordinate) arrayCoords.get(arrayCoords
184
                                .size() - 1);
185
                if (!isClosed(firstCoord, lastCoord)) {
186
                        arrayCoords.add(firstCoord);
187
                }
188
                points = CoordinateArrays.toCoordinateArray(arrayCoords);
189

    
190
                try {
191
                        LinearRing ring = geomFactory.createLinearRing(points);
192

    
193
                        if (CGAlgorithms.isCCW(points)) {
194
                                holes.add(ring);
195
                        } else {
196
                                shells.add(ring);
197
                        }
198
                        ring.setSRID(srid);
199
                } catch (Exception e) {
200
                        /* (jaume) caso cuando todos los puntos son iguales
201
                         * devuelvo el propio punto
202
                         */
203
                        boolean same = true;
204
                        for (int i = 0; i < points.length-1 && same; i++) {
205
                                if (points[i].x != points[i+1].x ||
206
                                                points[i].y != points[i+1].y /*||
207
                                                points[i].z != points[i+1].z*/
208
                                ) {
209
                                        same = false;
210
                                }
211
                        }
212
                        if (same) {
213
                                com.vividsolutions.jts.geom.Geometry geoJTS = geomFactory.createPoint(points[0]);
214
                                geoJTS.setSRID(srid);
215
                                return geoJTS;
216
                        }
217
                        /*
218
                         * caso cuando es una l�nea de 3 puntos, no creo un LinearRing, sino
219
                         * una linea
220
                         */
221
                        if (points.length>1 && points.length<=3) {
222
                                // return geomFactory.createLineString(points);
223
                                com.vividsolutions.jts.geom.Geometry geoJTS = geomFactory
224
                                                .createMultiLineString(new LineString[] { geomFactory
225
                                                                .createLineString(points) });
226
                                geoJTS.setSRID(srid);
227
                                return geoJTS;
228
                        }
229
                        System.err.println(
230
                        "Caught Topology exception in GMLLinearRingHandler");
231

    
232
                        return null;
233
                }
234

    
235
                /* linRing = new GeometryFactory().createLinearRing(
236
                 CoordinateArrays.toCoordinateArray(arrayCoords)); */
237

    
238
                // System.out.println("NumParts = " + numParts);
239
                //now we have a list of all shells and all holes
240
                ArrayList holesForShells = new ArrayList(shells.size());
241

    
242
                for (int i = 0; i < shells.size(); i++) {
243
                        holesForShells.add(new ArrayList());
244
                }
245

    
246
                //find homes
247
                for (int i = 0; i < holes.size(); i++) {
248
                        LinearRing testRing = (LinearRing) holes.get(i);
249
                        LinearRing minShell = null;
250
                        Envelope minEnv = null;
251
                        Envelope testEnv = testRing.getEnvelopeInternal();
252
                        Coordinate testPt = testRing.getCoordinateN(0);
253
                        LinearRing tryRing = null;
254

    
255
                        for (int j = 0; j < shells.size(); j++) {
256
                                tryRing = (LinearRing) shells.get(j);
257

    
258
                                Envelope tryEnv = tryRing.getEnvelopeInternal();
259

    
260
                                if (minShell != null) {
261
                                        minEnv = minShell.getEnvelopeInternal();
262
                                }
263

    
264
                                boolean isContained = false;
265
                                Coordinate[] coordList = tryRing.getCoordinates();
266

    
267
                                if (tryEnv.contains(testEnv) &&
268
                                                (CGAlgorithms.isPointInRing(testPt, coordList) ||
269
                                                                (pointInList(testPt, coordList)))) {
270
                                        isContained = true;
271
                                }
272

    
273
                                // check if this new containing ring is smaller than the current minimum ring
274
                                if (isContained) {
275
                                        if ((minShell == null) || minEnv.contains(tryEnv)) {
276
                                                minShell = tryRing;
277
                                        }
278
                                }
279
                        }
280

    
281
                        if (minShell == null) {
282
//                                System.out.println(
283
//                                "polygon found with a hole thats not inside a shell");
284
//                                azabala: we do the assumption that this hole is really a shell (polygon)
285
//                                whose point werent digitized in the right order
286
                                Coordinate[] cs = testRing.getCoordinates();
287
                                Coordinate[] reversed = new Coordinate[cs.length];
288
                                int pointIndex = 0;
289
                                for(int z = cs.length-1; z >= 0; z--){
290
                                        reversed[pointIndex] = cs[z];
291
                                        pointIndex++;
292
                                }
293
                                LinearRing newRing = geomFactory.createLinearRing(reversed);
294
                                shells.add(newRing);
295
                                holesForShells.add(new ArrayList());
296
                        } else {
297
                                ((ArrayList) holesForShells.get(shells.indexOf(minShell))).add(testRing);
298
                        }
299
                }
300

    
301
                Polygon[] polygons = new Polygon[shells.size()];
302

    
303
                for (int i = 0; i < shells.size(); i++) {
304
                        polygons[i] = geomFactory.createPolygon((LinearRing) shells.get(
305
                                        i),
306
                                        (LinearRing[]) ((ArrayList) holesForShells.get(i)).toArray(
307
                                                        new LinearRing[0]));
308
                        polygons[i].setSRID(srid);
309
                }
310
        
311
                holesForShells = null;
312
                shells = null;
313
                holes = null;
314

    
315
                //com.vividsolutions.jts.geom.Geometry geoJTS = geomFactory.createMultiPolygon(polygons);
316
                polygons[0].setSRID(srid);
317
                return polygons[0];
318
        }
319
}