Statistics
| Revision:

svn-gvsig-desktop / trunk / prototypes / mobile / desktop / extensions / extExportMobile / src / es / prodevelop / gvsig / exportMobile / layerexporters / VectorialExporterTask.java @ 19196

History | View | Annotate | Download (18.1 KB)

1
package es.prodevelop.gvsig.exportMobile.layerexporters;
2

    
3
import java.awt.geom.Point2D;
4
import java.awt.geom.Rectangle2D;
5
import java.io.File;
6
import java.io.IOException;
7

    
8
import org.apache.log4j.Logger;
9
import org.cresques.cts.ICoordTrans;
10

    
11
import com.hardcode.driverManager.Driver;
12
import com.hardcode.gdbms.engine.values.Value;
13
import com.iver.andami.PluginServices;
14
import com.iver.cit.gvsig.fmap.DriverException;
15
import com.iver.cit.gvsig.fmap.core.DefaultFeature;
16
import com.iver.cit.gvsig.fmap.core.FShape;
17
import com.iver.cit.gvsig.fmap.core.IFeature;
18
import com.iver.cit.gvsig.fmap.core.IGeometry;
19
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
20
import com.iver.cit.gvsig.fmap.core.v02.FLabel;
21
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
22
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
23
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
24
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition;
25
import com.iver.cit.gvsig.fmap.drivers.SHPLayerDefinition;
26
import com.iver.cit.gvsig.fmap.drivers.shp.IndexedShpDriver;
27
import com.iver.cit.gvsig.fmap.edition.DefaultRowEdited;
28
import com.iver.cit.gvsig.fmap.edition.EditionException;
29
import com.iver.cit.gvsig.fmap.edition.IWriter;
30
import com.iver.cit.gvsig.fmap.edition.ShpSchemaManager;
31
import com.iver.cit.gvsig.fmap.edition.writers.shp.ShpWriter;
32
import com.iver.cit.gvsig.fmap.layers.FBitSet;
33
import com.iver.cit.gvsig.fmap.layers.FLayer;
34
import com.iver.cit.gvsig.fmap.layers.FLyrAnnotation;
35
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
36
import com.iver.cit.gvsig.fmap.layers.LayerFactory;
37
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
38
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
39
import com.iver.cit.gvsig.fmap.rendering.XmlBuilder;
40
import com.iver.cit.gvsig.geoprocess.core.fmap.DefinitionUtils;
41
import com.iver.utiles.swing.threads.AbstractMonitorableTask;
42
import com.iver.utiles.swing.threads.IMonitorableTask;
43

    
44
import es.prodevelop.gvsig.exportMobile.files.NewDir;
45
import es.prodevelop.gvsig.exportMobile.layerexporters.clip.ClipProcess;
46
import es.prodevelop.gvsig.exportMobile.rectangle.DrawRectangle;
47
import es.prodevelop.gvsig.exportMobile.xml.Style;
48
import es.prodevelop.gvsig.exportMobile.xml.XmlProjectTags;
49

    
50
/**
51
 * Exportation subtask to export a vectorial layer
52
 * It supports selecting features by rect, clipping
53
 * features by rect and exporting all features
54
 * It splits the input data in polygons, lines and
55
 * points to save it as shapefiles.
56
 * 
57
 * @author jcarras
58
 *
59
 */
