Statistics
| Revision:

root / org.gvsig.dxf / trunk / org.gvsig.dxf / org.gvsig.dxf.provider / src / main / java / org / gvsig / fmap / dal / store / dxf / DXFStoreProvider.java @ 155

History | View | Annotate | Download (66.6 KB)

1
package org.gvsig.fmap.dal.store.dxf;
2

    
3
import java.awt.geom.PathIterator;
4
import java.awt.geom.Point2D;
5
import java.io.File;
6
import java.text.MessageFormat;
7
import java.util.ArrayList;
8
import java.util.HashMap;
9
import java.util.Iterator;
10
import java.util.List;
11
import java.util.Map;
12
import java.util.Vector;
13

    
14
import org.apache.commons.io.FilenameUtils;
15
import org.cresques.cts.IProjection;
16
import org.slf4j.Logger;
17
import org.slf4j.LoggerFactory;
18

    
19
import org.gvsig.dxf.geo.Point3D;
20
import org.gvsig.dxf.io.DxfFile;
21
import org.gvsig.dxf.io.DxfGroup;
22
import org.gvsig.dxf.io.DxfGroupVector;
23
import org.gvsig.dxf.px.IObjList;
24
import org.gvsig.dxf.px.dxf.DxfEntityMaker;
25
import org.gvsig.dxf.px.dxf.DxfFeatureMaker;
26
import org.gvsig.dxf.px.dxf.DxfHeaderManager;
27
import org.gvsig.dxf.px.gml.Feature;
28
import org.gvsig.dxf.px.gml.LineString;
29
import org.gvsig.dxf.px.gml.LineString3D;
30
import org.gvsig.dxf.px.gml.Point;
31
import org.gvsig.dxf.px.gml.Polygon;
32
import org.gvsig.dxf.px.gml.Polygon3D;
33
import org.gvsig.fmap.dal.DALLocator;
34
import org.gvsig.fmap.dal.DataManager;
35
import org.gvsig.fmap.dal.DataServerExplorer;
36
import org.gvsig.fmap.dal.DataStore;
37
import org.gvsig.fmap.dal.DataStoreNotification;
38
import org.gvsig.fmap.dal.DataTypes;
39
import org.gvsig.fmap.dal.FileHelper;
40
import org.gvsig.fmap.dal.exception.DataException;
41
import org.gvsig.fmap.dal.exception.InitializeException;
42
import org.gvsig.fmap.dal.exception.LoadException;
43
import org.gvsig.fmap.dal.exception.OpenException;
44
import org.gvsig.fmap.dal.exception.ReadException;
45
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
46
import org.gvsig.fmap.dal.exception.WriteException;
47
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
48
import org.gvsig.fmap.dal.feature.EditableFeatureType;
49
import org.gvsig.fmap.dal.feature.FeatureSet;
50
import org.gvsig.fmap.dal.feature.FeatureType;
51
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
52
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
53
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
54
import org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider;
55
import org.gvsig.fmap.dal.resource.ResourceAction;
56
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
57
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyCloseException;
58
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyOpenException;
59
import org.gvsig.fmap.dal.resource.file.FileResource;
60
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
61
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
62
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
63
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
64
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
65
import org.gvsig.fmap.geom.Geometry;
66
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
67
import org.gvsig.fmap.geom.Geometry.TYPES;
68
import org.gvsig.fmap.geom.GeometryLocator;
69
import org.gvsig.fmap.geom.GeometryManager;
70
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
71
import org.gvsig.fmap.geom.exception.CreateGeometryException;
72
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
73
import org.gvsig.fmap.geom.operation.distance.PointDistance;
74
import org.gvsig.fmap.geom.operation.utils.PointGetAngle;
75
import org.gvsig.fmap.geom.primitive.Arc;
76
import org.gvsig.fmap.geom.primitive.Circle;
77
import org.gvsig.fmap.geom.primitive.Ellipse;
78
import org.gvsig.fmap.geom.primitive.Envelope;
79
import org.gvsig.fmap.geom.primitive.Line;
80
import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
81
import org.gvsig.fmap.geom.type.GeometryType;
82
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
83
import org.gvsig.fmap.geom.type.GeometryTypeNotValidException;
84
import org.gvsig.tools.ToolsLocator;
85
import org.gvsig.tools.dispose.DisposableIterator;
86
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
87
import org.gvsig.tools.dynobject.exception.DynMethodException;
88
import org.gvsig.tools.exception.BaseException;
89
import org.gvsig.tools.exception.NotYetImplemented;
90
import org.gvsig.tools.locator.LocatorException;
91
import org.gvsig.tools.logger.FilteredLogger;
92
import org.gvsig.tools.persistence.PersistentState;
93
import org.gvsig.tools.persistence.exception.PersistenceException;
94
import org.gvsig.tools.task.SimpleTaskStatus;
95
import org.gvsig.tools.task.TaskStatusManager;
96

    
97
/**
98
 * @author gvSIG team
99
 *
100
 */
101
public class DXFStoreProvider extends AbstractMemoryStoreProvider implements
102
ResourceConsumer {
103
    private static final Logger logger = LoggerFactory.getLogger(DXFStoreProvider.class);
104

    
105
    public static final String NAME = "DXF";
106
    public static final String DESCRIPTION = "DXF file";
107

    
108
    public static final String METADATA_DEFINITION_NAME = NAME;
109

    
110
    public static final String NAME_FIELD_ID = "ID";
111
    public static final String NAME_FIELD_GEOMETRY = "Geometry";
112
    public static final String NAME_FIELD_ENTITY = "Entity";
113
    public static final String NAME_FIELD_LAYER = "Layer";
114
    public static final String NAME_FIELD_COLOR = "Color";
115
    public static final String NAME_FIELD_ELEVATION = "Elevation";
116
    public static final String NAME_FIELD_THICKNESS = "Thickness";
117
    public static final String NAME_FIELD_TEXT = "Text";
118
    public static final String NAME_FIELD_HEIGHTTEXT = "HeightText";
119
    public static final String NAME_FIELD_ROTATIONTEXT = "Rotation";
120

    
121
    private static final int ID_FIELD_ID = 0;
122
    private static final int ID_FIELD_GEOMETRY = 1;
123
    private static final int ID_FIELD_ENTITY = 2;
124
    private static final int ID_FIELD_LAYER = 3;
125
    private static final int ID_FIELD_COLOR = 4;
126
    private static final int ID_FIELD_ELEVATION = 5;
127
    private static final int ID_FIELD_THICKNESS = 6;
128
    private static final int ID_FIELD_TEXT = 7;
129
    private static final int ID_FIELD_HEIGHTTEXT = 8;
130
    private static final int ID_FIELD_ROTATIONTEXT = 9;
131

    
132
    private IProjection projection;
133
    private ResourceProvider resource;
134
    private LegendBuilder legendBuilder;
135

    
136
    private long counterNewsOIDs = 0;
137
    private Envelope envelope;
138
    private Writer writer;
139
    protected GeometryManager geomManager = GeometryLocator.getGeometryManager();
140

    
141
    private SimpleTaskStatus taskStatus;
142

    
143

    
144
    /**
145
     * @param parameters
146
     * @param storeServices
147
     * @throws InitializeException
148
     */
149
    public DXFStoreProvider(DXFStoreParameters parameters,
150
        DataStoreProviderServices storeServices) throws InitializeException {
151
        super(
152
            parameters,
153
            storeServices,
154
            FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME)
155
        );
156

    
157
        TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
158
        this.taskStatus = manager.createDefaultSimpleTaskStatus("DXF");
159

    
160
        counterNewsOIDs = 0;
161
        //                projection = CRSFactory.getCRS(getParameters().getSRSID());
162

    
163
        File file = getDXFParameters().getFile();
164
        resource = this.createResource(
165
            FileResource.NAME,
166
            new Object[] { file.getAbsolutePath() }
167
        );
168

    
169
        resource.addConsumer(this);
170

    
171
        this.projection = this.getDXFParameters().getCRS();
172

    
173

    
174
        try {
175
            legendBuilder = (LegendBuilder) this.invokeDynMethod(
176
                LegendBuilder.DYNMETHOD_BUILDER_NAME, null);
177
        } catch (DynMethodException e) {
178
            legendBuilder = null;
179
        } catch (Exception e) {
180
            throw new InitializeException(e);
181
        }
182

    
183
        this.initializeFeatureTypes();
184
    }
185

    
186
    private DXFStoreParameters getDXFParameters() {
187
        return (DXFStoreParameters) this.getParameters();
188
    }
189

    
190
    public String getProviderName() {
191
        return NAME;
192
    }
193

    
194
    public boolean allowWrite() {
195
        return true;
196
    }
197

    
198
    /**
199
     * @return the legend
200
     * @throws OpenException
201
     */
202
    public Object getLegend() throws OpenException {
203
        this.open();
204
        if (legendBuilder == null) {
205
            return null;
206
        }
207
        return legendBuilder.getLegend();
208
    }
209

    
210
    /**
211
     * @return the labeling strategy
212
     * @throws OpenException
213
     */
