Statistics
| Revision:

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

History | View | Annotate | Download (61.8 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.Line;
79
import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
80
import org.gvsig.fmap.geom.primitive.Surface;
81
import org.gvsig.fmap.geom.type.GeometryType;
82
import org.gvsig.tools.ToolsLocator;
83
import org.gvsig.tools.dispose.DisposableIterator;
84
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
85
import org.gvsig.tools.dynobject.exception.DynMethodException;
86
import org.gvsig.tools.exception.NotYetImplemented;
87
import org.gvsig.tools.persistence.PersistentState;
88
import org.gvsig.tools.persistence.exception.PersistenceException;
89
import org.gvsig.tools.task.SimpleTaskStatus;
90
import org.gvsig.tools.task.TaskStatusManager;
91

    
92
public class DXFStoreProvider extends AbstractMemoryStoreProvider implements
93
ResourceConsumer {
94
    private static final Logger logger = LoggerFactory.getLogger(DXFStoreProvider.class);
95

    
96
    public static final String NAME = "DXF";
97
    public static final String DESCRIPTION = "DXF file";
98

    
99
    public static final String METADATA_DEFINITION_NAME = NAME;
100

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

    
112
    private static final int ID_FIELD_ID = 0;
113
    private static final int ID_FIELD_GEOMETRY = 1;
114
    private static final int ID_FIELD_ENTITY = 2;
115
    private static final int ID_FIELD_LAYER = 3;
116
    private static final int ID_FIELD_COLOR = 4;
117
    private static final int ID_FIELD_ELEVATION = 5;
118
    private static final int ID_FIELD_THICKNESS = 6;
119
    private static final int ID_FIELD_TEXT = 7;
120
    private static final int ID_FIELD_HEIGHTTEXT = 8;
121
    private static final int ID_FIELD_ROTATIONTEXT = 9;
122

    
123
    private IProjection projection;
124
    private ResourceProvider resource;
125
    private LegendBuilder legendBuilder;
126

    
127
    private long counterNewsOIDs = 0;
128
    private Envelope envelope;
129
    private Writer writer;
130
    protected GeometryManager geomManager = GeometryLocator.getGeometryManager();
131

    
132
    private SimpleTaskStatus taskStatus;
133

    
134

    
135
    public DXFStoreProvider(DXFStoreParameters parameters,
136
        DataStoreProviderServices storeServices) throws InitializeException {
137
        super(
138
            parameters, 
139
            storeServices,
140
            FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME)
141
        );
142

    
143
        TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
144
        this.taskStatus = manager.creteDefaultSimpleTaskStatus("DXF");
145

    
146
        counterNewsOIDs = 0;
147
        //                projection = CRSFactory.getCRS(getParameters().getSRSID());
148

    
149
        File file = getDXFParameters().getFile();
150
        resource = this.createResource(
151
            FileResource.NAME,
152
            new Object[] { file.getAbsolutePath() }
153
        );
154

    
155
        resource.addConsumer(this);
156

    
157
        this.projection = this.getDXFParameters().getCRS();
158

    
159

    
160
        try {
161
            legendBuilder = (LegendBuilder) this.invokeDynMethod(
162
                LegendBuilder.DYNMETHOD_BUILDER_NAME, null);
163
        } catch (DynMethodException e) {
164
            legendBuilder = null;
165
        } catch (Exception e) {
166
            throw new InitializeException(e);
167
        }
168

    
169
        this.initializeFeatureTypes();
170

    
171
    }
172

    
173
    private DXFStoreParameters getDXFParameters() {
174
        return (DXFStoreParameters) this.getParameters();
175
    }
176

    
177
    public String getProviderName() {
178
        return NAME;
179
    }
180

    
181
    public boolean allowWrite() {
182
        return true;
183
    }
184

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

    
193
    public Object getLabeling() throws OpenException {
194
        this.open();
195
        if (legendBuilder == null) {
196
            return null;
197
        }
198
        return legendBuilder.getLabeling();
199
    }
200

    
201
    private class DXFData {
202
        public List data = null;
203
        public FeatureType defaultFType = null;
204
        public List fTypes = null;
205
        public Envelope envelope = null;
206
        public IProjection projection;
207
        public LegendBuilder legendBuilder;
208
        public Envelope getEnvelopeCopy() throws CreateEnvelopeException {
209
            if (envelope == null) {
210
                return null;
211
            }
212
            Envelope newEnvelope;
213
            if (envelope.getDimension() == 2) {
214
                newEnvelope = geomManager.createEnvelope(SUBTYPES.GEOM2D);
215
            } else {
216
                newEnvelope = geomManager.createEnvelope(SUBTYPES.GEOM3D);
217

    
218
            }
219
            newEnvelope.setLowerCorner(envelope.getLowerCorner());
220
            newEnvelope.setUpperCorner(envelope.getUpperCorner());
221
            return newEnvelope;
222
        }
223
    }
224

    
225
    public void open() throws OpenException {
226
        if (this.data != null) {
227
            return;
228
        }
229
        openEver();
230
    }
231

    
232
    private void openEver() throws OpenException {
233
        try {
234
            this.taskStatus.add();
235
            getResource().execute(new ResourceAction() {
236
                public Object run() throws Exception {
237
                    DXFData dxfData = null;
238
                    resource.setData(new HashMap());
239
                    FeatureStoreProviderServices store = getStoreServices();
240
                    dxfData = new DXFData();
241
                    dxfData.data = new ArrayList();
242
                    data = dxfData.data;
243
                    counterNewsOIDs = 0;
244
                    Reader reader = new Reader().initialice(
245
                        getMemoryProvider(),
246
                        (File) resource.get(),
247
                        projection,
248
                        legendBuilder
249
                    );
250
                    reader.begin(store);
251
                    dxfData.defaultFType = reader.getDefaultType()
252
                    .getNotEditableCopy();
253
                    ArrayList types = new ArrayList();
254
                    Iterator it = reader.getTypes().iterator();
255
                    EditableFeatureType fType;
256
                    while (it.hasNext()) {
257
                        fType = (EditableFeatureType) it.next();
258
                        if (fType.getId().equals(dxfData.defaultFType.getId())) {
259
                            types.add(dxfData.defaultFType);
260
                        } else {
261
                            types.add(fType.getNotEditableCopy());
262
                        }
263
                    }
264
                    dxfData.fTypes = types;
265

    
266
                    resource.notifyOpen();
267
                    store.setFeatureTypes(dxfData.fTypes, dxfData.defaultFType);
268
                    reader.load();
269

    
270
                    dxfData.envelope = reader.getEnvelope();
271

    
272
                    dxfData.legendBuilder = legendBuilder;
273

    
274
                    dxfData.projection = projection;
275

    
276
                    reader.end();
277
                    resource.notifyClose();
278
                    ((Map) resource.getData()).put(projection.getAbrev(),
279
                        dxfData); // OJO la reproyeccion
280

    
281
                    data = dxfData.data;
282
                    store.setFeatureTypes(dxfData.fTypes, dxfData.defaultFType);
283
                    legendBuilder = dxfData.legendBuilder;
284
                    envelope= dxfData.getEnvelopeCopy();
285
                    // setDynValue("CRS", projection.getAbrev());
286
                    counterNewsOIDs = data.size();
287
                    return null;
288
                }
289
            });
290
            this.taskStatus.terminate();
291
        } catch (Exception e) {
292
            data = null;
293
            this.taskStatus.abort();
294
            try {
295
                throw new OpenException(resource.getName(), e);
296
            } catch (AccessResourceException e1) {
297
                throw new OpenException(getProviderName(), e);
298
            }
299
        } finally {
300
            this.taskStatus.remove();
301
        }
302
    }
303

    
304

    
305
    public DataServerExplorer getExplorer() throws ReadException {
306
        DataManager manager = DALLocator.getDataManager();
307
        FilesystemServerExplorerParameters params;
308
        try {
309
            params = (FilesystemServerExplorerParameters) manager
310
            .createServerExplorerParameters(FilesystemServerExplorer.NAME);
311
            params.setRoot(this.getDXFParameters().getFile().getParent());
312
            return manager.openServerExplorer(FilesystemServerExplorer.NAME,params);
313
        } catch (DataException e) {
314
            throw new ReadException(this.getProviderName(), e);
315
        } catch (ValidateDataParametersException e) {
316
            throw new ReadException(this.getProviderName(), e);
317
        }
318

    
319
    }
320

    
321

    
322

    
323
    public void performChanges(Iterator deleteds, Iterator inserteds, Iterator updateds, Iterator originalFeatureTypesUpdated) throws PerformEditingException {
324

    
325
        try {
326
            this.taskStatus.add();
327
            taskStatus.message("_preparing");
328
            getResource().execute(new ResourceAction() {
329
                public Object run() throws Exception {
330
                    FeatureSet features = null;
331
                    DisposableIterator it = null;
332
                    try {
333
                        File file = (File) resource.get();
334
                        String fileName = file.getAbsolutePath();
335
                        writer = new Writer().initialice(file, projection);
336
                        features =
337
                            getStoreServices().getFeatureStore()
338
                            .getFeatureSet();
339
                        List newdata = new ArrayList();
340
                        writer.begin();
341
                        it = features.fastIterator();
342
                        taskStatus.setRangeOfValues(0,0);
343
                        long counter=0;
344
                        while (it.hasNext()) {
345
                            taskStatus.setCurValue(counter++);
346
                            FeatureProvider feature = getStoreServices().getFeatureProviderFromFeature(
347
                                (org.gvsig.fmap.dal.feature.Feature) it.next());
348
                            writer.add(feature);
349
                            if (feature.getOID() == null){
350
                                logger.warn("feature without OID");
351
                                feature.setOID(createNewOID());
352
                            }
353
                            newdata.add(feature);
354
                        }
355
                        data = newdata;
356
                        writer.end();
357
                        if (writer.getEnvelope() != null){
358
                            envelope = writer.getEnvelope().getGeometry().getEnvelope();
359
                        }
360
                        resource.notifyChanges();
361
                        //                                        counterNewsOIDs = 0;
362
                    } finally {
363
                        if (it != null) {
364
                            it.dispose();
365
                        }
366
                        if (features != null) {
367
                            features.dispose();
368
                        }
369
                    }
370
                    return null;
371
                }
372
            });
373
            this.taskStatus.terminate();
374
        } catch (Exception e) {
375
            this.taskStatus.abort();
376
            throw new PerformEditingException(getResource().toString(), e);
377
        } finally {
378
            this.taskStatus.remove();
379
        }
380
    }
381
    
382
    public static void initializeFeatureType(EditableFeatureType featureType, IProjection projection, int geometrySubtype){
383
        featureType.setHasOID(true);
384

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

    
390
        EditableFeatureAttributeDescriptor attr = featureType.add(
391
            NAME_FIELD_GEOMETRY, DataTypes.GEOMETRY);
392
        attr.setSRS(projection);
393
        attr.setGeometryType(Geometry.TYPES.GEOMETRY);                        
394
        //If is a 3D file, set the geometry subtype
395
        attr.setGeometrySubType(geometrySubtype);
396
        
397
//        ID_FIELD_GEOMETRY = 1; //attr.getIndex();
398

    
399
        featureType.setDefaultGeometryAttributeName(NAME_FIELD_GEOMETRY);
400

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

    
408
        // FIXME: Cual es el size de Layer ?
409
//        ID_FIELD_LAYER = 3;
410
        featureType.add(NAME_FIELD_LAYER,
411
            DataTypes.STRING, 100)
412
            .setDefaultValue(
413
            "default").getIndex();
414

    
415
//        ID_FIELD_COLOR = 4;
416
        featureType.add(NAME_FIELD_COLOR,
417
            DataTypes.INT)
418
            .setDefaultValue(
419
                Integer.valueOf(0)).getIndex();
420

    
421
//        ID_FIELD_ELEVATION = 5;
422
        featureType.add(NAME_FIELD_ELEVATION,
423
            DataTypes.DOUBLE)
424
            .setDefaultValue(
425
                Double.valueOf(0)).getIndex();
426

    
427
//        ID_FIELD_THICKNESS = 6;
428
        featureType.add(NAME_FIELD_THICKNESS,
429
            DataTypes.DOUBLE)
430
            .setDefaultValue(
431
                Double.valueOf(0)).getIndex();
432

    
433
        // FIXME: Cual es el size de Text ?
434
//        ID_FIELD_TEXT = 7;
435
        featureType.add(NAME_FIELD_TEXT,
436
            DataTypes.STRING, 100)
437
            .setDefaultValue("")
438
            .getIndex();
439

    
440
//        ID_FIELD_HEIGHTTEXT = 8;
441
        featureType.add(NAME_FIELD_HEIGHTTEXT,
442
            DataTypes.DOUBLE).setDefaultValue(
443
                Double.valueOf(10)).getIndex();
444

    
445
//        ID_FIELD_ROTATIONTEXT = 9;
446
        featureType.add(NAME_FIELD_ROTATIONTEXT,
447
            DataTypes.DOUBLE).setDefaultValue(
448
                Double.valueOf(0)).getIndex();
449

    
450
        // FIXME: Parece que el DXF puede tener mas atributos opcionales.
451
        // Habria que ver de pillarlos ?
452

    
453
    }
454

    
455
    public class Reader {
456
        private File file;
457
        private String fileName;
458
        private IProjection projection;
459
        private List types;
460
        private LegendBuilder leyendBuilder;
461
        private AbstractMemoryStoreProvider store;
462
        private Envelope envelope;
463

    
464
        //Next two variables are used to read the DXF file
465
        private DxfFile.EntityFactory featureMaker;
466
        private DxfFile.VarSettings headerManager;
467

    
468
        public Reader initialice(AbstractMemoryStoreProvider store, File file,
469
            IProjection projection,
470
            LegendBuilder leyendBuilder) {
471
            this.store = store;
472
            this.file = file;
473
            this.fileName = file.getAbsolutePath();
474
            this.projection = projection;
475
            this.leyendBuilder = leyendBuilder;
476
            if (leyendBuilder != null) {
477
                leyendBuilder.initialize(store);
478
            }
479
            return this;
480
        }
481

    
482
        public Envelope getEnvelope() {
483
            return this.envelope;
484
        }
485

    
486
        public void begin(FeatureStoreProviderServices store) throws LoadException {
487
            taskStatus.message("_preloading_data");
488
            featureMaker = new DxfFeatureMaker(projection);
489
            headerManager = new DxfHeaderManager();
490
            DxfFile dxfFeatureFile = new DxfFile(projection, file
491
                .getAbsolutePath(), featureMaker, headerManager);
492

    
493
            try {
494
                dxfFeatureFile.load();
495
            } catch (Exception e1) {
496
                throw new LoadException(e1, fileName);
497
            }
498

    
499
            taskStatus.message("_preparing_featureType");
500
            int geometrySubtype;
501
                        if (featureMaker.isDxf3DFile() && headerManager.isWritedDxf3D()){
502
                geometrySubtype = Geometry.SUBTYPES.GEOM3D;
503
            }else{
504
                    geometrySubtype = Geometry.SUBTYPES.GEOM2D;
505
            }                        
506
                        EditableFeatureType featureType = store.createFeatureType(getName());
507
            initializeFeatureType(featureType, this.projection, geometrySubtype);
508

    
509
            types = new ArrayList();
510
            types.add(featureType);
511

    
512
            if (leyendBuilder != null) {
513
                taskStatus.message("_preparing_leyend");
514
                leyendBuilder.begin();
515
            }
516

    
517
        }
518

    
519
        public void end() {
520
            if (leyendBuilder != null) {
521
                leyendBuilder.end();
522
            }
523
        }
524

    
525
        public List getTypes() {
526
            return types;
527
        }
528

    
529
        public EditableFeatureType getDefaultType() {
530
            return (EditableFeatureType) types.get(0);
531
        }
532

    
533
        private Double toDouble(String value) {
534
            if (value == null) {
535
                return Double.valueOf(0);
536
            }
537
            return Double.valueOf(value);
538
        }
539

    
540
        public void load() throws DataException {
541

    
542
            this.envelope = null;
543

    
544
            IObjList.vector features = (IObjList.vector) ((DxfFeatureMaker) featureMaker)
545
            .getObjects();
546
            String acadVersion = ((DxfHeaderManager) headerManager)
547
            .getAcadVersion();
548

    
549

    
550
            logger.info("load: acadVersion = '" + acadVersion + "'");
551

    
552
            GeometryManager gManager = GeometryLocator.getGeometryManager();
553

    
554
            taskStatus.setRangeOfValues(0,features.size());
555

    
556
            if (!featureMaker.isDxf3DFile() && !headerManager.isWritedDxf3D()) {
557
                // y no est�n todos a 9999
558
                taskStatus.message("_fixing_3dgeometries");
559
                Feature[] features2D = new Feature[features.size()];
560
                for (int i = 0; i < features.size(); i++) {
561
                    taskStatus.setCurValue(i);
562
                    Feature fea = (Feature) features.get(i);
563
                    if (fea.getGeometry() instanceof org.gvsig.dxf.px.gml.Point3D) {
564
                        Point point = (Point) fea.getGeometry();
565
                        Point point2 = new Point();
566
                        for (int j = 0; j < point.pointNr(); j++) {
567
                            point2.add(point.get(j));
568
                        }
569
                        point2.setTextPoint(point.isTextPoint());
570
                        fea.setGeometry(point2);
571
                        features2D[i] = fea;
572

    
573
                    } else if (fea.getGeometry() instanceof LineString3D) {
574
                        LineString lineString = (LineString) fea.getGeometry();
575
                        LineString lineString2 = new LineString();
576
                        for (int j = 0; j < lineString.pointNr(); j++) {
577
                            lineString2.add(lineString.get(j));
578
                        }
579
                        fea.setGeometry(lineString2);
580
                        features2D[i] = fea;
581
                    } else if (fea.getGeometry() instanceof Polygon3D) {
582
                        Polygon polygon = (Polygon) fea.getGeometry();
583
                        Polygon polygon2 = new Polygon();
584
                        for (int j = 0; j < polygon.pointNr(); j++) {
585
                            polygon2.add(polygon.get(j));
586
                        }
587
                        fea.setGeometry(polygon2);
588
                        features2D[i] = fea;
589
                    }
590
                }
591
                features.clear();
592
                for (int i = 0; i < features2D.length; i++) {
593
                    features.add(features2D[i]);
594
                }
595
            }
596

    
597

    
598

    
599
            taskStatus.message("_loading");
600
            for (int i = 0; i < features.size(); i++) {
601

    
602
                taskStatus.setCurValue(i);
603

    
604
                FeatureProvider feature = store.createFeatureProvider(store
605
                    .getStoreServices().getDefaultFeatureType());
606

    
607
                Feature fea = (Feature) features.get(i);
608
                try {
609

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

    
628
                    // FIXME: Habia una incongruencia en el codigo ya que al
629
                    // campo
630
                    // ID_FIELD_GEOMETRY igual le asignaba una geometria que un
631
                    // valor de cadena como 'Point3D', 'Polyline2D' o
632
                    // 'Polyline3D'
633
                    // Faltaria un atributo ID_FIELD_FSHAPE ?
634
                    //
635

    
636
                    Geometry geometry = null;
637

    
638
                    if (fea.getGeometry() instanceof org.gvsig.dxf.px.gml.Point3D) {
639
                        org.gvsig.dxf.px.gml.Point3D point = (org.gvsig.dxf.px.gml.Point3D) fea.getGeometry();
640
                        Point3D pto = point.getPoint3D(0);
641
                        org.gvsig.fmap.geom.primitive.Point geom = gManager.createPoint(pto.getX(), pto.getY(),SUBTYPES.GEOM3D);
642
                        geom.setCoordinateAt(Geometry.DIMENSIONS.Z, pto.getZ());
643

    
644
                        geometry = geom;
645
                        
646
                        if (point.isTextPoint()) {
647
                            /// TODO labeling
648
                        }
649

    
650
                    } else if (fea.getGeometry() instanceof Point ) {
651
                        Point point = (Point) fea.getGeometry();
652
                        Point2D pto = point.get(0);
653

    
654
                        geometry = gManager.createPoint(pto.getX(), pto.getY(),SUBTYPES.GEOM2D);
655

    
656
                        if (point.isTextPoint()) {
657
                            /// TODO labeling
658
                        }
659
                        
660
                    } else if (fea.getGeometry() instanceof LineString3D) {                        
661
                        Line line = gManager.createLine(SUBTYPES.GEOM3D);
662
                        for (int j = 0; j < fea.getGeometry().pointNr(); j++) {
663
                            Point3D point = ((LineString3D) fea.getGeometry()).getPoint3D(j);
664
                            line.addVertex(point.getX(), point.getY(),point.getZ());
665
                        }
666
                        geometry = line;                       
667

    
668
                    } else if (fea.getGeometry() instanceof LineString ) {
669
                        Line line = gManager.createLine(SUBTYPES.GEOM2D);
670
                        for (int j = 0; j < fea.getGeometry().pointNr(); j++) {
671
                            Point2D point = fea.getGeometry().get(j);
672
                            line.addVertex(point.getX(), point.getY());
673
                        }
674
                        geometry = line;                        
675

    
676
                    } else if (fea.getGeometry() instanceof Polygon3D) {                       
677
                        org.gvsig.fmap.geom.primitive.Polygon polygon = gManager.createPolygon(SUBTYPES.GEOM3D);
678
                        for (int j = 0; j < fea.getGeometry().pointNr(); j++) {
679
                            Point3D point = ((LineString3D) fea.getGeometry()).getPoint3D(j);
680
                            polygon.addVertex(point.getX(), point.getY(),point.getZ());
681
                        }
682
                        Point3D point = ((LineString3D) fea.getGeometry()).getPoint3D(0);
683
                        polygon.addVertex(point.getX(), point.getY(),point.getZ());
684
                        geometry = polygon;                       
685

    
686
                    } else if (fea.getGeometry() instanceof Polygon ) {
687
                        org.gvsig.fmap.geom.primitive.Polygon polygon = gManager.createPolygon(SUBTYPES.GEOM2D);
688
                        for (int j = 0; j < fea.getGeometry().pointNr(); j++) {
689
                            Point2D point = fea.getGeometry().get(j);
690
                            polygon.addVertex(point.getX(), point.getY());
691
                        }
692
                        Point2D point = fea.getGeometry().get(0);
693
                        polygon.addVertex(point.getX(), point.getY());
694
                        geometry = polygon;
695

    
696
                    } else {                                            
697
                        logger.warn(
698
                            MessageFormat.format(
699
                                "load: geometry type {1} not supported",
700
                                new Object[] { fea.getGeometry().getClass().getName() }
701
                            )
702
                        );
703
                    }
704

    
705
                    feature.set(ID_FIELD_GEOMETRY, geometry);
706
                    feature.setDefaultGeometry(geometry);
707
                    if (this.envelope == null) {
708
                        this.envelope = geometry.getEnvelope();
709
                    } else {
710
                        this.envelope.add(geometry.getEnvelope());
711
                    }
712

    
713
                    //Add the feature to the store
714
                    store.addFeatureProvider(feature);
715

    
716
                } catch (Exception e) {
717
                    //throw new LoadException(e, fileName);
718
                    // FIXME: add to log max 10
719
                }
720
                if (leyendBuilder != null) {
721
                    try {
722
                        leyendBuilder.process(feature);
723
                    } catch (Exception e) {
724
                        logger.warn(
725
                            MessageFormat.format(
726
                                "load: legendBuilder process fails in the feature {1}",
727
                                fea
728
                            )
729
                        );
730
                    }
731
                }
732

    
733
            }
734
        }
735

    
736
    }
737

    
738
    public class Writer {
739
        private Double DEFAULT_ELEVATION = new Double(0);
740

    
741
        private DxfFile.EntityFactory entityMaker;
742

    
743
        private IProjection proj = null;
744

    
745
        private int handle = 40; // Revisar porqu� es 40.
746

    
747
        private int k = 0;
748

    
749
        private boolean dxf3DFile = false;
750
        private String fileName;
751
        private Envelope envelope;
752

    
753
        public Writer initialice(File file, IProjection projection) {
754
            this.proj = projection;
755
            this.fileName = file.getAbsolutePath();
756
            entityMaker = new DxfEntityMaker(proj);
757
            return this;
758
        }
759

    
760
        public void begin() {
761
            envelope = null;
762
            entityMaker = new DxfEntityMaker(proj);
763
        }
764

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

    
779
        public void add(FeatureProvider feature) throws WriteException {
780
            try {
781
                Geometry geom = feature.getDefaultGeometry();
782
                if(geom == null){
783
                    //FIXME: tirar al log y avisar al usuario
784
                    return;
785
                }
786
                GeometryType type = geom.getGeometryType();
787
                boolean geometrySupported = true;
788

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

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

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

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

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

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

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

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

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

    
819
                } else {
820
                    geometrySupported = false;
821
                    logger.warn(
822
                        MessageFormat.format(
823
                            "Geometry '{1}' not yet supported",
824
                            new Object[] {geom.getClass().getName()}
825
                        )
826
                    );
827
                    k++;
828
                }
829
                if (geometrySupported){
830
                    if (this.envelope != null){
831
                        this.envelope.add(feature.getDefaultEnvelope());
832
                    } else {
833
                        this.envelope = feature.getDefaultEnvelope().getGeometry().getEnvelope();
834
                    }
835
                }
836
            } catch (Exception e) {
837
                throw new WriteException(fileName, e);
838
            }
839

    
840
        }
841

    
842
        private boolean hasText(FeatureProvider feature) {
843
            if (feature.isNull(ID_FIELD_TEXT)) {
844
                return false;
845
            }
846
            if (feature.get(ID_FIELD_TEXT).equals("")) {
847
                return false;
848
            }
849
            return true;
850
        }
851

    
852
        private DxfGroupVector updateProperties(FeatureProvider feature, int k) {
853
            DxfGroupVector polv = new DxfGroupVector();
854

    
855
            String layer = (String) feature.get(ID_FIELD_LAYER);
856
            Integer color = (Integer) feature.get(ID_FIELD_COLOR);
857
            Double thickness = (Double) feature.get(ID_FIELD_THICKNESS);
858

    
859
            DxfGroup geometryLayer = new DxfGroup(8, layer);
860

    
861
            DxfGroup handleGroup = new DxfGroup();
862
            handleGroup.setCode(5);
863
            handleGroup.setData(new Integer(handle + k).toString());
864

    
865
            DxfGroup handleColor = new DxfGroup();
866
            handleColor.setCode(62);
867
            handleColor.setData(color);
868

    
869
            DxfGroup handleThickness = new DxfGroup();
870
            handleThickness.setCode(39);
871
            handleThickness.setData(thickness);
872

    
873
            polv.add(geometryLayer);
874
            polv.add(handleGroup);
875
            polv.add(handleColor);
876
            return polv;
877
        }
878

    
879
        private int createPoint2D(int handle, int k, FeatureProvider feature)
880
        throws Exception {
881

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

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

    
915
        private int createText2D(int handle, int k, FeatureProvider feature)
916
        throws Exception {
917

    
918
            String text = feature.get(ID_FIELD_TEXT).toString();
919
            Double heightText = (Double) feature.get(ID_FIELD_HEIGHTTEXT);
920
            Double rotationText = (Double) feature.get(ID_FIELD_ROTATIONTEXT);
921

    
922
            DxfGroup handleText = new DxfGroup();
923
            handleText.setCode(1);
924
            handleText.setData(text);
925

    
926
            DxfGroup handleHeightText = new DxfGroup();
927
            handleHeightText.setCode(40);
928
            handleHeightText.setData(heightText);
929

    
930
            DxfGroup handleRotationText = new DxfGroup();
931
            handleRotationText.setCode(50);
932
            handleRotationText.setData(rotationText);
933

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

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

    
1008
            DxfGroupVector pv = updateProperties(feature, k);
1009
            pv.add(handleElevation);
1010
            pv.add(px);
1011
            pv.add(py);
1012
            pv.add(pz);
1013
            entityMaker.createPoint(pv);
1014
            k++;
1015
            return k;
1016
        }
1017

    
1018
        private int createText3D(int handle, int k, FeatureProvider feature)
1019
        throws Exception {
1020

    
1021
            double velev = ((org.gvsig.fmap.geom.primitive.Point) feature.getDefaultGeometry())
1022
            .getCoordinateAt(0);
1023

    
1024
            Double elevation = new Double(velev);
1025
            String text = feature.get(ID_FIELD_TEXT).toString();
1026
            Double heightText = (Double) feature.get(ID_FIELD_HEIGHTTEXT);
1027
            Double rotationText = (Double) feature.get(ID_FIELD_ROTATIONTEXT);
1028

    
1029
            DxfGroup handleText = new DxfGroup();
1030
            handleText.setCode(1);
1031
            handleText.setData(text);
1032

    
1033
            DxfGroup handleHeightText = new DxfGroup();
1034
            handleHeightText.setCode(40);
1035
            handleHeightText.setData(heightText);
1036

    
1037
            DxfGroup handleRotationText = new DxfGroup();
1038
            handleRotationText.setCode(50);
1039
            handleRotationText.setData(rotationText);
1040

    
1041
            DxfGroup handleElevation = new DxfGroup();
1042
            handleElevation.setCode(38);
1043
            handleElevation.setData(elevation);
1044

    
1045
            org.gvsig.fmap.geom.primitive.Point point =
1046
                (org.gvsig.fmap.geom.primitive.Point) (feature
1047
                    .getDefaultGeometry()).getInternalShape();
1048

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

    
1075
        private int createLwPolyline2D(int handle, int k, FeatureProvider feature,
1076
            boolean isPolygon) throws Exception {
1077
            boolean first = true;
1078
            DxfGroupVector polv = updateProperties(feature, k);
1079
            Vector vpoints = new Vector();
1080

    
1081
            DxfGroup polylineFlag = new DxfGroup();
1082
            polylineFlag.setCode(70);
1083
            if (isPolygon) {
1084
                polylineFlag.setData(new Integer(1)); // cerrada
1085
            } else {
1086
                polylineFlag.setData(new Integer(0)); // abierta
1087
            }
1088

    
1089
            PathIterator theIterator = (feature.getDefaultGeometry())
1090
            .getPathIterator(null, geomManager.getFlatness()); // polyLine.
1091
            // getPathIterator
1092
            // (null,
1093
            // flatness);
1094

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

    
1118
                        entityMaker.createLwPolyline(polv);
1119
                        k++;
1120
                        polv = updateProperties(feature, k);
1121

    
1122
                    }
1123
                    first = false;
1124
                    polv.add(polylineFlag);
1125
                    vpoints.clear();
1126
                    vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1127
                    break;
1128
                case PathIterator.SEG_LINETO:
1129
                    vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1130
                    break;
1131
                case PathIterator.SEG_QUADTO:
1132
                    break;
1133
                case PathIterator.SEG_CUBICTO:
1134
                    break;
1135
                case PathIterator.SEG_CLOSE:
1136
                    polylineFlag.setData(new Integer(1)); // cerrada
1137
                    break;
1138

    
1139
                }
1140
                theIterator.next();
1141
            }
1142

    
1143
            for (int j = 0; j < vpoints.size(); j++) {
1144
                DxfGroup xvertex = new DxfGroup();
1145
                xvertex.setCode(10);
1146
                xvertex
1147
                .setData(new Double(
1148
                    ((org.gvsig.fmap.geom.primitive.Point) vpoints
1149
                        .get(j)).getX()));
1150
                DxfGroup yvertex = new DxfGroup();
1151
                yvertex.setCode(20);
1152
                yvertex
1153
                .setData(new Double(
1154
                    ((org.gvsig.fmap.geom.primitive.Point) vpoints
1155
                        .get(j)).getY()));
1156
                polv.add(xvertex);
1157
                polv.add(yvertex);
1158
            }
1159

    
1160
            entityMaker.createLwPolyline(polv);
1161
            k++;
1162
            return k;
1163
        }