60
public class VectorialExporterTask extends ExporterSubTask {
61

    
62
        public static final int CLIPRECT = 1;
63
        public static final int SELECTRECT = 2;
64
        public static final int ALL = 3;
65
        
66
        protected String destPath;
67
        protected String XMLDefinition = "";
68
        protected int processType;
69
        protected FieldDescription[] fieldsDescription;
70
        protected FLyrVect inLayerVec;
71
        
72
        public static final  String CLIPSUFFIX = "_clip";
73
        public static final  String SELECTSUFFIX = "_select";
74
        public static final  String ALLSUFFIX = "_copy";
75
        public static final  String POINTSSUFFIX = "_points";
76
        public static final  String POLYGONSSUFFIX = "_polygons";
77
        public static final  String LINESSUFFIX = "_lines";
78
        public static final  String NOSUFFIX = "";
79
        public static final  String SHAPESUFFIX = ".shp";
80
        
81
        /**
82
         * Returns the suffix associated wit the input process type
83
         * @param processType
84
         * @return the corresponding suffix
85
         */
86
        public String getSuffix(int processType){
87
                if (processType == CLIPRECT)
88
                        return CLIPSUFFIX;
89
                if (processType == SELECTRECT)
90
                        return SELECTSUFFIX;
91
                if (processType == ALL)
92
                        return ALLSUFFIX;
93
                return NOSUFFIX;
94
        }
95

    
96
        /**
97
         * Remove the defined suffixes of the input string with the objective
98
         * of not adding twice the suffixes on several exportations
99
         * 
100
         * @param name
101
         * @return the input string without the suffixes
102
         */
103
        public String removeSuffixes(String name){
104
                String res = name;
105
                
106
                String[] suf = new String[7];
107
                suf[0] = CLIPSUFFIX.toLowerCase();
108
                suf[1] = SELECTSUFFIX.toLowerCase();
109
                suf[2] = ALLSUFFIX.toLowerCase();
110
                suf[3] = POINTSSUFFIX.toLowerCase();
111
                suf[4] = POLYGONSSUFFIX.toLowerCase();
112
                suf[5] = LINESSUFFIX.toLowerCase();
113
                suf[6] = SHAPESUFFIX.toLowerCase();
114
                
115
                boolean modified=true;
116
                while(modified){
117
                        modified=false;
118
                        for (int i = 0; i<7; i++){
119
                                if (name.toLowerCase().endsWith(suf[i])){
120
                                        name=name.substring(0,name.toLowerCase().lastIndexOf(suf[i]));
121
                                        modified=true;
122
                                }
123
                        }
124
                }
125
                
126
                return res;
127
        }
128

    
129
        private Logger logger = Logger.getLogger(this.getClass());
130

    
131
/**
132
 * Constructor with all the needed attributes
133
 * @param parentProcess
134
 * @param layer
135
 * @param rect
136
 * @param destPath
137
 * @param processType One of those VectorialExporterTask.CLIPRECT, VectorialExporterTask.ALL or VectorialExporterTask.SELECTRECT 
138
 * @param fieldsDescription Description of the fields of the resulting layers
139
 * @param xml 
140
 */
141
        public VectorialExporterTask(AbstractMonitorableTask parentProcess,
142
                        FLayer layer, Rectangle2D rect, String destPath, int processType,
143
                        FieldDescription[] fieldsDescription, XmlBuilder xml) {
144

    
145
                super(parentProcess, layer, rect, xml);
146
                this.destPath = destPath;
147
                this.processType = processType;
148
                this.fieldsDescription = fieldsDescription;
149
                this.inLayerVec = (FLyrVect) layer;
150

    
151
        }
152

    
153
        private void writeFeatures(IWriter writer, Driver reader, FBitSet bitSet, int numStepsToReport)
154
                        throws DriverException, DriverIOException, EditionException {
155
                writer.preProcess();
156
                ReadableVectorial va = inLayerVec.getSource();
157
                va.start();
158
                ICoordTrans ct = inLayerVec.getCoordTrans();
159
                SelectableDataSource sds = this.inLayerVec.getRecordset();
160
                DriverAttributes attr = va.getDriverAttributes();
161
                boolean bMustClone = false;
162
                if (attr != null) {
163
                        if (attr.isLoadedInMemory()) {
164
                                bMustClone = attr.isLoadedInMemory();
165
                        }
166
                }
167
                
168
                long shapesPerStep = bitSet.cardinality() / numStepsToReport;
169
                int stepsPerShape = 0;
170
                if (shapesPerStep==0)
171
                        stepsPerShape = numStepsToReport / bitSet.cardinality();
172
                        
173
                int counter = 0;
174
                for (int i = bitSet.nextSetBit(0); i >= 0; i = bitSet.nextSetBit(i + 1)) {
175
                        try {
176
                                IGeometry geom = va.getShape(i);
177

    
178
                                if (inLayerVec instanceof FLyrAnnotation
179
                                                && geom.getGeometryType() != FShape.POINT) {
180
                                        Point2D p = FLabel.createLabelPoint((FShape) geom
181
                                                        .getInternalShape());
182
                                        geom = ShapeFactory.createPoint2D(p.getX(), p.getY());
183
                                }
184
                                if (ct != null) {
185
                                        if (bMustClone)
186
                                                geom = geom.cloneGeometry();
187
                                        geom.reProject(ct);
188
                                }
189

    
190
                                
191
                                if (parent.isCanceled())
192
                                        break;
193

    
194
                                if (geom != null) {
195

    
196
                                        Value[] values = extractValues(sds, fieldsDescription, i);
197
                                        IFeature feat = new DefaultFeature(geom, values, "" + i);
198
                                        DefaultRowEdited edRow = new DefaultRowEdited(feat,
199
                                                        DefaultRowEdited.STATUS_ADDED, i);
200
                                        edRow.setAttributes(values);
201
                                        writer.process(edRow);
202
                                }
203
                        } catch (Exception ee) {
204
                                ee.printStackTrace();
205
                        } finally{
206
                                counter++;
207
                                if (shapesPerStep>0){
208
                                        if (counter % shapesPerStep == 0){
209
                                                reportStep();
210
                                        }
211
                                }else {
212
                                        reportSteps(stepsPerShape);
213
                                }
214
                        }
215
                }
216

    
217
                writer.postProcess();
218
                va.stop();
219

    
220

    
221
        }
222
        
223
        private void clipFeatures(IWriter writer, Driver reader, FBitSet bitSet, ShpSchemaManager schemaManager, ILayerDefinition outputDef, int numStepsToReport){
224
                ClipProcess clip = new ClipProcess(
225
                                inLayerVec, 
226
                                fieldsDescription, bitSet);
227

    
228
                /* build the second operand */
229
                FLyrVect lyrRect = DrawRectangle.createRectangleLayer(rect, inLayer.getProjection());
230
                clip.setSecondOperand(lyrRect);
231
                clip.setResultLayerDefinition(outputDef);
232
                clip.setResultLayerProperties(writer, schemaManager);
233
                try {
234
                        clip.checkPreconditions();
235
                        IMonitorableTask task = clip.createTask();
236
                        task.run();
237
                } catch (Exception e) {
238
                        e.printStackTrace();
239
                } finally {
240
                        reportSteps(numStepsToReport);
241
                }
242
                
243
        }
244

    
245
        /**
246
         * Makes the exportation
247
         */
248
        public void  export() {
249
                setNote(PluginServices.getText(this, "exporting_") + " " + inLayer.getName());
250
                
251
                SHPLayerDefinition definition = new SHPLayerDefinition();
252
                 try {
253
                        definition = DefinitionUtils.
254
                                createLayerDefinition(inLayerVec);
255
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
256
                        // TODO Auto-generated catch block
257
                        e.printStackTrace();
258
                } catch (DriverException e) {
259
                        // TODO Auto-generated catch block
260
                        e.printStackTrace();
261
                }
262
                        
263
                definition.setFieldsDesc(fieldsDescription);
264
                String basename = inLayer.getName();
265
                if (basename.toLowerCase().endsWith(".shp"))
266
                        basename=basename.substring(0,basename.lastIndexOf("."));
267

    
268
                // POINTS
269
                try{
270
                        FBitSet bitSet;
271
                        if (processType==ALL)
272
                                bitSet = queryByRectAndType(null, FShape.POINT);
273
                        else
274
                                bitSet = queryByRectAndType(rect, FShape.POINT);
275
                        logger.debug("Found " + bitSet.cardinality() + " points");
276
                        if (bitSet.cardinality() > 0) {
277
                                initXML();
278
                                ShpWriter writer = (ShpWriter) LayerFactory.getWM().getWriter(
279
                                                "Shape Writer");
280
                                
281
                                File tempFile = NewDir.getTempShpFile();
282
                                
283
                                definition.setFile(tempFile);
284
                                definition.setName(tempFile.getName());
285
                                definition.setShapeType(FShape.POINT);
286
                                writer.setFile(tempFile);
287
                                writer.initialize(definition);
288
                                Driver driver = getOpenShpDriver(tempFile);
289
                                ShpSchemaManager schemaManager = new ShpSchemaManager(tempFile.getAbsolutePath());
290

    
291
                                if (processType==CLIPRECT)
292
                                        clipFeatures(writer, driver, bitSet, schemaManager,definition,33);
293
                                else
294
                                        writeFeatures(writer, driver, bitSet, 33);
295
                                                                        
296
                                String lyrName = removeSuffixes(basename);
297
                                lyrName += getSuffix(processType);
298
                                lyrName += POINTSSUFFIX;
299
                                File filePoints = new File(destPath + File.separator + lyrName + SHAPESUFFIX);
300
                                filePoints = getFreeFile(filePoints);
301
                                NewDir.copyShpDbfShxTempToFinal(tempFile, filePoints);
302
                                writeXML(lyrName, FShape.POINT, filePoints.getName());
303
                        }
304
                } catch (EditionException e1){
305
                        e1.printStackTrace();
306
                } catch (IOException e2){
307
                        e2.printStackTrace();
308
                } catch (DriverIOException e3){
309
                        e3.printStackTrace();
310
                } catch (DriverException e4){
311
                        e4.printStackTrace();
312
                } finally{
313
                        closeXML();
314
                        //reportStep();
315
                }
316

    
317
                // LINES
318
                try{
319
                        FBitSet bitSet;
320
                        if (processType==ALL)
321
                                bitSet = queryByRectAndType(null, FShape.LINE);
322
                        else
323
                                bitSet = queryByRectAndType(rect, FShape.LINE);
324
                        logger.debug("Found " + bitSet.cardinality() + " lines");
325
                        if (bitSet.cardinality() > 0) {
326
                                initXML();
327
                                ShpWriter writer = (ShpWriter) LayerFactory.getWM().getWriter(
328
                                                "Shape Writer");
329
                                
330
                                File tempFile = NewDir.getTempShpFile();
331
                                
332
                                definition.setFile(tempFile);
333
                                definition.setName(tempFile.getName());
334
                                definition.setShapeType(FShape.LINE);
335
                                writer.setFile(tempFile);
336
                                writer.initialize(definition);
337
                                Driver driver = getOpenShpDriver(tempFile);
338
                                ShpSchemaManager schemaManager = new ShpSchemaManager(tempFile.getAbsolutePath());
339

    
340
                                if (processType==CLIPRECT)
341
                                        clipFeatures(writer, driver, bitSet, schemaManager,definition,33);
342
                                else
343
                                        writeFeatures(writer, driver, bitSet, 33);
344
                                                                
345
                                String lyrName = removeSuffixes(basename);
346
                                lyrName += getSuffix(processType);
347
                                lyrName += LINESSUFFIX;
348
                                File filePoints = new File(destPath + File.separator + lyrName + SHAPESUFFIX);
349
                                filePoints = getFreeFile(filePoints);
350
                                NewDir.copyShpDbfShxTempToFinal(tempFile, filePoints);
351

    
352
                                writeXML(lyrName, FShape.LINE, filePoints.getName());
353
                        }
354
                } catch (EditionException e1){
355
                        e1.printStackTrace();
356
                } catch (IOException e2){
357
                        e2.printStackTrace();
358
                } catch (DriverIOException e3){
359
                        e3.printStackTrace();
360
                } catch (DriverException e4){
361
                        e4.printStackTrace();
362
                } finally{
363
                        closeXML();
364
                        //reportStep();
365
                }
366

    
367
                // POLYGONS
368
                try{
369
                        FBitSet bitSet;
370
                        if (processType==ALL)
371
                                bitSet = queryByRectAndType(null, FShape.POLYGON);
372
                        else
373
                                bitSet = queryByRectAndType(rect, FShape.POLYGON);
374
                        logger.debug("Found " + bitSet.cardinality() + " polygons");
375
                        if (bitSet.cardinality() > 0) {
376
                                initXML();
377
                                ShpWriter writer = (ShpWriter) LayerFactory.getWM().getWriter(
378
                                                "Shape Writer");
379
                                
380
                                File tempFile = NewDir.getTempShpFile();
381
                                
382
                                definition.setFile(tempFile);
383
                                definition.setName(tempFile.getName());
384
                                definition.setShapeType(FShape.POLYGON);
385
                                
386
                                
387
                                writer.setFile(tempFile);
388
                                writer.initialize(definition);
389
                                Driver driver = getOpenShpDriver(tempFile);
390
                                ShpSchemaManager schemaManager = new ShpSchemaManager(tempFile.getAbsolutePath());
391

    
392
                                if (processType==CLIPRECT){
393
                                        clipFeatures(writer, driver, bitSet, schemaManager, definition,33);
394
                                        
395
                                }
396
                                else
397
                                        writeFeatures(writer, driver, bitSet, 33);
398
                                
399
                                String lyrName = removeSuffixes(basename);
400
                                lyrName += getSuffix(processType);
401
                                lyrName += POLYGONSSUFFIX;
402
                                File filePoints = new File(destPath + File.separator + lyrName + SHAPESUFFIX);
403
                                filePoints = getFreeFile(filePoints);
404
                                NewDir.copyShpDbfShxTempToFinal(tempFile, filePoints);
405
                                writeXML(lyrName, FShape.POLYGON, filePoints.getName());
406
                        }
407
                } catch (EditionException e1){
408
                        e1.printStackTrace();
409
                } catch (IOException e2){
410
                        e2.printStackTrace();
411
                } catch (DriverIOException e3){
412
                        e3.printStackTrace();
413
                } catch (DriverException e4){
414
                        e4.printStackTrace();
415
                } finally{
416
                        closeXML();
417
                        reportToEnd();
418
                }
419

    
420
                
421
        }
422

    
423
        /**
424
         * It iterates over every feature to return a bitSet with the features of
425
         * the input type and inside the input rectangle
426
         * @param rect
427
         * @param type
428
         * @return
429
         * @throws DriverException
430
         */
431
        public FBitSet queryByRectAndType(Rectangle2D rect, int type)
432
                        throws DriverException {
433

    
434
                ReadableVectorial va = inLayerVec.getSource();
435
                ICoordTrans ct = inLayerVec.getCoordTrans();
436

    
437
                FBitSet bitset = new FBitSet();
438
                try {
439
                        va.start();
440
                        int numShp = va.getShapeCount();
441
                        DriverAttributes attr = va.getDriverAttributes();
442
                        boolean bMustClone = false;
443
                        if (attr != null) {
444
                                if (attr.isLoadedInMemory()) {
445
                                        bMustClone = attr.isLoadedInMemory();
446
                                }
447
                        }
448

    
449
                        for (int i = 0; i < numShp; i++) {
450
                                // if it's not the type expected we discard it
451
                                IGeometry geom = va.getShape(i);
452
                                if (geom == null)
453
                                        continue;
454
                                if (type != (geom.getGeometryType() % 512))
455
                                        continue;
456
                                // idRec = (Integer) lyr.getSource().getShape(i).get;
457
                                // index = i;//dRec.intValue();
458
                                // if we want the whole features we select it
459
                                if (rect == null) {
460
                                        bitset.set(i, true);
461
                                        continue;
462
                                }
463
                                // IGeometry geom = shp;
464

    
465
                                if (ct != null) {
466
                                        if (bMustClone)
467
                                                geom = geom.cloneGeometry();
468
                                        geom.reProject(ct);
469
                                }
470
                                if (geom.intersects(rect))
471
                                        bitset.set(i, true);
472
                        }
473
                        va.stop();
474
                } catch (DriverIOException e) {
475
                        // TODO Auto-generated catch block
476
                        e.printStackTrace();
477
                }
478
                return bitset;
479

    
480
        }
481

    
482
        
483
        private IndexedShpDriver getOpenShpDriver(File file) throws IOException {
484

    
485
                IndexedShpDriver drv = new IndexedShpDriver();
486
                if (!file.exists()) {
487

    
488
                        file.createNewFile();
489
                        File newFileSHX = new File(file.getAbsolutePath().replaceAll(
490
                                        "[.]shp", ".shx"));
491
                        newFileSHX.createNewFile();
492
                        File newFileDBF = new File(file.getAbsolutePath().replaceAll(
493
                                        "[.]shp", ".dbf"));
494
                        newFileDBF.createNewFile();
495
                }
496
                drv.open(file);
497
                return drv;
498
        }
499

    
500
        private Value[] extractValues(SelectableDataSource sds2,
501
                        FieldDescription[] descripExLyr2, int i)
502
                        throws com.hardcode.gdbms.engine.data.driver.DriverException {
503

    
504
                FieldDescription[] desLyrTot = sds2.getFieldsDescription();
505
                int[] indices = getArrayIndex(descripExLyr2, desLyrTot);
506
                Value[] newvalue = new Value[indices.length];
507

    
508
                try {
509
                        // geom description
510
                        Value[] val = sds2.getRow(i);
511

    
512
                        for (int k = 0; k < indices.length; k++) {
513

    
514
                                int indx = indices[k];
515
                                Value valu = val[indx];
516
                                newvalue[k] = valu;
517
                        }
518

    
519
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
520
                        // TODO Auto-generated catch block
521
                        e.printStackTrace();
522
                }
523
                // TODO Auto-generated method stub
524
                return newvalue;
525
        }
526

    
527
        /**
528
         * Compare two FieldsDescription[], and show which atributes agreed. Then we
529
         * create a new array index of this atributes
530
         * 
531
         * @param descripSel,
532
         *            selected layer`s description
533
         * @param descripTot,
534
         *            original layer`s description
535
         * @return
536
         */
537
        private int[] getArrayIndex(FieldDescription[] descripSel,
538
                        FieldDescription[] descripTot) {
539

    
540
                int[] index = new int[descripSel.length];
541
                int cont = 0;
542

    
543
                for (int i = 0; i < descripTot.length; i++) {
544

    
545
                        String nameFieldTot = descripTot[i].getFieldName();
546
                        for (int j = 0; j < descripSel.length; j++) {
547

    
548
                                String nameFielSele = descripSel[j].getFieldName();
549
                                if (nameFieldTot.equals(nameFielSele)) {
550

    
551
                                        cont = i;
552
                                        index[j] = cont;
553

    
554
                                }
555
                        }
556
                }
557
                return index;
558
        }
559

    
560
        /**
561
         * Number of steps the Exportation will report
562
         */
563
        public int getFinalStep() {
564
                return 100;
565
        }
566

    
567
        /**
568
         * Runs the exportation task
569
         */
570
        public void  run() {
571
                export();
572
        }
573
        
574
        /**
575
         * Writes the layer attributes to the input xml
576
         * @param name
577
         * @param shpType
578
         * @param path
579
         */
580
        private void writeXML(String name, int shpType, String path){
581
                //xml.openTag(XmlProjectTags.LAYER);
582
                //<Type>
583
                xml.writeTag(XmlProjectTags.TYPE, "SHP");
584
                //</Type>
585
                
586
                //<Path>                                                
587
                xml.writeTag(XmlProjectTags.PATH, path);
588
                //</Path>
589
                
590
                //<Name>
591
                xml.writeTag(XmlProjectTags.NAME, name);
592
                //</Name>
593
                
594
                //<Visible>
595
                String isVisible = (inLayer.isVisible()) ? "1" : "0"; 
596
                xml.writeTag(XmlProjectTags.VISIBLE, isVisible);
597
                //</Visible>
598
                
599
                // scale max min
600
                double scaleMax = inLayer.getMaxScale();
601
                double scaleMin = inLayer.getMinScale();
602
                xml.writeTag(XmlProjectTags.SCALE_MAX, "" + Double.toString(scaleMax));
603
                xml.writeTag(XmlProjectTags.SCALE_MIN, "" + Double.toString(scaleMin));
604

    
605
                Style style = new Style();
606
                style.setLayer(inLayerVec,shpType);
607
                style.setXML(xml);
608
                style.createXML();
609
                
610
                //xml.closeTag();
611
        }
612
}