Statistics
| Revision:

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

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

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

    
94
        public static final String METADATA_DEFINITION_NAME = NAME;
95

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

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

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

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

    
127

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

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

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

    
145
                resource.addConsumer(this);
146

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

    
149

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

    
159
                this.initializeFeatureTypes();
160

    
161
        }
162

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

    
167
        public String getName() {
168
                return NAME;
169
        }
170

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

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

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

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

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

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

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

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

    
266
                                                dxfData.legendBuilder = legendBuilder;
267

    
268
                                                dxfData.projection = projection;
269

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

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

    
295

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

    
310
        }
311

    
312

    
313

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

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

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

    
354
        public class Reader {
355
                private File file;
356
                private String fileName;
357
                private IProjection projection;
358
                private List types;
359
                private LegendBuilder leyendBuilder;
360
                private AbstractMemoryStoreProvider store;
361
                private Envelope envelope;
362

    
363
                public Reader initialice(AbstractMemoryStoreProvider store, File file,
364
                                IProjection projection,
365
                                LegendBuilder leyendBuilder) {
366
                        this.store = store;
367
                        this.file = file;
368
                        this.fileName = file.getAbsolutePath();
369
                        this.projection = projection;
370
                        this.leyendBuilder = leyendBuilder;
371
                        if (leyendBuilder != null) {
372
                                leyendBuilder.initialize(store);
373
                        }
374
                        return this;
375
                }
376

    
377
                public Envelope getEnvelope() {
378
                        return this.envelope;
379
                }
380

    
381
                public void begin(FeatureStoreProviderServices store) {
382

    
383
                        EditableFeatureType featureType = store.createFeatureType();
384

    
385
                        featureType.setHasOID(true);
386

    
387
                        ID_FIELD_ID = featureType.add(NAME_FIELD_ID, DataTypes.INT)
388
                                        .setDefaultValue(Integer.valueOf(0))
389
                                .getIndex();
390

    
391
                        EditableFeatureAttributeDescriptor attr = featureType.add(
392
                                        NAME_FIELD_GEOMETRY, DataTypes.GEOMETRY);
393
                        attr.setSRS(this.projection);
394
                        attr.setGeometryType(Geometry.TYPES.GEOMETRY);
395
                        ID_FIELD_GEOMETRY = attr.getIndex();
396

    
397
                        featureType.setDefaultGeometryAttributeName(NAME_FIELD_GEOMETRY);
398

    
399
                        // FIXME: Cual es el size y el valor por defecto para Entity ?
400
                        ID_FIELD_ENTITY = featureType.add(NAME_FIELD_ENTITY,
401
                                        DataTypes.STRING, 100)
402
                                        .setDefaultValue("")
403
                                        .getIndex();
404

    
405
                        // FIXME: Cual es el size de Layer ?
406
                        ID_FIELD_LAYER = featureType.add(NAME_FIELD_LAYER,
407
                                        DataTypes.STRING, 100)
408
                                        .setDefaultValue(
409
                                        "default").getIndex();
410

    
411
                        ID_FIELD_COLOR = featureType.add(NAME_FIELD_COLOR,
412
                                        DataTypes.INT)
413
                                        .setDefaultValue(
414
                                        Integer.valueOf(0)).getIndex();
415

    
416
                        ID_FIELD_ELEVATION = featureType.add(NAME_FIELD_ELEVATION,
417
                                        DataTypes.DOUBLE)
418
                                        .setDefaultValue(
419
                                        Double.valueOf(0)).getIndex();
420

    
421
                        ID_FIELD_THICKNESS = featureType.add(NAME_FIELD_THICKNESS,
422
                                        DataTypes.DOUBLE)
423
                                        .setDefaultValue(
424
                                        Double.valueOf(0)).getIndex();
425

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

    
432
                        ID_FIELD_HEIGHTTEXT = featureType.add(NAME_FIELD_HEIGHTTEXT,
433
                                        DataTypes.DOUBLE).setDefaultValue(
434
                                        Double.valueOf(10)).getIndex();
435

    
436
                        ID_FIELD_ROTATIONTEXT = featureType.add(NAME_FIELD_ROTATIONTEXT,
437
                                        DataTypes.DOUBLE).setDefaultValue(
438
                                        Double.valueOf(0)).getIndex();
439

    
440

    
441

    
442
                        // FIXME: Parece que el DXF puede tener mas atributos opcionales.
443
                        // Habria que ver de pillarlos ?
444

    
445
                        types = new ArrayList();
446
                        types.add(featureType);
447

    
448
                        if (leyendBuilder != null) {
449
                                leyendBuilder.begin();
450
                        }
451

    
452
                }
453

    
454
                public void end() {
455
                        if (leyendBuilder != null) {
456
                                leyendBuilder.end();
457
                        }
458
                }
459

    
460
                public List getTypes() {
461
                        return types;
462
                }
463

    
464
                public EditableFeatureType getDefaultType() {
465
                        return (EditableFeatureType) types.get(0);
466
                }
467

    
468
                private Double toDouble(String value) {
469
                        if (value == null) {
470
                                return Double.valueOf(0);
471
                        }
472
                        return Double.valueOf(value);
473
                }
474

    
475
                public void load() throws DataException {
476

    
477
                        this.envelope = null;
478

    
479
                        DxfFile.EntityFactory featureMaker = new DxfFeatureMaker(projection);
480
                        DxfFile.VarSettings headerManager = new DxfHeaderManager();
481
                        DxfFile dxfFeatureFile = new DxfFile(projection, file
482
                                        .getAbsolutePath(), featureMaker, headerManager);
483

    
484
                        try {
485
                                dxfFeatureFile.load();
486
                        } catch (Exception e1) {
487
                                throw new LoadException(e1, fileName);
488
                        }
489

    
490
                        IObjList.vector features = (IObjList.vector) ((DxfFeatureMaker) featureMaker)
491
                                        .getObjects();
492
                        String acadVersion = ((DxfHeaderManager) headerManager)
493
                                        .getAcadVersion();
494

    
495

    
496
                        logger.info("load: acadVersion = '" + acadVersion + "'");
497

    
498
                        GeometryManager gManager = GeometryLocator.getGeometryManager();
499

    
500
                        if (!featureMaker.isDxf3DFile() && !headerManager.isWritedDxf3D()) {
501
                                // y no est?n todos a 9999
502
                                Feature[] features2D = new Feature[features.size()];
503
                                for (int i = 0; i < features.size(); i++) {
504
                                        Feature fea = (Feature) features.get(i);
505
                                        if (fea.getGeometry() instanceof org.gvsig.dxf.px.gml.Point3D) {
506
                                                Point point = (Point) fea.getGeometry();
507
                                                Point point2 = new Point();
508
                                                for (int j = 0; j < point.pointNr(); j++) {
509
                                                        point2.add(point.get(j));
510
                                                }
511
                                                point2.setTextPoint(point.isTextPoint());
512
                                                fea.setGeometry(point2);
513
                                                features2D[i] = fea;
514

    
515
                                        } else if (fea.getGeometry() instanceof LineString3D) {
516
                                                LineString lineString = (LineString) fea.getGeometry();
517
                                                LineString lineString2 = new LineString();
518
                                                for (int j = 0; j < lineString.pointNr(); j++) {
519
                                                        lineString2.add(lineString.get(j));
520
                                                }
521
                                                fea.setGeometry(lineString2);
522
                                                features2D[i] = fea;
523
                                        } else if (fea.getGeometry() instanceof Polygon3D) {
524
                                                Polygon polygon = (Polygon) fea.getGeometry();
525
                                                Polygon polygon2 = new Polygon();
526
                                                for (int j = 0; j < polygon.pointNr(); j++) {
527
                                                        polygon2.add(polygon.get(j));
528
                                                }
529
                                                fea.setGeometry(polygon2);
530
                                                features2D[i] = fea;
531
                                        }
532
                                }
533
                                features.clear();
534
                                for (int i = 0; i < features2D.length; i++) {
535
                                        features.add(features2D[i]);
536
                                }
537
                        }
538

    
539

    
540

    
541
                        for (int i = 0; i < features.size(); i++) {
542

    
543
                                FeatureProvider feature = store.createFeatureProvider(store
544
                                                .getStoreServices().getDefaultFeatureType());
545

    
546
                                try {
547
                                        Feature fea = (Feature) features.get(i);
548

    
549
                                        feature.setOID(new Long(i));
550
                                        feature.set(ID_FIELD_ID, Integer.valueOf(i));
551
                                        feature.set(ID_FIELD_ENTITY, fea.getProp("dxfEntity"));
552
                                        feature.set(ID_FIELD_LAYER, fea.getProp("layer"));
553
                                        feature.set(ID_FIELD_COLOR, Integer.valueOf(fea
554
                                                        .getProp("color")));
555
                                        feature.set(ID_FIELD_TEXT, fea.getProp("text"));
556
                                        feature.set(ID_FIELD_HEIGHTTEXT, toDouble(fea
557
                                                        .getProp("textHeight")));
558
                                        feature.set(ID_FIELD_ROTATIONTEXT, toDouble(fea
559
                                                        .getProp("textRotation")));
560
                                        feature.set(ID_FIELD_ELEVATION, toDouble(fea
561
                                                        .getProp("elevation")));
562
                                        feature.set(ID_FIELD_THICKNESS, toDouble(fea
563
                                                        .getProp("thickness")));
564
                                        // FIXME: Abria que pillar el resto de atributos del DXF.
565

    
566
                                        store.addFeatureProvider(feature);
567

    
568

    
569
                                        // FIXME: Habia una incongruencia en el codigo ya que al
570
                                        // campo
571
                                        // ID_FIELD_GEOMETRY igual le asignaba una geometria que un
572
                                        // valor de cadena como 'Point3D', 'Polyline2D' o
573
                                        // 'Polyline3D'
574
                                        // Faltaria un atributo ID_FIELD_FSHAPE ?
575
                                        //
576

    
577
                                        if (fea.getGeometry() instanceof Point
578
                                                        && !(fea.getGeometry() instanceof org.gvsig.dxf.px.gml.Point3D)) {
579
                                                Point point = (Point) fea.getGeometry();
580
                                                Point2D pto = new Point2D.Double();
581
                                                pto = point.get(0);
582

    
583
                                                org.gvsig.fmap.geom.primitive.Point geom = (org.gvsig.fmap.geom.primitive.Point)gManager.create(TYPES.POINT , SUBTYPES.GEOM2D);
584
                                                geom.setX(pto.getX());
585
                                                geom.setY(pto.getY());
586
                                                feature.set(ID_FIELD_GEOMETRY, geom);
587
                                                if (this.envelope == null) {
588
                                                        this.envelope = geom.getEnvelope();
589
                                                } else {
590
                                                        this.envelope.add(geom.getEnvelope());
591
                                                }
592

    
593
                                                if (point.isTextPoint()) {
594
                                                        /// TODO labeling
595
                                                }
596
                                        } else if (fea.getGeometry() instanceof org.gvsig.dxf.px.gml.Point3D) {
597
                                                org.gvsig.dxf.px.gml.Point3D point = (org.gvsig.dxf.px.gml.Point3D) fea
598
                                                                .getGeometry();
599
                                                Point3D pto = new Point3D();
600
                                                pto = point.getPoint3D(0);
601
                                                org.gvsig.fmap.geom.primitive.Point geom = (org.gvsig.fmap.geom.primitive.Point)gManager.create(TYPES.POINT , SUBTYPES.GEOM2DZ);
602
                                                geom.setX(pto.getX());
603
                                                geom.setY(pto.getY());
604
                                                geom.setCoordinateAt(2, pto.getZ());
605

    
606
                                                feature.set(ID_FIELD_GEOMETRY, geom);
607
                                                if (this.envelope == null) {
608
                                                        this.envelope = geom.getEnvelope();
609
                                                } else {
610
                                                        this.envelope.add(geom.getEnvelope());
611
                                                }
612

    
613
                                                if (point.isTextPoint()) {
614
                                                        /// TODO labeling
615
                                                }
616
                                        } else if (fea.getGeometry() instanceof LineString
617
                                                        && !(fea.getGeometry() instanceof LineString3D)) {
618
                                                GeneralPathX genPathX = new GeneralPathX();
619
                                                Point2D[] pts = new Point2D[fea.getGeometry().pointNr()];
620
                                                for (int j = 0; j < fea.getGeometry().pointNr(); j++) {
621
                                                        pts[j] = fea.getGeometry().get(j);
622
                                                }
623
                                                genPathX.moveTo(pts[0].getX(), pts[0].getY());
624
                                                for (int j = 1; j < pts.length; j++) {
625
                                                        genPathX.lineTo(pts[j].getX(), pts[j].getY());
626
                                                }
627
                                                Curve geom = (Curve)gManager.create(TYPES.CURVE , SUBTYPES.GEOM2D);
628
                                                geom.setGeneralPath(genPathX);
629
                                                feature.set(ID_FIELD_GEOMETRY, geom);
630
                                                if (this.envelope == null) {
631
                                                        this.envelope = geom.getEnvelope();
632
                                                } else {
633
                                                        this.envelope.add(geom.getEnvelope());
634
                                                }
635

    
636
                                        } else if (fea.getGeometry() instanceof LineString3D) {
637
                                                GeneralPathX genPathX = new GeneralPathX();
638
                                                Point3D[] pts = new Point3D[fea.getGeometry().pointNr()];
639
                                                for (int j = 0; j < fea.getGeometry().pointNr(); j++) {
640
                                                        pts[j] = ((LineString3D) fea.getGeometry())
641
                                                                        .getPoint3D(j);
642
                                                }
643
                                                genPathX.moveTo(pts[0].getX(), pts[0].getY());
644
                                                for (int j = 1; j < pts.length; j++) {
645
                                                        genPathX.lineTo(pts[j].getX(), pts[j].getY());
646
                                                }
647
                                                double[] elevations = new double[pts.length];
648
                                                for (int j = 0; j < pts.length; j++) {
649
                                                        elevations[j] = pts[j].getZ();
650
                                                }
651
                                                Curve geom = (Curve)gManager.create(TYPES.CURVE , SUBTYPES.GEOM2DZ);
652
                                                geom.setGeneralPath(genPathX);
653
                                                for (int j=0 ; j<elevations.length ; j++){
654
                                                        geom.setCoordinateAt(j, 2, elevations[j]);
655
                                                }
656
                                                feature.set(ID_FIELD_GEOMETRY, geom);
657
                                                if (this.envelope == null) {
658
                                                        this.envelope = geom.getEnvelope();
659
                                                } else {
660
                                                        this.envelope.add(geom.getEnvelope());
661
                                                }
662

    
663
                                        } else if (fea.getGeometry() instanceof Polygon
664
                                                        && !(fea.getGeometry() instanceof Polygon3D)) {
665
                                                GeneralPathX genPathX = new GeneralPathX();
666
                                                Point2D firstPt = new Point2D.Double();
667
                                                firstPt = fea.getGeometry().get(0);
668
                                                Point2D[] pts = new Point2D[fea.getGeometry().pointNr() + 1];
669
                                                for (int j = 0; j < fea.getGeometry().pointNr(); j++) {
670
                                                        pts[j] = fea.getGeometry().get(j);
671
                                                }
672
                                                pts[fea.getGeometry().pointNr()] = firstPt;
673
                                                genPathX.moveTo(pts[0].getX(), pts[0].getY());
674
                                                for (int j = 1; j < pts.length; j++) {
675
                                                        genPathX.lineTo(pts[j].getX(), pts[j].getY());
676
                                                }
677
                                                Surface geom = (Surface)gManager.create(TYPES.SURFACE , SUBTYPES.GEOM2D);
678
                                                geom.setGeneralPath(genPathX);
679
                                                feature.set(ID_FIELD_GEOMETRY, geom);
680
                                                if (this.envelope == null) {
681
                                                        this.envelope = geom.getEnvelope();
682
                                                } else {
683
                                                        this.envelope.add(geom.getEnvelope());
684
                                                }
685

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

    
730
                        }
731
                }
732

    
733
        }
734

    
735
        public class Writer {
736
                private Double DEFAULT_ELEVATION = new Double(0);
737

    
738
                private DxfFile.EntityFactory entityMaker;
739

    
740
                private IProjection proj = null;
741

    
742
                private int handle = 40; // Revisar porqu? es 40.
743

    
744
                private int k = 0;
745

    
746
                private boolean dxf3DFile = false;
747
                private String fileName;
748

    
749
                public Writer initialice(File file, IProjection projection) {
750
                        this.proj = projection;
751
                        this.fileName = file.getAbsolutePath();
752
                        entityMaker = new DxfEntityMaker(proj);
753

    
754
                        return this;
755
                }
756

    
757
                public void begin() {
758
                        entityMaker = new DxfEntityMaker(proj);
759
                }
760

    
761
                public void end() throws WriteException {
762
                        try {
763
                                DxfFile dxfFile = new DxfFile(null, fileName, entityMaker);
764
                                dxfFile.setCadFlag(true);
765
                                if (dxf3DFile) {
766
                                        dxfFile.setDxf3DFlag(true);
767
                                }
768
                                dxfFile.save(fileName);
769
                                dxfFile.close();
770
                        } catch (Exception e) {
771
                                throw new WriteException(fileName, e);
772
                        }
773
                }
774

    
775
                public void add(FeatureProvider feature) throws WriteException {
776
                        try {
777
                                Geometry geom = feature.getDefaultGeometry();
778
                                GeometryType type = geom.getGeometryType();
779

    
780
                                if ((TYPES.POINT == type.getType()) && (SUBTYPES.GEOM2DZ == type.getSubType())) {
781
                                        dxf3DFile = true;
782
                                        k = createPoint3D(handle, k, feature);
783

    
784
                                } else if ((TYPES.POINT == type.getType()) && (SUBTYPES.GEOM2D == type.getSubType())) {
785
                                        k = createPoint2D(handle, k, feature);
786

    
787
                                } else if ((TYPES.CURVE == type.getType()) && (SUBTYPES.GEOM2DZ == type.getSubType())) {
788
                                        dxf3DFile = true;
789
                                        k = createPolyline3D(handle, k, feature);
790

    
791
                                } else if ((TYPES.ARC == type.getType()) && (SUBTYPES.GEOM2D == type.getSubType())) {
792
                                        k = createArc2D(handle, k, feature);
793

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

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

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

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

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

    
810
                                } else {
811
                                        logger.warn(
812
                                                        MessageFormat.format(
813
                                                                        "Geometry '{1}' not yet supported",
814
                                                                        new Object[] {geom.getClass().getName()}
815
                                                                )
816
                                                );
817
                                        k++;
818
                                }
819
                        } catch (Exception e) {
820
                                throw new WriteException(fileName, e);
821
                        }
822

    
823
                }
824

    
825
                private boolean hasText(FeatureProvider feature) {
826
                        if (feature.isNull(ID_FIELD_TEXT)) {
827
                                return false;
828
                        }
829
                        if (feature.get(ID_FIELD_TEXT).equals("")) {
830
                                return false;
831
                        }
832
                        return true;
833
                }
834

    
835
                private DxfGroupVector updateProperties(FeatureProvider feature, int k) {
836
                        DxfGroupVector polv = new DxfGroupVector();
837

    
838
                        String layer = (String) feature.get(ID_FIELD_LAYER);
839
                        Integer color = (Integer) feature.get(ID_FIELD_COLOR);
840
                        Double thickness = (Double) feature.get(ID_FIELD_THICKNESS);
841

    
842
                        DxfGroup geometryLayer = new DxfGroup(8, layer);
843

    
844
                        DxfGroup handleGroup = new DxfGroup();
845
                        handleGroup.setCode(5);
846
                        handleGroup.setData(new Integer(handle + k).toString());
847

    
848
                        DxfGroup handleColor = new DxfGroup();
849
                        handleColor.setCode(62);
850
                        handleColor.setData(color);
851

    
852
                        DxfGroup handleThickness = new DxfGroup();
853
                        handleThickness.setCode(39);
854
                        handleThickness.setData(thickness);
855

    
856
                        polv.add(geometryLayer);
857
                        polv.add(handleGroup);
858
                        polv.add(handleColor);
859
                        return polv;
860
                }
861

    
862
                private int createPoint2D(int handle, int k, FeatureProvider feature)
863
                                throws Exception {
864

    
865
                        if (hasText(feature)) {
866
                                return createText2D(handle, k, feature);
867
                        }
868
                        org.gvsig.fmap.geom.primitive.Point point = geomManager.createPoint(0, 0, SUBTYPES.GEOM2D);
869
                        double[] pointCoords = new double[6];
870
                        PathIterator pointIt = (feature.getDefaultGeometry())
871
                                        .getPathIterator(null);
872
                        while (!pointIt.isDone()) {
873
                                pointIt.currentSegment(pointCoords);
874
                                point = geomManager.createPoint(pointCoords[0], pointCoords[1], SUBTYPES.GEOM2D);
875
                                pointIt.next();
876
                        }
877
                        Point2D pto = new Point2D.Double(point.getX(), point.getY());
878

    
879
                        DxfGroup px = new DxfGroup();
880
                        DxfGroup py = new DxfGroup();
881
                        DxfGroup pz = new DxfGroup();
882
                        px.setCode(10);
883
                        px.setData(new Double(pto.getX()));
884
                        py.setCode(20);
885
                        py.setData(new Double(pto.getY()));
886
                        pz.setCode(30);
887
                        // FIXME: POINT del DXF tiene cota. Le asigno cero arbitrariamente.
888
                        pz.setData(new Double(0.0));
889
                        DxfGroupVector pv = updateProperties(feature, k);
890
                        pv.add(px);
891
                        pv.add(py);
892
                        pv.add(pz);
893
                        entityMaker.createPoint(pv);
894
                        k++;
895
                        return k;
896
                }
897

    
898
                private int createText2D(int handle, int k, FeatureProvider feature)
899
                                throws Exception {
900

    
901
                        String text = feature.get(ID_FIELD_TEXT).toString();
902
                        Double heightText = (Double) feature.get(ID_FIELD_HEIGHTTEXT);
903
                        Double rotationText = (Double) feature.get(ID_FIELD_ROTATIONTEXT);
904

    
905
                        DxfGroup handleText = new DxfGroup();
906
                        handleText.setCode(1);
907
                        handleText.setData(text);
908

    
909
                        DxfGroup handleHeightText = new DxfGroup();
910
                        handleHeightText.setCode(40);
911
                        handleHeightText.setData(heightText);
912

    
913
                        DxfGroup handleRotationText = new DxfGroup();
914
                        handleRotationText.setCode(50);
915
                        handleRotationText.setData(rotationText);
916

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

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

    
991
                        DxfGroupVector pv = updateProperties(feature, k);
992
                        pv.add(handleElevation);
993
                        pv.add(px);
994
                        pv.add(py);
995
                        pv.add(pz);
996
                        entityMaker.createPoint(pv);
997
                        k++;
998
                        return k;
999
                }
1000

    
1001
                private int createText3D(int handle, int k, FeatureProvider feature)
1002
                                throws Exception {
1003

    
1004
                        double velev = ((org.gvsig.fmap.geom.primitive.Point) feature.getDefaultGeometry())
1005
                        .getCoordinateAt(0);
1006

    
1007
                        Double elevation = new Double(velev);
1008
                        String text = feature.get(ID_FIELD_TEXT).toString();
1009
                        Double heightText = (Double) feature.get(ID_FIELD_HEIGHTTEXT);
1010
                        Double rotationText = (Double) feature.get(ID_FIELD_ROTATIONTEXT);
1011

    
1012
                        DxfGroup handleText = new DxfGroup();
1013
                        handleText.setCode(1);
1014
                        handleText.setData(text);
1015

    
1016
                        DxfGroup handleHeightText = new DxfGroup();
1017
                        handleHeightText.setCode(40);
1018
                        handleHeightText.setData(heightText);
1019

    
1020
                        DxfGroup handleRotationText = new DxfGroup();
1021
                        handleRotationText.setCode(50);
1022
                        handleRotationText.setData(rotationText);
1023

    
1024
                        DxfGroup handleElevation = new DxfGroup();
1025
                        handleElevation.setCode(38);
1026
                        handleElevation.setData(elevation);
1027

    
1028
                        org.gvsig.fmap.geom.primitive.Point point =
1029
                                (org.gvsig.fmap.geom.primitive.Point) (feature
1030
                                        .getDefaultGeometry()).getInternalShape();
1031

    
1032
                        DxfGroup handleGroup = new DxfGroup();
1033
                        handleGroup.setCode(5);
1034
                        handleGroup.setData(new Integer(handle + k).toString());
1035
                        DxfGroup px = new DxfGroup();
1036
                        DxfGroup py = new DxfGroup();
1037
                        DxfGroup pz = new DxfGroup();
1038
                        px.setCode(10);
1039
                        px.setData(new Double(point.getX()));
1040
                        py.setCode(20);
1041
                        py.setData(new Double(point.getY()));
1042
                        pz.setCode(30);
1043
                        pz.setData(new Double(point.getCoordinateAt(2)));
1044
                        DxfGroupVector pv = updateProperties(feature, k);
1045
                        pv.add(handleElevation);
1046
                        pv.add(handleText);
1047
                        pv.add(handleHeightText);
1048
                        pv.add(handleRotationText);
1049
                        pv.add(handleGroup);
1050
                        pv.add(px);
1051
                        pv.add(py);
1052
                        pv.add(pz);
1053
                        entityMaker.createText(pv);
1054
                        k++;
1055
                        return k;
1056
                }
1057

    
1058
                private int createLwPolyline2D(int handle, int k, FeatureProvider feature,
1059
                                boolean isPolygon) throws Exception {
1060
                        boolean first = true;
1061
                        DxfGroupVector polv = updateProperties(feature, k);
1062
                        Vector vpoints = new Vector();
1063

    
1064
                        DxfGroup polylineFlag = new DxfGroup();
1065
                        polylineFlag.setCode(70);
1066
                        if (isPolygon) {
1067
                                polylineFlag.setData(new Integer(1)); // cerrada
1068
                        } else {
1069
                                polylineFlag.setData(new Integer(0)); // abierta
1070
                        }
1071

    
1072
                        PathIterator theIterator = (feature.getDefaultGeometry())
1073
                                        .getPathIterator(null, geomManager.getFlatness()); // polyLine.
1074
                                                                                                                                // getPathIterator
1075
                                                                                                                                // (null,
1076
                        // flatness);
1077

    
1078
                        double[] theData = new double[6];
1079
                        while (!theIterator.isDone()) {
1080
                                int theType = theIterator.currentSegment(theData);
1081
                                switch (theType) {
1082
                                case PathIterator.SEG_MOVETO:
1083
                                        if (!first) {
1084
                                                for (int j = 0; j < vpoints.size(); j++) {
1085
                                                        DxfGroup xvertex = new DxfGroup();
1086
                                                        xvertex.setCode(10);
1087
                                                        xvertex
1088
                                                                        .setData(new Double(
1089
                                                                                        ((org.gvsig.fmap.geom.primitive.Point) vpoints
1090
                                                                                                        .get(j)).getX()));
1091
                                                        DxfGroup yvertex = new DxfGroup();
1092
                                                        yvertex.setCode(20);
1093
                                                        yvertex
1094
                                                                        .setData(new Double(
1095
                                                                                        ((org.gvsig.fmap.geom.primitive.Point) vpoints
1096
                                                                                                        .get(j)).getY()));
1097
                                                        polv.add(xvertex);
1098
                                                        polv.add(yvertex);
1099
                                                }
1100

    
1101
                                                entityMaker.createLwPolyline(polv);
1102
                                                k++;
1103
                                                polv = updateProperties(feature, k);
1104

    
1105
                                        }
1106
                                        first = false;
1107
                                        polv.add(polylineFlag);
1108
                                        vpoints.clear();
1109
                                        vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1110
                                        break;
1111
                                case PathIterator.SEG_LINETO:
1112
                                        vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1113
                                        break;
1114
                                case PathIterator.SEG_QUADTO:
1115
                                        break;
1116
                                case PathIterator.SEG_CUBICTO:
1117
                                        break;
1118
                                case PathIterator.SEG_CLOSE:
1119
                                        polylineFlag.setData(new Integer(1)); // cerrada
1120
                                        break;
1121

    
1122
                                }
1123
                                theIterator.next();
1124
                        }
1125

    
1126
                        for (int j = 0; j < vpoints.size(); j++) {
1127
                                DxfGroup xvertex = new DxfGroup();
1128
                                xvertex.setCode(10);
1129
                                xvertex
1130
                                                .setData(new Double(
1131
                                                                ((org.gvsig.fmap.geom.primitive.Point) vpoints
1132
                                                                                .get(j)).getX()));
1133
                                DxfGroup yvertex = new DxfGroup();
1134
                                yvertex.setCode(20);
1135
                                yvertex
1136
                                                .setData(new Double(
1137
                                                                ((org.gvsig.fmap.geom.primitive.Point) vpoints
1138
                                                                                .get(j)).getY()));
1139
                                polv.add(xvertex);
1140
                                polv.add(yvertex);
1141
                        }
1142

    
1143
                        entityMaker.createLwPolyline(polv);
1144
                        k++;
1145
                        return k;
1146
                }
1147

    
1148
                private int createPolyline3D(int handle, int k, FeatureProvider feature)
1149
                                throws Exception {
1150
                        DxfGroupVector polv = updateProperties(feature, k);
1151
                        Vector vpoints = new Vector();
1152
                        PathIterator theIterator = (feature.getDefaultGeometry())
1153
                                        .getPathIterator(null, geomManager.getFlatness()); // polyLine.
1154
                                                                                                                                // getPathIterator
1155
                                                                                                                                // (null,
1156
                        // flatness);
1157
                        double[] theData = new double[6];
1158
                        Curve curve = (Curve) feature.getDefaultGeometry();
1159
                        double[] velev = new double[curve.getNumVertices()];
1160
                        for (int i = 0; i < curve.getNumVertices(); i++) {
1161
                                velev[i] = curve.getCoordinateAt(i, 2);
1162
                        }
1163

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

    
1270
                private boolean constantElevation(double[] velev) {
1271
                        boolean constant = true;
1272
                        for (int i = 0; i < velev.length; i++) {
1273
                                for (int j = 0; j < velev.length; j++) {
1274
                                        if (j > i) {
1275
                                                if (velev[i] != velev[j]) {
1276
                                                        constant = false;
1277
                                                        break;
1278
                                                }
1279
                                        }
1280
                                }
1281
                                break;
1282
                        }
1283
                        return constant;
1284
                }
1285

    
1286
                private int createCircle2D(int handle, int k, FeatureProvider feature)
1287
                                throws Exception {
1288
                        DxfGroupVector polv = updateProperties(feature, k);
1289
                        DxfGroup circleFlag = new DxfGroup();
1290
                        circleFlag.setCode(100);
1291
                        polv.add(circleFlag);
1292

    
1293
                        DxfGroup xvertex = new DxfGroup();
1294
                        xvertex.setCode(10);
1295
                        Circle circle = (Circle) (feature
1296
                                        .getDefaultGeometry()).getInternalShape();
1297
                        xvertex.setData(new Double(circle.getCenter().getX()));
1298
                        DxfGroup yvertex = new DxfGroup();
1299
                        yvertex.setCode(20);
1300
                        yvertex.setData(new Double(circle.getCenter().getY()));
1301
                        DxfGroup zvertex = new DxfGroup();
1302
                        zvertex.setCode(30);
1303
                        // TODO: COORDENADA Z. REVISAR ESTO PARA ENTIDADES 3D
1304
                        zvertex.setData(new Double(0));
1305

    
1306
                        DxfGroup radius = new DxfGroup();
1307
                        radius.setCode(40);
1308
                        radius.setData(new Double(circle.getRadious()));
1309

    
1310
                        polv.add(xvertex);
1311
                        polv.add(yvertex);
1312
                        polv.add(zvertex);
1313
                        polv.add(radius);
1314

    
1315
                        entityMaker.createCircle(polv);
1316
                        k++;
1317
                        return k;
1318
                }
1319

    
1320
                private int createArc2D(int handle, int k, FeatureProvider feature)
1321
                                throws Exception {
1322
                        Arc arc = (Arc) (feature.getDefaultGeometry())
1323
                                        .getInternalShape();
1324
                        org.gvsig.fmap.geom.primitive.Point[] pts = new org.gvsig.fmap.geom.primitive.Point[3];
1325
                        pts[0] = arc.getInitPoint();
1326
                        pts[1] = arc.getCenterPoint();
1327
                        pts[2] = arc.getEndPoint();
1328
                        org.gvsig.fmap.geom.primitive.Point center = arc.getCenterPoint();
1329
                        GeometryOperationContext ctx = new GeometryOperationContext();
1330
                        ctx.setAttribute("geom", pts[0]);
1331
                        double radius = ((Double)geomManager.invokeOperation(PointDistance.CODE, center, ctx)).doubleValue();
1332

    
1333
                        double initAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1334
                        initAngle = Math.toDegrees(initAngle);
1335
                        ctx.setAttribute("geom", pts[1]);
1336
                        double midAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1337
                        midAngle = Math.toDegrees(midAngle);
1338
                        ctx.setAttribute("geom", pts[2]);
1339
                        double endAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1340
                        endAngle = Math.toDegrees(endAngle);
1341

    
1342
                        DxfGroup ax = new DxfGroup();
1343
                        DxfGroup ay = new DxfGroup();
1344
                        DxfGroup ac = new DxfGroup();
1345
                        DxfGroup ai = new DxfGroup();
1346
                        DxfGroup ae = new DxfGroup();
1347
                        ax.setCode(10);
1348
                        ax.setData(new Double(center.getX()));
1349
                        ay.setCode(20);
1350
                        ay.setData(new Double(center.getY()));
1351
                        ac.setCode(40);
1352
                        ac.setData(new Double(radius));
1353
                        ai.setCode(50);
1354
                        ai.setData(new Double(initAngle));
1355
                        ae.setCode(51);
1356
                        ae.setData(new Double(endAngle));
1357
                        DxfGroupVector av = updateProperties(feature, k);
1358
                        av.add(ax);
1359
                        av.add(ay);
1360
                        av.add(ac);
1361
                        av.add(ai);
1362
                        av.add(ae);
1363
                        entityMaker.createArc(av);
1364
                        k++;
1365
                        return k;
1366
                }
1367

    
1368
                private int createEllipse2D(int handle, int k, FeatureProvider feature)
1369
                                throws Exception {
1370
                        Ellipse ellipse = (Ellipse) (feature
1371
                                        .getDefaultGeometry()).getInternalShape();
1372

    
1373
                        org.gvsig.fmap.geom.primitive.Point center = (org.gvsig.fmap.geom.primitive.Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM2D);
1374
                        center.setCoordinateAt(0, (ellipse.getAxis1Start().getX() + ellipse.getAxis1End().getX()) / 2);
1375
                        center.setCoordinateAt(1, (ellipse.getAxis1Start().getY() + ellipse.getAxis1End().getY()) / 2);
1376

    
1377
                        double mAxisL = ellipse.getAxis2Dist() * 2;
1378
                        GeometryOperationContext ctx = new GeometryOperationContext();
1379
                        ctx.setAttribute("geom", ellipse.getAxis1End());
1380
                        double maAxisL = ((Double)geomManager.invokeOperation(PointDistance.CODE, ellipse.getAxis1Start(), ctx)).doubleValue();
1381

    
1382
                        Point2D endPointOfMajorAxis = new Point2D.Double(ellipse.getAxis1End().getX(), ellipse.getAxis1End().getY());
1383
                        double azimut = Math
1384
                                        .atan2(endPointOfMajorAxis.getX() - center.getX(),
1385
                                                        endPointOfMajorAxis.getY() - center.getY());
1386
                        double azimut2 = azimut + Math.PI / 2.0;
1387
                        if (azimut2 >= Math.PI * 2) {
1388
                                azimut2 = azimut2 - Math.PI * 2;
1389
                        }
1390
                        Point2D endPointOfMinorAxis = new Point2D.Double(center.getX()
1391
                                        + (ellipse.getAxis2Dist() * Math.sin(azimut2)), center.getY()
1392
                                        + (ellipse.getAxis2Dist() * Math.cos(azimut2)));
1393

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

    
1431
        }
1432

    
1433
        public boolean closeResourceRequested(ResourceProvider resource) {
1434
                return true;
1435
        }
1436

    
1437
        public int getOIDType() {
1438
                return DataTypes.LONG;
1439
        }
1440

    
1441
        public boolean supportsAppendMode() {
1442
                return false;
1443
        }
1444

    
1445
        public void append(FeatureProvider featureProvider) {
1446
                try {
1447
                        writer.add(featureProvider);
1448
                } catch (WriteException e) {
1449
                        // TODO Auto-generated catch block
1450
                        e.printStackTrace();
1451
                }
1452
        }
1453

    
1454
        public void beginAppend() {
1455
                try {
1456
                        writer = new Writer().initialice((File) resource.get(), projection);
1457
                        writer.begin();
1458
                } catch (AccessResourceException e) {
1459
                        // TODO Auto-generated catch block
1460
                        e.printStackTrace();
1461
                }
1462
        }
1463

    
1464
        public void endAppend() {
1465
                try {
1466
                        resource.notifyOpen();
1467
                        writer.end();
1468
                        resource.notifyClose();
1469
                        counterNewsOIDs = 0;
1470
                } catch (ResourceNotifyOpenException e) {
1471
                        // TODO Auto-generated catch block
1472
                        e.printStackTrace();
1473
                } catch (ResourceNotifyCloseException e) {
1474
                        // TODO Auto-generated catch block
1475
                        e.printStackTrace();
1476
                } catch (WriteException e) {
1477
                        // TODO Auto-generated catch block
1478
                        e.printStackTrace();
1479
                }
1480
        }
1481

    
1482
        public void saveToState(PersistentState state) throws PersistenceException {
1483
                // TODO Auto-generated method stub
1484
                throw new NotYetImplemented();
1485
        }
1486

    
1487
        public void loadFromState(PersistentState state) throws PersistenceException {
1488
                // TODO Auto-generated method stub
1489
                throw new NotYetImplemented();
1490
        }
1491

    
1492
        public Object createNewOID() {
1493
                return new Long(counterNewsOIDs++);
1494
        }
1495

    
1496
        protected void initializeFeatureTypes() throws InitializeException {
1497
                try {
1498
                        this.open();
1499
                } catch (OpenException e) {
1500
                        throw new InitializeException(this.getName(), e);
1501
                }
1502
        }
1503

    
1504
        public Envelope getEnvelope() throws DataException {
1505
                this.open();
1506
                return this.envelope;
1507
        }
1508

    
1509
        public Object getDynValue(String name) throws DynFieldNotFoundException {
1510
                if( DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name) ) {
1511
                        try {
1512
                                return this.getEnvelope();
1513
                        } catch (DataException e) {
1514
                                return null;
1515
                        }
1516
                }
1517
                return super.getDynValue(name);
1518
        }
1519
        
1520
        
1521
        /*
1522
         * (non-Javadoc)
1523
         *
1524
         * @see
1525
         * org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
1526
         * gvsig.fmap.dal.resource.spi.ResourceProvider)
1527
         */
1528
        public void resourceChanged(ResourceProvider resource) {
1529
                this.getStoreServices().notifyChange(
1530
                                DataStoreNotification.RESOURCE_CHANGED,
1531
                                resource);
1532
        }
1533

    
1534

    
1535
        public Object getSourceId() {
1536
                return this.getDXFParameters().getFile();
1537
        }
1538

    
1539
        public ResourceProvider getResource() {
1540
                return resource;
1541
        }
1542

    
1543
}