1164

    
1165
        private int createPolyline3D(int handle, int k, FeatureProvider feature)
1166
        throws Exception {
1167
            DxfGroupVector polv = updateProperties(feature, k);
1168
            Vector vpoints = new Vector();
1169
            PathIterator theIterator = (feature.getDefaultGeometry())
1170
            .getPathIterator(null, geomManager.getFlatness()); // polyLine.
1171
            // getPathIterator
1172
            // (null,
1173
            // flatness);
1174
            double[] theData = new double[6];
1175
            OrientablePrimitive curve = (OrientablePrimitive) feature.getDefaultGeometry();
1176
            double[] velev = new double[curve.getNumVertices()];
1177
            for (int i = 0; i < curve.getNumVertices(); i++) {
1178
                velev[i] = curve.getCoordinateAt(i, 2);
1179
            }
1180

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

    
1287
        private boolean constantElevation(double[] velev) {
1288
            boolean constant = true;
1289
            for (int i = 0; i < velev.length; i++) {
1290
                for (int j = 0; j < velev.length; j++) {
1291
                    if (j > i) {
1292
                        if (velev[i] != velev[j]) {
1293
                            constant = false;
1294
                            break;
1295
                        }
1296
                    }
1297
                }
1298
                break;
1299
            }
1300
            return constant;
1301
        }
1302

    
1303
        private int createCircle2D(int handle, int k, FeatureProvider feature)
1304
        throws Exception {
1305
            DxfGroupVector polv = updateProperties(feature, k);
1306
            DxfGroup circleFlag = new DxfGroup();
1307
            circleFlag.setCode(100);
1308
            polv.add(circleFlag);
1309

    
1310
            DxfGroup xvertex = new DxfGroup();
1311
            xvertex.setCode(10);
1312
            Circle circle = (Circle) (feature
1313
                .getDefaultGeometry()).getInternalShape();
1314
            xvertex.setData(new Double(circle.getCenter().getX()));
1315
            DxfGroup yvertex = new DxfGroup();
1316
            yvertex.setCode(20);
1317
            yvertex.setData(new Double(circle.getCenter().getY()));
1318
            DxfGroup zvertex = new DxfGroup();
1319
            zvertex.setCode(30);
1320
            // TODO: COORDENADA Z. REVISAR ESTO PARA ENTIDADES 3D
1321
            zvertex.setData(new Double(0));
1322

    
1323
            DxfGroup radius = new DxfGroup();
1324
            radius.setCode(40);
1325
            radius.setData(new Double(circle.getRadious()));
1326

    
1327
            polv.add(xvertex);
1328
            polv.add(yvertex);
1329
            polv.add(zvertex);
1330
            polv.add(radius);
1331

    
1332
            entityMaker.createCircle(polv);
1333
            k++;
1334
            return k;
1335
        }
1336

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

    
1350
            double initAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1351
            initAngle = Math.toDegrees(initAngle);
1352
            ctx.setAttribute("geom", pts[1]);
1353
            double midAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1354
            midAngle = Math.toDegrees(midAngle);
1355
            ctx.setAttribute("geom", pts[2]);
1356
            double endAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1357
            endAngle = Math.toDegrees(endAngle);
1358

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

    
1385
        private int createEllipse2D(int handle, int k, FeatureProvider feature)
1386
        throws Exception {
1387
            Ellipse ellipse = (Ellipse) (feature
1388
                .getDefaultGeometry()).getInternalShape();
1389

    
1390
            org.gvsig.fmap.geom.primitive.Point center = (org.gvsig.fmap.geom.primitive.Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM2D);
1391
            center.setCoordinateAt(0, (ellipse.getAxis1Start().getX() + ellipse.getAxis1End().getX()) / 2);
1392
            center.setCoordinateAt(1, (ellipse.getAxis1Start().getY() + ellipse.getAxis1End().getY()) / 2);
1393

    
1394
            double mAxisL = ellipse.getAxis2Dist() * 2;
1395
            GeometryOperationContext ctx = new GeometryOperationContext();
1396
            ctx.setAttribute("geom", ellipse.getAxis1End());
1397
            double maAxisL = ((Double)geomManager.invokeOperation(PointDistance.CODE, ellipse.getAxis1Start(), ctx)).doubleValue();
1398

    
1399
            Point2D endPointOfMajorAxis = new Point2D.Double(ellipse.getAxis1End().getX(), ellipse.getAxis1End().getY());
1400
            double azimut = Math
1401
            .atan2(endPointOfMajorAxis.getX() - center.getX(),
1402
                endPointOfMajorAxis.getY() - center.getY());
1403
            double azimut2 = azimut + Math.PI / 2.0;
1404
            if (azimut2 >= Math.PI * 2) {
1405
                azimut2 = azimut2 - Math.PI * 2;
1406
            }
1407
            Point2D endPointOfMinorAxis = new Point2D.Double(center.getX()
1408
                + (ellipse.getAxis2Dist() * Math.sin(azimut2)), center.getY()
1409
                + (ellipse.getAxis2Dist() * Math.cos(azimut2)));
1410

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

    
1448
        public Envelope getEnvelope() {
1449
            return this.envelope;
1450
        }
1451

    
1452
    }
1453

    
1454
    public boolean closeResourceRequested(ResourceProvider resource) {
1455
        return true;
1456
    }
1457

    
1458
    public int getOIDType() {
1459
        return DataTypes.LONG;
1460
    }
1461

    
1462
    public boolean supportsAppendMode() {
1463
        return false;
1464
    }
1465

    
1466
    public void append(FeatureProvider featureProvider) {
1467
        try {
1468
            writer.add(featureProvider);
1469
        } catch (WriteException e) {
1470
            // TODO Auto-generated catch block
1471
            e.printStackTrace();
1472
        }
1473
    }
1474

    
1475
    public void beginAppend() {
1476
        try {
1477
            writer = new Writer().initialice((File) resource.get(), projection);
1478
            writer.begin();
1479
        } catch (AccessResourceException e) {
1480
            // TODO Auto-generated catch block
1481
            e.printStackTrace();
1482
        }
1483
    }
1484

    
1485
    public void endAppend() {
1486
        try {
1487
            resource.notifyOpen();
1488
            writer.end();
1489
            resource.notifyClose();
1490
            counterNewsOIDs = 0;
1491
        } catch (ResourceNotifyOpenException e) {
1492
            // TODO Auto-generated catch block
1493
            e.printStackTrace();
1494
        } catch (ResourceNotifyCloseException e) {
1495
            // TODO Auto-generated catch block
1496
            e.printStackTrace();
1497
        } catch (WriteException e) {
1498
            // TODO Auto-generated catch block
1499
            e.printStackTrace();
1500
        }
1501
    }
1502

    
1503
    public void saveToState(PersistentState state) throws PersistenceException {
1504
        // TODO Auto-generated method stub
1505
        throw new NotYetImplemented();
1506
    }
1507

    
1508
    public void loadFromState(PersistentState state) throws PersistenceException {
1509
        // TODO Auto-generated method stub
1510
        throw new NotYetImplemented();
1511
    }
1512

    
1513
    public Object createNewOID() {
1514
        return new Long(counterNewsOIDs++);
1515
    }
1516

    
1517
    protected void initializeFeatureTypes() throws InitializeException {
1518
        try {
1519
            this.open();
1520
        } catch (OpenException e) {
1521
            throw new InitializeException(this.getProviderName(), e);
1522
        }
1523
    }
1524

    
1525
    public Envelope getEnvelope() throws DataException {
1526
        this.open();
1527
        return this.envelope;
1528
    }
1529

    
1530
    public Object getDynValue(String name) throws DynFieldNotFoundException {
1531
        if( DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name) ) {
1532
            try {
1533
                return this.getEnvelope();
1534
            } catch (DataException e) {
1535
                return null;
1536
            }
1537
        } else {
1538
            if( DataStore.METADATA_CRS.equalsIgnoreCase(name) ) {
1539
                IProjection pro = this.getDXFParameters().getCRS();
1540
                if (pro != null){
1541
                    return pro;
1542
                }
1543
            }
1544
        }
1545
        return super.getDynValue(name);
1546
    }
1547

    
1548

    
1549
    /*
1550
     * (non-Javadoc)
1551
     *
1552
     * @see
1553
     * org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
1554
     * gvsig.fmap.dal.resource.spi.ResourceProvider)
1555
     */
1556
    public void resourceChanged(ResourceProvider resource) {
1557
        this.getStoreServices().notifyChange(
1558
            DataStoreNotification.RESOURCE_CHANGED,
1559
            resource);
1560
    }
1561

    
1562

    
1563
    public Object getSourceId() {
1564
        return this.getDXFParameters().getFile();
1565
    }
1566

    
1567
    public String getName() {
1568
        String name = this.getDXFParameters().getFile().getName();
1569
        int n = name.lastIndexOf(".");
1570
        if( n<1 ) {
1571
            return name;
1572
        }
1573
        return name.substring(0, n);
1574
    }
1575

    
1576
    public String getFullName() {
1577
        return this.getDXFParameters().getFile().getAbsolutePath();
1578
    }
1579

    
1580
    public ResourceProvider getResource() {
1581
        return resource;
1582
    }
1583

    
1584
}