Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / 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 @ 40490

History | View | Annotate | Download (19.5 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.dal.store.shp.SHPStoreParameters;
54
import org.gvsig.fmap.geom.Geometry;
55
import org.gvsig.fmap.geom.GeometryLocator;
56
import org.gvsig.fmap.geom.GeometryManager;
57
import org.gvsig.fmap.geom.aggregate.Aggregate;
58
import org.gvsig.fmap.geom.exception.CreateGeometryException;
59
import org.gvsig.fmap.geom.operation.GeometryOperationException;
60
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
61
import org.gvsig.fmap.geom.primitive.Curve;
62
import org.gvsig.fmap.geom.primitive.Point;
63
import org.gvsig.fmap.geom.primitive.Surface;
64
import org.gvsig.fmap.geom.type.GeometryType;
65
import org.gvsig.tools.dispose.DisposableIterator;
66
import org.gvsig.tools.dispose.DisposeUtils;
67
import org.gvsig.tools.task.AbstractMonitorableTask;
68

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

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

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

    
89
    private ExporttoServiceFinishAction exporttoServiceFinishAction;
90

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

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

    
101
        ExporttoServiceException throw_exp = null;
102
        File item_shp = null;
103
        String pathFile = theShapeFile.getAbsolutePath();
104
        String withoutShp = pathFile.replaceAll("\\.shp", "");
105
        
106
        File single_file = new File(withoutShp + ".shp");
107
        
108
        String layer_name = single_file.getName();
109
        int lastp = layer_name.lastIndexOf(".shp");
110
        if (lastp > -1) {
111
            layer_name = layer_name.substring(0, lastp);
112
        }
113
        
114
        initializeParams(featureSet, single_file);
115

    
116
        if (geometryType == Geometry.TYPES.GEOMETRY) {
117
            // POINT
118
            String fileName = withoutShp + "_point" + ".shp";
119
            item_shp = new File(fileName);
120
            initializeParams(featureSet, item_shp);
121
            
122
            newFeatureStoreParameters.setDynValue("shpfile", item_shp);
123
            taskStatus.setTittle("Exporting points");
124
            
125
            try {
126
                export(filesystemServerExplorer, newFeatureStoreParameters,
127
                    featureSet, Geometry.TYPES.POINT, true);
128
            } catch (ExporttoServiceException ee) {
129
                throw_exp = ee;
130
            }
131
            
132
            finishAction(layer_name + " (point)", item_shp, projection);
133

    
134
            // CURVE
135
            fileName = withoutShp + "_curve" + ".shp";
136
            item_shp = new File(fileName);
137
            initializeParams(featureSet, item_shp);
138
            newFeatureStoreParameters.setDynValue("shpfile", item_shp);
139
            taskStatus.setTittle("Exporting curves");
140
            
141
            try {
142
                export(filesystemServerExplorer, newFeatureStoreParameters,
143
                    featureSet, Geometry.TYPES.CURVE, true);
144
            } catch (ExporttoServiceException ee) {
145
                throw_exp = ee;
146
            }
147
            
148
            finishAction(layer_name + " (curve)", item_shp, projection);
149

    
150
            // SURFACE
151
            fileName = withoutShp + "_surface" + ".shp";
152
            item_shp = new File(fileName);
153
            initializeParams(featureSet, item_shp);
154
            newFeatureStoreParameters.setDynValue("shpfile", item_shp);
155
            taskStatus.setTittle("Exporting surfaces");
156
            
157
            try {
158
                export(filesystemServerExplorer, newFeatureStoreParameters,
159
                    featureSet, Geometry.TYPES.SURFACE, true);
160
            } catch (ExporttoServiceException ee) {
161
                throw_exp = ee;
162
            }
163
            finishAction(layer_name + " (surface)", item_shp, projection);
164

    
165
        } else {
166
            
167
            // params already initialized
168
            newFeatureStoreParameters.setDynValue("shpfile", single_file);
169
            try {
170
                export(filesystemServerExplorer, newFeatureStoreParameters,
171
                    featureSet, geometryType, false);
172
            } catch (ExporttoServiceException ee) {
173
                throw_exp = ee;
174
            }
175
            finishAction(layer_name, single_file, projection);
176
        }
177
        this.taskStatus.terminate();
178
        this.taskStatus.remove();
179
        
180
        if (throw_exp != null) {
181
            throw throw_exp;
182
        }
183
    }
184

    
185
    private void initializeParams(
186
        FeatureSet featureSet, File out_shp_file)