214
    public Object getLabeling() throws OpenException {
215
        this.open();
216
        if (legendBuilder == null) {
217
            return null;
218
        }
219
        return legendBuilder.getLabeling();
220
    }
221

    
222
    private class DXFData {
223
        public List<FeatureProvider> data = null;
224
        public FeatureType defaultFType = null;
225
        public List<FeatureType> fTypes = null;
226
        public Envelope envelope = null;
227
        public IProjection projection;
228
        public LegendBuilder legendBuilder;
229
        public Envelope getEnvelopeCopy() throws CreateEnvelopeException {
230
            if (envelope == null) {
231
                return null;
232
            }
233
            Envelope newEnvelope;
234
            if (envelope.getDimension() == 2) {
235
                newEnvelope = geomManager.createEnvelope(SUBTYPES.GEOM2D);
236
            } else {
237
                newEnvelope = geomManager.createEnvelope(SUBTYPES.GEOM3D);
238

    
239
            }
240
            newEnvelope.setLowerCorner(envelope.getLowerCorner());
241
            newEnvelope.setUpperCorner(envelope.getUpperCorner());
242
            return newEnvelope;
243
        }
244
    }
245

    
246
    public void open() throws OpenException {
247
        if (this.data != null) {
248
            return;
249
        }
250
        openEver();
251
    }
252

    
253
    private void openEver() throws OpenException {
254
        try {
255
            this.taskStatus.add();
256
            getResource().execute(new ResourceAction() {
257
                public Object run() throws Exception {
258
                    DXFData dxfData = null;
259
                    resource.setData(new HashMap<Object, Object>());
260
                    FeatureStoreProviderServices store = getStoreServices();
261
                    dxfData = new DXFData();
262
                    dxfData.data = new ArrayList<FeatureProvider>();
263
                    data = dxfData.data;
264
                    counterNewsOIDs = 0;
265
                    File file = (File) resource.get();
266
                    Reader reader = new Reader().initialice(
267
                        getMemoryProvider(),
268
                        file,
269
                        projection,
270
                        legendBuilder
271
                    );
272
                    reader.begin(store);
273
                    dxfData.defaultFType = reader.getDefaultType()
274
                    .getNotEditableCopy();
275
                    ArrayList<FeatureType> types = new ArrayList<FeatureType>();
276
                    Iterator<EditableFeatureType> it = reader.getTypes().iterator();
277
                    EditableFeatureType fType;
278
                    while (it.hasNext()) {
279
                        fType = it.next();
280
                        if (fType.getId().equals(dxfData.defaultFType.getId())) {
281
                            types.add(dxfData.defaultFType);
282
                        } else {
283
                            types.add(fType.getNotEditableCopy());
284
                        }
285
                    }
286
                    dxfData.fTypes = types;
287

    
288
                    resource.notifyOpen();
289
                    store.setFeatureTypes(dxfData.fTypes, dxfData.defaultFType);
290
                    reader.load();
291

    
292
                    dxfData.envelope = reader.getEnvelope();
293

    
294
                    dxfData.legendBuilder = legendBuilder;
295

    
296
                    dxfData.projection = projection;
297

    
298
                    reader.end();
299
                    resource.notifyClose();
300
                    ((Map<String, DXFData>) resource.getData()).put(projection.getAbrev(),
301
                        dxfData); // OJO la reproyeccion
302

    
303
                    data = dxfData.data;
304
                    store.setFeatureTypes(dxfData.fTypes, dxfData.defaultFType);
305
                    legendBuilder = dxfData.legendBuilder;
306
                    envelope= dxfData.getEnvelopeCopy();
307
                    // setDynValue("CRS", projection.getAbrev());
308
                    counterNewsOIDs = data.size();
309
                    return null;
310
                }
311
            });
312
            this.taskStatus.terminate();
313
        } catch (Exception e) {
314
            data = null;
315
            this.taskStatus.abort();
316
            try {
317
                throw new OpenException(resource.getName(), e);
318
            } catch (AccessResourceException e1) {
319
                throw new OpenException(getProviderName(), e);
320
            }
321
        } finally {
322
            this.taskStatus.remove();
323
        }
324
    }
325

    
326

    
327
    public DataServerExplorer getExplorer() throws ReadException {
328
        DataManager manager = DALLocator.getDataManager();
329
        FilesystemServerExplorerParameters params;
330
        try {
331
            params = (FilesystemServerExplorerParameters) manager
332
            .createServerExplorerParameters(FilesystemServerExplorer.NAME);
333
            params.setRoot(this.getDXFParameters().getFile().getParent());
334
            return manager.openServerExplorer(FilesystemServerExplorer.NAME,params);
335
        } catch (DataException e) {
336
            throw new ReadException(this.getProviderName(), e);
337
        } catch (ValidateDataParametersException e) {
338
            throw new ReadException(this.getProviderName(), e);
339
        }
340

    
341
    }
342

    
343

    
344

    
345
    public void performChanges(Iterator deleteds, Iterator inserteds, Iterator updateds, Iterator originalFeatureTypesUpdated) throws PerformEditingException {
346

    
347
        try {
348
            this.taskStatus.add();
349
            taskStatus.message("_preparing");
350
            getResource().execute(new ResourceAction() {
351
                public Object run() throws Exception {
352
                    FeatureSet features = null;
353
                    DisposableIterator it = null;
354
                    counterNewsOIDs = 0;
355
                    try {
356
                        File file = (File) resource.get();
357
                        writer = new Writer().initialice(file, projection);
358
                        features =
359
                            getStoreServices().getFeatureStore()
360
                            .getFeatureSet();
361
                        List<FeatureProvider> newdata = new ArrayList<FeatureProvider>();
362
                        writer.begin();
363
                        it = features.fastIterator();
364
                        taskStatus.setRangeOfValues(0,0);
365
                        long counter=0;
366
                        while (it.hasNext()) {
367
                            taskStatus.setCurValue(counter++);
368
                            FeatureProvider featureProvider = getStoreServices().getFeatureProviderFromFeature(
369
                                (org.gvsig.fmap.dal.feature.Feature) it.next());
370
                            writer.add(featureProvider);
371
                            featureProvider.setOID(createNewOID());
372
                            newdata.add(featureProvider);
373
                        }
374
                        data = newdata;
375
                        writer.end();
376
                        if (writer.getEnvelope() != null){
377
                            envelope = writer.getEnvelope().getGeometry().getEnvelope();
378
                        }
379
                        resource.notifyChanges();
380
//                        counterNewsOIDs = 0;
381

    
382
                        savePrjFile(file, projection);
383

    
384
                    } finally {
385
                        if (it != null) {
386
                            it.dispose();
387
                        }
388
                        if (features != null) {
389
                            features.dispose();
390
                        }
391
                    }
392
                    return null;
393
                }
394
            });
395
            this.taskStatus.terminate();
396
        } catch (Exception e) {
397
            this.taskStatus.abort();
398
            throw new PerformEditingException(getResource().toString(), e);
399
        } finally {
400
            this.taskStatus.remove();
401
        }
402
    }
403

    
404
    /**
405
     * @param featureType
406
     * @param projection
407
     * @param geometrySubtype
408
     * @throws LocatorException
409
     * @throws GeometryTypeNotValidException
410
     * @throws GeometryTypeNotSupportedException
411
     */
