Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / org.gvsig.exportto / org.gvsig.exportto.swing / org.gvsig.exportto.swing.prov / org.gvsig.exportto.swing.prov.shape / src / main / java / org / gvsig / exportto / swing / prov / shape / ExporttoShapeService.java @ 39101

History | View | Annotate | Download (18.6 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
package org.gvsig.exportto.swing.prov.shape;
23

    
24
import java.io.File;
25
import java.util.ArrayList;
26
import java.util.List;
27

    
28
import org.cresques.cts.ICoordTrans;
29
import org.cresques.cts.IProjection;
30
import org.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32

    
33
import org.gvsig.exportto.ExporttoService;
34
import org.gvsig.exportto.ExporttoServiceException;
35
import org.gvsig.exportto.ExporttoServiceFinishAction;
36
import org.gvsig.fmap.dal.DALLocator;
37
import org.gvsig.fmap.dal.DataManager;
38
import org.gvsig.fmap.dal.exception.DataException;
39
import org.gvsig.fmap.dal.exception.InitializeException;
40
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
41
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
42
import org.gvsig.fmap.dal.feature.EditableFeature;
43
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
44
import org.gvsig.fmap.dal.feature.EditableFeatureType;
45
import org.gvsig.fmap.dal.feature.Feature;
46
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
47
import org.gvsig.fmap.dal.feature.FeatureSet;
48
import org.gvsig.fmap.dal.feature.FeatureStore;
49
import org.gvsig.fmap.dal.feature.FeatureType;
50
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
51
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
52
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
53
import org.gvsig.fmap.geom.Geometry;
54
import org.gvsig.fmap.geom.GeometryLocator;
55
import org.gvsig.fmap.geom.GeometryManager;
56
import org.gvsig.fmap.geom.aggregate.Aggregate;
57
import org.gvsig.fmap.geom.exception.CreateGeometryException;
58
import org.gvsig.fmap.geom.operation.GeometryOperationException;
59
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
60
import org.gvsig.fmap.geom.primitive.Curve;
61
import org.gvsig.fmap.geom.primitive.Point;
62
import org.gvsig.fmap.geom.primitive.Surface;
63
import org.gvsig.fmap.geom.type.GeometryType;
64
import org.gvsig.tools.dispose.DisposableIterator;
65
import org.gvsig.tools.dispose.DisposeUtils;
66
import org.gvsig.tools.task.AbstractMonitorableTask;
67

    
68
/**
69
 * @author gvSIG Team
70
 * @version $Id$
71
 * 
72
 */
73
public class ExporttoShapeService extends AbstractMonitorableTask implements
74
    ExporttoService {
75

    
76
    private static Logger logger = LoggerFactory.getLogger(ExporttoShapeService.class);
77
    
78
    private File theShapeFile;
79
    private IProjection projection;
80
    private FeatureStore featureStore;
81

    
82
    private int geometryType = -1;
83
    private NewFeatureStoreParameters newFeatureStoreParameters;
84
    private FilesystemServerExplorer filesystemServerExplorer;
85
    
86
    private static GeometryManager geoManager = GeometryLocator.getGeometryManager();
87

    
88
    private ExporttoServiceFinishAction exporttoServiceFinishAction;
89

    
90
    public ExporttoShapeService(File shapeFile, FeatureStore featureStore,
91
        IProjection projection) {
92
        super("Export to shape");
93
        this.featureStore = featureStore;
94
        this.theShapeFile = shapeFile;
95
        this.projection = projection;
96
    }
97

    
98
    public void export(FeatureSet featureSet) throws ExporttoServiceException {
99

    
100
        ExporttoServiceException throw_exp = null;
101
        File item_shp = null;
102
        String pathFile = theShapeFile.getAbsolutePath();
103
        String withoutShp = pathFile.replaceAll("\\.shp", "");
104
        
105
        File single_file = new File(withoutShp + ".shp");
106
        initializeParams(featureSet, single_file);
107

    
108
        if (geometryType == Geometry.TYPES.GEOMETRY) {
109
            // POINT
110
            String fileName = withoutShp + "_point" + ".shp";
111
            item_shp = new File(fileName);
112
            initializeParams(featureSet, item_shp);
113
            
114
            newFeatureStoreParameters.setDynValue("shpfile", item_shp);
115
            taskStatus.setTittle("Exporting points");
116
            
117
            try {
118
                export(filesystemServerExplorer, newFeatureStoreParameters,
119
                    featureSet, Geometry.TYPES.POINT, true);
120
            } catch (ExporttoServiceException ee) {
121
                throw_exp = ee;
122
            }
123
            
124
            finishAction(fileName, newFeatureStoreParameters);
125

    
126
            // CURVE
127
            fileName = withoutShp + "_curve" + ".shp";
128
            item_shp = new File(fileName);
129
            initializeParams(featureSet, item_shp);
130
            newFeatureStoreParameters.setDynValue("shpfile", item_shp);
131
            taskStatus.setTittle("Exporting curves");
132
            
133
            try {
134
                export(filesystemServerExplorer, newFeatureStoreParameters,
135
                    featureSet, Geometry.TYPES.CURVE, true);
136
            } catch (ExporttoServiceException ee) {
137
                throw_exp = ee;
138
            }
139
            
140
            finishAction(fileName, newFeatureStoreParameters);
141

    
142
            // SURFACE
143
            fileName = withoutShp + "_surface" + ".shp";
144
            item_shp = new File(fileName);
145
            initializeParams(featureSet, item_shp);
146
            newFeatureStoreParameters.setDynValue("shpfile", item_shp);
147
            taskStatus.setTittle("Exporting surfaces");
148
            
149
            try {
150
                export(filesystemServerExplorer, newFeatureStoreParameters,
151
                    featureSet, Geometry.TYPES.SURFACE, true);
152
            } catch (ExporttoServiceException ee) {
153
                throw_exp = ee;
154
            }
155
            finishAction(fileName, newFeatureStoreParameters);
156

    
157
        } else {
158
            
159
            // params already initialized
160
            newFeatureStoreParameters.setDynValue("shpfile", single_file);
161
            try {
162
                export(filesystemServerExplorer, newFeatureStoreParameters,
163
                    featureSet, geometryType, false);
164
            } catch (ExporttoServiceException ee) {
165
                throw_exp = ee;
166
            }
167
            finishAction(single_file.getName(), newFeatureStoreParameters);
168
        }
169
        this.taskStatus.terminate();
170
        this.taskStatus.remove();
171
        
172
        if (throw_exp != null) {
173
            throw throw_exp;
174
        }
175
    }
176

    
177
    private void initializeParams(
178
        FeatureSet featureSet, File out_shp_file)
179
        throws ExporttoServiceException {
180

    
181
        DataManager dataManager = DALLocator.getDataManager();
182

    
183
        FilesystemServerExplorerParameters explorerParams;
184
        try {
185
            explorerParams =
186
                (FilesystemServerExplorerParameters) dataManager
187
                    .createServerExplorerParameters(FilesystemServerExplorer.NAME);
188
        } catch (InitializeException e) {
189
            throw new ExporttoServiceException(e);
190
        } catch (ProviderNotRegisteredException e) {
191
            throw new ExporttoServiceException(e);
192
        }
193
        explorerParams.setRoot(out_shp_file.getParent());
194

    
195
        try {
196
            filesystemServerExplorer =
197
                (FilesystemServerExplorer) dataManager.openServerExplorer(
198
                    "FilesystemExplorer", explorerParams);
199
        } catch (ValidateDataParametersException e) {
200
            throw new ExporttoServiceException(e);
201
        } catch (InitializeException e) {
202
            throw new ExporttoServiceException(e);
203
        } catch (ProviderNotRegisteredException e) {
204
            throw new ExporttoServiceException(e);
205
        }
206

    
207
        try {
208
            newFeatureStoreParameters =
209
                (NewFeatureStoreParameters) filesystemServerExplorer
210
                    .getAddParameters(out_shp_file);
211
        } catch (DataException e) {
212
            throw new ExporttoServiceException(e);
213
        }
214

    
215
        newFeatureStoreParameters.setDynValue("CRS", projection);
216

    
217
        geometryType =
218
            featureSet.getDefaultFeatureType().getDefaultGeometryAttribute()
219
                .getGeomType().getType();
220

    
221
    }
222

    
223
    private void export(FilesystemServerExplorer explorer,
224
        NewFeatureStoreParameters params, FeatureSet featureSet,
225
        int geometryType, boolean checkType) throws ExporttoServiceException {
226

    
227
        String providerName = params.getDataStoreName();
228
        String explorerName = explorer.getProviderName();
229
        boolean there_was_error = false;
230

    
231
        DisposableIterator it = null;
232
        try {
233
            EditableFeatureType type =
234
                featureStore.getDefaultFeatureType().getEditable();
235
            FeatureAttributeDescriptor fad =
236
                (FeatureAttributeDescriptor) type.get(type
237
                    .getDefaultGeometryAttributeName());
238
            type.remove(fad.getName());
239
            EditableFeatureAttributeDescriptor efad =
240
                type.add(fad.getName(), fad.getType(), fad.getSize());
241
            efad.setDefaultValue(fad.getDefaultValue());
242
            
243
            GeometryType gty = null;
244
            try {
245
                gty = geoManager.getGeometryType(
246
                    geometryType, Geometry.SUBTYPES.GEOM2D);
247
            } catch (Exception e) {
248
                throw new ExporttoServiceException(e);
249
            }
250
            
251
            efad.setGeometryType(gty);
252
            
253
            efad.setPrecision(fad.getPrecision());
254
            type.setDefaultGeometryAttributeName(fad.getName());
255
            params.setDefaultFeatureType(type);
256
            
257
            params.setDynValue("geometryType", null);
258

    
259
            DataManager manager = DALLocator.getDataManager();
260

    
261
            manager.newStore(explorerName, providerName, params, true);
262
            FeatureStore target =
263
                (FeatureStore) manager.openStore(providerName, params);
264

    
265
            FeatureType targetType = target.getDefaultFeatureType();
266

    
267
            taskStatus.setRangeOfValues(0, featureSet.getSize());
268

    
269
            target.edit(FeatureStore.MODE_APPEND);
270
            it = featureSet.fastIterator();
271
            int featureCount = 0;
272

    
273
            // ================================================
274
            // Reprojection stuff
275
            Geometry reproj_geom = null;
276
            EditableFeature edit_feat = null;
277
            IProjection sourceProjection =
278
                featureStore.getDefaultFeatureType().getDefaultGeometryAttribute().getSRS();
279

    
280
            ICoordTrans coord_trans = null;
281
            // this comparison is perhaps too preventive
282
            // we could  have two instances of same projection
283
            // so we would do more computations than needed
284
            if (sourceProjection != this.projection) {
285
                coord_trans = sourceProjection.getCT(this.projection); 
286
            }
287
            // ================================================
288

    
289
            List<Geometry> extracted = null;
290
            Geometry gitem = null;
291
            
292
            while (it.hasNext()) {
293
                
294
                Feature feature = (Feature) it.next();
295
                gitem = feature.getDefaultGeometry();
296

    
297
                if (checkType) {
298
                    extracted = getGeometriesFrom(gitem, geometryType);
299
                    if (extracted.size() == 0) {
300
                        // found no geometries of correct type
301
                        continue;
302
                    } else {
303
                        if (geometryType != Geometry.TYPES.POINT) {
304
                            // If not points, merge geometries
305
                            // (curves or surfaces)
306
                            try {
307
                                gitem = union(extracted);
308
                                extracted = new ArrayList<Geometry>();
309
                                extracted.add(gitem);
310
                            } catch (Exception ex) {
311
                                there_was_error = true;
312
                                logger.info("Error in union.", ex);
313
                            }
314
                        } else {
315
                            // only in the case of points, we can have several
316
                            // geometries if source is multipoint
317
                        }
318
                    }
319
                } else {
320
                    extracted = new ArrayList<Geometry>();
321
                    extracted.add(gitem);
322
                }
323

    
324
                for (int i=0; i<extracted.size(); i++) {
325
                    gitem = extracted.get(i);
326
                    gitem = force2D(gitem, geometryType);
327
                    edit_feat = target.createNewFeature(true);
328
                    there_was_error = there_was_error |
329
                        // accumulate error boolean
330
                        setNonNulls(targetType, feature, edit_feat);
331
                    edit_feat.setDefaultGeometry(gitem);
332
                    // ================================================
333
                    // Reprojection stuff
334
                    if (coord_trans != null) {
335
                        reproj_geom = edit_feat.getDefaultGeometry();
336
                        reproj_geom = reproj_geom.cloneGeometry();
337
                        reproj_geom.reProject(coord_trans);
338
                        edit_feat.setDefaultGeometry(reproj_geom);
339
                    }
340
                    // ================================================
341
                    target.insert(edit_feat);
342
                }
343

    
344
                featureCount++;
345
                this.taskStatus.setCurValue(featureCount);
346

    
347
                if (this.taskStatus.isCancellationRequested()) {
348
                    return;
349
                }
350
            }
351
            target.finishEditing();
352
            target.dispose();
353
        } catch (Exception e) {
354
            throw new ExporttoServiceException(e);
355
        } finally {
356
            DisposeUtils.dispose(it);
357
        }
358
        
359
        if (there_was_error) {
360
            Exception cause = new Exception(
361
                "_Issues_with_attributes_or_geometries");
362
            throw new ExporttoServiceException(cause);
363
        }
364
    }
365

    
366
    
367
    /**
368
     * @param gitem
369
     * @param geometryType2
370
     * @return
371
     */
372
    private Geometry force2D(Geometry ge, int gt) throws CreateGeometryException {
373
        
374
        if (ge.getGeometryType().getSubType() == Geometry.SUBTYPES.GEOM2D) {
375
            return ge;
376
        } else {
377
            switch (gt) {
378
            case Geometry.TYPES.POINT:
379
                Point p = (Point) ge;
380
                return geoManager.createPoint(
381
                    p.getX(), p.getY(),
382
                    Geometry.SUBTYPES.GEOM2D);
383
            case Geometry.TYPES.CURVE:
384
                return geoManager.createCurve(ge.getGeneralPath(), Geometry.SUBTYPES.GEOM2D);
385
            case Geometry.TYPES.SURFACE:
386
                return geoManager.createSurface(ge.getGeneralPath(), Geometry.SUBTYPES.GEOM2D);
387
            default:
388
                return ge;
389
            }
390
        }
391
    }
392

    
393
    /**
394
     * @param feature
395
     * @param edit_feat
396
     */
397
    private boolean setNonNulls(
398
        FeatureType ft,
399
        Feature feat, EditableFeature edit_f) {
400
        
401
        boolean error = false;
402
        FeatureAttributeDescriptor[] atts = ft.getAttributeDescriptors();
403
        for (int i=0; i<atts.length; i++) {
404
            if (atts[i].getType() != org.gvsig.fmap.geom.DataTypes.GEOMETRY) {
405
                
406
                Object val = null;
407
                
408
                try {
409
                    val = feat.get(atts[i].getName());
410
                    if (val != null) {
411
                        edit_f.set(
412
                            atts[i].getName(),
413
                            feat.get(atts[i].getName()));
414
                    }
415
                } catch (Exception ex) {
416
                    logger.info("Error while getting/setting value", ex);
417
                    error = true;
418
                }
419
            }
420
        }
421
        return error;
422
    }
423

    
424
    private Geometry union(List<Geometry> geoms)
425
        throws GeometryOperationNotSupportedException, GeometryOperationException {
426
        
427
        if (geoms == null || geoms.size() == 0) {
428
            return null;
429
        }
430
        
431
        if (geoms.size() == 1) {
432
            return geoms.get(0);
433
        }
434
        
435
        Geometry resp = geoms.get(0);
436
        for (int i=1; i<geoms.size(); i++) {
437
            resp = resp.union(geoms.get(i));
438
        }
439
        return resp;
440
    }
441
    /**
442
     * @param feat_geom_type
443
     * @param type must be POINT, LINE or POLYGON (Geometry.TYPES)
444
     * @return
445
     */
446
    private List<Geometry> getGeometriesFrom(Geometry in_geom, int type) {
447
        
448
        List<Geometry> resp = new ArrayList<Geometry>();
449
        Aggregate agg = null;
450
        
451
        /*
452
         * If input geometry is aggregate, search its
453
         * primitives
454
         */
455
        if (in_geom instanceof Aggregate) {
456
            agg = (Aggregate) in_geom;
457
            Geometry item = null;
458
            List<Geometry> add_parts = new ArrayList<Geometry>();
459
            for (int i=0; i<agg.getPrimitivesNumber(); i++) {
460
                item = agg.getPrimitiveAt(i);
461
                add_parts = getGeometriesFrom(item, type);
462
                resp.addAll(add_parts);
463
            }
464
            return resp;
465
        }
466
        
467
        // ============================================
468
        
469
        switch (type) {
470
        case Geometry.TYPES.POINT:
471
            if (in_geom instanceof Point) {
472
                resp.add(in_geom);
473
            }
474
            // =======================================================
475
            break;
476
        case Geometry.TYPES.CURVE:
477
            if (in_geom instanceof Curve) {
478
                resp.add(in_geom);
479
            }
480
            // =======================================================
481
            break;
482
        case Geometry.TYPES.SURFACE:
483
            if (in_geom instanceof Surface) {
484
                resp.add(in_geom);
485
            }
486
            // =======================================================
487
            break;
488
        }
489
        return resp;
490
    }
491

    
492
    private void finishAction(String layerName,
493
        NewFeatureStoreParameters newFeatureStoreParameters) {
494
        if (exporttoServiceFinishAction != null) {
495
            exporttoServiceFinishAction.finished(layerName,
496
                newFeatureStoreParameters);
497
        }
498
    }
499

    
500
    public void setFinishAction(
501
        ExporttoServiceFinishAction exporttoServiceFinishAction) {
502
        this.exporttoServiceFinishAction = exporttoServiceFinishAction;
503
    }
504
}