Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2057 / 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 @ 39182

History | View | Annotate | Download (18.8 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
        
107
        String layer_name = single_file.getName();
108
        int lastp = layer_name.lastIndexOf(".shp");
109
        if (lastp > -1) {
110
            layer_name = layer_name.substring(0, lastp);
111
        }
112
        
113
        initializeParams(featureSet, single_file);
114

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

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

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

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

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

    
188
        DataManager dataManager = DALLocator.getDataManager();
189

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

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

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

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

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

    
228
    }
229

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

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

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

    
266
            DataManager manager = DALLocator.getDataManager();
267

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

    
272
            FeatureType targetType = target.getDefaultFeatureType();
273

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

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

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

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

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

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

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

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

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

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

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

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

    
499
    private void finishAction(String layerName,
500
        NewFeatureStoreParameters newFeatureStoreParameters) {
501
        if (exporttoServiceFinishAction != null) {
502
            exporttoServiceFinishAction.finished(layerName,
503
                newFeatureStoreParameters);
504
        }
505
    }
506

    
507
    public void setFinishAction(
508
        ExporttoServiceFinishAction exporttoServiceFinishAction) {
509
        this.exporttoServiceFinishAction = exporttoServiceFinishAction;
510
    }
511
}