412
    public static void initializeFeatureType(EditableFeatureType featureType, IProjection projection, int geometrySubtype) {
413
        featureType.setHasOID(true);
414

    
415
//        ID_FIELD_ID = 0;
416
        featureType.add(NAME_FIELD_ID, DataTypes.INT)
417
        .setDefaultValue(Integer.valueOf(0))
418
        .getIndex();
419

    
420
        EditableFeatureAttributeDescriptor attr = featureType.add(
421
            NAME_FIELD_GEOMETRY, DataTypes.GEOMETRY);
422
        attr.setSRS(projection);
423
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
424

    
425
        try {
426
            GeometryType geometryType = geometryManager.getGeometryType(Geometry.TYPES.GEOMETRY, geometrySubtype);
427
            attr.setGeometryType(geometryType);
428
        } catch (GeometryTypeNotSupportedException | GeometryTypeNotValidException e) {
429
            logger.error("Can't create geometry type " + Geometry.TYPES.GEOMETRY + " with subtype " + geometrySubtype, e);
430
            attr.setGeometryType(Geometry.TYPES.GEOMETRY);
431
            attr.setGeometrySubType(geometrySubtype);
432
        }
433

    
434
//        ID_FIELD_GEOMETRY = 1; //attr.getIndex();
435

    
436
        featureType.setDefaultGeometryAttributeName(NAME_FIELD_GEOMETRY);
437

    
438
        // FIXME: Cual es el size y el valor por defecto para Entity ?
439
//        ID_FIELD_ENTITY = 2;
440
        featureType.add(NAME_FIELD_ENTITY,
441
            DataTypes.STRING, 100)
442
            .setDefaultValue("")
443
            .getIndex();
444

    
445
        // FIXME: Cual es el size de Layer ?
446
//        ID_FIELD_LAYER = 3;
447
        featureType.add(NAME_FIELD_LAYER,
448
            DataTypes.STRING, 100)
449
            .setDefaultValue(
450
            "default").getIndex();
451

    
452
//        ID_FIELD_COLOR = 4;
453
        featureType.add(NAME_FIELD_COLOR,
454
            DataTypes.INT)
455
            .setDefaultValue(
456
                Integer.valueOf(0)).getIndex();
457

    
458
//        ID_FIELD_ELEVATION = 5;
459
        featureType.add(NAME_FIELD_ELEVATION,
460
            DataTypes.DOUBLE)
461
            .setDefaultValue(
462
                Double.valueOf(0)).getIndex();
463

    
464
//        ID_FIELD_THICKNESS = 6;
465
        featureType.add(NAME_FIELD_THICKNESS,
466
            DataTypes.DOUBLE)
467
            .setDefaultValue(
468
                Double.valueOf(0)).getIndex();
469

    
470
        // FIXME: Cual es el size de Text ?
471
//        ID_FIELD_TEXT = 7;
472
        featureType.add(NAME_FIELD_TEXT,
473
            DataTypes.STRING, 100)
474
            .setDefaultValue("")
475
            .getIndex();
476

    
477
//        ID_FIELD_HEIGHTTEXT = 8;
478
        featureType.add(NAME_FIELD_HEIGHTTEXT,
479
            DataTypes.DOUBLE).setDefaultValue(
480
                Double.valueOf(10)).getIndex();
481

    
482
//        ID_FIELD_ROTATIONTEXT = 9;
483
        featureType.add(NAME_FIELD_ROTATIONTEXT,
484
            DataTypes.DOUBLE).setDefaultValue(
485
                Double.valueOf(0)).getIndex();
486

    
487
        // FIXME: Parece que el DXF puede tener mas atributos opcionales.
488
        // Habria que ver de pillarlos ?
489

    
490
    }
491

    
492
    /**
493
     * @author gvSIG team
494
     *
495
     */
