Statistics
| Revision:

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

History | View | Annotate | Download (9.35 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
                while (!theIterator.isDone()) {
72
                        //while not done
73
                        theType = theIterator.currentSegment(theData);
74

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

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

    
88
                                        try {
89
                                                LinearRing ring = geomFactory.createLinearRing(points);
90

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

    
121
                                                System.err.println(
122
                                                "Caught Topology exception in GMLLinearRingHandler");
123

    
124
                                                return null;
125
                                        }
126

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

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

    
145
                                break;
146

    
147
                        case PathIterator.SEG_LINETO:
148

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

    
153
                                break;
154

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

    
158
                                break;
159

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

    
163
                                break;
164

    
165
                        case PathIterator.SEG_CLOSE:
166

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

    
172
                                break;
173
                        } //end switch
174

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

    
179

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

    
188
                try {
189
                        LinearRing ring = geomFactory.createLinearRing(points);
190

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

    
230
                        return null;
231
                }
232

    
233
                /* linRing = new GeometryFactory().createLinearRing(
234
                 CoordinateArrays.toCoordinateArray(arrayCoords)); */
235

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

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

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

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

    
256
                                Envelope tryEnv = tryRing.getEnvelopeInternal();
257

    
258
                                if (minShell != null) {
259
                                        minEnv = minShell.getEnvelopeInternal();
260
                                }
261

    
262
                                boolean isContained = false;
263
                                Coordinate[] coordList = tryRing.getCoordinates();
264

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

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

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

    
299
                Polygon[] polygons = new Polygon[shells.size()];
300

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

    
313
                //com.vividsolutions.jts.geom.Geometry geoJTS = geomFactory.createMultiPolygon(polygons);
314
                polygons[0].setSRID(srid);
315

    
316
                com.vividsolutions.jts.geom.Geometry geoJTS;
317
        if (polygons.length == 1) {
318
            geoJTS = polygons[0];
319
        } else {
320
            // its a multi part
321
            geoJTS = geomFactory.createMultiPolygon(polygons);
322
        }
323
        geoJTS.setSRID(srid);
324
                return geoJTS;
325
        }
326
}