Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_dalfile / src / org / gvsig / fmap / dal / store / dxf / DXFStoreProvider.java @ 34899

History | View | Annotate | Download (48.7 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.cresques.cts.IProjection;
15
import org.slf4j.Logger;
16
import org.slf4j.LoggerFactory;
17

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

    
88
public class DXFStoreProvider extends AbstractMemoryStoreProvider implements
89
                ResourceConsumer {
90
        private static final Logger logger = LoggerFactory.getLogger(DXFStoreProvider.class);
91
        
92
        public static final String NAME = "DXF";
93
        public static final String DESCRIPTION = "DXF file";
94

    
95
        public static final String METADATA_DEFINITION_NAME = NAME;
96

    
97
        public static final String NAME_FIELD_ID = "ID";
98
        public static final String NAME_FIELD_GEOMETRY = "Geometry";
99
        public static final String NAME_FIELD_ENTITY = "Entity";
100
        public static final String NAME_FIELD_LAYER = "Layer";
101
        public static final String NAME_FIELD_COLOR = "Color";
102
        public static final String NAME_FIELD_ELEVATION = "Elevation";
103
        public static final String NAME_FIELD_THICKNESS = "Thickness";
104
        public static final String NAME_FIELD_TEXT = "Text";
105
        public static final String NAME_FIELD_HEIGHTTEXT = "HeightText";
106
        public static final String NAME_FIELD_ROTATIONTEXT = "Rotation";
107

    
108
        private int ID_FIELD_ID = 0;
109
        private int ID_FIELD_GEOMETRY = 1;
110
        private int ID_FIELD_ENTITY = 2;
111
        private int ID_FIELD_LAYER = 3;
112
        private int ID_FIELD_COLOR = 4;
113
        private int ID_FIELD_ELEVATION = 5;
114
        private int ID_FIELD_THICKNESS = 6;
115
        private int ID_FIELD_TEXT = 7;
116
        private int ID_FIELD_HEIGHTTEXT = 8;
117
        private int ID_FIELD_ROTATIONTEXT = 9;
118

    
119
        private IProjection projection;
120
        private ResourceProvider resource;
121
        private LegendBuilder legendBuilder;
122

    
123
        private long counterNewsOIDs = 0;
124
        private Envelope envelope;
125
        private Writer writer;
126
        protected GeometryManager geomManager = GeometryLocator.getGeometryManager();
127

    
128

    
129
        public DXFStoreProvider(DXFStoreParameters parameters,
130
                        DataStoreProviderServices storeServices) throws InitializeException {
131
                super(
132
                                parameters, 
133
                                storeServices,
134
                                FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME)
135
                );
136

    
137
                counterNewsOIDs = 0;
138
                //                projection = CRSFactory.getCRS(getParameters().getSRSID());
139

    
140
                File file = getDXFParameters().getFile();
141
                resource = this.createResource(
142
                                FileResource.NAME,
143
                                new Object[] { file.getAbsolutePath() }
144
                        );
145

    
146
                resource.addConsumer(this);
147

    
148
                this.projection = this.getDXFParameters().getCRS();
149

    
150

    
151
                try {
152
                        legendBuilder = (LegendBuilder) this.invokeDynMethod(
153
                                        LegendBuilder.DYNMETHOD_BUILDER_NAME, null);
154
                } catch (DynMethodException e) {
155
                        legendBuilder = null;
156
                } catch (Exception e) {
157
                        throw new InitializeException(e);
158
                }
159

    
160
                this.initializeFeatureTypes();
161

    
162
        }
163

    
164
        private DXFStoreParameters getDXFParameters() {
165
                return (DXFStoreParameters) this.getParameters();
166
        }
167

    
168
        public String getProviderName() {
169
                return NAME;
170
        }
171

    
172
        public boolean allowWrite() {
173
                return true;
174
        }
175

    
176
        public Object getLegend() throws OpenException {
177
                this.open();
178
                if (legendBuilder == null) {
179
                        return null;
180
                }
181
                return legendBuilder.getLegend();
182
        }
183

    
184
        public Object getLabeling() throws OpenException {
185
                this.open();
186
                if (legendBuilder == null) {
187
                        return null;
188
                }
189
                return legendBuilder.getLabeling();
190
        }
191

    
192
        private class DXFData {
193
                public List data = null;
194
                public FeatureType defaultFType = null;
195
                public List fTypes = null;
196
                public Envelope envelope = null;
197
                public IProjection projection;
198
                public LegendBuilder legendBuilder;
199
                public Envelope getEnvelopeCopy() throws CreateEnvelopeException {
200
                        if (envelope == null) {
201
                                return null;
202
                        }
203
                        Envelope newEnvelope;
204
                        if (envelope.getDimension() == 2) {
205
                                newEnvelope = geomManager.createEnvelope(SUBTYPES.GEOM2D);
206
                        } else {
207
                                newEnvelope = geomManager.createEnvelope(SUBTYPES.GEOM3D);
208

    
209
                        }
210
                        newEnvelope.setLowerCorner(envelope.getLowerCorner());
211
                        newEnvelope.setUpperCorner(envelope.getUpperCorner());
212
                        return newEnvelope;
213
                }
214
        }
215

    
216
        public void open() throws OpenException {
217
                if (this.data != null) {
218
                        return;
219
                }
220
                try {
221
                        getResource().execute(new ResourceAction() {
222
                                public Object run() throws Exception {
223
                                        DXFData dxfData = null;
224
                                        if (resource.getData() != null) {
225
                                                dxfData = (DXFData) ((Map) resource.getData())
226
                                                                .get(projection
227
                                                                .getAbrev()); // OJO no es del todo correcto (puede
228
                                                                                                // llevar reproyeccion)
229
                                        } else {
230
                                                resource.setData(new HashMap());
231
                                        }
232
                                        FeatureStoreProviderServices store = getStoreServices();
233
                                        if (dxfData == null) {
234
                                                dxfData = new DXFData();
235
                                                dxfData.data = new ArrayList();
236
                                                data = dxfData.data;
237
                                                counterNewsOIDs = 0;
238
                                                Reader reader = new Reader().initialice(
239
                                                                getMemoryProvider(),
240
                                                                new File((String) resource.get()),
241
                                                                projection,
242
                                                                legendBuilder
243
                                                        );
244
                                                reader.begin(store);
245
                                                dxfData.defaultFType = reader.getDefaultType()
246
                                                                .getNotEditableCopy();
247
                                                ArrayList types = new ArrayList();
248
                                                Iterator it = reader.getTypes().iterator();
249
                                                EditableFeatureType fType;
250
                                                while (it.hasNext()) {
251
                                                        fType = (EditableFeatureType) it.next();
252
                                                        if (fType.getId().equals(dxfData.defaultFType.getId())) {
253
                                                                types.add(dxfData.defaultFType);
254
                                                        } else {
255
                                                                types.add(fType.getNotEditableCopy());
256
                                                        }
257
                                                }
258
                                                dxfData.fTypes = types;
259

    
260
                                                resource.notifyOpen();
261
                                                store.setFeatureTypes(dxfData.fTypes, dxfData.defaultFType);
262
                                                reader.load();
263
                                                //                                envelope = reader.getEnvelope();
264

    
265
                                                dxfData.envelope = reader.getEnvelope();
266

    
267
                                                dxfData.legendBuilder = legendBuilder;
268

    
269
                                                dxfData.projection = projection;
270

    
271
                                                reader.end();
272
                                                resource.notifyClose();
273
                                                ((Map) resource.getData()).put(projection.getAbrev(),
274
                                                                dxfData); // OJO la reproyeccion
275
                                        }
276

    
277
                                        data = dxfData.data;
278
                                        store.setFeatureTypes(dxfData.fTypes, dxfData.defaultFType);
279
                                        legendBuilder = dxfData.legendBuilder;
280
                                        envelope= dxfData.getEnvelopeCopy();
281
                                        // setDynValue("CRS", projection.getAbrev());
282
                                        counterNewsOIDs = data.size();
283
                                        return null;
284
                                }
285
                        });
286
                } catch (Exception e) {
287
                        data = null;
288
                        try {
289
                                throw new OpenException(resource.getName(), e);
290
                        } catch (AccessResourceException e1) {
291
                                throw new OpenException(getProviderName(), e);
292
                        }
293
                }
294
        }
295

    
296

    
297
        public DataServerExplorer getExplorer() throws ReadException {
298
                DataManager manager = DALLocator.getDataManager();
299
                FilesystemServerExplorerParameters params;
300
                try {
301
                        params = (FilesystemServerExplorerParameters) manager
302
                                .createServerExplorerParameters(FilesystemServerExplorer.NAME);
303
                        params.setRoot(this.getDXFParameters().getFile().getParent());
304
                        return manager.openServerExplorer(FilesystemServerExplorer.NAME,params);
305
                } catch (DataException e) {
306
                        throw new ReadException(this.getProviderName(), e);
307
                } catch (ValidateDataParametersException e) {
308
                        throw new ReadException(this.getProviderName(), e);
309
                }
310

    
311
        }
312

    
313

    
314

    
315
        public void performChanges(Iterator deleteds, Iterator inserteds, Iterator updateds, Iterator originalFeatureTypesUpdated) throws PerformEditingException {
316

    
317
                try {
318
                        getResource().execute(new ResourceAction() {
319
                                public Object run() throws Exception {
320
                                        FeatureSet features = null;
321
                                        DisposableIterator it = null;
322
                                        try {
323
                                        File file = (File) resource.get();
324
                                        String fileName = file.getAbsolutePath();
325
                                        writer = new Writer().initialice(file, projection);
326
                                                features =
327
                                                        getStoreServices().getFeatureStore()
328
                                                                        .getFeatureSet();
329

    
330
                                        writer.begin();
331
                                                it = features.fastIterator();
332
                                        while (it.hasNext()) {
333
                                                writer.add(getStoreServices().getFeatureProviderFromFeature(
334
                                                                (org.gvsig.fmap.dal.feature.Feature) it.next()));
335
                                        }
336
                                        writer.end();
337
                                        resource.notifyChanges();
338
                                        counterNewsOIDs = 0;
339
                                        } finally {
340
                                                if (it != null) {
341
                                                        it.dispose();
342
                                                }
343
                                                if (features != null) {
344
                                                        features.dispose();
345
                                                }
346
                                        }
347
                                        return null;
348
                                }
349
                        });
350
                } catch (Exception e) {
351
                        throw new PerformEditingException(getResource().toString(), e);
352
                }
353
        }
354

    
355
        public class Reader {
356
                private File file;
357
                private String fileName;
358
                private IProjection projection;
359
                private List types;
360
                private LegendBuilder leyendBuilder;
361
                private AbstractMemoryStoreProvider store;
362
                private Envelope envelope;
363
                
364
                 //Next two variables are used to read the DXF file
365
        private DxfFile.EntityFactory featureMaker;
366
        private DxfFile.VarSettings headerManager;
367

    
368
                public Reader initialice(AbstractMemoryStoreProvider store, File file,
369
                                IProjection projection,
370
                                LegendBuilder leyendBuilder) {
371
                        this.store = store;
372
                        this.file = file;
373
                        this.fileName = file.getAbsolutePath();
374
                        this.projection = projection;
375
                        this.leyendBuilder = leyendBuilder;
376
                        if (leyendBuilder != null) {
377
                                leyendBuilder.initialize(store);
378
                        }
379
                        return this;
380
                }
381

    
382
                public Envelope getEnvelope() {
383
                        return this.envelope;
384
                }
385

    
386
                public void begin(FeatureStoreProviderServices store) throws LoadException {
387
                    featureMaker = new DxfFeatureMaker(projection);
388
            headerManager = new DxfHeaderManager();
389
            DxfFile dxfFeatureFile = new DxfFile(projection, file
390
                .getAbsolutePath(), featureMaker, headerManager);
391

    
392
            try {
393
                dxfFeatureFile.load();
394
            } catch (Exception e1) {
395
                throw new LoadException(e1, fileName);
396
            }
397
            
398
                        EditableFeatureType featureType = store.createFeatureType();
399

    
400
                        featureType.setHasOID(true);
401

    
402
                        ID_FIELD_ID = featureType.add(NAME_FIELD_ID, DataTypes.INT)
403
                                        .setDefaultValue(Integer.valueOf(0))
404
                                .getIndex();
405

    
406
                        EditableFeatureAttributeDescriptor attr = featureType.add(
407
                                        NAME_FIELD_GEOMETRY, DataTypes.GEOMETRY);
408
                        attr.setSRS(this.projection);
409
                        attr.setGeometryType(Geometry.TYPES.GEOMETRY);                        
410
                         //If is a 3D file, set the geometry subtype
411
            if (featureMaker.isDxf3DFile() && headerManager.isWritedDxf3D()){
412
                attr.setGeometrySubType(Geometry.SUBTYPES.GEOM3D);
413
            }else{
414
                attr.setGeometrySubType(Geometry.SUBTYPES.GEOM2D);
415
            }                        
416
                        ID_FIELD_GEOMETRY = attr.getIndex();
417

    
418
                        featureType.setDefaultGeometryAttributeName(NAME_FIELD_GEOMETRY);
419

    
420
                        // FIXME: Cual es el size y el valor por defecto para Entity ?
421
                        ID_FIELD_ENTITY = featureType.add(NAME_FIELD_ENTITY,
422
                                        DataTypes.STRING, 100)
423
                                        .setDefaultValue("")
424
                                        .getIndex();
425

    
426
                        // FIXME: Cual es el size de Layer ?
427
                        ID_FIELD_LAYER = featureType.add(NAME_FIELD_LAYER,
428
                                        DataTypes.STRING, 100)
429
                                        .setDefaultValue(
430
                                        "default").getIndex();
431

    
432
                        ID_FIELD_COLOR = featureType.add(NAME_FIELD_COLOR,
433
                                        DataTypes.INT)
434
                                        .setDefaultValue(
435
                                        Integer.valueOf(0)).getIndex();
436

    
437
                        ID_FIELD_ELEVATION = featureType.add(NAME_FIELD_ELEVATION,
438
                                        DataTypes.DOUBLE)
439
                                        .setDefaultValue(
440
                                        Double.valueOf(0)).getIndex();
441

    
442
                        ID_FIELD_THICKNESS = featureType.add(NAME_FIELD_THICKNESS,
443
                                        DataTypes.DOUBLE)
444
                                        .setDefaultValue(
445
                                        Double.valueOf(0)).getIndex();
446

    
447
                        // FIXME: Cual es el size de Text ?
448
                        ID_FIELD_TEXT = featureType.add(NAME_FIELD_TEXT,
449
                                        DataTypes.STRING, 100)
450
                                        .setDefaultValue("")
451
                                        .getIndex();
452

    
453
                        ID_FIELD_HEIGHTTEXT = featureType.add(NAME_FIELD_HEIGHTTEXT,
454
                                        DataTypes.DOUBLE).setDefaultValue(
455
                                        Double.valueOf(10)).getIndex();
456

    
457
                        ID_FIELD_ROTATIONTEXT = featureType.add(NAME_FIELD_ROTATIONTEXT,
458
                                        DataTypes.DOUBLE).setDefaultValue(
459
                                        Double.valueOf(0)).getIndex();
460

    
461

    
462

    
463
                        // FIXME: Parece que el DXF puede tener mas atributos opcionales.
464
                        // Habria que ver de pillarlos ?
465

    
466
                        types = new ArrayList();
467
                        types.add(featureType);
468

    
469
                        if (leyendBuilder != null) {
470
                                leyendBuilder.begin();
471
                        }
472

    
473
                }
474

    
475
                public void end() {
476
                        if (leyendBuilder != null) {
477
                                leyendBuilder.end();
478
                        }
479
                }
480

    
481
                public List getTypes() {
482
                        return types;
483
                }
484

    
485
                public EditableFeatureType getDefaultType() {
486
                        return (EditableFeatureType) types.get(0);
487
                }
488

    
489
                private Double toDouble(String value) {
490
                        if (value == null) {
491
                                return Double.valueOf(0);
492
                        }
493
                        return Double.valueOf(value);
494
                }
495

    
496
                public void load() throws DataException {
497

    
498
                        this.envelope = null;
499

    
500
                        IObjList.vector features = (IObjList.vector) ((DxfFeatureMaker) featureMaker)
501
                                        .getObjects();
502
                        String acadVersion = ((DxfHeaderManager) headerManager)
503
                                        .getAcadVersion();
504

    
505

    
506
                        logger.info("load: acadVersion = '" + acadVersion + "'");
507

    
508
                        GeometryManager gManager = GeometryLocator.getGeometryManager();
509

    
510
                        if (!featureMaker.isDxf3DFile() && !headerManager.isWritedDxf3D()) {
511
                                // y no est?n todos a 9999
512
                                Feature[] features2D = new Feature[features.size()];
513
                                for (int i = 0; i < features.size(); i++) {
514
                                        Feature fea = (Feature) features.get(i);
515
                                        if (fea.getGeometry() instanceof org.gvsig.dxf.px.gml.Point3D) {
516
                                                Point point = (Point) fea.getGeometry();
517
                                                Point point2 = new Point();
518
                                                for (int j = 0; j < point.pointNr(); j++) {
519
                                                        point2.add(point.get(j));
520
                                                }
521
                                                point2.setTextPoint(point.isTextPoint());
522
                                                fea.setGeometry(point2);
523
                                                features2D[i] = fea;
524

    
525
                                        } else if (fea.getGeometry() instanceof LineString3D) {
526
                                                LineString lineString = (LineString) fea.getGeometry();
527
                                                LineString lineString2 = new LineString();
528
                                                for (int j = 0; j < lineString.pointNr(); j++) {
529
                                                        lineString2.add(lineString.get(j));
530
                                                }
531
                                                fea.setGeometry(lineString2);
532
                                                features2D[i] = fea;
533
                                        } else if (fea.getGeometry() instanceof Polygon3D) {
534
                                                Polygon polygon = (Polygon) fea.getGeometry();
535
                                                Polygon polygon2 = new Polygon();
536
                                                for (int j = 0; j < polygon.pointNr(); j++) {
537
                                                        polygon2.add(polygon.get(j));
538
                                                }
539
                                                fea.setGeometry(polygon2);
540
                                                features2D[i] = fea;
541
                                        }
542
                                }
543
                                features.clear();
544
                                for (int i = 0; i < features2D.length; i++) {
545
                                        features.add(features2D[i]);
546
                                }
547
                        }
548

    
549

    
550

    
551
                        for (int i = 0; i < features.size(); i++) {
552

    
553
                                FeatureProvider feature = store.createFeatureProvider(store
554
                                                .getStoreServices().getDefaultFeatureType());
555

    
556
                                try {
557
                                        Feature fea = (Feature) features.get(i);
558

    
559
                                        feature.setOID(new Long(i));
560
                                        feature.set(ID_FIELD_ID, Integer.valueOf(i));
561
                                        feature.set(ID_FIELD_ENTITY, fea.getProp("dxfEntity"));
562
                                        feature.set(ID_FIELD_LAYER, fea.getProp("layer"));
563
                                        feature.set(ID_FIELD_COLOR, Integer.valueOf(fea
564
                                                        .getProp("color")));
565
                                        feature.set(ID_FIELD_TEXT, fea.getProp("text"));
566
                                        feature.set(ID_FIELD_HEIGHTTEXT, toDouble(fea
567
                                                        .getProp("textHeight")));
568
                                        feature.set(ID_FIELD_ROTATIONTEXT, toDouble(fea
569
                                                        .getProp("textRotation")));
570
                                        feature.set(ID_FIELD_ELEVATION, toDouble(fea
571
                                                        .getProp("elevation")));
572
                                        feature.set(ID_FIELD_THICKNESS, toDouble(fea
573
                                                        .getProp("thickness")));
574
                                        // FIXME: Abria que pillar el resto de atributos del DXF.
575

    
576
                                        store.addFeatureProvider(feature);
577

    
578

    
579
                                        // FIXME: Habia una incongruencia en el codigo ya que al
580
                                        // campo
581
                                        // ID_FIELD_GEOMETRY igual le asignaba una geometria que un
582
                                        // valor de cadena como 'Point3D', 'Polyline2D' o
583
                                        // 'Polyline3D'
584
                                        // Faltaria un atributo ID_FIELD_FSHAPE ?
585
                                        //
586

    
587
                                        if (fea.getGeometry() instanceof Point
588
                                                        && !(fea.getGeometry() instanceof org.gvsig.dxf.px.gml.Point3D)) {
589
                                                Point point = (Point) fea.getGeometry();
590
                                                Point2D pto = new Point2D.Double();
591
                                                pto = point.get(0);
592

    
593
                                                org.gvsig.fmap.geom.primitive.Point geom = (org.gvsig.fmap.geom.primitive.Point)gManager.create(TYPES.POINT , SUBTYPES.GEOM2D);
594
                                                geom.setX(pto.getX());
595
                                                geom.setY(pto.getY());
596
                                                feature.set(ID_FIELD_GEOMETRY, geom);
597
                                                if (this.envelope == null) {
598
                                                        this.envelope = geom.getEnvelope();
599
                                                } else {
600
                                                        this.envelope.add(geom.getEnvelope());
601
                                                }
602

    
603
                                                if (point.isTextPoint()) {
604
                                                        /// TODO labeling
605
                                                }
606
                                        } else if (fea.getGeometry() instanceof org.gvsig.dxf.px.gml.Point3D) {
607
                                                org.gvsig.dxf.px.gml.Point3D point = (org.gvsig.dxf.px.gml.Point3D) fea
608
                                                                .getGeometry();
609
                                                Point3D pto = new Point3D();
610
                                                pto = point.getPoint3D(0);
611
                                                org.gvsig.fmap.geom.primitive.Point geom = (org.gvsig.fmap.geom.primitive.Point)gManager.create(TYPES.POINT , SUBTYPES.GEOM3D);
612
                                                geom.setX(pto.getX());
613
                                                geom.setY(pto.getY());
614
                                                geom.setCoordinateAt(2, pto.getZ());
615

    
616
                                                feature.set(ID_FIELD_GEOMETRY, geom);
617
                                                if (this.envelope == null) {
618
                                                        this.envelope = geom.getEnvelope();
619
                                                } else {
620
                                                        this.envelope.add(geom.getEnvelope());
621
                                                }
622

    
623
                                                if (point.isTextPoint()) {
624
                                                        /// TODO labeling
625
                                                }
626
                                        } else if (fea.getGeometry() instanceof LineString
627
                                                        && !(fea.getGeometry() instanceof LineString3D)) {
628
                                                GeneralPathX genPathX = new GeneralPathX();
629
                                                Point2D[] pts = new Point2D[fea.getGeometry().pointNr()];
630
                                                for (int j = 0; j < fea.getGeometry().pointNr(); j++) {
631
                                                        pts[j] = fea.getGeometry().get(j);
632
                                                }
633
                                                genPathX.moveTo(pts[0].getX(), pts[0].getY());
634
                                                for (int j = 1; j < pts.length; j++) {
635
                                                        genPathX.lineTo(pts[j].getX(), pts[j].getY());
636
                                                }
637
                                                Curve geom = (Curve)gManager.create(TYPES.CURVE , SUBTYPES.GEOM2D);
638
                                                geom.setGeneralPath(genPathX);
639
                                                feature.set(ID_FIELD_GEOMETRY, geom);
640
                                                if (this.envelope == null) {
641
                                                        this.envelope = geom.getEnvelope();
642
                                                } else {
643
                                                        this.envelope.add(geom.getEnvelope());
644
                                                }
645

    
646
                                        } else if (fea.getGeometry() instanceof LineString3D) {
647
                                                GeneralPathX genPathX = new GeneralPathX();
648
                                                Point3D[] pts = new Point3D[fea.getGeometry().pointNr()];
649
                                                for (int j = 0; j < fea.getGeometry().pointNr(); j++) {
650
                                                        pts[j] = ((LineString3D) fea.getGeometry())
651
                                                                        .getPoint3D(j);
652
                                                }
653
                                                genPathX.moveTo(pts[0].getX(), pts[0].getY());
654
                                                for (int j = 1; j < pts.length; j++) {
655
                                                        genPathX.lineTo(pts[j].getX(), pts[j].getY());
656
                                                }
657
                                                double[] elevations = new double[pts.length];
658
                                                for (int j = 0; j < pts.length; j++) {
659
                                                        elevations[j] = pts[j].getZ();
660
                                                }
661
                                                Curve geom = (Curve)gManager.create(TYPES.CURVE , SUBTYPES.GEOM3D);
662
                                                geom.setGeneralPath(genPathX);
663
                                                for (int j=0 ; j<elevations.length ; j++){
664
                                                        geom.setCoordinateAt(j, 2, elevations[j]);
665
                                                }
666
                                                feature.set(ID_FIELD_GEOMETRY, geom);
667
                                                if (this.envelope == null) {
668
                                                        this.envelope = geom.getEnvelope();
669
                                                } else {
670
                                                        this.envelope.add(geom.getEnvelope());
671
                                                }
672

    
673
                                        } else if (fea.getGeometry() instanceof Polygon
674
                                                        && !(fea.getGeometry() instanceof Polygon3D)) {
675
                                                GeneralPathX genPathX = new GeneralPathX();
676
                                                Point2D firstPt = new Point2D.Double();
677
                                                firstPt = fea.getGeometry().get(0);
678
                                                Point2D[] pts = new Point2D[fea.getGeometry().pointNr() + 1];
679
                                                for (int j = 0; j < fea.getGeometry().pointNr(); j++) {
680
                                                        pts[j] = fea.getGeometry().get(j);
681
                                                }
682
                                                pts[fea.getGeometry().pointNr()] = firstPt;
683
                                                genPathX.moveTo(pts[0].getX(), pts[0].getY());
684
                                                for (int j = 1; j < pts.length; j++) {
685
                                                        genPathX.lineTo(pts[j].getX(), pts[j].getY());
686
                                                }
687
                                                Surface geom = (Surface)gManager.create(TYPES.SURFACE , SUBTYPES.GEOM2D);
688
                                                geom.setGeneralPath(genPathX);
689
                                                feature.set(ID_FIELD_GEOMETRY, geom);
690
                                                if (this.envelope == null) {
691
                                                        this.envelope = geom.getEnvelope();
692
                                                } else {
693
                                                        this.envelope.add(geom.getEnvelope());
694
                                                }
695

    
696
                                        } else if (fea.getGeometry() instanceof Polygon3D) {
697
                                                GeneralPathX genPathX = new GeneralPathX();
698
                                                Point3D firstPt = new Point3D();
699
                                                firstPt = ((Polygon3D) fea.getGeometry()).getPoint3D(0);
700
                                                Point3D[] pts = new Point3D[fea.getGeometry().pointNr() + 1];
701
                                                for (int j = 0; j < fea.getGeometry().pointNr(); j++) {
702
                                                        pts[j] = ((Polygon3D) fea.getGeometry())
703
                                                                        .getPoint3D(j);
704
                                                }
705
                                                pts[fea.getGeometry().pointNr()] = firstPt;
706
                                                genPathX.moveTo(pts[0].getX(), pts[0].getY());
707
                                                for (int j = 1; j < pts.length; j++) {
708
                                                        genPathX.lineTo(pts[j].getX(), pts[j].getY());
709
                                                }
710
                                                double[] elevations = new double[pts.length];
711
                                                for (int j = 0; j < pts.length; j++) {
712
                                                        elevations[j] = pts[j].getZ();
713
                                                }
714
                                                Surface geom = (Surface)gManager.create(TYPES.SURFACE , SUBTYPES.GEOM3D);
715
                                                geom.setGeneralPath(genPathX);
716
                                                for (int j=0 ; j<elevations.length ; j++){
717
                                                        geom.setCoordinateAt(j, 2, elevations[j]);
718
                                                }
719
                                                feature.set(ID_FIELD_GEOMETRY, geom);
720
                                                if (this.envelope == null) {
721
                                                        this.envelope = geom.getEnvelope();
722
                                                } else {
723
                                                        this.envelope.add(geom.getEnvelope());
724
                                                }
725
                                        } else {
726
                                                logger.warn(
727
                                                        MessageFormat.format(
728
                                                                "load: geometry type {1} not supported",
729
                                                                new Object[] { fea.getGeometry().getClass().getName() }
730
                                                        )
731
                                                );
732
                                        }
733
                                } catch (Exception e) {
734
                                        throw new LoadException(e, fileName);
735
                                }
736
                                if (leyendBuilder != null) {
737
                                        leyendBuilder.process(feature);
738
                                }
739

    
740
                        }
741
                }
742

    
743
        }
744

    
745
        public class Writer {
746
                private Double DEFAULT_ELEVATION = new Double(0);
747

    
748
                private DxfFile.EntityFactory entityMaker;
749

    
750
                private IProjection proj = null;
751

    
752
                private int handle = 40; // Revisar porqu? es 40.
753

    
754
                private int k = 0;
755

    
756
                private boolean dxf3DFile = false;
757
                private String fileName;
758

    
759
                public Writer initialice(File file, IProjection projection) {
760
                        this.proj = projection;
761
                        this.fileName = file.getAbsolutePath();
762
                        entityMaker = new DxfEntityMaker(proj);
763

    
764
                        return this;
765
                }
766

    
767
                public void begin() {
768
                        entityMaker = new DxfEntityMaker(proj);
769
                }
770

    
771
                public void end() throws WriteException {
772
                        try {
773
                                DxfFile dxfFile = new DxfFile(null, fileName, entityMaker);
774
                                dxfFile.setCadFlag(true);
775
                                if (dxf3DFile) {
776
                                        dxfFile.setDxf3DFlag(true);
777
                                }
778
                                dxfFile.save(fileName);
779
                                dxfFile.close();
780
                        } catch (Exception e) {
781
                                throw new WriteException(fileName, e);
782
                        }
783
                }
784

    
785
                public void add(FeatureProvider feature) throws WriteException {
786
                        try {
787
                                Geometry geom = feature.getDefaultGeometry();
788
                                GeometryType type = geom.getGeometryType();
789

    
790
                                if ((TYPES.POINT == type.getType()) && (SUBTYPES.GEOM3D == type.getSubType())) {
791
                                        dxf3DFile = true;
792
                                        k = createPoint3D(handle, k, feature);
793

    
794
                                } else if ((TYPES.POINT == type.getType()) && (SUBTYPES.GEOM2D == type.getSubType())) {
795
                                        k = createPoint2D(handle, k, feature);
796

    
797
                                } else if ((TYPES.CURVE == type.getType()) && (SUBTYPES.GEOM3D == type.getSubType())) {
798
                                        dxf3DFile = true;
799
                                        k = createPolyline3D(handle, k, feature);
800

    
801
                                } else if ((TYPES.ARC == type.getType()) && (SUBTYPES.GEOM2D == type.getSubType())) {
802
                                        k = createArc2D(handle, k, feature);
803

    
804
                                } else if ((TYPES.CURVE == type.getType()) && (SUBTYPES.GEOM2D == type.getSubType())) {
805
                                        k = createLwPolyline2D(handle, k, feature, false);
806

    
807
                                } else if ((TYPES.SURFACE == type.getType()) && (SUBTYPES.GEOM3D == type.getSubType())) {
808
                                        dxf3DFile = true;
809
                                        k = createPolyline3D(handle, k, feature);
810

    
811
                                } else if ((TYPES.CIRCLE == type.getType()) && (SUBTYPES.GEOM2D == type.getSubType())) {
812
                                        k = createCircle2D(handle, k, feature);
813

    
814
                                } else if ((TYPES.ELLIPSE == type.getType()) && (SUBTYPES.GEOM2D == type.getSubType())) {
815
                                        k = createEllipse2D(handle, k, feature);
816

    
817
                                } else if ((TYPES.SURFACE == type.getType()) && (SUBTYPES.GEOM2D == type.getSubType())) {
818
                                        k = createLwPolyline2D(handle, k, feature, true);
819

    
820
                                } else {
821
                                        logger.warn(
822
                                                        MessageFormat.format(
823
                                                                        "Geometry '{1}' not yet supported",
824
                                                                        new Object[] {geom.getClass().getName()}
825
                                                                )
826
                                                );
827
                                        k++;
828
                                }
829
                        } catch (Exception e) {
830
                                throw new WriteException(fileName, e);
831
                        }
832

    
833
                }
834

    
835
                private boolean hasText(FeatureProvider feature) {
836
                        if (feature.isNull(ID_FIELD_TEXT)) {
837
                                return false;
838
                        }
839
                        if (feature.get(ID_FIELD_TEXT).equals("")) {
840
                                return false;
841
                        }
842
                        return true;
843
                }
844

    
845
                private DxfGroupVector updateProperties(FeatureProvider feature, int k) {
846
                        DxfGroupVector polv = new DxfGroupVector();
847

    
848
                        String layer = (String) feature.get(ID_FIELD_LAYER);
849
                        Integer color = (Integer) feature.get(ID_FIELD_COLOR);
850
                        Double thickness = (Double) feature.get(ID_FIELD_THICKNESS);
851

    
852
                        DxfGroup geometryLayer = new DxfGroup(8, layer);
853

    
854
                        DxfGroup handleGroup = new DxfGroup();
855
                        handleGroup.setCode(5);
856
                        handleGroup.setData(new Integer(handle + k).toString());
857

    
858
                        DxfGroup handleColor = new DxfGroup();
859
                        handleColor.setCode(62);
860
                        handleColor.setData(color);
861

    
862
                        DxfGroup handleThickness = new DxfGroup();
863
                        handleThickness.setCode(39);
864
                        handleThickness.setData(thickness);
865

    
866
                        polv.add(geometryLayer);
867
                        polv.add(handleGroup);
868
                        polv.add(handleColor);
869
                        return polv;
870
                }
871

    
872
                private int createPoint2D(int handle, int k, FeatureProvider feature)
873
                                throws Exception {
874

    
875
                        if (hasText(feature)) {
876
                                return createText2D(handle, k, feature);
877
                        }
878
                        org.gvsig.fmap.geom.primitive.Point point = geomManager.createPoint(0, 0, SUBTYPES.GEOM2D);
879
                        double[] pointCoords = new double[6];
880
                        PathIterator pointIt = (feature.getDefaultGeometry())
881
                                        .getPathIterator(null);
882
                        while (!pointIt.isDone()) {
883
                                pointIt.currentSegment(pointCoords);
884
                                point = geomManager.createPoint(pointCoords[0], pointCoords[1], SUBTYPES.GEOM2D);
885
                                pointIt.next();
886
                        }
887
                        Point2D pto = new Point2D.Double(point.getX(), point.getY());
888

    
889
                        DxfGroup px = new DxfGroup();
890
                        DxfGroup py = new DxfGroup();
891
                        DxfGroup pz = new DxfGroup();
892
                        px.setCode(10);
893
                        px.setData(new Double(pto.getX()));
894
                        py.setCode(20);
895
                        py.setData(new Double(pto.getY()));
896
                        pz.setCode(30);
897
                        // FIXME: POINT del DXF tiene cota. Le asigno cero arbitrariamente.
898
                        pz.setData(new Double(0.0));
899
                        DxfGroupVector pv = updateProperties(feature, k);
900
                        pv.add(px);
901
                        pv.add(py);
902
                        pv.add(pz);
903
                        entityMaker.createPoint(pv);
904
                        k++;
905
                        return k;
906
                }
907

    
908
                private int createText2D(int handle, int k, FeatureProvider feature)
909
                                throws Exception {
910

    
911
                        String text = feature.get(ID_FIELD_TEXT).toString();
912
                        Double heightText = (Double) feature.get(ID_FIELD_HEIGHTTEXT);
913
                        Double rotationText = (Double) feature.get(ID_FIELD_ROTATIONTEXT);
914

    
915
                        DxfGroup handleText = new DxfGroup();
916
                        handleText.setCode(1);
917
                        handleText.setData(text);
918

    
919
                        DxfGroup handleHeightText = new DxfGroup();
920
                        handleHeightText.setCode(40);
921
                        handleHeightText.setData(heightText);
922

    
923
                        DxfGroup handleRotationText = new DxfGroup();
924
                        handleRotationText.setCode(50);
925
                        handleRotationText.setData(rotationText);
926

    
927
                        org.gvsig.fmap.geom.primitive.Point point = geomManager.createPoint(0, 0, SUBTYPES.GEOM2D);
928
                        double[] pointCoords = new double[6];
929
                        PathIterator pointIt = (feature.getDefaultGeometry())
930
                                        .getPathIterator(null);
931
                        while (!pointIt.isDone()) {
932
                                pointIt.currentSegment(pointCoords);
933
                                point = geomManager.createPoint(pointCoords[0], pointCoords[1], SUBTYPES.GEOM2D);
934
                                pointIt.next();
935
                        }
936
                        Point2D pto = new Point2D.Double(point.getX(), point.getY());
937
                        DxfGroup handleGroup = new DxfGroup();
938
                        handleGroup.setCode(5);
939
                        handleGroup.setData(new Integer(handle + k).toString());
940
                        DxfGroup px = new DxfGroup();
941
                        DxfGroup py = new DxfGroup();
942
                        DxfGroup pz = new DxfGroup();
943
                        px.setCode(10);
944
                        px.setData(new Double(pto.getX()));
945
                        py.setCode(20);
946
                        py.setData(new Double(pto.getY()));
947
                        pz.setCode(30);
948
                        // FIXME: POINT del DXF tiene cota. Le asigno cero arbitrariamente.
949
                        pz.setData(new Double(0.0));
950
                        DxfGroupVector pv = updateProperties(feature, k);
951
                        pv.add(handleText);
952
                        pv.add(handleHeightText);
953
                        pv.add(handleRotationText);
954
                        pv.add(handleGroup);
955
                        pv.add(px);
956
                        pv.add(py);
957
                        pv.add(pz);
958
                        entityMaker.createText(pv);
959
                        k++;
960
                        return k;
961
                }
962

    
963
                private int createPoint3D(int handle, int k, FeatureProvider feature)
964
                                throws Exception {
965
                        if (hasText(feature)) {
966
                                return createText3D(handle, k, feature);
967
                        }
968
                        org.gvsig.fmap.geom.primitive.Point point = (org.gvsig.fmap.geom.primitive.Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM3D);
969
                        double[] pointCoords = new double[6];
970
                        PathIterator pointIt = (feature.getDefaultGeometry())
971
                                        .getPathIterator(null);
972
                        while (!pointIt.isDone()) {
973
                                pointIt.currentSegment(pointCoords);
974
                                point = (org.gvsig.fmap.geom.primitive.Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM3D);
975
                                point.setCoordinateAt(0, pointCoords[0]);
976
                                point.setCoordinateAt(1, pointCoords[1]);
977
                                point.setCoordinateAt(2, pointCoords[2]);
978
                                pointIt.next();
979
                        }
980
                        org.gvsig.fmap.geom.primitive.Point pto = (org.gvsig.fmap.geom.primitive.Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM3D);
981
                        pto.setCoordinateAt(0, point.getCoordinateAt(0));
982
                        pto.setCoordinateAt(1,  point.getCoordinateAt(1));
983
                        pto.setCoordinateAt(2, point.getCoordinateAt(2));
984
                        DxfGroup px = new DxfGroup();
985
                        DxfGroup py = new DxfGroup();
986
                        DxfGroup pz = new DxfGroup();
987
                        px.setCode(10);
988
                        px.setData(new Double(pto.getX()));
989
                        py.setCode(20);
990
                        py.setData(new Double(pto.getY()));
991
                        pz.setCode(30);
992
                        pz.setData(new Double(pto.getCoordinateAt(2)));
993
                        double velev = ((org.gvsig.fmap.geom.primitive.Point) feature.getDefaultGeometry())
994
                                        .getCoordinateAt(2);
995
                        Double elevation = DEFAULT_ELEVATION;
996
                        elevation = new Double(velev);
997
                        DxfGroup handleElevation = new DxfGroup();
998
                        handleElevation.setCode(38);
999
                        handleElevation.setData(elevation);
1000

    
1001
                        DxfGroupVector pv = updateProperties(feature, k);
1002
                        pv.add(handleElevation);
1003
                        pv.add(px);
1004
                        pv.add(py);
1005
                        pv.add(pz);
1006
                        entityMaker.createPoint(pv);
1007
                        k++;
1008
                        return k;
1009
                }
1010

    
1011
                private int createText3D(int handle, int k, FeatureProvider feature)
1012
                                throws Exception {
1013

    
1014
                        double velev = ((org.gvsig.fmap.geom.primitive.Point) feature.getDefaultGeometry())
1015
                        .getCoordinateAt(0);
1016

    
1017
                        Double elevation = new Double(velev);
1018
                        String text = feature.get(ID_FIELD_TEXT).toString();
1019
                        Double heightText = (Double) feature.get(ID_FIELD_HEIGHTTEXT);
1020
                        Double rotationText = (Double) feature.get(ID_FIELD_ROTATIONTEXT);
1021

    
1022
                        DxfGroup handleText = new DxfGroup();
1023
                        handleText.setCode(1);
1024
                        handleText.setData(text);
1025

    
1026
                        DxfGroup handleHeightText = new DxfGroup();
1027
                        handleHeightText.setCode(40);
1028
                        handleHeightText.setData(heightText);
1029

    
1030
                        DxfGroup handleRotationText = new DxfGroup();
1031
                        handleRotationText.setCode(50);
1032
                        handleRotationText.setData(rotationText);
1033

    
1034
                        DxfGroup handleElevation = new DxfGroup();
1035
                        handleElevation.setCode(38);
1036
                        handleElevation.setData(elevation);
1037

    
1038
                        org.gvsig.fmap.geom.primitive.Point point =
1039
                                (org.gvsig.fmap.geom.primitive.Point) (feature
1040
                                        .getDefaultGeometry()).getInternalShape();
1041

    
1042
                        DxfGroup handleGroup = new DxfGroup();
1043
                        handleGroup.setCode(5);
1044
                        handleGroup.setData(new Integer(handle + k).toString());
1045
                        DxfGroup px = new DxfGroup();
1046
                        DxfGroup py = new DxfGroup();
1047
                        DxfGroup pz = new DxfGroup();
1048
                        px.setCode(10);
1049
                        px.setData(new Double(point.getX()));
1050
                        py.setCode(20);
1051
                        py.setData(new Double(point.getY()));
1052
                        pz.setCode(30);
1053
                        pz.setData(new Double(point.getCoordinateAt(2)));
1054
                        DxfGroupVector pv = updateProperties(feature, k);
1055
                        pv.add(handleElevation);
1056
                        pv.add(handleText);
1057
                        pv.add(handleHeightText);
1058
                        pv.add(handleRotationText);
1059
                        pv.add(handleGroup);
1060
                        pv.add(px);
1061
                        pv.add(py);
1062
                        pv.add(pz);
1063
                        entityMaker.createText(pv);
1064
                        k++;
1065
                        return k;
1066
                }
1067

    
1068
                private int createLwPolyline2D(int handle, int k, FeatureProvider feature,
1069
                                boolean isPolygon) throws Exception {
1070
                        boolean first = true;
1071
                        DxfGroupVector polv = updateProperties(feature, k);
1072
                        Vector vpoints = new Vector();
1073

    
1074
                        DxfGroup polylineFlag = new DxfGroup();
1075
                        polylineFlag.setCode(70);
1076
                        if (isPolygon) {
1077
                                polylineFlag.setData(new Integer(1)); // cerrada
1078
                        } else {
1079
                                polylineFlag.setData(new Integer(0)); // abierta
1080
                        }
1081

    
1082
                        PathIterator theIterator = (feature.getDefaultGeometry())
1083
                                        .getPathIterator(null, geomManager.getFlatness()); // polyLine.
1084
                                                                                                                                // getPathIterator
1085
                                                                                                                                // (null,
1086
                        // flatness);
1087

    
1088
                        double[] theData = new double[6];
1089
                        while (!theIterator.isDone()) {
1090
                                int theType = theIterator.currentSegment(theData);
1091
                                switch (theType) {
1092
                                case PathIterator.SEG_MOVETO:
1093
                                        if (!first) {
1094
                                                for (int j = 0; j < vpoints.size(); j++) {
1095
                                                        DxfGroup xvertex = new DxfGroup();
1096
                                                        xvertex.setCode(10);
1097
                                                        xvertex
1098
                                                                        .setData(new Double(
1099
                                                                                        ((org.gvsig.fmap.geom.primitive.Point) vpoints
1100
                                                                                                        .get(j)).getX()));
1101
                                                        DxfGroup yvertex = new DxfGroup();
1102
                                                        yvertex.setCode(20);
1103
                                                        yvertex
1104
                                                                        .setData(new Double(
1105
                                                                                        ((org.gvsig.fmap.geom.primitive.Point) vpoints
1106
                                                                                                        .get(j)).getY()));
1107
                                                        polv.add(xvertex);
1108
                                                        polv.add(yvertex);
1109
                                                }
1110

    
1111
                                                entityMaker.createLwPolyline(polv);
1112
                                                k++;
1113
                                                polv = updateProperties(feature, k);
1114

    
1115
                                        }
1116
                                        first = false;
1117
                                        polv.add(polylineFlag);
1118
                                        vpoints.clear();
1119
                                        vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1120
                                        break;
1121
                                case PathIterator.SEG_LINETO:
1122
                                        vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1123
                                        break;
1124
                                case PathIterator.SEG_QUADTO:
1125
                                        break;
1126
                                case PathIterator.SEG_CUBICTO:
1127
                                        break;
1128
                                case PathIterator.SEG_CLOSE:
1129
                                        polylineFlag.setData(new Integer(1)); // cerrada
1130
                                        break;
1131

    
1132
                                }
1133
                                theIterator.next();
1134
                        }
1135

    
1136
                        for (int j = 0; j < vpoints.size(); j++) {
1137
                                DxfGroup xvertex = new DxfGroup();
1138
                                xvertex.setCode(10);
1139
                                xvertex
1140
                                                .setData(new Double(
1141
                                                                ((org.gvsig.fmap.geom.primitive.Point) vpoints
1142
                                                                                .get(j)).getX()));
1143
                                DxfGroup yvertex = new DxfGroup();
1144
                                yvertex.setCode(20);
1145
                                yvertex
1146
                                                .setData(new Double(
1147
                                                                ((org.gvsig.fmap.geom.primitive.Point) vpoints
1148
                                                                                .get(j)).getY()));
1149
                                polv.add(xvertex);
1150
                                polv.add(yvertex);
1151
                        }
1152

    
1153
                        entityMaker.createLwPolyline(polv);
1154
                        k++;
1155
                        return k;
1156
                }
1157

    
1158
                private int createPolyline3D(int handle, int k, FeatureProvider feature)
1159
                                throws Exception {
1160
                        DxfGroupVector polv = updateProperties(feature, k);
1161
                        Vector vpoints = new Vector();
1162
                        PathIterator theIterator = (feature.getDefaultGeometry())
1163
                                        .getPathIterator(null, geomManager.getFlatness()); // polyLine.
1164
                                                                                                                                // getPathIterator
1165
                                                                                                                                // (null,
1166
                        // flatness);
1167
                        double[] theData = new double[6];
1168
                        Curve curve = (Curve) feature.getDefaultGeometry();
1169
                        double[] velev = new double[curve.getNumVertices()];
1170
                        for (int i = 0; i < curve.getNumVertices(); i++) {
1171
                                velev[i] = curve.getCoordinateAt(i, 2);
1172
                        }
1173

    
1174
                        while (!theIterator.isDone()) {
1175
                                int theType = theIterator.currentSegment(theData);
1176
                                switch (theType) {
1177
                                case PathIterator.SEG_MOVETO:
1178
                                        vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1179
                                        break;
1180
                                case PathIterator.SEG_LINETO:
1181
                                        vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1182
                                        break;
1183
                                }
1184
                                theIterator.next();
1185
                        }
1186
                        if (constantElevation(velev)) {
1187
                                DxfGroup polylineFlag = new DxfGroup();
1188
                                polylineFlag.setCode(70);
1189
                                polylineFlag.setData(new Integer(0));
1190
                                polv.add(polylineFlag);
1191
                                DxfGroup elevation = new DxfGroup();
1192
                                elevation.setCode(38);
1193
                                elevation.setData(new Double(velev[0]));
1194
                                polv.add(elevation);
1195
                                for (int j = 0; j < vpoints.size(); j++) {
1196
                                        DxfGroup xvertex = new DxfGroup();
1197
                                        xvertex.setCode(10);
1198
                                        xvertex.setData(new Double(
1199
                                                        ((org.gvsig.fmap.geom.primitive.Point) vpoints
1200
                                                                        .get(j)).getX()));
1201
                                        DxfGroup yvertex = new DxfGroup();
1202
                                        yvertex.setCode(20);
1203
                                        yvertex.setData(new Double(
1204
                                                        ((org.gvsig.fmap.geom.primitive.Point) vpoints
1205
                                                                        .get(j)).getY()));
1206
                                        polv.add(xvertex);
1207
                                        polv.add(yvertex);
1208
                                }
1209
                                entityMaker.createLwPolyline(polv);
1210
                                k++;
1211
                        } else {
1212
                                DxfGroup polylineFlag = new DxfGroup();
1213
                                polylineFlag.setCode(70);
1214
                                polylineFlag.setData(new Integer(8));
1215
                                polv.add(polylineFlag);
1216
                                DxfGroup xgroup = new DxfGroup();
1217
                                xgroup.setCode(10);
1218
                                xgroup.setData(new Double(0.0));
1219
                                polv.add(xgroup);
1220
                                DxfGroup ygroup = new DxfGroup();
1221
                                ygroup.setCode(20);
1222
                                ygroup.setData(new Double(0.0));
1223
                                polv.add(ygroup);
1224
                                DxfGroup elevation = new DxfGroup();
1225
                                elevation.setCode(30);
1226
                                elevation.setData(new Double(0.0));
1227
                                polv.add(elevation);
1228
                                DxfGroup subclassMarker = new DxfGroup(100, "AcDb3dPolyline");
1229
                                polv.add(subclassMarker);
1230
                                entityMaker.createPolyline(polv);
1231
                                k++;
1232
                                for (int j = 0; j < vpoints.size(); j++) {
1233
                                        DxfGroupVector verv = new DxfGroupVector();
1234
                                        DxfGroup entityType = new DxfGroup(0, "VERTEX");
1235
                                        verv.add(entityType);
1236
                                        DxfGroup generalSubclassMarker = new DxfGroup(100,
1237
                                                        "AcDbEntity");
1238
                                        verv.add(generalSubclassMarker);
1239
                                        DxfGroup layerName = new DxfGroup(8, "default");
1240
                                        verv.add(layerName);
1241
                                        DxfGroup vertexSubclassMarker = new DxfGroup(100,
1242
                                                        "AcDbVertex");
1243
                                        verv.add(vertexSubclassMarker);
1244
                                        DxfGroup xvertex = new DxfGroup();
1245
                                        xvertex.setCode(10);
1246
                                        xvertex.setData(new Double(
1247
                                                        ((org.gvsig.fmap.geom.primitive.Point) vpoints
1248
                                                                        .get(j)).getX()));
1249
                                        DxfGroup yvertex = new DxfGroup();
1250
                                        yvertex.setCode(20);
1251
                                        yvertex.setData(new Double(
1252
                                                        ((org.gvsig.fmap.geom.primitive.Point) vpoints
1253
                                                                        .get(j)).getY()));
1254
                                        DxfGroup zvertex = new DxfGroup();
1255
                                        zvertex.setCode(30);
1256
                                        zvertex.setData(new Double(velev[j]));
1257
                                        verv.add(xvertex);
1258
                                        verv.add(yvertex);
1259
                                        verv.add(zvertex);
1260
                                        entityMaker.addVertex(verv);
1261
                                        k++;
1262
                                }
1263
                                DxfGroupVector seqv = new DxfGroupVector();
1264
                                DxfGroup entityType = new DxfGroup(0, "SEQEND");
1265
                                seqv.add(entityType);
1266
                                DxfGroup generalSubclassMarker = new DxfGroup(100, "AcDbEntity");
1267
                                seqv.add(generalSubclassMarker);
1268
                                DxfGroup layerName = new DxfGroup(8, "default");
1269
                                seqv.add(layerName);
1270
                                DxfGroup handleSeqGroup = new DxfGroup();
1271
                                handleSeqGroup.setCode(5);
1272
                                handleSeqGroup.setData(new Integer(handle + k).toString());
1273
                                seqv.add(handleSeqGroup);
1274
                                entityMaker.endSeq();
1275
                                k++;
1276
                        }
1277
                        return k;
1278
                }
1279

    
1280
                private boolean constantElevation(double[] velev) {
1281
                        boolean constant = true;
1282
                        for (int i = 0; i < velev.length; i++) {
1283
                                for (int j = 0; j < velev.length; j++) {
1284
                                        if (j > i) {
1285
                                                if (velev[i] != velev[j]) {
1286
                                                        constant = false;
1287
                                                        break;
1288
                                                }
1289
                                        }
1290
                                }
1291
                                break;
1292
                        }
1293
                        return constant;
1294
                }
1295

    
1296
                private int createCircle2D(int handle, int k, FeatureProvider feature)
1297
                                throws Exception {
1298
                        DxfGroupVector polv = updateProperties(feature, k);
1299
                        DxfGroup circleFlag = new DxfGroup();
1300
                        circleFlag.setCode(100);
1301
                        polv.add(circleFlag);
1302

    
1303
                        DxfGroup xvertex = new DxfGroup();
1304
                        xvertex.setCode(10);
1305
                        Circle circle = (Circle) (feature
1306
                                        .getDefaultGeometry()).getInternalShape();
1307
                        xvertex.setData(new Double(circle.getCenter().getX()));
1308
                        DxfGroup yvertex = new DxfGroup();
1309
                        yvertex.setCode(20);
1310
                        yvertex.setData(new Double(circle.getCenter().getY()));
1311
                        DxfGroup zvertex = new DxfGroup();
1312
                        zvertex.setCode(30);
1313
                        // TODO: COORDENADA Z. REVISAR ESTO PARA ENTIDADES 3D
1314
                        zvertex.setData(new Double(0));
1315

    
1316
                        DxfGroup radius = new DxfGroup();
1317
                        radius.setCode(40);
1318
                        radius.setData(new Double(circle.getRadious()));
1319

    
1320
                        polv.add(xvertex);
1321
                        polv.add(yvertex);
1322
                        polv.add(zvertex);
1323
                        polv.add(radius);
1324

    
1325
                        entityMaker.createCircle(polv);
1326
                        k++;
1327
                        return k;
1328
                }
1329

    
1330
                private int createArc2D(int handle, int k, FeatureProvider feature)
1331
                                throws Exception {
1332
                        Arc arc = (Arc) (feature.getDefaultGeometry())
1333
                                        .getInternalShape();
1334
                        org.gvsig.fmap.geom.primitive.Point[] pts = new org.gvsig.fmap.geom.primitive.Point[3];
1335
                        pts[0] = arc.getInitPoint();
1336
                        pts[1] = arc.getCenterPoint();
1337
                        pts[2] = arc.getEndPoint();
1338
                        org.gvsig.fmap.geom.primitive.Point center = arc.getCenterPoint();
1339
                        GeometryOperationContext ctx = new GeometryOperationContext();
1340
                        ctx.setAttribute("geom", pts[0]);
1341
                        double radius = ((Double)geomManager.invokeOperation(PointDistance.CODE, center, ctx)).doubleValue();
1342

    
1343
                        double initAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1344
                        initAngle = Math.toDegrees(initAngle);
1345
                        ctx.setAttribute("geom", pts[1]);
1346
                        double midAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1347
                        midAngle = Math.toDegrees(midAngle);
1348
                        ctx.setAttribute("geom", pts[2]);
1349
                        double endAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1350
                        endAngle = Math.toDegrees(endAngle);
1351

    
1352
                        DxfGroup ax = new DxfGroup();
1353
                        DxfGroup ay = new DxfGroup();
1354
                        DxfGroup ac = new DxfGroup();
1355
                        DxfGroup ai = new DxfGroup();
1356
                        DxfGroup ae = new DxfGroup();
1357
                        ax.setCode(10);
1358
                        ax.setData(new Double(center.getX()));
1359
                        ay.setCode(20);
1360
                        ay.setData(new Double(center.getY()));
1361
                        ac.setCode(40);
1362
                        ac.setData(new Double(radius));
1363
                        ai.setCode(50);
1364
                        ai.setData(new Double(initAngle));
1365
                        ae.setCode(51);
1366
                        ae.setData(new Double(endAngle));
1367
                        DxfGroupVector av = updateProperties(feature, k);
1368
                        av.add(ax);
1369
                        av.add(ay);
1370
                        av.add(ac);
1371
                        av.add(ai);
1372
                        av.add(ae);
1373
                        entityMaker.createArc(av);
1374
                        k++;
1375
                        return k;
1376
                }
1377

    
1378
                private int createEllipse2D(int handle, int k, FeatureProvider feature)
1379
                                throws Exception {
1380
                        Ellipse ellipse = (Ellipse) (feature
1381
                                        .getDefaultGeometry()).getInternalShape();
1382

    
1383
                        org.gvsig.fmap.geom.primitive.Point center = (org.gvsig.fmap.geom.primitive.Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM2D);
1384
                        center.setCoordinateAt(0, (ellipse.getAxis1Start().getX() + ellipse.getAxis1End().getX()) / 2);
1385
                        center.setCoordinateAt(1, (ellipse.getAxis1Start().getY() + ellipse.getAxis1End().getY()) / 2);
1386

    
1387
                        double mAxisL = ellipse.getAxis2Dist() * 2;
1388
                        GeometryOperationContext ctx = new GeometryOperationContext();
1389
                        ctx.setAttribute("geom", ellipse.getAxis1End());
1390
                        double maAxisL = ((Double)geomManager.invokeOperation(PointDistance.CODE, ellipse.getAxis1Start(), ctx)).doubleValue();
1391

    
1392
                        Point2D endPointOfMajorAxis = new Point2D.Double(ellipse.getAxis1End().getX(), ellipse.getAxis1End().getY());
1393
                        double azimut = Math
1394
                                        .atan2(endPointOfMajorAxis.getX() - center.getX(),
1395
                                                        endPointOfMajorAxis.getY() - center.getY());
1396
                        double azimut2 = azimut + Math.PI / 2.0;
1397
                        if (azimut2 >= Math.PI * 2) {
1398
                                azimut2 = azimut2 - Math.PI * 2;
1399
                        }
1400
                        Point2D endPointOfMinorAxis = new Point2D.Double(center.getX()
1401
                                        + (ellipse.getAxis2Dist() * Math.sin(azimut2)), center.getY()
1402
                                        + (ellipse.getAxis2Dist() * Math.cos(azimut2)));
1403

    
1404
                        if (mAxisL >= maAxisL) {
1405
                                // El menor debe ser menor que el mayor. Los cambiamos.
1406
                                double aux = mAxisL;
1407
                                mAxisL = maAxisL;
1408
                                maAxisL = aux;
1409
                                // Tambi?n cambiamos los puntos finales de los ejes.
1410
                                Point2D pAux = endPointOfMinorAxis;
1411
                                endPointOfMinorAxis = endPointOfMajorAxis;
1412
                                endPointOfMajorAxis = pAux;
1413
                        }
1414
                        double mToMAR = mAxisL / maAxisL;
1415
                        DxfGroup x = new DxfGroup();
1416
                        DxfGroup y = new DxfGroup();
1417
                        DxfGroup xc = new DxfGroup();
1418
                        DxfGroup yc = new DxfGroup();
1419
                        DxfGroup minToMaj = new DxfGroup();
1420
                        x.setCode(10);
1421
                        x.setData(new Double(center.getX()));
1422
                        y.setCode(20);
1423
                        y.setData(new Double(center.getY()));
1424
                        xc.setCode(11);
1425
                        xc.setData(new Double(endPointOfMajorAxis.getX() - center.getX()));
1426
                        yc.setCode(21);
1427
                        yc.setData(new Double(endPointOfMajorAxis.getY() - center.getY()));
1428
                        minToMaj.setCode(40);
1429
                        minToMaj.setData(new Double(mToMAR));
1430
                        DxfGroupVector av = updateProperties(feature, k);
1431
                        av.add(x);
1432
                        av.add(y);
1433
                        av.add(xc);
1434
                        av.add(yc);
1435
                        av.add(minToMaj);
1436
                        entityMaker.createEllipse(av);
1437
                        k++;
1438
                        return k;
1439
                }
1440

    
1441
        }
1442

    
1443
        public boolean closeResourceRequested(ResourceProvider resource) {
1444
                return true;
1445
        }
1446

    
1447
        public int getOIDType() {
1448
                return DataTypes.LONG;
1449
        }
1450

    
1451
        public boolean supportsAppendMode() {
1452
                return false;
1453
        }
1454

    
1455
        public void append(FeatureProvider featureProvider) {
1456
                try {
1457
                        writer.add(featureProvider);
1458
                } catch (WriteException e) {
1459
                        // TODO Auto-generated catch block
1460
                        e.printStackTrace();
1461
                }
1462
        }
1463

    
1464
        public void beginAppend() {
1465
                try {
1466
                        writer = new Writer().initialice((File) resource.get(), projection);
1467
                        writer.begin();
1468
                } catch (AccessResourceException e) {
1469
                        // TODO Auto-generated catch block
1470
                        e.printStackTrace();
1471
                }
1472
        }
1473

    
1474
        public void endAppend() {
1475
                try {
1476
                        resource.notifyOpen();
1477
                        writer.end();
1478
                        resource.notifyClose();
1479
                        counterNewsOIDs = 0;
1480
                } catch (ResourceNotifyOpenException e) {
1481
                        // TODO Auto-generated catch block
1482
                        e.printStackTrace();
1483
                } catch (ResourceNotifyCloseException e) {
1484
                        // TODO Auto-generated catch block
1485
                        e.printStackTrace();
1486
                } catch (WriteException e) {
1487
                        // TODO Auto-generated catch block
1488
                        e.printStackTrace();
1489
                }
1490
        }
1491

    
1492
        public void saveToState(PersistentState state) throws PersistenceException {
1493
                // TODO Auto-generated method stub
1494
                throw new NotYetImplemented();
1495
        }
1496

    
1497
        public void loadFromState(PersistentState state) throws PersistenceException {
1498
                // TODO Auto-generated method stub
1499
                throw new NotYetImplemented();
1500
        }
1501

    
1502
        public Object createNewOID() {
1503
                return new Long(counterNewsOIDs++);
1504
        }
1505

    
1506
        protected void initializeFeatureTypes() throws InitializeException {
1507
                try {
1508
                        this.open();
1509
                } catch (OpenException e) {
1510
                        throw new InitializeException(this.getProviderName(), e);
1511
                }
1512
        }
1513

    
1514
        public Envelope getEnvelope() throws DataException {
1515
                this.open();
1516
                return this.envelope;
1517
        }
1518

    
1519
        public Object getDynValue(String name) throws DynFieldNotFoundException {
1520
                if( DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name) ) {
1521
                        try {
1522
                                return this.getEnvelope();
1523
                        } catch (DataException e) {
1524
                                return null;
1525
                        }
1526
                }
1527
                return super.getDynValue(name);
1528
        }
1529
        
1530
        
1531
        /*
1532
         * (non-Javadoc)
1533
         *
1534
         * @see
1535
         * org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
1536
         * gvsig.fmap.dal.resource.spi.ResourceProvider)
1537
         */
1538
        public void resourceChanged(ResourceProvider resource) {
1539
                this.getStoreServices().notifyChange(
1540
                                DataStoreNotification.RESOURCE_CHANGED,
1541
                                resource);
1542
        }
1543

    
1544

    
1545
        public Object getSourceId() {
1546
                return this.getDXFParameters().getFile();
1547
        }
1548

    
1549
        public String getName() {
1550
                String name = this.getDXFParameters().getFile().getName();
1551
                int n = name.lastIndexOf(".");
1552
                if( n<1 ) {
1553
                        return name;
1554
                }
1555
                return name.substring(0, n);
1556
        }
1557
        
1558
        public String getFullName() {
1559
                return this.getDXFParameters().getFile().getAbsolutePath();
1560
        }
1561
                
1562
        public ResourceProvider getResource() {
1563
                return resource;
1564
        }
1565

    
1566
}