496
    public class Reader {
497
        private File file;
498
        private String fileName;
499
        private IProjection projection;
500
        private List<EditableFeatureType> types;
501
        private LegendBuilder leyendBuilder;
502
        private AbstractMemoryStoreProvider store;
503
        private Envelope envelope;
504

    
505
        //Next two variables are used to read the DXF file
506
        private DxfFeatureMaker featureMaker;
507
        private DxfHeaderManager headerManager;
508

    
509
        /**
510
         * @param store
511
         * @param file
512
         * @param projection
513
         * @param leyendBuilder
514
         * @return the reader
515
         */
516
        public Reader initialice(AbstractMemoryStoreProvider store, File file,
517
            IProjection projection,
518
            LegendBuilder leyendBuilder) {
519
            this.store = store;
520
            this.file = file;
521
            this.fileName = file.getAbsolutePath();
522
            this.projection = projection;
523
            this.leyendBuilder = leyendBuilder;
524
            if (leyendBuilder != null) {
525
                leyendBuilder.initialize(store);
526
            }
527
            return this;
528
        }
529

    
530
        /**
531
         * @return the envelope
532
         */
533
        public Envelope getEnvelope() {
534
            return this.envelope;
535
        }
536

    
537
        /**
538
         * @param store
539
         * @throws LoadException
540
         */
541
        public void begin(FeatureStoreProviderServices store) throws LoadException {
542
            taskStatus.message("_preloading_data");
543
            featureMaker = new DxfFeatureMaker(projection);
544
            headerManager = new DxfHeaderManager();
545
            DxfFile dxfFeatureFile = new DxfFile(projection, file
546
                .getAbsolutePath(), featureMaker, headerManager);
547

    
548
            try {
549
                dxfFeatureFile.load();
550
            } catch (Exception e1) {
551
                throw new LoadException(e1, fileName);
552
            }
553

    
554
            taskStatus.message("_preparing_featureType");
555
            int geometrySubtype;
556
                        if (featureMaker.isDxf3DFile() && headerManager.isWritedDxf3D()){
557
                geometrySubtype = Geometry.SUBTYPES.GEOM3D;
558
            }else{
559
                    geometrySubtype = Geometry.SUBTYPES.GEOM2D;
560
            }
561
                        EditableFeatureType featureType = store.createFeatureType(getName());
562
                        initializeFeatureType(featureType, this.projection, geometrySubtype);
563

    
564
            types = new ArrayList<EditableFeatureType>();
565
            types.add(featureType);
566

    
567
            if (leyendBuilder != null) {
568
                taskStatus.message("_preparing_leyend");
569
                leyendBuilder.begin();
570
            }
571

    
572
        }
573

    
574
        /**
575
         *
576
         */
577
        public void end() {
578
            if (leyendBuilder != null) {
579
                leyendBuilder.end();
580
            }
581
        }
582

    
583
        /**
584
         * @return the list of feature types
585
         */
586
        public List<EditableFeatureType> getTypes() {
587
            return types;
588
        }
589

    
590
        /**
591
         * @return the default editable feature type
592
         */
593
        public EditableFeatureType getDefaultType() {
594
            return types.get(0);
595
        }
596

    
597
        private Double toDouble(String value) {
598
            if (value == null) {
599
                return Double.valueOf(0);
600
            }
601
            return Double.valueOf(value);
602
        }
603

    
604
        private FeatureProvider createFeature(Feature fea, FeatureType ft, int id) throws DataException {
605

    
606
            FeatureProvider feature = store.createFeatureProvider(ft);
607

    
608
            feature.setOID(new Long(id));
609
            feature.set(ID_FIELD_ID, Integer.valueOf(id));
610
            feature.set(ID_FIELD_ENTITY, fea.getProp("dxfEntity"));
611
            feature.set(ID_FIELD_LAYER, fea.getProp("layer"));
612
            feature.set(ID_FIELD_COLOR, Integer.valueOf(fea.getProp("color")));
613
            feature.set(ID_FIELD_TEXT, fea.getProp("text"));
614
            feature.set(ID_FIELD_HEIGHTTEXT, toDouble(fea.getProp("textHeight")));
615
            feature.set(ID_FIELD_ROTATIONTEXT, toDouble(fea.getProp("textRotation")));
616
            feature.set(ID_FIELD_ELEVATION, toDouble(fea.getProp("elevation")));
617
            feature.set(ID_FIELD_THICKNESS, toDouble(fea.getProp("thickness")));
618
            feature.set(ID_FIELD_GEOMETRY, null);
619
            // FIXME: Habria que pillar el resto de atributos del DXF.
620

    
621
            // FIXME: Habia una incongruencia en el codigo ya que al
622
            // campo
623
            // ID_FIELD_GEOMETRY igual le asignaba una geometria que un
624
            // valor de cadena como 'Point3D', 'Polyline2D' o
625
            // 'Polyline3D'
626
            // Faltaria un atributo ID_FIELD_FSHAPE ?
627
            //
628
            return feature;
629
        }
630

    
631
        private Geometry processPoints(GeometryManager gManager, Feature dxffeature) throws CreateGeometryException {
632
            if (dxffeature.getGeometry() instanceof org.gvsig.dxf.px.gml.Point3D) {
633
                org.gvsig.dxf.px.gml.Point3D point = (org.gvsig.dxf.px.gml.Point3D) dxffeature.getGeometry();
634
                Point3D pto = point.getPoint3D(0);
635
                org.gvsig.fmap.geom.primitive.Point geom = gManager.createPoint(pto.getX(), pto.getY(), SUBTYPES.GEOM3D);
636
                geom.setCoordinateAt(Geometry.DIMENSIONS.Z, pto.getZ());
637

    
638
                if (point.isTextPoint()) {
639
                    /// TODO labeling
640
                }
641
                return geom;
642

    
643
            }
644
            if (dxffeature.getGeometry() instanceof Point) {
645
                Point point = (Point) dxffeature.getGeometry();
646
                Point2D pto = point.get(0);
647

    
648
                org.gvsig.fmap.geom.primitive.Point geom = gManager.createPoint(pto.getX(), pto.getY(), SUBTYPES.GEOM2D);
649

    
650
                if (point.isTextPoint()) {
651
                    /// TODO labeling
652
                }
653
                return geom;
654
            }
655
            return null;
656
        }
657

    
658
        private Geometry processLines(GeometryManager gManager, Feature dxffeature) throws CreateGeometryException {
659
            if (dxffeature.getGeometry() instanceof LineString3D) {
660
                Line line = gManager.createLine(SUBTYPES.GEOM3D);
661
                for (int j = 0; j < dxffeature.getGeometry().pointNr(); j++) {
662
                    Point3D point = ((LineString3D) dxffeature.getGeometry()).getPoint3D(j);
663
                    line.addVertex(point.getX(), point.getY(), point.getZ());
664
                }
665
                return line;
666

    
667
            }
668
            if (dxffeature.getGeometry() instanceof LineString) {
669
                Line line = gManager.createLine(SUBTYPES.GEOM2D);
670
                for (int j = 0; j < dxffeature.getGeometry().pointNr(); j++) {
671
                    Point2D point = dxffeature.getGeometry().get(j);
672
                    line.addVertex(point.getX(), point.getY());
673
                }
674
                return line;
675
            }
676
            return null;
677
        }
678

    
679
        private Geometry processPolygons(GeometryManager gManager, Feature dxffeature) throws CreateGeometryException {
680
            if (dxffeature.getGeometry() instanceof Polygon3D) {
681
                org.gvsig.fmap.geom.primitive.Polygon polygon = gManager.createPolygon(SUBTYPES.GEOM3D);
682
                for (int j = 0; j < dxffeature.getGeometry().pointNr(); j++) {
683
                    Point3D point = ((Polygon3D) dxffeature.getGeometry()).getPoint3D(j);
684
                    polygon.addVertex(point.getX(), point.getY(), point.getZ());
685
                }
686
                Point3D point = ((Polygon3D) dxffeature.getGeometry()).getPoint3D(0);
687
                polygon.addVertex(point.getX(), point.getY(), point.getZ());
688
                return polygon;
689

    
690
            }
691
            if (dxffeature.getGeometry() instanceof Polygon) {
692
                org.gvsig.fmap.geom.primitive.Polygon polygon = gManager.createPolygon(SUBTYPES.GEOM2D);
693
                for (int j = 0; j < dxffeature.getGeometry().pointNr(); j++) {
694
                    Point2D point = dxffeature.getGeometry().get(j);
695
                    polygon.addVertex(point.getX(), point.getY());
696
                }
697
                Point2D point = dxffeature.getGeometry().get(0);
698
                polygon.addVertex(point.getX(), point.getY());
699
                return polygon;
700
            }
701
            return null;
702
        }
703

    
704
        private void addGeometryToFeature(Geometry geometry, FeatureProvider feature) {
705
            if( geometry != null ) {
706
                feature.set(ID_FIELD_GEOMETRY, geometry);
707
                feature.setDefaultGeometry(geometry);
708
                if (this.envelope == null) {
709
                    this.envelope = geometry.getEnvelope();
710
                } else {
711
                    this.envelope.add(geometry.getEnvelope());
712
                }
713
            }
714
        }
715

    
716
        private void addfeatureToLegend(FeatureProvider feature) {
717
            if (leyendBuilder != null) {
718
                try {
719
                    leyendBuilder.process(feature);
720
                } catch (Exception e) {
721
                    logger.warn(
722
                        MessageFormat.format(
723
                            "load: legendBuilder process fails in the feature {1}",
724
                            feature
725
                        )
726
                    );
727
                }
728
            }
729
        }
730

    
731
        /**
732
         * @throws DataException
733
         */
734
        public void load() throws DataException {
735

    
736
            this.envelope = null;
737

    
738
            IObjList.vector features = (IObjList.vector)featureMaker.getObjects();
739
            String acadVersion = headerManager.getAcadVersion();
740

    
741
            logger.info("load: acadVersion = '" + acadVersion + "'");
742

    
743
            GeometryManager gManager = GeometryLocator.getGeometryManager();
744

    
745
            if (!featureMaker.isDxf3DFile() && !headerManager.isWritedDxf3D()) {
746
                taskStatus.message("_fixing_3dgeometries");
747
                Feature[] features2D = new Feature[features.size()];
748
                taskStatus.setRangeOfValues(0,features.size());
749
                for (int i = 0; i < features.size(); i++) {
750
                    taskStatus.setCurValue(i);
751
                    Feature fea = (Feature) features.get(i);
752
                    if (fea.getGeometry() instanceof org.gvsig.dxf.px.gml.Point3D) {
753
                        Point point = (Point) fea.getGeometry();
754
                        Point point2 = new Point();
755
                        for (int j = 0; j < point.pointNr(); j++) {
756
                            point2.add(point.get(j));
757
                        }
758
                        point2.setTextPoint(point.isTextPoint());
759
                        fea.setGeometry(point2);
760
                        features2D[i] = fea;
761

    
762
                    } else if (fea.getGeometry() instanceof LineString3D) {
763
                        LineString lineString = (LineString) fea.getGeometry();
764
                        LineString lineString2 = new LineString();
765
                        for (int j = 0; j < lineString.pointNr(); j++) {
766
                            lineString2.add(lineString.get(j));
767
                        }
768
                        fea.setGeometry(lineString2);
769
                        features2D[i] = fea;
770
                    } else if (fea.getGeometry() instanceof Polygon3D) {
771
                        Polygon polygon = (Polygon) fea.getGeometry();
772
                        Polygon polygon2 = new Polygon();
773
                        for (int j = 0; j < polygon.pointNr(); j++) {
774
                            polygon2.add(polygon.get(j));
775
                        }
776
                        fea.setGeometry(polygon2);
777
                        features2D[i] = fea;
778
                    }
779
                }
780
                features.clear();
781
                for (int i = 0; i < features2D.length; i++) {
782
                    features.add(features2D[i]);
783
                }
784
            }
785

    
786
            FilteredLogger logger = new FilteredLogger(DXFStoreProvider.logger,"DXFLoafing",20);
787

    
788
            FeatureType ft = store.getStoreServices().getDefaultFeatureType();
789
            taskStatus.message("_loading");
790
            // Nos recorremos las geometrias tres veces para cargarlas en orden:
791
            // - poligonos
792
            // - lineas
793
            // - puntos
794
            // Y garantizar que siempre se pinten los puntos sobre lineas y
795
            // poligonos y las lineas sobre los polignos.
796
            int n = 0;
797
            taskStatus.setRangeOfValues(0,features.size()*3);
798
            for (int i = 0; i < features.size(); i++) {
799
                taskStatus.setCurValue(n++);
800
                try {
801
                    Feature dxffeature = (Feature) features.get(i);
802
                    FeatureProvider feature = createFeature(dxffeature, ft, i);
803
                    Geometry geometry = processPolygons(gManager, dxffeature);
804
                    if( geometry != null ) {
805
                        addGeometryToFeature(geometry, feature);
806
                        store.addFeatureProvider(feature);
807
                        addfeatureToLegend(feature);
808
                    }
809
                } catch (Exception e) {
810
                    logger.warn("Can't proccess feature '"+i+", of file '"+fileName+"'.", e);
811
                }
812
            }
813
            for (int i = 0; i < features.size(); i++) {
814
                taskStatus.setCurValue(n++);
815
                try {
816
                    Feature dxffeature = (Feature) features.get(i);
817
                    FeatureProvider feature = createFeature(dxffeature, ft, i);
818
                    Geometry geometry = processLines(gManager, dxffeature);
819
                    if( geometry != null ) {
820
                        addGeometryToFeature(geometry, feature);
821
                        store.addFeatureProvider(feature);
822
                        addfeatureToLegend(feature);
823
                    }
824
                } catch (Exception e) {
825
                    logger.warn("Can't proccess feature '"+i+", of file '"+fileName+"'.", e);
826
                }
827
            }
828
            for (int i = 0; i < features.size(); i++) {
829
                taskStatus.setCurValue(n++);
830
                try {
831
                    Feature dxffeature = (Feature) features.get(i);
832
                    FeatureProvider feature = createFeature(dxffeature, ft, i);
833
                    Geometry geometry = processPoints(gManager, dxffeature);
834
                    if( geometry != null ) {
835
                        addGeometryToFeature(geometry, feature);
836
                        store.addFeatureProvider(feature);
837
                        addfeatureToLegend(feature);
838
                    }
839
                } catch (Exception e) {
840
                    logger.warn("Can't proccess feature '"+i+", of file '"+fileName+"'.", e);
841
                }
842
            }
843
        }
844

    
845
    }
846

    
847
    /**
848
     * @author gvSIG team
849
     *
850
     */
