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 @ 40767

History | View | Annotate | Download (9.35 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
 
25
package org.gvsig.fmap.geom.operation.tojts;
26

    
27
import java.awt.geom.PathIterator;
28
import java.util.ArrayList;
29

    
30
import org.gvsig.fmap.geom.Geometry;
31
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
32
import org.gvsig.fmap.geom.operation.GeometryOperationException;
33

    
34
import com.vividsolutions.jts.algorithm.CGAlgorithms;
35
import com.vividsolutions.jts.geom.Coordinate;
36
import com.vividsolutions.jts.geom.CoordinateArrays;
37
import com.vividsolutions.jts.geom.Envelope;
38
import com.vividsolutions.jts.geom.LineString;
39
import com.vividsolutions.jts.geom.LinearRing;
40
import com.vividsolutions.jts.geom.Polygon;
41

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

    
64
                ArrayList shells = new ArrayList();
65
                ArrayList holes = new ArrayList();
66
                Coordinate[] points = null;
67

    
68
                while (!theIterator.isDone()) {
69
                        //while not done
70
                        theType = theIterator.currentSegment(theData);
71

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

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

    
85
                                        try {
86
                                                LinearRing ring = geomFactory.createLinearRing(points);
87

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

    
118
                                                System.err.println(
119
                                                "Caught Topology exception in GMLLinearRingHandler");
120

    
121
                                                return null;
122
                                        }
123

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

    
138
                                numParts++;
139
                                arrayCoords.add(new Coordinate(theData[0],
140
                                                theData[1]));
141

    
142
                                break;
143

    
144
                        case PathIterator.SEG_LINETO:
145

    
146
                                // System.out.println("SEG_LINETO");
147
                                arrayCoords.add(new Coordinate(theData[0],
148
                                                theData[1]));
149

    
150
                                break;
151

    
152
                        case PathIterator.SEG_QUADTO:
153
                                System.out.println("SEG_QUADTO Not supported here");
154

    
155
                                break;
156

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

    
160
                                break;
161

    
162
                        case PathIterator.SEG_CLOSE:
163

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

    
169
                                break;
170
                        } //end switch
171

    
172
                        // System.out.println("theData[0] = " + theData[0] + " theData[1]=" + theData[1]);
173
                        theIterator.next();
174
                } //end while loop
175

    
176

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

    
185
                try {
186
                        LinearRing ring = geomFactory.createLinearRing(points);
187

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

    
227
                        return null;
228
                }
229

    
230
                /* linRing = new GeometryFactory().createLinearRing(
231
                 CoordinateArrays.toCoordinateArray(arrayCoords)); */
232

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

    
237
                for (int i = 0; i < shells.size(); i++) {
238
                        holesForShells.add(new ArrayList());
239
                }
240

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

    
250
                        for (int j = 0; j < shells.size(); j++) {
251
                                tryRing = (LinearRing) shells.get(j);
252

    
253
                                Envelope tryEnv = tryRing.getEnvelopeInternal();
254

    
255
                                if (minShell != null) {
256
                                        minEnv = minShell.getEnvelopeInternal();
257
                                }
258

    
259
                                boolean isContained = false;
260
                                Coordinate[] coordList = tryRing.getCoordinates();
261

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

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

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

    
296
                Polygon[] polygons = new Polygon[shells.size()];
297

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

    
310
                //com.vividsolutions.jts.geom.Geometry geoJTS = geomFactory.createMultiPolygon(polygons);
311
                polygons[0].setSRID(srid);
312

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