Statistics
| Revision:

gvsig-geoprocess / org.gvsig.geoprocess / trunk / org.gvsig.geoprocess / org.gvsig.geoprocess.algorithm / org.gvsig.geoprocess.algorithm.base / src / main / java / org / gvsig / geoprocess / algorithm / base / core / DALFeaturePersister.java @ 268

History | View | Annotate | Download (15.4 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2012 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 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
 * 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.geoprocess.algorithm.base.core;
25

    
26
import java.util.ArrayList;
27

    
28
import org.gvsig.fmap.dal.exception.DataException;
29
import org.gvsig.fmap.dal.exception.ReadException;
30
import org.gvsig.fmap.dal.feature.EditableFeature;
31
import org.gvsig.fmap.dal.feature.Feature;
32
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
33
import org.gvsig.fmap.dal.feature.FeatureStore;
34
import org.gvsig.fmap.dal.feature.FeatureType;
35
import org.gvsig.fmap.geom.GeometryLocator;
36
import org.gvsig.fmap.geom.GeometryManager;
37
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
38
import org.gvsig.fmap.geom.Geometry.TYPES;
39
import org.gvsig.fmap.geom.aggregate.MultiCurve;
40
import org.gvsig.fmap.geom.aggregate.MultiPoint;
41
import org.gvsig.fmap.geom.exception.CreateGeometryException;
42
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
43
import org.gvsig.fmap.geom.operation.GeometryOperationException;
44
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
45
import org.gvsig.fmap.geom.operation.fromjts.FromJTS;
46
import org.gvsig.fmap.geom.primitive.Curve;
47
import org.gvsig.fmap.geom.primitive.Point;
48
import org.gvsig.geoprocess.algorithm.base.util.GeometryUtil;
49

    
50
import com.vividsolutions.jts.geom.Geometry;
51
import com.vividsolutions.jts.geom.GeometryCollection;
52
import com.vividsolutions.jts.geom.MultiLineString;
53
import com.vividsolutions.jts.geom.MultiPolygon;
54

    
55
import es.unex.sextante.core.Sextante;
56

    
57
/**
58
 * Writes features in a FeatureStore
59
 * @author Nacho Brodin (nachobrodin@gmail.com)
60
 */
61
public class DALFeaturePersister {
62
        private FeatureStore              store             = null;
63
        private String[]                  fieldNames        = null;
64
        private GeometryManager           geometryManager   = null;
65
        
66
        /**
67
         * Sets the output FeatureType
68
         * @param out
69
         * @throws DataException 
70
         */
71
        public DALFeaturePersister(FeatureStore out, String[] fieldNames) {
72
                this.store = out;
73
                this.fieldNames = fieldNames;
74
                try {
75
                        if(!store.isEditing())
76
                                store.edit();
77
                } catch (DataException e) {
78
                } catch (NullPointerException e) {
79
                }
80
                geometryManager = GeometryLocator.getGeometryManager();
81
        }
82
        
83
        /**
84
         * Adds a JTS feature to the FeatureStore
85
         * @param entry
86
         * @param newGeom
87
         * @throws CreateGeometryException
88
         * @throws DataException
89
         */
90
        public EditableFeature addFeature(Feature feature1, Feature feature2, Geometry newGeom) 
91
                throws CreateGeometryException, DataException {
92
                
93
                int outPutType = getOutputFeatureStore().getDefaultFeatureType()
94
                                                                .getDefaultGeometryAttribute().getGeomType().getType();
95
                
96
                //Si el objeto que viene es un GeometryCollection hay que convertirlo a una lista de geometrias
97
                //solo del tipo que pueda salvarse en la capa eliminando el resto. Esto sucede sobre todo en la intersecci?n
98
                //que devuelve tipos mezclados. Cada uno debe salvarse en el tipo de capa de salida apropiado
99
                ArrayList<org.gvsig.fmap.geom.Geometry> dalGeomList = null;
100
                try {
101
                        dalGeomList = convertGeometryCollection2GeometryList(newGeom, outPutType);
102
                } catch (GeometryOperationNotSupportedException e1) {
103
                        Sextante.addErrorToLog(e1);
104
                } catch (GeometryOperationException e1) {
105
                        Sextante.addErrorToLog(e1);
106
                }
107
                org.gvsig.fmap.geom.Geometry newDalGeom = null;
108
                
109
                //Si lo que venia no era un GeometryCollection se convierte a geometr?a de DAL 
110
                if(dalGeomList == null) {
111
                        GeometryOperationContext ctx = new GeometryOperationContext();
112
                        ctx.setAttribute(FromJTS.PARAM, newGeom);
113
                        try {
114
                                newDalGeom = (org.gvsig.fmap.geom.Geometry)geometryManager.invokeOperation(FromJTS.NAME, ctx);
115
                        } catch (GeometryOperationNotSupportedException e) {
116
                                Sextante.addErrorToLog(e);
117
                                return null;
118
                        } catch (GeometryOperationException e) {
119
                                Sextante.addErrorToLog(e);
120
                                return null;
121
                        }
122
                }
123
                
124
                EditableFeature feat = store.createNewFeature();
125
                
126
                int globalIndex = 0;
127
                int localIndex = 0;
128
                Object value = feature1.get(localIndex);
129
                while(value != null && !(value instanceof org.gvsig.fmap.geom.Geometry)) {
130
                        feat.set(globalIndex, value);
131
                        value = feature1.get(++localIndex);
132
                        globalIndex ++;
133
                }
134
                
135
                localIndex = 0;
136
                value = feature2.get(localIndex);
137
                while(value != null && !(value instanceof org.gvsig.fmap.geom.Geometry)) {
138
                        feat.set(globalIndex, value);
139
                        value = feature2.get(++localIndex);
140
                        globalIndex ++;
141
                }
142

    
143
                if(newDalGeom != null && acceptType(store, newDalGeom)) {
144
                        feat.setGeometry("GEOMETRY", convertGeometry2MultiGeometry(newDalGeom));
145
                        store.insert(feat);
146
                        return feat;
147
                } else if(dalGeomList != null) {
148
                        for (int i = 0; i < dalGeomList.size(); i++) {
149
                                if(acceptType(store, dalGeomList.get(i))) {
150
                                        feat.setGeometry("GEOMETRY", convertGeometry2MultiGeometry(dalGeomList.get(i)));
151
                                        store.insert(feat);
152
                                }
153
                        }
154
                        return feat;
155
                }
156
                return null;
157
        }
158
        
159
        /**
160
         * Converts a geometry collection from JTS to a list of geometries of the selected type.
161
         * The GeometryCollection is converted only when it is a heterogeneous collection of geometries 
162
         * @param col
163
         * @param type
164
         * @return
165
         * @throws CreateGeometryException 
166
         * @throws GeometryOperationException 
167
         * @throws GeometryOperationNotSupportedException 
168
         */
169
        public ArrayList<org.gvsig.fmap.geom.Geometry> convertGeometryCollection2GeometryList(Geometry g, int type) throws GeometryOperationNotSupportedException, GeometryOperationException {
170
                if( g instanceof GeometryCollection && 
171
                        !(g instanceof com.vividsolutions.jts.geom.MultiLineString) && 
172
                        !(g instanceof com.vividsolutions.jts.geom.MultiPoint) && 
173
                        !(g instanceof com.vividsolutions.jts.geom.MultiPolygon)) {
174
                        GeometryCollection col = (GeometryCollection)g;
175
                        ArrayList<org.gvsig.fmap.geom.Geometry> geometries = new ArrayList<org.gvsig.fmap.geom.Geometry>();
176
                        
177
                        if(type == TYPES.MULTIPOINT || type == TYPES.POINT) {
178
                                for (int i = 0; i < col.getNumGeometries(); i++) {
179
                                        Geometry gx = col.getGeometryN(i);
180
                                        if( gx instanceof com.vividsolutions.jts.geom.Point || 
181
                                                gx instanceof com.vividsolutions.jts.geom.MultiPoint) {
182
                                                GeometryOperationContext ctx = new GeometryOperationContext();
183
                                                ctx.setAttribute(FromJTS.PARAM, gx);
184
                                                org.gvsig.fmap.geom.Geometry newDalGeom = (org.gvsig.fmap.geom.Geometry)geometryManager.invokeOperation(FromJTS.NAME, ctx);
185
                                                geometries.add(newDalGeom);
186
                                        }
187
                                }
188
                        }
189
                        
190
                        if(type == TYPES.MULTICURVE || type == TYPES.CURVE) {
191
                                for (int i = 0; i < col.getNumGeometries(); i++) {
192
                                        Geometry gx = col.getGeometryN(i);
193
                                        if( gx instanceof com.vividsolutions.jts.geom.LineString || 
194
                                                gx instanceof com.vividsolutions.jts.geom.MultiLineString) {
195
                                                GeometryOperationContext ctx = new GeometryOperationContext();
196
                                                ctx.setAttribute(FromJTS.PARAM, gx);
197
                                                org.gvsig.fmap.geom.Geometry newDalGeom = (org.gvsig.fmap.geom.Geometry)geometryManager.invokeOperation(FromJTS.NAME, ctx);
198
                                                geometries.add(newDalGeom);
199
                                        }
200
                                }
201
                        }
202
                        if(type == TYPES.MULTISURFACE || type == TYPES.SURFACE) {
203
                                for (int i = 0; i < col.getNumGeometries(); i++) {
204
                                        Geometry gx = col.getGeometryN(i);
205
                                        if( gx instanceof com.vividsolutions.jts.geom.Polygon || 
206
                                                gx instanceof com.vividsolutions.jts.geom.MultiPolygon) {
207
                                                GeometryOperationContext ctx = new GeometryOperationContext();
208
                                                ctx.setAttribute(FromJTS.PARAM, gx);
209
                                                org.gvsig.fmap.geom.Geometry newDalGeom = (org.gvsig.fmap.geom.Geometry)geometryManager.invokeOperation(FromJTS.NAME, ctx);
210
                                                geometries.add(newDalGeom);
211
                                        }
212
                                }
213
                        }
214
                        return geometries;
215
                }
216
                return null;
217
        }
218
        
219
        /**
220
         * Converts a geometry into a multigeometry
221
         * @param g
222
         * @return
223
         * @throws CreateGeometryException
224
         */
225
        private org.gvsig.fmap.geom.Geometry convertGeometry2MultiGeometry(org.gvsig.fmap.geom.Geometry g) throws CreateGeometryException {
226
                if(g instanceof Point) {
227
                        MultiPoint pNew = (MultiPoint)geometryManager.create(TYPES.MULTIPOINT, SUBTYPES.GEOM2D);
228
                        pNew.addPoint((Point)g);
229
                        return pNew;
230
                }
231
                if(g instanceof Curve) {
232
                        MultiCurve cNew = (MultiCurve)geometryManager.create(TYPES.MULTICURVE, SUBTYPES.GEOM2D);
233
                        cNew.addCurve((Curve)g);
234
                        return cNew;
235
                }
236
                return g;
237
        }
238
        
239
        /**
240
         * Checks if the type of the feature store and the geometry are compatibles.
241
         * @param store
242
         * @param geom
243
         * @return
244
         * @throws ReadException
245
         */
246
        private boolean acceptType(FeatureStore store, org.gvsig.fmap.geom.Geometry geom) throws ReadException {
247
                int fType = getShapeType(store);
248
                int gType = geom.getType();
249
                
250
                if(fType == gType)
251
                        return true;
252
                if( fType == org.gvsig.fmap.geom.Geometry.TYPES.MULTICURVE &&
253
                        gType == org.gvsig.fmap.geom.Geometry.TYPES.CURVE)
254
                        return true;
255
                if( fType == org.gvsig.fmap.geom.Geometry.TYPES.MULTISURFACE &&
256
                        gType == org.gvsig.fmap.geom.Geometry.TYPES.SURFACE)
257
                        return true;
258
                if( fType == org.gvsig.fmap.geom.Geometry.TYPES.MULTIPOINT &&
259
                        gType == org.gvsig.fmap.geom.Geometry.TYPES.POINT)
260
                        return true;
261
                if( fType == org.gvsig.fmap.geom.Geometry.TYPES.MULTISOLID &&
262
                        gType == org.gvsig.fmap.geom.Geometry.TYPES.SOLID)
263
                                return true;
264
                return false;
265
        }
266

    
267
        /**
268
         * Adds a JTS feature to the FeatureStore
269
         * @param entry
270
         * @param newGeom
271
         * @throws CreateGeometryException
272
         * @throws DataException
273
         */
274
        public EditableFeature addFeature(Feature feature, Geometry newGeom) throws CreateGeometryException, DataException {
275
                org.gvsig.fmap.geom.Geometry newDalGeom = null;
276
                        
277
                GeometryOperationContext ctx = new GeometryOperationContext();
278
                ctx.setAttribute(FromJTS.PARAM, newGeom);
279
                try {
280
                        newDalGeom = (org.gvsig.fmap.geom.Geometry)geometryManager.invokeOperation(FromJTS.NAME, ctx);
281
                } catch (GeometryOperationNotSupportedException e) {
282
                        Sextante.addErrorToLog(e);
283
                        return null;
284
                } catch (GeometryOperationException e) {
285
                        Sextante.addErrorToLog(e);
286
                        return null;
287
                }
288

    
289
                if(acceptType(store, newDalGeom)) {
290
                        EditableFeature feat = store.createNewFeature(store.getDefaultFeatureType(), true);
291
                        FeatureAttributeDescriptor[] attrDesc = feature.getType().getAttributeDescriptors();
292
                        for (int i = 0; i < attrDesc.length; i++) {
293
                                String name = attrDesc[i].getName();
294
                                if(name.compareTo("GEOMETRY") != 0) {
295
                                        Object value = feature.get(name);
296
                                        if(value != null) {
297
                                                feat.set(name, value);
298
                                        }
299
                                }
300
                        }
301
                        feat.setGeometry("GEOMETRY", convertGeometry2MultiGeometry(newDalGeom));
302
                        store.insert(feat);
303
                        return feat;
304
                }
305
                return null;
306
        }
307
        
308
        /**
309
         * Adds a JTS feature to the FeatureStore
310
         * @param entry
311
         * @param newGeom
312
         * @throws CreateGeometryException
313
         * @throws DataException
314
         */
315
        public EditableFeature addFeature(Geometry newGeom, int id, double value) throws CreateGeometryException, DataException {
316
                org.gvsig.fmap.geom.Geometry newDalGeom = GeometryUtil.jtsToGeom(newGeom);
317

    
318
                if(newDalGeom != null && acceptType(store, newDalGeom)) {
319
                        EditableFeature feat = store.createNewFeature();
320
                        feat.set(0, id);
321
                        feat.set(1, value);
322
                        feat.setGeometry("GEOMETRY", convertGeometry2MultiGeometry(newDalGeom));
323
                        store.insert(feat);
324
                        return feat;
325
                }
326
                return null;
327
        }
328
        
329
        /**
330
         * Adds a JTS feature to the FeatureStore
331
         * @param entry
332
         * @param newGeom
333
         * @throws CreateGeometryException
334
         * @throws DataException
335
         */
336
        public EditableFeature addFeature(Geometry newGeom, int id, double value1, double value2) throws CreateGeometryException, DataException {
337
                org.gvsig.fmap.geom.Geometry newDalGeom = GeometryUtil.jtsToGeom(newGeom);
338

    
339
                if(newDalGeom != null && acceptType(store, newDalGeom)) {
340
                        EditableFeature feat = store.createNewFeature();
341
                        feat.set(0, id);
342
                        feat.set(1, value1);
343
                        feat.set(2, value2);
344
                        feat.setGeometry("GEOMETRY", convertGeometry2MultiGeometry(newDalGeom));
345
                        store.insert(feat);
346
                        return feat;
347
                }
348
                return null;
349
        }
350
        
351
        /**
352
         * Adds a DAL feature to the FeatureStore when the field structure in the new feature 
353
         * is different to the source field structure.
354
         * @param entry
355
         * @param newGeom
356
         * @throws CreateGeometryException
357
         * @throws DataException
358
         */
359
        public EditableFeature addDifferentFieldFeature(Feature feature, org.gvsig.fmap.geom.Geometry newGeom) throws CreateGeometryException, DataException {
360
                if(acceptType(store, newGeom)) {
361
                        //Builds a new empty feature
362
                        EditableFeature feat = store.createNewFeature(store.getDefaultFeatureType(), true);
363
                        
364
                        //Writes only values with the same name and data type in both features
365
                        for (int i = 0; i < fieldNames.length; i++) {
366
                                if(feature.getType().getIndex(fieldNames[i]) != -1) {
367
                                        Object obj1 = feature.get(fieldNames[i]);
368
                                        if(feat.getType().getIndex(fieldNames[i]) != -1) {
369
                                                Object obj2 = feat.get(fieldNames[i]);
370
                                                if(obj1 != null && obj2 != null && obj1.getClass() == obj2.getClass())
371
                                                        feat.set(i, obj1);
372
                                        }
373
                                }
374
                        }
375
                        
376
                        //Sets the geometry
377
                        feat.setGeometry(fieldNames.length, newGeom);
378
                        store.insert(feat);
379
                        return feat;
380
                }
381
                return null;
382
        }
383
        
384
        /**
385
         * Adds a DAL feature to the FeatureStore
386
         * @param entry
387
         * @param newGeom
388
         * @throws CreateGeometryException
389
         * @throws DataException
390
         */
391
        public EditableFeature addFeature(Feature feature, org.gvsig.fmap.geom.Geometry newGeom) throws CreateGeometryException, DataException {
392
                if(acceptType(store, newGeom)) {
393
                        EditableFeature feat = store.createNewFeature(store.getDefaultFeatureType(), feature);
394
                        feat.setGeometry(fieldNames.length, convertGeometry2MultiGeometry(newGeom));
395
                        store.insert(feat);
396
                        return feat;
397
                }
398
                return null;
399
        }
400
        
401
        /**
402
         * Adds a DAL feature to the FeatureStore
403
         * @param entry
404
         * @param newGeom
405
         * @throws CreateGeometryException
406
         * @throws DataException
407
         */
408
        public EditableFeature addGeometryToExistingFeature(EditableFeature feature, org.gvsig.fmap.geom.Geometry newGeom) throws CreateGeometryException, DataException {
409
                //Y esto para que c... sirve?
410
                for (int i = 0; i < fieldNames.length; i++) 
411
                        feature.set(fieldNames[i], feature.get(i));
412
                
413
                if(acceptType(store, newGeom)) {
414
                        feature.setGeometry(fieldNames.length, newGeom);
415
                        store.update(feature);
416
                        return feature;
417
                }
418
                return null;
419
        }
420
        
421
        /**
422
         * Ends the edition and closes the FeatureStore
423
         */
424
        public void end() {
425
                try {
426
                        store.finishEditing();
427
                } catch (DataException e) {
428
                        Sextante.addErrorToLog(e);
429
                }
430
                store.dispose();
431
        }
432
        
433
        /**
434
         * Gets the shape type of the selected feature store
435
         * @param FeatureStore source
436
         * @return shape type
437
         * @throws ReadException
438
         */
439
        public int getShapeType(FeatureStore storeLayer1) throws ReadException {
440
                FeatureType featureType;
441
                try {
442
                        featureType = storeLayer1.getDefaultFeatureType();
443
                } catch (DataException e) {
444
                        throw new ReadException(storeLayer1.getName(), e);
445
                }
446
                int indexGeom = featureType.getDefaultGeometryAttributeIndex();
447
                return featureType.getAttributeDescriptor(indexGeom).getGeometryType();
448
        }
449
        
450
        /**
451
         * Gets the output FeatureStore
452
         * @return
453
         */
454
        public FeatureStore getOutputFeatureStore() {
455
                return store;
456
        }
457
}
458