851
    public class Writer {
852
        private Double DEFAULT_ELEVATION = new Double(0);
853

    
854
        private DxfFile.EntityFactory entityMaker;
855

    
856
        private IProjection proj = null;
857

    
858
        private int handle = 40; // Revisar porqu� es 40.
859

    
860
        private int k = 0;
861

    
862
        private boolean dxf3DFile = false;
863
        private String fileName;
864
        private Envelope envelope;
865

    
866
        /**
867
         * @param file
868
         * @param projection
869
         * @return the writer
870
         */
871
        public Writer initialice(File file, IProjection projection) {
872
            this.proj = projection;
873
            this.fileName = file.getAbsolutePath();
874
            entityMaker = new DxfEntityMaker(proj);
875
            return this;
876
        }
877

    
878
        /**
879
         *
880
         */
881
        public void begin() {
882
            envelope = null;
883
            entityMaker = new DxfEntityMaker(proj);
884
        }
885

    
886
        /**
887
         * @throws WriteException
888
         */
889
        public void end() throws WriteException {
890
            try {
891
                DxfFile dxfFile = new DxfFile(null, fileName, entityMaker);
892
                dxfFile.setCadFlag(true);
893
                if (dxf3DFile) {
894
                    dxfFile.setDxf3DFlag(true);
895
                }
896
                dxfFile.save(fileName);
897
                dxfFile.close();
898
            } catch (Exception e) {
899
                throw new WriteException(fileName, e);
900
            }
901
        }
902

    
903
        /**
904
         * @param feature
905
         * @throws WriteException
906
         */
907
        public void add(FeatureProvider feature) throws WriteException {
908
            try {
909
                Geometry geom = feature.getDefaultGeometry();
910
                if(geom == null){
911
                    //FIXME: tirar al log y avisar al usuario
912
                    return;
913
                }
914
                GeometryType type = geom.getGeometryType();
915
                boolean geometrySupported = true;
916

    
917
                if ((type.isTypeOf(TYPES.POINT)) && (SUBTYPES.GEOM3D == type.getSubType())) {
918
                    dxf3DFile = true;
919
                    k = createPoint3D(handle, k, feature);
920

    
921
                } else if ((type.isTypeOf(TYPES.POINT)) && (SUBTYPES.GEOM2D == type.getSubType())) {
922
                    k = createPoint2D(handle, k, feature);
923

    
924
                } else if ((type.isTypeOf(TYPES.ARC)) && (SUBTYPES.GEOM2D == type.getSubType())) {
925
                    k = createArc2D(handle, k, feature);
926

    
927
                } else if ((type.isTypeOf(TYPES.CURVE) || type.isTypeOf(TYPES.MULTICURVE)) && (SUBTYPES.GEOM3D == type.getSubType())) {
928
                    dxf3DFile = true;
929
                    k = createPolyline3D(handle, k, feature);
930

    
931
                } else if ((type.isTypeOf(TYPES.CURVE) || type.isTypeOf(TYPES.MULTICURVE)) && (SUBTYPES.GEOM2D == type.getSubType())) {
932
                    k = createLwPolyline2D(handle, k, feature, false);
933

    
934
                } else if ((type.isTypeOf(TYPES.CIRCLE)) && (SUBTYPES.GEOM2D == type.getSubType())) {
935
                    k = createCircle2D(handle, k, feature);
936

    
937
                } else if ((type.isTypeOf(TYPES.ELLIPSE)) && (SUBTYPES.GEOM2D == type.getSubType())) {
938
                    k = createEllipse2D(handle, k, feature);
939

    
940
                } else if ((type.isTypeOf(TYPES.SURFACE) || (type.isTypeOf(TYPES.MULTISURFACE))) && (SUBTYPES.GEOM3D == type.getSubType())) {
941
                    dxf3DFile = true;
942
                    k = createPolyline3D(handle, k, feature);
943

    
944
                } else if ((type.isTypeOf(TYPES.SURFACE) || (type.isTypeOf(TYPES.MULTISURFACE))) && (SUBTYPES.GEOM2D == type.getSubType())) {
945
                    k = createLwPolyline2D(handle, k, feature, true);
946

    
947
                } else {
948
                    geometrySupported = false;
949
                    logger.warn(
950
                        MessageFormat.format(
951
                            "Geometry '{1}' not yet supported",
952
                            new Object[] {geom.getClass().getName()}
953
                        )
954
                    );
955
                    k++;
956
                }
957
                if (geometrySupported){
958
                    if (this.envelope != null){
959
                        this.envelope.add(feature.getDefaultEnvelope());
960
                    } else {
961
                        this.envelope = feature.getDefaultEnvelope().getGeometry().getEnvelope();
962
                    }
963
                }
964
            } catch (Exception e) {
965
                throw new WriteException(fileName, e);
966
            }
967

    
968
        }
969

    
970
        private boolean hasText(FeatureProvider feature) {
971
            if (feature.isNull(ID_FIELD_TEXT)) {
972
                return false;
973
            }
974
            if (feature.get(ID_FIELD_TEXT).equals("")) {
975
                return false;
976
            }
977
            return true;
978
        }
979

    
980
        private DxfGroupVector updateProperties(FeatureProvider feature, int k) {
981
            DxfGroupVector polv = new DxfGroupVector();
982

    
983
            String layer = (String) feature.get(ID_FIELD_LAYER);
984
            Integer color = (Integer) feature.get(ID_FIELD_COLOR);
985
            Double thickness = (Double) feature.get(ID_FIELD_THICKNESS);
986

    
987
            DxfGroup geometryLayer = new DxfGroup(8, layer);
988

    
989
            DxfGroup handleGroup = new DxfGroup();
990
            handleGroup.setCode(5);
991
            handleGroup.setData(new Integer(handle + k).toString());
992

    
993
            DxfGroup handleColor = new DxfGroup();
994
            handleColor.setCode(62);
995
            handleColor.setData(color);
996

    
997
            DxfGroup handleThickness = new DxfGroup();
998
            handleThickness.setCode(39);
999
            handleThickness.setData(thickness);
1000

    
1001
            polv.add(geometryLayer);
1002
            polv.add(handleGroup);
1003
            polv.add(handleColor);
1004
            return polv;
1005
        }
1006

    
1007
        private int createPoint2D(int handle, int k, FeatureProvider feature)
1008
        throws Exception {
1009

    
1010
            if (hasText(feature)) {
1011
                return createText2D(handle, k, feature);
1012
            }
1013
            org.gvsig.fmap.geom.primitive.Point point = geomManager.createPoint(0, 0, SUBTYPES.GEOM2D);
1014
            double[] pointCoords = new double[6];
1015
            PathIterator pointIt = (feature.getDefaultGeometry())
1016
            .getPathIterator(null);
1017
            while (!pointIt.isDone()) {
1018
                pointIt.currentSegment(pointCoords);
1019
                point = geomManager.createPoint(pointCoords[0], pointCoords[1], SUBTYPES.GEOM2D);
1020
                pointIt.next();
1021
            }
1022
            Point2D pto = new Point2D.Double(point.getX(), point.getY());
1023

    
1024
            DxfGroup px = new DxfGroup();
1025
            DxfGroup py = new DxfGroup();
1026
            DxfGroup pz = new DxfGroup();
1027
            px.setCode(10);
1028
            px.setData(new Double(pto.getX()));
1029
            py.setCode(20);
1030
            py.setData(new Double(pto.getY()));
1031
            pz.setCode(30);
1032
            // FIXME: POINT del DXF tiene cota. Le asigno cero arbitrariamente.
1033
            pz.setData(new Double(0.0));
1034
            DxfGroupVector pv = updateProperties(feature, k);
1035
            pv.add(px);
1036
            pv.add(py);
1037
            pv.add(pz);
1038
            entityMaker.createPoint(pv);
1039
            k++;
1040
            return k;
1041
        }
1042

    
1043
        private int createText2D(int handle, int k, FeatureProvider feature)
1044
        throws Exception {
1045

    
1046
            String text = feature.get(ID_FIELD_TEXT).toString();
1047
            Double heightText = (Double) feature.get(ID_FIELD_HEIGHTTEXT);
1048
            Double rotationText = (Double) feature.get(ID_FIELD_ROTATIONTEXT);
1049

    
1050
            DxfGroup handleText = new DxfGroup();
1051
            handleText.setCode(1);
1052
            handleText.setData(text);
1053

    
1054
            DxfGroup handleHeightText = new DxfGroup();
1055
            handleHeightText.setCode(40);
1056
            handleHeightText.setData(heightText);
1057

    
1058
            DxfGroup handleRotationText = new DxfGroup();
1059
            handleRotationText.setCode(50);
1060
            handleRotationText.setData(rotationText);
1061

    
1062
            org.gvsig.fmap.geom.primitive.Point point = geomManager.createPoint(0, 0, SUBTYPES.GEOM2D);
1063
            double[] pointCoords = new double[6];
1064
            PathIterator pointIt = (feature.getDefaultGeometry())
1065
            .getPathIterator(null);
1066
            while (!pointIt.isDone()) {
1067
                pointIt.currentSegment(pointCoords);
1068
                point = geomManager.createPoint(pointCoords[0], pointCoords[1], SUBTYPES.GEOM2D);
1069
                pointIt.next();
1070
            }
1071
            Point2D pto = new Point2D.Double(point.getX(), point.getY());
1072
            DxfGroup handleGroup = new DxfGroup();
1073
            handleGroup.setCode(5);
1074
            handleGroup.setData(new Integer(handle + k).toString());
1075
            DxfGroup px = new DxfGroup();
1076
            DxfGroup py = new DxfGroup();
1077
            DxfGroup pz = new DxfGroup();
1078
            px.setCode(10);
1079
            px.setData(new Double(pto.getX()));
1080
            py.setCode(20);
1081
            py.setData(new Double(pto.getY()));
1082
            pz.setCode(30);
1083
            // FIXME: POINT del DXF tiene cota. Le asigno cero arbitrariamente.
1084
            pz.setData(new Double(0.0));
1085
            DxfGroupVector pv = updateProperties(feature, k);
1086
            pv.add(handleText);
1087
            pv.add(handleHeightText);
1088
            pv.add(handleRotationText);
1089
            pv.add(handleGroup);
1090
            pv.add(px);
1091
            pv.add(py);
1092
            pv.add(pz);
1093
            entityMaker.createText(pv);
1094
            k++;
1095
            return k;
1096
        }
1097

    
1098
        private int createPoint3D(int handle, int k, FeatureProvider feature)
1099
        throws Exception {
1100
            if (hasText(feature)) {
1101
                return createText3D(handle, k, feature);
1102
            }
1103
            org.gvsig.fmap.geom.primitive.Point point = (org.gvsig.fmap.geom.primitive.Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM3D);
1104
            double[] pointCoords = new double[6];
1105
            PathIterator pointIt = (feature.getDefaultGeometry())
1106
            .getPathIterator(null);
1107
            while (!pointIt.isDone()) {
1108
                pointIt.currentSegment(pointCoords);
1109
                point = (org.gvsig.fmap.geom.primitive.Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM3D);
1110
                point.setCoordinateAt(0, pointCoords[0]);
1111
                point.setCoordinateAt(1, pointCoords[1]);
1112
                point.setCoordinateAt(2, pointCoords[2]);
1113
                pointIt.next();
1114
            }
1115
            org.gvsig.fmap.geom.primitive.Point pto = (org.gvsig.fmap.geom.primitive.Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM3D);
1116
            pto.setCoordinateAt(0, point.getCoordinateAt(0));
1117
            pto.setCoordinateAt(1,  point.getCoordinateAt(1));
1118
            pto.setCoordinateAt(2, point.getCoordinateAt(2));
1119
            DxfGroup px = new DxfGroup();
1120
            DxfGroup py = new DxfGroup();
1121
            DxfGroup pz = new DxfGroup();
1122
            px.setCode(10);
1123
            px.setData(new Double(pto.getX()));
1124
            py.setCode(20);
1125
            py.setData(new Double(pto.getY()));
1126
            pz.setCode(30);
1127
            pz.setData(new Double(pto.getCoordinateAt(2)));
1128
            double velev = ((org.gvsig.fmap.geom.primitive.Point) feature.getDefaultGeometry())
1129
            .getCoordinateAt(2);
1130
            Double elevation = DEFAULT_ELEVATION;
1131
            elevation = new Double(velev);
1132
            DxfGroup handleElevation = new DxfGroup();
1133
            handleElevation.setCode(38);
1134
            handleElevation.setData(elevation);
1135

    
1136
            DxfGroupVector pv = updateProperties(feature, k);
1137
            pv.add(handleElevation);
1138
            pv.add(px);
1139
            pv.add(py);
1140
            pv.add(pz);
1141
            entityMaker.createPoint(pv);
1142
            k++;
1143
            return k;
1144
        }
1145

    
1146
        private int createText3D(int handle, int k, FeatureProvider feature)
1147
        throws Exception {
1148

    
1149
            double velev = ((org.gvsig.fmap.geom.primitive.Point) feature.getDefaultGeometry())
1150
            .getCoordinateAt(0);
1151

    
1152
            Double elevation = new Double(velev);
1153
            String text = feature.get(ID_FIELD_TEXT).toString();
1154
            Double heightText = (Double) feature.get(ID_FIELD_HEIGHTTEXT);
1155
            Double rotationText = (Double) feature.get(ID_FIELD_ROTATIONTEXT);
1156

    
1157
            DxfGroup handleText = new DxfGroup();
1158
            handleText.setCode(1);
1159
            handleText.setData(text);
1160

    
1161
            DxfGroup handleHeightText = new DxfGroup();
1162
            handleHeightText.setCode(40);
1163
            handleHeightText.setData(heightText);
1164

    
1165
            DxfGroup handleRotationText = new DxfGroup();
1166
            handleRotationText.setCode(50);
1167
            handleRotationText.setData(rotationText);
1168

    
1169
            DxfGroup handleElevation = new DxfGroup();
1170
            handleElevation.setCode(38);
1171
            handleElevation.setData(elevation);
1172

    
1173
            org.gvsig.fmap.geom.primitive.Point point =
1174
                (org.gvsig.fmap.geom.primitive.Point) (feature
1175
                    .getDefaultGeometry());
1176

    
1177
            DxfGroup handleGroup = new DxfGroup();
1178
            handleGroup.setCode(5);
1179
            handleGroup.setData(new Integer(handle + k).toString());
1180
            DxfGroup px = new DxfGroup();
1181
            DxfGroup py = new DxfGroup();
1182
            DxfGroup pz = new DxfGroup();
1183
            px.setCode(10);
1184
            px.setData(new Double(point.getX()));
1185
            py.setCode(20);
1186
            py.setData(new Double(point.getY()));
1187
            pz.setCode(30);
1188
            pz.setData(new Double(point.getCoordinateAt(2)));
1189
            DxfGroupVector pv = updateProperties(feature, k);
1190
            pv.add(handleElevation);
1191
            pv.add(handleText);
1192
            pv.add(handleHeightText);
1193
            pv.add(handleRotationText);
1194
            pv.add(handleGroup);
1195
            pv.add(px);
1196
            pv.add(py);
1197
            pv.add(pz);
1198
            entityMaker.createText(pv);
1199
            k++;
1200
            return k;
1201
        }
1202

    
1203
        private int createLwPolyline2D(int handle, int k, FeatureProvider feature,
1204
            boolean isPolygon) throws Exception {
1205
            boolean first = true;
1206
            DxfGroupVector polv = updateProperties(feature, k);
1207
            Vector<org.gvsig.fmap.geom.primitive.Point> vpoints = new Vector<org.gvsig.fmap.geom.primitive.Point>();
1208

    
1209
            DxfGroup polylineFlag = new DxfGroup();
1210
            polylineFlag.setCode(70);
1211
            if (isPolygon) {
1212
                polylineFlag.setData(new Integer(1)); // cerrada
1213
            } else {
1214
                polylineFlag.setData(new Integer(0)); // abierta
1215
            }
1216

    
1217
            PathIterator theIterator = (feature.getDefaultGeometry())
1218
            .getPathIterator(null, geomManager.getFlatness()); // polyLine.
1219
            // getPathIterator
1220
            // (null,
1221
            // flatness);
1222

    
1223
            double[] theData = new double[6];
1224
            while (!theIterator.isDone()) {
1225
                int theType = theIterator.currentSegment(theData);
1226
                switch (theType) {
1227
                case PathIterator.SEG_MOVETO:
1228
                    if (!first) {
1229
                        for (int j = 0; j < vpoints.size(); j++) {
1230
                            DxfGroup xvertex = new DxfGroup();
1231
                            xvertex.setCode(10);
1232
                            xvertex
1233
                            .setData(new Double(
1234
                                vpoints
1235
                                    .get(j).getX()));
1236
                            DxfGroup yvertex = new DxfGroup();
1237
                            yvertex.setCode(20);
1238
                            yvertex
1239
                            .setData(new Double(
1240
                                vpoints
1241
                                    .get(j).getY()));
1242
                            polv.add(xvertex);
1243
                            polv.add(yvertex);
1244
                        }
1245

    
1246
                        entityMaker.createLwPolyline(polv);
1247
                        k++;
1248
                        polv = updateProperties(feature, k);
1249

    
1250
                    }
1251
                    first = false;
1252
                    polv.add(polylineFlag);
1253
                    vpoints.clear();
1254
                    vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1255
                    break;
1256
                case PathIterator.SEG_LINETO:
1257
                    vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1258
                    break;
1259
                case PathIterator.SEG_QUADTO:
1260
                    break;
1261
                case PathIterator.SEG_CUBICTO:
1262
                    break;
1263
                case PathIterator.SEG_CLOSE:
1264
                    polylineFlag.setData(new Integer(1)); // cerrada
1265
                    break;
1266

    
1267
                }
1268
                theIterator.next();
1269
            }
1270

    
1271
            for (int j = 0; j < vpoints.size(); j++) {
1272
                DxfGroup xvertex = new DxfGroup();
1273
                xvertex.setCode(10);
1274
                xvertex
1275
                .setData(new Double(
1276
                    vpoints
1277
                        .get(j).getX()));
1278
                DxfGroup yvertex = new DxfGroup();
1279
                yvertex.setCode(20);
1280
                yvertex
1281
                .setData(new Double(
1282
                    vpoints
1283
                        .get(j).getY()));
1284
                polv.add(xvertex);
1285
                polv.add(yvertex);
1286
            }
1287

    
1288
            entityMaker.createLwPolyline(polv);
1289
            k++;
1290
            return k;
1291
        }
1292

    
1293
        private int createPolyline3D(int handle, int k, FeatureProvider feature)
1294
        throws Exception {
1295
            DxfGroupVector polv = updateProperties(feature, k);
1296
            Vector<org.gvsig.fmap.geom.primitive.Point> vpoints = new Vector<org.gvsig.fmap.geom.primitive.Point>();
1297
            PathIterator theIterator = (feature.getDefaultGeometry())
1298
            .getPathIterator(null, geomManager.getFlatness());
1299
            double[] theData = new double[6];
1300
            OrientablePrimitive curve = (OrientablePrimitive) feature.getDefaultGeometry();
1301
            double[] velev = new double[curve.getNumVertices()];
1302
            for (int i = 0; i < curve.getNumVertices(); i++) {
1303
                velev[i] = curve.getCoordinateAt(i, 2);
1304
            }
1305

    
1306
            while (!theIterator.isDone()) {
1307
                int theType = theIterator.currentSegment(theData);
1308
                switch (theType) {
1309
                case PathIterator.SEG_MOVETO:
1310
                    vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1311
                    break;
1312
                case PathIterator.SEG_LINETO:
1313
                    vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1314
                    break;
1315
                }
1316
                theIterator.next();
1317
            }
1318
            if (constantElevation(velev)) {
1319
                DxfGroup polylineFlag = new DxfGroup();
1320
                polylineFlag.setCode(70);
1321
                polylineFlag.setData(new Integer(0));
1322
                polv.add(polylineFlag);
1323
                DxfGroup elevation = new DxfGroup();
1324
                elevation.setCode(38);
1325
                elevation.setData(new Double(velev[0]));
1326
                polv.add(elevation);
1327
                for (int j = 0; j < vpoints.size(); j++) {
1328
                    DxfGroup xvertex = new DxfGroup();
1329
                    xvertex.setCode(10);
1330
                    xvertex.setData(new Double(
1331
                        vpoints
1332
                            .get(j).getX()));
1333
                    DxfGroup yvertex = new DxfGroup();
1334
                    yvertex.setCode(20);
1335
                    yvertex.setData(new Double(
1336
                        vpoints
1337
                            .get(j).getY()));
1338
                    polv.add(xvertex);
1339
                    polv.add(yvertex);
1340
                }
1341
                entityMaker.createLwPolyline(polv);
1342
                k++;
1343
            } else {
1344
                DxfGroup polylineFlag = new DxfGroup();
1345
                polylineFlag.setCode(70);
1346
                polylineFlag.setData(new Integer(8));
1347
                polv.add(polylineFlag);
1348
                DxfGroup xgroup = new DxfGroup();
1349
                xgroup.setCode(10);
1350
                xgroup.setData(new Double(0.0));
1351
                polv.add(xgroup);
1352
                DxfGroup ygroup = new DxfGroup();
1353
                ygroup.setCode(20);
1354
                ygroup.setData(new Double(0.0));
1355
                polv.add(ygroup);
1356
                DxfGroup elevation = new DxfGroup();
1357
                elevation.setCode(30);
1358
                elevation.setData(new Double(0.0));
1359
                polv.add(elevation);
1360
                DxfGroup subclassMarker = new DxfGroup(100, "AcDb3dPolyline");
1361
                polv.add(subclassMarker);
1362
                entityMaker.createPolyline(polv);
1363
                k++;
1364
                for (int j = 0; j < vpoints.size(); j++) {
1365
                    DxfGroupVector verv = new DxfGroupVector();
1366
                    DxfGroup entityType = new DxfGroup(0, "VERTEX");
1367
                    verv.add(entityType);
1368
                    DxfGroup generalSubclassMarker = new DxfGroup(100,
1369
                    "AcDbEntity");
1370
                    verv.add(generalSubclassMarker);
1371
                    DxfGroup layerName = new DxfGroup(8, "default");
1372
                    verv.add(layerName);
1373
                    DxfGroup vertexSubclassMarker = new DxfGroup(100,
1374
                    "AcDbVertex");
1375
                    verv.add(vertexSubclassMarker);
1376
                    DxfGroup xvertex = new DxfGroup();
1377
                    xvertex.setCode(10);
1378
                    xvertex.setData(new Double(
1379
                        vpoints
1380
                            .get(j).getX()));
1381
                    DxfGroup yvertex = new DxfGroup();
1382
                    yvertex.setCode(20);
1383
                    yvertex.setData(new Double(
1384
                        vpoints
1385
                            .get(j).getY()));
1386
                    DxfGroup zvertex = new DxfGroup();
1387
                    zvertex.setCode(30);
1388
                    zvertex.setData(new Double(velev[j]));
1389
                    verv.add(xvertex);
1390
                    verv.add(yvertex);
1391
                    verv.add(zvertex);
1392
                    entityMaker.addVertex(verv);
1393
                    k++;
1394
                }
1395
                DxfGroupVector seqv = new DxfGroupVector();
1396
                DxfGroup entityType = new DxfGroup(0, "SEQEND");
1397
                seqv.add(entityType);
1398
                DxfGroup generalSubclassMarker = new DxfGroup(100, "AcDbEntity");
1399
                seqv.add(generalSubclassMarker);
1400
                DxfGroup layerName = new DxfGroup(8, "default");
1401
                seqv.add(layerName);
1402
                DxfGroup handleSeqGroup = new DxfGroup();
1403
                handleSeqGroup.setCode(5);
1404
                handleSeqGroup.setData(new Integer(handle + k).toString());
1405
                seqv.add(handleSeqGroup);
1406
                entityMaker.endSeq();
1407
                k++;
1408
            }
1409
            return k;
1410
        }
1411

    
1412
        private boolean constantElevation(double[] velev) {
1413
            boolean constant = true;
1414
            for (int i = 0; i < velev.length; i++) {
1415
                for (int j = 0; j < velev.length; j++) {
1416
                    if (j > i) {
1417
                        if (velev[i] != velev[j]) {
1418
                            constant = false;
1419
                            break;
1420
                        }
1421
                    }
1422
                }
1423
                break;
1424
            }
1425
            return constant;
1426
        }
1427

    
1428
        private int createCircle2D(int handle, int k, FeatureProvider feature)
1429
        throws Exception {
1430
            DxfGroupVector polv = updateProperties(feature, k);
1431
            DxfGroup circleFlag = new DxfGroup();
1432
            circleFlag.setCode(100);
1433
            polv.add(circleFlag);
1434

    
1435
            DxfGroup xvertex = new DxfGroup();
1436
            xvertex.setCode(10);
1437
            Circle circle = (Circle) (feature
1438
                .getDefaultGeometry());
1439
            xvertex.setData(new Double(circle.getCenter().getX()));
1440
            DxfGroup yvertex = new DxfGroup();
1441
            yvertex.setCode(20);
1442
            yvertex.setData(new Double(circle.getCenter().getY()));
1443
            DxfGroup zvertex = new DxfGroup();
1444
            zvertex.setCode(30);
1445
            // TODO: COORDENADA Z. REVISAR ESTO PARA ENTIDADES 3D
1446
            zvertex.setData(new Double(0));
1447

    
1448
            DxfGroup radius = new DxfGroup();
1449
            radius.setCode(40);
1450
            radius.setData(new Double(circle.getRadious()));
1451

    
1452
            polv.add(xvertex);
1453
            polv.add(yvertex);
1454
            polv.add(zvertex);
1455
            polv.add(radius);
1456

    
1457
            entityMaker.createCircle(polv);
1458
            k++;
1459
            return k;
1460
        }
1461

    
1462
        private int createArc2D(int handle, int k, FeatureProvider feature)
1463
        throws Exception {
1464
            Arc arc = (Arc) (feature.getDefaultGeometry());
1465

    
1466
            org.gvsig.fmap.geom.primitive.Point[] pts = new org.gvsig.fmap.geom.primitive.Point[3];
1467
            pts[0] = arc.getInitPoint();
1468
            pts[1] = arc.getMiddlePoint();
1469
            pts[2] = arc.getEndPoint();
1470
            org.gvsig.fmap.geom.primitive.Point center = arc.getCenterPoint();
1471
            GeometryOperationContext ctx = new GeometryOperationContext();
1472
            ctx.setAttribute("geom", pts[0]);
1473
            double radius = ((Double)geomManager.invokeOperation(PointDistance.CODE, center, ctx)).doubleValue();
1474

    
1475
            double initAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1476
            initAngle = Math.toDegrees(initAngle);
1477
            ctx.setAttribute("geom", pts[1]);
1478
            double midAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1479
            midAngle = Math.toDegrees(midAngle);
1480
            ctx.setAttribute("geom", pts[2]);
1481
            double endAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1482
            endAngle = Math.toDegrees(endAngle);
1483

    
1484
            double aux;
1485
            if(initAngle<=endAngle){
1486
                if(initAngle<=midAngle && midAngle<=endAngle){
1487
                    //do nothing
1488
                } else {
1489
                    aux = initAngle;
1490
                    initAngle = endAngle;
1491
                    endAngle = aux;
1492
                }
1493
            } else {
1494
                if(initAngle>=midAngle && midAngle>=endAngle){
1495
                    aux = initAngle;
1496
                    initAngle = endAngle;
1497
                    endAngle = aux;
1498
                } else {
1499
                    //do nothing
1500
                }
1501
            }
1502

    
1503
            DxfGroup ax = new DxfGroup();
1504
            DxfGroup ay = new DxfGroup();
1505
            DxfGroup ac = new DxfGroup();
1506
            DxfGroup ai = new DxfGroup();
1507
            DxfGroup ae = new DxfGroup();
1508
            ax.setCode(10);
1509
            ax.setData(new Double(center.getX()));
1510
            ay.setCode(20);
1511
            ay.setData(new Double(center.getY()));
1512
            ac.setCode(40);
1513
            ac.setData(new Double(radius));
1514
            ai.setCode(50);
1515
            ai.setData(new Double(initAngle));
1516
            ae.setCode(51);
1517
            ae.setData(new Double(endAngle));
1518
            DxfGroupVector av = updateProperties(feature, k);
1519
            av.add(ax);
1520
            av.add(ay);
1521
            av.add(ac);
1522
            av.add(ai);
1523
            av.add(ae);
1524
            entityMaker.createArc(av);
1525
            k++;
1526
            return k;
1527
        }
1528

    
1529
        private int createEllipse2D(int handle, int k, FeatureProvider feature)
1530
        throws Exception {
1531
            Ellipse ellipse = (Ellipse) (feature
1532
                .getDefaultGeometry());
1533

    
1534
            org.gvsig.fmap.geom.primitive.Point center = (org.gvsig.fmap.geom.primitive.Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM2D);
1535
            center.setCoordinateAt(0, (ellipse.getAxis1Start().getX() + ellipse.getAxis1End().getX()) / 2);
1536
            center.setCoordinateAt(1, (ellipse.getAxis1Start().getY() + ellipse.getAxis1End().getY()) / 2);
1537

    
1538
            double mAxisL = ellipse.getAxis2Dist() * 2;
1539
            GeometryOperationContext ctx = new GeometryOperationContext();
1540
            ctx.setAttribute("geom", ellipse.getAxis1End());
1541
            double maAxisL = ((Double)geomManager.invokeOperation(PointDistance.CODE, ellipse.getAxis1Start(), ctx)).doubleValue();
1542

    
1543
            Point2D endPointOfMajorAxis = new Point2D.Double(ellipse.getAxis1End().getX(), ellipse.getAxis1End().getY());
1544
            double azimut = Math
1545
            .atan2(endPointOfMajorAxis.getX() - center.getX(),
1546
                endPointOfMajorAxis.getY() - center.getY());
1547
            double azimut2 = azimut + Math.PI / 2.0;
1548
            if (azimut2 >= Math.PI * 2) {
1549
                azimut2 = azimut2 - Math.PI * 2;
1550
            }
1551
            Point2D endPointOfMinorAxis = new Point2D.Double(center.getX()
1552
                + (ellipse.getAxis2Dist() * Math.sin(azimut2)), center.getY()
1553
                + (ellipse.getAxis2Dist() * Math.cos(azimut2)));
1554

    
1555
            if (mAxisL >= maAxisL) {
1556
                // El menor debe ser menor que el mayor. Los cambiamos.
1557
                double aux = mAxisL;
1558
                mAxisL = maAxisL;
1559
                maAxisL = aux;
1560
                // Tambi�n cambiamos los puntos finales de los ejes.
1561
                Point2D pAux = endPointOfMinorAxis;
1562
                endPointOfMinorAxis = endPointOfMajorAxis;
1563
                endPointOfMajorAxis = pAux;
1564
            }
1565
            double mToMAR = mAxisL / maAxisL;
1566
            DxfGroup x = new DxfGroup();
1567
            DxfGroup y = new DxfGroup();
1568
            DxfGroup xc = new DxfGroup();
1569
            DxfGroup yc = new DxfGroup();
1570
            DxfGroup minToMaj = new DxfGroup();
1571
            x.setCode(10);
1572
            x.setData(new Double(center.getX()));
1573
            y.setCode(20);
1574
            y.setData(new Double(center.getY()));
1575
            xc.setCode(11);
1576
            xc.setData(new Double(endPointOfMajorAxis.getX() - center.getX()));
1577
            yc.setCode(21);
1578
            yc.setData(new Double(endPointOfMajorAxis.getY() - center.getY()));
1579
            minToMaj.setCode(40);
1580
            minToMaj.setData(new Double(mToMAR));
1581
            DxfGroupVector av = updateProperties(feature, k);
1582
            av.add(x);
1583
            av.add(y);
1584
            av.add(xc);
1585
            av.add(yc);
1586
            av.add(minToMaj);
1587
            entityMaker.createEllipse(av);
1588
            k++;
1589
            return k;
1590
        }
1591

    
1592
        /**
1593
         * @return the envelope
1594
         */
1595
        public Envelope getEnvelope() {
1596
            return this.envelope;
1597
        }
1598

    
1599
    }