187
        throws ExporttoServiceException {
188

    
189
        DataManager dataManager = DALLocator.getDataManager();
190

    
191
        FilesystemServerExplorerParameters explorerParams;
192
        try {
193
            explorerParams =
194
                (FilesystemServerExplorerParameters) dataManager
195
                    .createServerExplorerParameters(FilesystemServerExplorer.NAME);
196
        } catch (InitializeException e) {
197
            throw new ExporttoServiceException(e);
198
        } catch (ProviderNotRegisteredException e) {
199
            throw new ExporttoServiceException(e);
200
        }
201
        explorerParams.setRoot(out_shp_file.getParent());
202

    
203
        try {
204
            filesystemServerExplorer =
205
                (FilesystemServerExplorer) dataManager.openServerExplorer(
206
                    "FilesystemExplorer", explorerParams);
207
        } catch (ValidateDataParametersException e) {
208
            throw new ExporttoServiceException(e);
209
        } catch (InitializeException e) {
210
            throw new ExporttoServiceException(e);
211
        } catch (ProviderNotRegisteredException e) {
212
            throw new ExporttoServiceException(e);
213
        }
214

    
215
        try {
216
            newFeatureStoreParameters =
217
                (NewFeatureStoreParameters) filesystemServerExplorer
218
                    .getAddParameters(out_shp_file);
219
        } catch (DataException e) {
220
            throw new ExporttoServiceException(e);
221
        }
222

    
223
        newFeatureStoreParameters.setDynValue("CRS", projection);
224

    
225
        geometryType =
226
            featureSet.getDefaultFeatureType().getDefaultGeometryAttribute()
227
                .getGeomType().getType();
228

    
229
    }
230

    
231
    private void export(FilesystemServerExplorer explorer,
232
        NewFeatureStoreParameters params, FeatureSet featureSet,
233
        int geometryType, boolean checkType) throws ExporttoServiceException {
234

    
235
        String providerName = params.getDataStoreName();
236
        String explorerName = explorer.getProviderName();
237
        boolean there_was_error = false;
238

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

    
267
            DataManager manager = DALLocator.getDataManager();
268

    
269
            manager.newStore(explorerName, providerName, params, true);
270
            FeatureStore target =
271
                (FeatureStore) manager.openStore(providerName, params);
272

    
273
            FeatureType targetType = target.getDefaultFeatureType();
274

    
275
            taskStatus.setRangeOfValues(0, featureSet.getSize());
276

    
277
            target.edit(FeatureStore.MODE_APPEND);
278
            it = featureSet.fastIterator();
279
            int featureCount = 0;
280

    
281
            // ================================================
282
            // Reprojection stuff
283
            Geometry reproj_geom = null;
284
            EditableFeature edit_feat = null;
285
            IProjection sourceProjection =
286
                featureStore.getDefaultFeatureType().getDefaultGeometryAttribute().getSRS();
287

    
288
            ICoordTrans coord_trans = null;
289
            // this comparison is perhaps too preventive
290
            // we could  have two instances of same projection
291
            // so we would do more computations than needed
292
            if (sourceProjection != this.projection) {
293
                coord_trans = sourceProjection.getCT(this.projection); 
294
            }
295
            // ================================================
296

    
297
            List<Geometry> extracted = null;
298
            Geometry gitem = null;
299
            
300
            while (it.hasNext()) {
301
                
302
                Feature feature = (Feature) it.next();
303
                gitem = feature.getDefaultGeometry();
304

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

    
332
                for (int i=0; i<extracted.size(); i++) {
333
                    gitem = extracted.get(i);
334
                    gitem = force2D(gitem, geometryType);
335
                    edit_feat = target.createNewFeature(true);
336
                    there_was_error = there_was_error |
337
                        // accumulate error boolean
338
                        setNonNulls(targetType, feature, edit_feat);
339
                    edit_feat.setDefaultGeometry(gitem);
340
                    // ================================================
341
                    // Reprojection stuff
342
                    if (coord_trans != null) {
343
                        reproj_geom = edit_feat.getDefaultGeometry();
344
                        reproj_geom = reproj_geom.cloneGeometry();
345
                        reproj_geom.reProject(coord_trans);
346
                        edit_feat.setDefaultGeometry(reproj_geom);
347
                    }
348
                    // ================================================
349
                    target.insert(edit_feat);
350
                }
351

    
352
                featureCount++;
353
                this.taskStatus.setCurValue(featureCount);
354

    
355
                if (this.taskStatus.isCancellationRequested()) {
356
                    return;
357
                }
358
            }
359
            target.finishEditing();
360
            target.dispose();
361
        } catch (Exception e) {
362
            throw new ExporttoServiceException(e);
363
        } finally {
364
            DisposeUtils.dispose(it);
365
        }
366
        
367
        if (there_was_error) {
368
            Exception cause = new Exception(
369
                "_Issues_with_attributes_or_geometries");
370
            throw new ExporttoServiceException(cause);
371
        }
372
    }
373

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

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

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

    
500
    private void finishAction(String layerName, File shp_file, IProjection proj)
501
    throws ExporttoServiceException {
502
        
503
        
504
        
505
        
506
        
507
        if (exporttoServiceFinishAction != null) {
508
            
509
            /*
510
             * Export is done. We notify with a SHPStoreParameters,
511
             * not with the NewSHPParameters we have used:
512
             */
513
            
514
            
515
            SHPStoreParameters shp_params = new SHPStoreParameters();
516
            
517
            
518
            shp_params.setSHPFile(shp_file);
519
            shp_params.setCRS(proj);
520
            shp_params.fixParameters();
521
            try {
522
                shp_params.validate();
523
            } catch (ValidateDataParametersException e) {
524
                throw new ExporttoServiceException(e);
525
            }
526
            exporttoServiceFinishAction.finished(layerName, shp_params);
527
        }
528
    }
529

    
530
    public void setFinishAction(
531
        ExporttoServiceFinishAction exporttoServiceFinishAction) {
532
        this.exporttoServiceFinishAction = exporttoServiceFinishAction;
533
    }
534
}