Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.geometry / org.gvsig.fmap.geometry.jts / src / main / java / org / gvsig / fmap / geom / jts / coerce / CoerceToGeometry.java @ 45673

History | View | Annotate | Download (15 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
package org.gvsig.fmap.geom.jts.coerce;
25

    
26
import java.util.Iterator;
27
import java.util.logging.Level;
28
import java.util.logging.Logger;
29
import org.apache.commons.lang3.StringUtils;
30
import org.gvsig.fmap.geom.Geometry;
31
import org.gvsig.fmap.geom.GeometryCoercionContext;
32
import static org.gvsig.fmap.geom.GeometryCoercionContext.MODE_ONERROR_DONTCONVERT;
33
import static org.gvsig.fmap.geom.GeometryCoercionContext.MODE_ONERROR_NULL;
34
import static org.gvsig.fmap.geom.GeometryCoercionContext.MODE_ONERROR_THROW;
35
import org.gvsig.fmap.geom.GeometryLocator;
36
import org.gvsig.fmap.geom.GeometryManager;
37
import org.gvsig.fmap.geom.aggregate.MultiLine;
38
import org.gvsig.fmap.geom.aggregate.MultiPoint;
39
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
40
import org.gvsig.fmap.geom.jts.AbstractGeometry;
41
import org.gvsig.fmap.geom.operation.GeometryOperationException;
42
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
43
import org.gvsig.fmap.geom.primitive.Line;
44
import org.gvsig.fmap.geom.primitive.Point;
45
import org.gvsig.fmap.geom.primitive.Polygon;
46
import org.gvsig.fmap.geom.primitive.Primitive;
47
import org.gvsig.fmap.geom.type.GeometryType;
48
import org.gvsig.tools.dataTypes.AbstractCoercion;
49
import org.gvsig.tools.dataTypes.CoercionException;
50
import org.gvsig.tools.dataTypes.CoercionContext;
51

    
52
/**
53
 * Convert a object to Geometry.
54
 *
55
 * Support convert: - Geometry to Geometry (do nothing) - WKB (byte[]) to
56
 * Geometry - WKT (String/toString) to Geometry
57
 *
58
 *
59
 * @author gvSIG Team
60
 * @version $Id$
61
 *
62
 */
63
@SuppressWarnings("UseSpecificCatch")
64
public class CoerceToGeometry extends AbstractCoercion {
65

    
66
    private static GeometryManager manager = null;
67
    
68
    @Override
69
    public Object coerce(Object value, CoercionContext context) throws CoercionException {
70
        if (value == null) {
71
            return value;
72
        }
73
        int mode = MODE_ONERROR_NULL;
74
        Geometry geom;
75
        GeometryType targetGeometryType = null;
76
        Geometry sourcegeom = null;
77
        try {
78
//            TODO: descomentarizar para que tengan efecto los cambios.
79
//            if ( context instanceof GeometryCoercionContext) {
80
//                GeometryCoercionContext geomContext = (GeometryCoercionContext) context;
81
//                targetGeometryType = geomContext.getGeometryType();
82
//                mode = geomContext.getMode();
83
//            }
84
            
85
            if ( value instanceof Geometry ) {
86
                geom = (Geometry) value;
87
            } else {
88
                if (value instanceof byte[]) {
89
                    geom = getManager().createFrom((byte[]) value);
90
                } else {
91
                    String wkt = value.toString();
92
                    if (StringUtils.isBlank(wkt)) {
93
                        return null;
94
                    }
95
                    geom = getManager().createFrom(value.toString());
96
                }
97
                if (geom == null) {
98
                    // Can't parse from WKB/WKT
99
                    switch(mode) {
100
                        case MODE_ONERROR_NULL:
101
                        case MODE_ONERROR_DONTCONVERT:
102
                            return null;
103
                        case MODE_ONERROR_THROW:
104
                        default:
105
                            throw new CoercionException();
106
                    }
107
                }
108
            }
109
            if ( targetGeometryType==null) {
110
                return geom;
111
            }
112
            sourcegeom = geom;
113
            if (geom.getGeometryType().equals(targetGeometryType)) {
114
                return geom;
115
            }
116
            switch (targetGeometryType.getType()) {
117
                case Geometry.TYPES.MULTIPOINT:
118
                    geom = this.convertToMultipoint(targetGeometryType, geom);
119
                    break;
120
                case Geometry.TYPES.MULTILINE:
121
                    geom = this.convertToMultiline(targetGeometryType, geom);
122
                    break;
123
                case Geometry.TYPES.MULTIPOLYGON:
124
                    geom = this.convertToMultipolygon(targetGeometryType, geom);
125
                    break;
126
                case Geometry.TYPES.POINT:
127
                    geom = this.convertToPoint(targetGeometryType, geom);
128
                    break;
129
                case Geometry.TYPES.LINE:
130
                    geom = this.convertToLine(targetGeometryType, geom);
131
                    break;
132
                case Geometry.TYPES.POLYGON:
133
                    geom = this.convertToPolygon(targetGeometryType, geom);
134
                    break;
135
                case Geometry.TYPES.GEOMETRY:
136
                    geom = this.convertToGeometry(targetGeometryType, geom);
137
                    break;
138
                default:
139
                    geom = null;
140
                    break;
141
            }
142
            if (geom != null) {
143
                // Return converted geometry
144
                return geom;
145
            }
146
            switch(mode) {
147
                case MODE_ONERROR_NULL:
148
                    return null;
149
                case MODE_ONERROR_DONTCONVERT:
150
                    return sourcegeom;
151
                case MODE_ONERROR_THROW:
152
                default:
153
                    throw new CoercionException();
154
            }
155
        } catch (Exception e) {
156
            switch(mode) {
157
                case MODE_ONERROR_NULL:
158
                    return null;
159
                case MODE_ONERROR_DONTCONVERT:
160
                    return sourcegeom;
161
                case MODE_ONERROR_THROW:
162
                default:
163
                    throw new CoercionException();
164
            }
165
        }
166
    }
167

    
168
    private static GeometryManager getManager() {
169
        if (manager == null) {
170
            manager = GeometryLocator.getGeometryManager();
171
        }
172
        return manager;
173
    }
174

    
175
    private Geometry convertToMultipoint(GeometryType geometryType, Geometry geom) {
176
        try {
177
            MultiPoint target = null;
178
            switch (geom.getType()) {
179
                case Geometry.TYPES.POINT:
180
                    target = (MultiPoint) geometryType.create();
181
                    target.addPoint((Point) geom);
182
                    break;
183
                case Geometry.TYPES.LINE:
184
                    if( geometryType.getSubType() == geom.getGeometryType().getSubType() ) {
185
                        target = ((Line) geom).toPoints();
186
                    } else {
187
                        target = (MultiPoint) geometryType.create();
188
                        for (Point point : convertPoints(geometryType, ((Line) geom).toPoints().iterator())) {
189
                            
190
                        }
191
                        target.addPoint((Point) geom);
192
                    }
193
                    break;
194
                case Geometry.TYPES.POLYGON:
195
                    target = ((Polygon) geom).toPoints();
196
                    break;
197
                case Geometry.TYPES.MULTILINE:
198
                    target = ((MultiLine) geom).toPoints();
199
                    break;
200
                case Geometry.TYPES.MULTIPOLYGON:
201
                    target = ((MultiPolygon) geom).toPoints();
202
                    break;
203
            }
204
            return target;
205
        } catch (Exception ex) {
206
            return null;
207
        }
208
    }
209

    
210
    private Geometry convertToMultiline(GeometryType geometryType, Geometry geom) {
211
        try {
212
            MultiLine target = null;
213
            switch (geom.getType()) {
214
                case Geometry.TYPES.LINE:
215
                    target = (MultiLine) geometryType.create();
216
                    target.addPrimitive((Primitive) geom);
217
                    break;
218
                case Geometry.TYPES.POLYGON:
219
                    target = (MultiLine) geometryType.create();
220
                    target.addPrimitive((Primitive) ((Polygon) geom).toLines());
221
                    break;
222
                case Geometry.TYPES.MULTIPOLYGON:
223
                    target = (MultiLine) geometryType.create();
224
                    for (Geometry polygon : ((MultiPolygon) geom)) {
225
                        target.addPrimitive((Primitive) ((Polygon) polygon).toLines());
226
                    }
227
                    break;
228
            }
229
            return target;
230
        } catch (Exception ex) {
231
            return null;
232
        }
233
    }
234

    
235
    private Geometry convertToMultipolygon(GeometryType geometryType, Geometry geom) {
236
        try {
237
            MultiPolygon target = null;
238
            switch (geom.getType()) {
239
                case Geometry.TYPES.LINE:
240
                    target = (MultiPolygon) geometryType.create();
241
                    Polygon polygon = getManager().createPolygon(geometryType.getSubType());
242
                    for (Point point : (Line)geom ) {
243
                        polygon.addVertex(point);
244
                    }
245
                    if( !polygon.isClosed() )  {
246
                        polygon.addVertex(polygon.getVertex(0));
247
                    }
248
                    target.addPrimitive(polygon);
249
                    break;
250

    
251
                case Geometry.TYPES.POLYGON:
252
                    target = (MultiPolygon) geometryType.create();
253
                    target.addPrimitive((Primitive) ((Polygon) geom));
254
                    break;
255
            }
256
            return target;
257
        } catch (Exception ex) {
258
            return null;
259
        }
260
    }
261

    
262
    private Geometry convertToPoint(GeometryType geometryType, Geometry geom) {
263
        try {
264
            Point target = null;
265
            switch (geom.getType()) {
266
                case Geometry.TYPES.MULTIPOINT:
267
                    MultiPoint multi = (MultiPoint)geom;
268
                    if( multi.getPrimitivesNumber()==1 ) {
269
                        target = (Point) multi.getPrimitiveAt(0);
270
                    }
271
                    break;
272

    
273
            }
274
            return target;
275
        } catch (Exception ex) {
276
            return null;
277
        }
278
    }
279

    
280
    private Geometry convertToLine(GeometryType geometryType, Geometry geom) {
281
        try {
282
            Line target = null;
283
            MultiLine multiline;
284
            MultiPolygon multipolygon;
285
            switch (geom.getType()) {
286
                case Geometry.TYPES.MULTILINE:
287
                    multiline = (MultiLine)geom;
288
                    if( multiline.getPrimitivesNumber()==1 ) {
289
                        target = (Line) multiline.getPrimitiveAt(0);
290
                    }
291
                    break;
292
                case Geometry.TYPES.POLYGON:
293
                    multiline = ((Polygon)geom).toLines();
294
                    if( multiline.getPrimitivesNumber()==1 ) {
295
                        target = (Line) multiline.getPrimitiveAt(0);
296
                    }
297
                    break;
298
                case Geometry.TYPES.MULTIPOLYGON:
299
                    multipolygon = (MultiPolygon)geom;
300
                    if( multipolygon.getPrimitivesNumber()==1 ) {
301
                        multiline = multipolygon.getPrimitiveAt(0).toLines();
302
                        if( multiline.getPrimitivesNumber()==1 ) {
303
                            target = (Line) multiline.getPrimitiveAt(0);
304
                        }
305
                    }
306
                    break;
307
            }
308
            return target;
309
        } catch (Exception ex) {
310
            return null;
311
        }
312
    }
313

    
314
    private Geometry convertToPolygon(GeometryType geometryType, Geometry geom) {
315
        try {
316
            Polygon target = null;
317
            switch (geom.getType()) {
318
                case Geometry.TYPES.LINE:
319
                    target = (Polygon) geometryType.create();
320
                    for (Point point : (Line)geom ) {
321
                        target.addVertex(point);
322
                    }
323
                    if( !target.isClosed() )  {
324
                        target.addVertex(target.getVertex(0));
325
                    }
326
                    break;
327
                case Geometry.TYPES.MULTILINE:
328
                    MultiLine multiline = (MultiLine)geom;
329
                    if( multiline.getPrimitivesNumber()==1 ) {
330
                        target = (Polygon) geometryType.create();
331
                        for (Point point : (Line) multiline.getPrimitiveAt(0) ) {
332
                            target.addVertex(point);
333
                        }
334
                        if( !target.isClosed() )  {
335
                            target.addVertex(target.getVertex(0));
336
                        }
337
                    }
338
                    break;
339
                case Geometry.TYPES.MULTIPOLYGON:
340
                    MultiPolygon multipolygon = (MultiPolygon)geom;
341
                    if( multipolygon.getPrimitivesNumber()==1 ) {
342
                        target = (Polygon) multipolygon.getPrimitiveAt(0);
343
                    }
344
                    break;
345
            }
346
            return target;
347
        } catch (Exception ex) {
348
            return null;
349
        }
350
    }
351

    
352
    private Geometry convertToGeometry(GeometryType geometryType, Geometry geom) {
353
        try {
354
            if( geom instanceof AbstractGeometry ) {
355
                ((AbstractGeometry)geom).setGeometryType(geometryType);
356
                return geom;
357
            }
358
            return null;
359
        } catch (Exception ex) {
360
            return null;
361
        }
362
    }
363

    
364
    private Iterable<Point> convertPoints(GeometryType geometryType, Iterator<Geometry> pointIterator) {
365
        Iterable<Point> iterable = () -> {
366
            Iterator<Point> iterator = new Iterator<Point>() {
367
                @Override
368
                public boolean hasNext() {
369
                    return pointIterator.hasNext();
370
                }
371
                
372
                @Override
373
                public Point next() {
374
                    Point sourcePoint = (Point) pointIterator.next();
375
                    if( geometryType.hasZ() ) {
376
                        if( geometryType.hasM() ) {
377
                            return sourcePoint.force3DM();
378
                        } else {
379
                            return (Point) sourcePoint.force3D();
380
                        }
381
                    } else if( geometryType.hasM() ) {
382
                        return sourcePoint.force2DM();
383
                    } else {
384
                        try {
385
                            return (Point) sourcePoint.force2D();
386
                        } catch (Exception ex) {
387
                            throw new RuntimeException(ex);
388
                        }
389
                    }
390
                }
391
            };
392
            return iterator;
393
        };
394
        return iterable;
395
    }
396

    
397

    
398
}