1600

    
1601
    public boolean closeResourceRequested(ResourceProvider resource) {
1602
        return true;
1603
    }
1604

    
1605
    public int getOIDType() {
1606
        return DataTypes.LONG;
1607
    }
1608

    
1609
    public boolean supportsAppendMode() {
1610
        return false;
1611
    }
1612

    
1613
    public void append(FeatureProvider featureProvider) {
1614
        try {
1615
            writer.add(featureProvider);
1616
        } catch (WriteException e) {
1617
            // TODO Auto-generated catch block
1618
            e.printStackTrace();
1619
        }
1620
    }
1621

    
1622
    public void beginAppend() {
1623
        try {
1624
            writer = new Writer().initialice((File) resource.get(), projection);
1625
            writer.begin();
1626
        } catch (AccessResourceException e) {
1627
            // TODO Auto-generated catch block
1628
            e.printStackTrace();
1629
        }
1630
    }
1631

    
1632
    public void endAppend() {
1633
        try {
1634
            resource.notifyOpen();
1635
            writer.end();
1636
            resource.notifyClose();
1637
            counterNewsOIDs = 0;
1638
        } catch (ResourceNotifyOpenException e) {
1639
            // TODO Auto-generated catch block
1640
            e.printStackTrace();
1641
        } catch (ResourceNotifyCloseException e) {
1642
            // TODO Auto-generated catch block
1643
            e.printStackTrace();
1644
        } catch (WriteException e) {
1645
            // TODO Auto-generated catch block
1646
            e.printStackTrace();
1647
        }
1648
    }
1649

    
1650
    /**
1651
     * @param state
1652
     * @throws PersistenceException
1653
     */
1654
    public void saveToState(PersistentState state) throws PersistenceException {
1655
        // TODO Auto-generated method stub
1656
        throw new NotYetImplemented();
1657
    }
1658

    
1659
    /**
1660
     * @param state
1661
     * @throws PersistenceException
1662
     */
1663
    public void loadFromState(PersistentState state) throws PersistenceException {
1664
        // TODO Auto-generated method stub
1665
        throw new NotYetImplemented();
1666
    }
1667

    
1668
    public Object createNewOID() {
1669
        return new Long(counterNewsOIDs++);
1670
    }
1671

    
1672
    protected void initializeFeatureTypes() throws InitializeException {
1673
        try {
1674
            this.open();
1675
        } catch (OpenException e) {
1676
            throw new InitializeException(this.getProviderName(), e);
1677
        }
1678
    }
1679

    
1680
    public Envelope getEnvelope() throws DataException {
1681
        this.open();
1682
        return this.envelope;
1683
    }
1684

    
1685
    public Object getDynValue(String name) throws DynFieldNotFoundException {
1686
        if( DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name) ) {
1687
            try {
1688
                return this.getEnvelope();
1689
            } catch (DataException e) {
1690
                return null;
1691
            }
1692
        } else {
1693
            if( DataStore.METADATA_CRS.equalsIgnoreCase(name) ) {
1694
                IProjection pro = this.getDXFParameters().getCRS();
1695
                if (pro != null){
1696
                    return pro;
1697
                }
1698
            }
1699
        }
1700
        return super.getDynValue(name);
1701
    }
1702

    
1703

    
1704
    /*
1705
     * (non-Javadoc)
1706
     *
1707
     * @see
1708
     * org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
1709
     * gvsig.fmap.dal.resource.spi.ResourceProvider)
1710
     */
1711
    public void resourceChanged(ResourceProvider resource) {
1712
        this.getStoreServices().notifyChange(
1713
            DataStoreNotification.RESOURCE_CHANGED,
1714
            resource);
1715
    }
1716

    
1717

    
1718
    public Object getSourceId() {
1719
        return this.getDXFParameters().getFile();
1720
    }
1721

    
1722
    public String getName() {
1723
        String name = this.getDXFParameters().getFile().getName();
1724

    
1725
        return FilenameUtils.getBaseName(name);
1726
    }
1727

    
1728
    public String getFullName() {
1729
        return this.getDXFParameters().getFile().getAbsolutePath();
1730
    }
1731

    
1732
    public ResourceProvider getResource() {
1733
        return resource;
1734
    }
1735

    
1736
    /* (non-Javadoc)
1737
     * @see org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider#doDispose()
1738
     */
1739
    @Override
1740
    protected void doDispose() throws BaseException {
1741
        super.doDispose();
1742
        resource.removeConsumer(this);
1743
    }
1744

    
1745
}