Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2057 / libraries / libFMap_dalfile / src / org / gvsig / fmap / dal / store / dxf / DXFStoreProvider.java @ 39169

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

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

    
94
    public static final String NAME = "DXF";
95
    public static final String DESCRIPTION = "DXF file";
96

    
97
    public static final String METADATA_DEFINITION_NAME = NAME;
98

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

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

    
121
    private IProjection projection;
122
    private ResourceProvider resource;
123
    private LegendBuilder legendBuilder;
124

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

    
130
    private SimpleTaskStatus taskStatus;
131

    
132

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

    
141
        TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
142
        this.taskStatus = manager.creteDefaultSimpleTaskStatus("DXF");
143

    
144
        counterNewsOIDs = 0;
145
        //                projection = CRSFactory.getCRS(getParameters().getSRSID());
146

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

    
153
        resource.addConsumer(this);
154

    
155
        this.projection = this.getDXFParameters().getCRS();
156

    
157

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

    
167
        this.initializeFeatureTypes();
168

    
169
    }
170

    
171
    private DXFStoreParameters getDXFParameters() {
172
        return (DXFStoreParameters) this.getParameters();
173
    }
174

    
175
    public String getProviderName() {
176
        return NAME;
177
    }
178

    
179
    public boolean allowWrite() {
180
        return true;
181
    }
182

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

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

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

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

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

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

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

    
268
                    dxfData.envelope = reader.getEnvelope();
269

    
270
                    dxfData.legendBuilder = legendBuilder;
271

    
272
                    dxfData.projection = projection;
273

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

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

    
302

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

    
317
    }
318

    
319

    
320

    
321
    public void performChanges(Iterator deleteds, Iterator inserteds, Iterator updateds, Iterator originalFeatureTypesUpdated) throws PerformEditingException {
322

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

    
380
    public static EditableFeatureType createFeatureType(IProjection projection, int geometrySubtype){
381
            DataManager manager = DALLocator.getDataManager();
382
            EditableFeatureType featureType = manager.createFeatureType();
383

    
384
        featureType.setHasOID(true);
385

    
386
//        ID_FIELD_ID = 0;
387
        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(projection);
394
        attr.setGeometryType(Geometry.TYPES.GEOMETRY);                        
395
        //If is a 3D file, set the geometry subtype
396
        attr.setGeometrySubType(geometrySubtype);
397
        
398
//        ID_FIELD_GEOMETRY = 1; //attr.getIndex();
399

    
400
        featureType.setDefaultGeometryAttributeName(NAME_FIELD_GEOMETRY);
401

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
500
            taskStatus.message("_preparing_featureType");
501
            int geometrySubtype;
502
                        if (featureMaker.isDxf3DFile() && headerManager.isWritedDxf3D()){
503
                geometrySubtype = Geometry.SUBTYPES.GEOM3D;
504
            }else{
505
                    geometrySubtype = Geometry.SUBTYPES.GEOM2D;
506
            }                        
507
            EditableFeatureType featureType = createFeatureType(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 Point
639
                        && !(fea.getGeometry() instanceof org.gvsig.dxf.px.gml.Point3D)) {
640
                        Point point = (Point) fea.getGeometry();
641
                        Point2D pto = new Point2D.Double();
642
                        pto = point.get(0);
643

    
644
                        geometry = gManager.createPoint(pto.getX(), pto.getY(),SUBTYPES.GEOM2D);
645

    
646
                        if (point.isTextPoint()) {
647
                            /// TODO labeling
648
                        }
649
                    } else if (fea.getGeometry() instanceof org.gvsig.dxf.px.gml.Point3D) {
650
                        org.gvsig.dxf.px.gml.Point3D point = (org.gvsig.dxf.px.gml.Point3D) fea.getGeometry();
651
                        Point3D pto = new Point3D();
652
                        pto = point.getPoint3D(0);
653
                        org.gvsig.fmap.geom.primitive.Point geom = gManager.createPoint(pto.getX(), pto.getY(),SUBTYPES.GEOM3D);
654
                        geom.setCoordinateAt(Geometry.DIMENSIONS.Z, pto.getZ());
655

    
656
                        geometry = geom;
657
                        
658
                        if (point.isTextPoint()) {
659
                            /// TODO labeling
660
                        }
661
                    } else if (fea.getGeometry() instanceof LineString
662
                        && !(fea.getGeometry() instanceof LineString3D)) {
663
                        Point2D[] pts = new Point2D[fea.getGeometry().pointNr()];
664
                        for (int j = 0; j < fea.getGeometry().pointNr(); j++) {
665
                            pts[j] = fea.getGeometry().get(j);
666
                        }
667

    
668
                        Curve curve = (Curve)gManager.create(TYPES.CURVE , SUBTYPES.GEOM2D);
669
                        curve.addMoveToVertex(gManager.createPoint(pts[0].getX(), pts[0].getY(), SUBTYPES.GEOM2D));                        
670
                        for (int j = 1; j < pts.length; j++) {
671
                            curve.addVertex(gManager.createPoint(pts[j].getX(), pts[j].getY(), SUBTYPES.GEOM2D));
672
                        }
673

    
674
                        geometry = curve;                        
675

    
676
                    } else if (fea.getGeometry() instanceof LineString3D) {                        
677
                        Point3D[] pts = new Point3D[fea.getGeometry().pointNr()];
678
                        for (int j = 0; j < fea.getGeometry().pointNr(); j++) {
679
                            pts[j] = ((LineString3D) fea.getGeometry()).getPoint3D(j);
680
                        }
681
                        double[] elevations = new double[pts.length];
682
                        for (int j = 0; j < pts.length; j++) {
683
                            elevations[j] = pts[j].getZ();
684
                        }
685

    
686
                        Curve curve = (Curve)gManager.create(TYPES.CURVE , SUBTYPES.GEOM2D);                   
687
                        org.gvsig.fmap.geom.primitive.Point point = gManager.createPoint(pts[0].getX(), pts[0].getY(), SUBTYPES.GEOM3D);            
688
                        point.setCoordinateAt(Geometry.DIMENSIONS.Z, elevations[0]);
689
                        curve.addMoveToVertex(point);
690
                        for (int j = 1; j < pts.length; j++) {
691
                            point = gManager.createPoint(pts[j].getX(), pts[j].getY(), SUBTYPES.GEOM3D);            
692
                            point.setCoordinateAt(Geometry.DIMENSIONS.Z, elevations[j]);
693
                            curve.addVertex(point);
694
                        }
695
                        geometry = curve;                       
696

    
697
                    } else if (fea.getGeometry() instanceof Polygon
698
                        && !(fea.getGeometry() instanceof Polygon3D)) {
699

    
700
                        Point2D firstPt = new Point2D.Double();
701
                        firstPt = fea.getGeometry().get(0);
702
                        Point2D[] pts = new Point2D[fea.getGeometry().pointNr() + 1];
703
                        for (int j = 0; j < fea.getGeometry().pointNr(); j++) {
704
                            pts[j] = fea.getGeometry().get(j);
705
                        }
706
                        pts[fea.getGeometry().pointNr()] = firstPt;
707

    
708
                        Surface surface = (Surface)gManager.create(TYPES.SURFACE , SUBTYPES.GEOM2D);
709
                        surface.addMoveToVertex(gManager.createPoint(pts[0].getX(), pts[0].getY(), SUBTYPES.GEOM2D));
710
                        for (int j = 1; j < pts.length; j++) {
711
                            surface.addVertex(gManager.createPoint(pts[j].getX(), pts[j].getY(), SUBTYPES.GEOM2D));
712
                        }
713
                        surface.closePrimitive();
714

    
715
                        geometry = surface;
716

    
717
                    } else if (fea.getGeometry() instanceof Polygon3D) {                       
718
                        Point3D firstPt = new Point3D();
719
                        firstPt = ((Polygon3D) fea.getGeometry()).getPoint3D(0);
720
                        Point3D[] pts = new Point3D[fea.getGeometry().pointNr() + 1];
721
                        for (int j = 0; j < fea.getGeometry().pointNr(); j++) {
722
                            pts[j] = ((Polygon3D) fea.getGeometry()).getPoint3D(j);
723
                        }
724
                        pts[fea.getGeometry().pointNr()] = firstPt;
725
                        double[] elevations = new double[pts.length];
726
                        for (int j = 0; j < pts.length; j++) {
727
                            elevations[j] = pts[j].getZ();
728
                        }
729
                        
730
                        Surface surface = (Surface)gManager.create(TYPES.SURFACE , SUBTYPES.GEOM3D);                   
731
                        org.gvsig.fmap.geom.primitive.Point point = gManager.createPoint(pts[0].getX(), pts[0].getY(), SUBTYPES.GEOM3D);            
732
                        point.setCoordinateAt(Geometry.DIMENSIONS.Z, elevations[0]);
733
                        surface.addMoveToVertex(point);                        
734
                        
735
                        for (int j = 1; j < pts.length; j++) {
736
                            point = gManager.createPoint(pts[j].getX(), pts[j].getY(), SUBTYPES.GEOM3D);            
737
                            point.setCoordinateAt(Geometry.DIMENSIONS.Z, elevations[0]);                            
738
                            surface.addVertex(point);
739
                        }
740
                        surface.closePrimitive();
741
                    
742
                       geometry = surface;                        
743
                    } else {                                            
744
                        logger.warn(
745
                            MessageFormat.format(
746
                                "load: geometry type {1} not supported",
747
                                new Object[] { fea.getGeometry().getClass().getName() }
748
                            )
749
                        );
750
                    }
751

    
752
                    if (geometry != null){
753
                        feature.set(ID_FIELD_GEOMETRY, geometry);
754
                        feature.setDefaultGeometry(geometry);
755
                        if (this.envelope == null) {
756
                            this.envelope = geometry.getEnvelope();
757
                        } else {
758
                            this.envelope.add(geometry.getEnvelope());
759
                        }
760
                    }else{
761
                        geometry = gManager.createNullGeometry(SUBTYPES.GEOM2D);
762
                    }
763

    
764
                    //Add the feature to the store
765
                    store.addFeatureProvider(feature);
766

    
767
                } catch (Exception e) {
768
                    //throw new LoadException(e, fileName);
769
                    // FIXME: add to log max 10
770
                }
771
                if (leyendBuilder != null) {
772
                    try {
773
                        leyendBuilder.process(feature);
774
                    } catch (Exception e) {
775
                        logger.warn(
776
                            MessageFormat.format(
777
                                "load: legendBuilder process fails in the feature {1}",
778
                                fea
779
                            )
780
                        );
781
                    }
782
                }
783

    
784
            }
785
        }
786

    
787
    }
788

    
789
    public class Writer {
790
        private Double DEFAULT_ELEVATION = new Double(0);
791

    
792
        private DxfFile.EntityFactory entityMaker;
793

    
794
        private IProjection proj = null;
795

    
796
        private int handle = 40; // Revisar porqu? es 40.
797

    
798
        private int k = 0;
799

    
800
        private boolean dxf3DFile = false;
801
        private String fileName;
802
        private Envelope envelope;
803

    
804
        public Writer initialice(File file, IProjection projection) {
805
            this.proj = projection;
806
            this.fileName = file.getAbsolutePath();
807
            entityMaker = new DxfEntityMaker(proj);
808
            return this;
809
        }
810

    
811
        public void begin() {
812
            envelope = null;
813
            entityMaker = new DxfEntityMaker(proj);
814
        }
815

    
816
        public void end() throws WriteException {
817
            try {
818
                DxfFile dxfFile = new DxfFile(null, fileName, entityMaker);
819
                dxfFile.setCadFlag(true);
820
                if (dxf3DFile) {
821
                    dxfFile.setDxf3DFlag(true);
822
                }
823
                dxfFile.save(fileName);
824
                dxfFile.close();
825
            } catch (Exception e) {
826
                throw new WriteException(fileName, e);
827
            }
828
        }
829

    
830
        public void add(FeatureProvider feature) throws WriteException {
831
            try {
832
                Geometry geom = feature.getDefaultGeometry();
833
                if(geom == null){
834
                    //FIXME: tirar al log y avisar al usuario
835
                    return;
836
                }
837
                GeometryType type = geom.getGeometryType();
838
                boolean geometrySupported = true;
839

    
840
                if ((TYPES.POINT == type.getType()) && (SUBTYPES.GEOM3D == type.getSubType())) {
841
                    dxf3DFile = true;
842
                    k = createPoint3D(handle, k, feature);
843

    
844
                } else if ((TYPES.POINT == type.getType()) && (SUBTYPES.GEOM2D == type.getSubType())) {
845
                    k = createPoint2D(handle, k, feature);
846

    
847
                } else if ((TYPES.CURVE == type.getType()) && (SUBTYPES.GEOM3D == type.getSubType())) {
848
                    dxf3DFile = true;
849
                    k = createPolyline3D(handle, k, feature);
850

    
851
                } else if ((TYPES.ARC == type.getType()) && (SUBTYPES.GEOM2D == type.getSubType())) {
852
                    k = createArc2D(handle, k, feature);
853

    
854
                } else if ((TYPES.CURVE == type.getType()) && (SUBTYPES.GEOM2D == type.getSubType())) {
855
                    k = createLwPolyline2D(handle, k, feature, false);
856

    
857
                } else if ((TYPES.SURFACE == type.getType()) && (SUBTYPES.GEOM3D == type.getSubType())) {
858
                    dxf3DFile = true;
859
                    k = createPolyline3D(handle, k, feature);
860

    
861
                } else if ((TYPES.CIRCLE == type.getType()) && (SUBTYPES.GEOM2D == type.getSubType())) {
862
                    k = createCircle2D(handle, k, feature);
863

    
864
                } else if ((TYPES.ELLIPSE == type.getType()) && (SUBTYPES.GEOM2D == type.getSubType())) {
865
                    k = createEllipse2D(handle, k, feature);
866

    
867
                } else if ((TYPES.SURFACE == type.getType()) && (SUBTYPES.GEOM2D == type.getSubType())) {
868
                    k = createLwPolyline2D(handle, k, feature, true);
869

    
870
                } else {
871
                    geometrySupported = false;
872
                    logger.warn(
873
                        MessageFormat.format(
874
                            "Geometry '{1}' not yet supported",
875
                            new Object[] {geom.getClass().getName()}
876
                        )
877
                    );
878
                    k++;
879
                }
880
                if (geometrySupported){
881
                    if (this.envelope != null){
882
                        this.envelope.add(feature.getDefaultEnvelope());
883
                    } else {
884
                        this.envelope = feature.getDefaultEnvelope().getGeometry().getEnvelope();
885
                    }
886
                }
887
            } catch (Exception e) {
888
                throw new WriteException(fileName, e);
889
            }
890

    
891
        }
892

    
893
        private boolean hasText(FeatureProvider feature) {
894
            if (feature.isNull(ID_FIELD_TEXT)) {
895
                return false;
896
            }
897
            if (feature.get(ID_FIELD_TEXT).equals("")) {
898
                return false;
899
            }
900
            return true;
901
        }
902

    
903
        private DxfGroupVector updateProperties(FeatureProvider feature, int k) {
904
            DxfGroupVector polv = new DxfGroupVector();
905

    
906
            String layer = (String) feature.get(ID_FIELD_LAYER);
907
            Integer color = (Integer) feature.get(ID_FIELD_COLOR);
908
            Double thickness = (Double) feature.get(ID_FIELD_THICKNESS);
909

    
910
            DxfGroup geometryLayer = new DxfGroup(8, layer);
911

    
912
            DxfGroup handleGroup = new DxfGroup();
913
            handleGroup.setCode(5);
914
            handleGroup.setData(new Integer(handle + k).toString());
915

    
916
            DxfGroup handleColor = new DxfGroup();
917
            handleColor.setCode(62);
918
            handleColor.setData(color);
919

    
920
            DxfGroup handleThickness = new DxfGroup();
921
            handleThickness.setCode(39);
922
            handleThickness.setData(thickness);
923

    
924
            polv.add(geometryLayer);
925
            polv.add(handleGroup);
926
            polv.add(handleColor);
927
            return polv;
928
        }
929

    
930
        private int createPoint2D(int handle, int k, FeatureProvider feature)
931
        throws Exception {
932

    
933
            if (hasText(feature)) {
934
                return createText2D(handle, k, feature);
935
            }
936
            org.gvsig.fmap.geom.primitive.Point point = geomManager.createPoint(0, 0, SUBTYPES.GEOM2D);
937
            double[] pointCoords = new double[6];
938
            PathIterator pointIt = (feature.getDefaultGeometry())
939
            .getPathIterator(null);
940
            while (!pointIt.isDone()) {
941
                pointIt.currentSegment(pointCoords);
942
                point = geomManager.createPoint(pointCoords[0], pointCoords[1], SUBTYPES.GEOM2D);
943
                pointIt.next();
944
            }
945
            Point2D pto = new Point2D.Double(point.getX(), point.getY());
946

    
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(px);
959
            pv.add(py);
960
            pv.add(pz);
961
            entityMaker.createPoint(pv);
962
            k++;
963
            return k;
964
        }
965

    
966
        private int createText2D(int handle, int k, FeatureProvider feature)
967
        throws Exception {
968

    
969
            String text = feature.get(ID_FIELD_TEXT).toString();
970
            Double heightText = (Double) feature.get(ID_FIELD_HEIGHTTEXT);
971
            Double rotationText = (Double) feature.get(ID_FIELD_ROTATIONTEXT);
972

    
973
            DxfGroup handleText = new DxfGroup();
974
            handleText.setCode(1);
975
            handleText.setData(text);
976

    
977
            DxfGroup handleHeightText = new DxfGroup();
978
            handleHeightText.setCode(40);
979
            handleHeightText.setData(heightText);
980

    
981
            DxfGroup handleRotationText = new DxfGroup();
982
            handleRotationText.setCode(50);
983
            handleRotationText.setData(rotationText);
984

    
985
            org.gvsig.fmap.geom.primitive.Point point = geomManager.createPoint(0, 0, SUBTYPES.GEOM2D);
986
            double[] pointCoords = new double[6];
987
            PathIterator pointIt = (feature.getDefaultGeometry())
988
            .getPathIterator(null);
989
            while (!pointIt.isDone()) {
990
                pointIt.currentSegment(pointCoords);
991
                point = geomManager.createPoint(pointCoords[0], pointCoords[1], SUBTYPES.GEOM2D);
992
                pointIt.next();
993
            }
994
            Point2D pto = new Point2D.Double(point.getX(), point.getY());
995
            DxfGroup handleGroup = new DxfGroup();
996
            handleGroup.setCode(5);
997
            handleGroup.setData(new Integer(handle + k).toString());
998
            DxfGroup px = new DxfGroup();
999
            DxfGroup py = new DxfGroup();
1000
            DxfGroup pz = new DxfGroup();
1001
            px.setCode(10);
1002
            px.setData(new Double(pto.getX()));
1003
            py.setCode(20);
1004
            py.setData(new Double(pto.getY()));
1005
            pz.setCode(30);
1006
            // FIXME: POINT del DXF tiene cota. Le asigno cero arbitrariamente.
1007
            pz.setData(new Double(0.0));
1008
            DxfGroupVector pv = updateProperties(feature, k);
1009
            pv.add(handleText);
1010
            pv.add(handleHeightText);
1011
            pv.add(handleRotationText);
1012
            pv.add(handleGroup);
1013
            pv.add(px);
1014
            pv.add(py);
1015
            pv.add(pz);
1016
            entityMaker.createText(pv);
1017
            k++;
1018
            return k;
1019
        }
1020

    
1021
        private int createPoint3D(int handle, int k, FeatureProvider feature)
1022
        throws Exception {
1023
            if (hasText(feature)) {
1024
                return createText3D(handle, k, feature);
1025
            }
1026
            org.gvsig.fmap.geom.primitive.Point point = (org.gvsig.fmap.geom.primitive.Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM3D);
1027
            double[] pointCoords = new double[6];
1028
            PathIterator pointIt = (feature.getDefaultGeometry())
1029
            .getPathIterator(null);
1030
            while (!pointIt.isDone()) {
1031
                pointIt.currentSegment(pointCoords);
1032
                point = (org.gvsig.fmap.geom.primitive.Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM3D);
1033
                point.setCoordinateAt(0, pointCoords[0]);
1034
                point.setCoordinateAt(1, pointCoords[1]);
1035
                point.setCoordinateAt(2, pointCoords[2]);
1036
                pointIt.next();
1037
            }
1038
            org.gvsig.fmap.geom.primitive.Point pto = (org.gvsig.fmap.geom.primitive.Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM3D);
1039
            pto.setCoordinateAt(0, point.getCoordinateAt(0));
1040
            pto.setCoordinateAt(1,  point.getCoordinateAt(1));
1041
            pto.setCoordinateAt(2, point.getCoordinateAt(2));
1042
            DxfGroup px = new DxfGroup();
1043
            DxfGroup py = new DxfGroup();
1044
            DxfGroup pz = new DxfGroup();
1045
            px.setCode(10);
1046
            px.setData(new Double(pto.getX()));
1047
            py.setCode(20);
1048
            py.setData(new Double(pto.getY()));
1049
            pz.setCode(30);
1050
            pz.setData(new Double(pto.getCoordinateAt(2)));
1051
            double velev = ((org.gvsig.fmap.geom.primitive.Point) feature.getDefaultGeometry())
1052
            .getCoordinateAt(2);
1053
            Double elevation = DEFAULT_ELEVATION;
1054
            elevation = new Double(velev);
1055
            DxfGroup handleElevation = new DxfGroup();
1056
            handleElevation.setCode(38);
1057
            handleElevation.setData(elevation);
1058

    
1059
            DxfGroupVector pv = updateProperties(feature, k);
1060
            pv.add(handleElevation);
1061
            pv.add(px);
1062
            pv.add(py);
1063
            pv.add(pz);
1064
            entityMaker.createPoint(pv);
1065
            k++;
1066
            return k;
1067
        }
1068

    
1069
        private int createText3D(int handle, int k, FeatureProvider feature)
1070
        throws Exception {
1071

    
1072
            double velev = ((org.gvsig.fmap.geom.primitive.Point) feature.getDefaultGeometry())
1073
            .getCoordinateAt(0);
1074

    
1075
            Double elevation = new Double(velev);
1076
            String text = feature.get(ID_FIELD_TEXT).toString();
1077
            Double heightText = (Double) feature.get(ID_FIELD_HEIGHTTEXT);
1078
            Double rotationText = (Double) feature.get(ID_FIELD_ROTATIONTEXT);
1079

    
1080
            DxfGroup handleText = new DxfGroup();
1081
            handleText.setCode(1);
1082
            handleText.setData(text);
1083

    
1084
            DxfGroup handleHeightText = new DxfGroup();
1085
            handleHeightText.setCode(40);
1086
            handleHeightText.setData(heightText);
1087

    
1088
            DxfGroup handleRotationText = new DxfGroup();
1089
            handleRotationText.setCode(50);
1090
            handleRotationText.setData(rotationText);
1091

    
1092
            DxfGroup handleElevation = new DxfGroup();
1093
            handleElevation.setCode(38);
1094
            handleElevation.setData(elevation);
1095

    
1096
            org.gvsig.fmap.geom.primitive.Point point =
1097
                (org.gvsig.fmap.geom.primitive.Point) (feature
1098
                    .getDefaultGeometry()).getInternalShape();
1099

    
1100
            DxfGroup handleGroup = new DxfGroup();
1101
            handleGroup.setCode(5);
1102
            handleGroup.setData(new Integer(handle + k).toString());
1103
            DxfGroup px = new DxfGroup();
1104
            DxfGroup py = new DxfGroup();
1105
            DxfGroup pz = new DxfGroup();
1106
            px.setCode(10);
1107
            px.setData(new Double(point.getX()));
1108
            py.setCode(20);
1109
            py.setData(new Double(point.getY()));
1110
            pz.setCode(30);
1111
            pz.setData(new Double(point.getCoordinateAt(2)));
1112
            DxfGroupVector pv = updateProperties(feature, k);
1113
            pv.add(handleElevation);
1114
            pv.add(handleText);
1115
            pv.add(handleHeightText);
1116
            pv.add(handleRotationText);
1117
            pv.add(handleGroup);
1118
            pv.add(px);
1119
            pv.add(py);
1120
            pv.add(pz);
1121
            entityMaker.createText(pv);
1122
            k++;
1123
            return k;
1124
        }
1125

    
1126
        private int createLwPolyline2D(int handle, int k, FeatureProvider feature,
1127
            boolean isPolygon) throws Exception {
1128
            boolean first = true;
1129
            DxfGroupVector polv = updateProperties(feature, k);
1130
            Vector vpoints = new Vector();
1131

    
1132
            DxfGroup polylineFlag = new DxfGroup();
1133
            polylineFlag.setCode(70);
1134
            if (isPolygon) {
1135
                polylineFlag.setData(new Integer(1)); // cerrada
1136
            } else {
1137
                polylineFlag.setData(new Integer(0)); // abierta
1138
            }
1139

    
1140
            PathIterator theIterator = (feature.getDefaultGeometry())
1141
            .getPathIterator(null, geomManager.getFlatness()); // polyLine.
1142
            // getPathIterator
1143
            // (null,
1144
            // flatness);
1145

    
1146
            double[] theData = new double[6];
1147
            while (!theIterator.isDone()) {
1148
                int theType = theIterator.currentSegment(theData);
1149
                switch (theType) {
1150
                case PathIterator.SEG_MOVETO:
1151
                    if (!first) {
1152
                        for (int j = 0; j < vpoints.size(); j++) {
1153
                            DxfGroup xvertex = new DxfGroup();
1154
                            xvertex.setCode(10);
1155
                            xvertex
1156
                            .setData(new Double(
1157
                                ((org.gvsig.fmap.geom.primitive.Point) vpoints
1158
                                    .get(j)).getX()));
1159
                            DxfGroup yvertex = new DxfGroup();
1160
                            yvertex.setCode(20);
1161
                            yvertex
1162
                            .setData(new Double(
1163
                                ((org.gvsig.fmap.geom.primitive.Point) vpoints
1164
                                    .get(j)).getY()));
1165
                            polv.add(xvertex);
1166
                            polv.add(yvertex);
1167
                        }
1168

    
1169
                        entityMaker.createLwPolyline(polv);
1170
                        k++;
1171
                        polv = updateProperties(feature, k);
1172

    
1173
                    }
1174
                    first = false;
1175
                    polv.add(polylineFlag);
1176
                    vpoints.clear();
1177
                    vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1178
                    break;
1179
                case PathIterator.SEG_LINETO:
1180
                    vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1181
                    break;
1182
                case PathIterator.SEG_QUADTO:
1183
                    break;
1184
                case PathIterator.SEG_CUBICTO:
1185
                    break;
1186
                case PathIterator.SEG_CLOSE:
1187
                    polylineFlag.setData(new Integer(1)); // cerrada
1188
                    break;
1189

    
1190
                }
1191
                theIterator.next();
1192
            }
1193

    
1194
            for (int j = 0; j < vpoints.size(); j++) {
1195
                DxfGroup xvertex = new DxfGroup();
1196
                xvertex.setCode(10);
1197
                xvertex
1198
                .setData(new Double(
1199
                    ((org.gvsig.fmap.geom.primitive.Point) vpoints
1200
                        .get(j)).getX()));
1201
                DxfGroup yvertex = new DxfGroup();
1202
                yvertex.setCode(20);
1203
                yvertex
1204
                .setData(new Double(
1205
                    ((org.gvsig.fmap.geom.primitive.Point) vpoints
1206
                        .get(j)).getY()));
1207
                polv.add(xvertex);
1208
                polv.add(yvertex);
1209
            }
1210

    
1211
            entityMaker.createLwPolyline(polv);
1212
            k++;
1213
            return k;
1214
        }
1215

    
1216
        private int createPolyline3D(int handle, int k, FeatureProvider feature)
1217
        throws Exception {
1218
            DxfGroupVector polv = updateProperties(feature, k);
1219
            Vector vpoints = new Vector();
1220
            PathIterator theIterator = (feature.getDefaultGeometry())
1221
            .getPathIterator(null, geomManager.getFlatness()); // polyLine.
1222
            // getPathIterator
1223
            // (null,
1224
            // flatness);
1225
            double[] theData = new double[6];
1226
            Curve curve = (Curve) feature.getDefaultGeometry();
1227
            double[] velev = new double[curve.getNumVertices()];
1228
            for (int i = 0; i < curve.getNumVertices(); i++) {
1229
                velev[i] = curve.getCoordinateAt(i, 2);
1230
            }
1231

    
1232
            while (!theIterator.isDone()) {
1233
                int theType = theIterator.currentSegment(theData);
1234
                switch (theType) {
1235
                case PathIterator.SEG_MOVETO:
1236
                    vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1237
                    break;
1238
                case PathIterator.SEG_LINETO:
1239
                    vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1240
                    break;
1241
                }
1242
                theIterator.next();
1243
            }
1244
            if (constantElevation(velev)) {
1245
                DxfGroup polylineFlag = new DxfGroup();
1246
                polylineFlag.setCode(70);
1247
                polylineFlag.setData(new Integer(0));
1248
                polv.add(polylineFlag);
1249
                DxfGroup elevation = new DxfGroup();
1250
                elevation.setCode(38);
1251
                elevation.setData(new Double(velev[0]));
1252
                polv.add(elevation);
1253
                for (int j = 0; j < vpoints.size(); j++) {
1254
                    DxfGroup xvertex = new DxfGroup();
1255
                    xvertex.setCode(10);
1256
                    xvertex.setData(new Double(
1257
                        ((org.gvsig.fmap.geom.primitive.Point) vpoints
1258
                            .get(j)).getX()));
1259
                    DxfGroup yvertex = new DxfGroup();
1260
                    yvertex.setCode(20);
1261
                    yvertex.setData(new Double(
1262
                        ((org.gvsig.fmap.geom.primitive.Point) vpoints
1263
                            .get(j)).getY()));
1264
                    polv.add(xvertex);
1265
                    polv.add(yvertex);
1266
                }
1267
                entityMaker.createLwPolyline(polv);
1268
                k++;
1269
            } else {
1270
                DxfGroup polylineFlag = new DxfGroup();
1271
                polylineFlag.setCode(70);
1272
                polylineFlag.setData(new Integer(8));
1273
                polv.add(polylineFlag);
1274
                DxfGroup xgroup = new DxfGroup();
1275
                xgroup.setCode(10);
1276
                xgroup.setData(new Double(0.0));
1277
                polv.add(xgroup);
1278
                DxfGroup ygroup = new DxfGroup();
1279
                ygroup.setCode(20);
1280
                ygroup.setData(new Double(0.0));
1281
                polv.add(ygroup);
1282
                DxfGroup elevation = new DxfGroup();
1283
                elevation.setCode(30);
1284
                elevation.setData(new Double(0.0));
1285
                polv.add(elevation);
1286
                DxfGroup subclassMarker = new DxfGroup(100, "AcDb3dPolyline");
1287
                polv.add(subclassMarker);
1288
                entityMaker.createPolyline(polv);
1289
                k++;
1290
                for (int j = 0; j < vpoints.size(); j++) {
1291
                    DxfGroupVector verv = new DxfGroupVector();
1292
                    DxfGroup entityType = new DxfGroup(0, "VERTEX");
1293
                    verv.add(entityType);
1294
                    DxfGroup generalSubclassMarker = new DxfGroup(100,
1295
                    "AcDbEntity");
1296
                    verv.add(generalSubclassMarker);
1297
                    DxfGroup layerName = new DxfGroup(8, "default");
1298
                    verv.add(layerName);
1299
                    DxfGroup vertexSubclassMarker = new DxfGroup(100,
1300
                    "AcDbVertex");
1301
                    verv.add(vertexSubclassMarker);
1302
                    DxfGroup xvertex = new DxfGroup();
1303
                    xvertex.setCode(10);
1304
                    xvertex.setData(new Double(
1305
                        ((org.gvsig.fmap.geom.primitive.Point) vpoints
1306
                            .get(j)).getX()));
1307
                    DxfGroup yvertex = new DxfGroup();
1308
                    yvertex.setCode(20);
1309
                    yvertex.setData(new Double(
1310
                        ((org.gvsig.fmap.geom.primitive.Point) vpoints
1311
                            .get(j)).getY()));
1312
                    DxfGroup zvertex = new DxfGroup();
1313
                    zvertex.setCode(30);
1314
                    zvertex.setData(new Double(velev[j]));
1315
                    verv.add(xvertex);
1316
                    verv.add(yvertex);
1317
                    verv.add(zvertex);
1318
                    entityMaker.addVertex(verv);
1319
                    k++;
1320
                }
1321
                DxfGroupVector seqv = new DxfGroupVector();
1322
                DxfGroup entityType = new DxfGroup(0, "SEQEND");
1323
                seqv.add(entityType);
1324
                DxfGroup generalSubclassMarker = new DxfGroup(100, "AcDbEntity");
1325
                seqv.add(generalSubclassMarker);
1326
                DxfGroup layerName = new DxfGroup(8, "default");
1327
                seqv.add(layerName);
1328
                DxfGroup handleSeqGroup = new DxfGroup();
1329
                handleSeqGroup.setCode(5);
1330
                handleSeqGroup.setData(new Integer(handle + k).toString());
1331
                seqv.add(handleSeqGroup);
1332
                entityMaker.endSeq();
1333
                k++;
1334
            }
1335
            return k;
1336
        }
1337

    
1338
        private boolean constantElevation(double[] velev) {
1339
            boolean constant = true;
1340
            for (int i = 0; i < velev.length; i++) {
1341
                for (int j = 0; j < velev.length; j++) {
1342
                    if (j > i) {
1343
                        if (velev[i] != velev[j]) {
1344
                            constant = false;
1345
                            break;
1346
                        }
1347
                    }
1348
                }
1349
                break;
1350
            }
1351
            return constant;
1352
        }
1353

    
1354
        private int createCircle2D(int handle, int k, FeatureProvider feature)
1355
        throws Exception {
1356
            DxfGroupVector polv = updateProperties(feature, k);
1357
            DxfGroup circleFlag = new DxfGroup();
1358
            circleFlag.setCode(100);
1359
            polv.add(circleFlag);
1360

    
1361
            DxfGroup xvertex = new DxfGroup();
1362
            xvertex.setCode(10);
1363
            Circle circle = (Circle) (feature
1364
                .getDefaultGeometry()).getInternalShape();
1365
            xvertex.setData(new Double(circle.getCenter().getX()));
1366
            DxfGroup yvertex = new DxfGroup();
1367
            yvertex.setCode(20);
1368
            yvertex.setData(new Double(circle.getCenter().getY()));
1369
            DxfGroup zvertex = new DxfGroup();
1370
            zvertex.setCode(30);
1371
            // TODO: COORDENADA Z. REVISAR ESTO PARA ENTIDADES 3D
1372
            zvertex.setData(new Double(0));
1373

    
1374
            DxfGroup radius = new DxfGroup();
1375
            radius.setCode(40);
1376
            radius.setData(new Double(circle.getRadious()));
1377

    
1378
            polv.add(xvertex);
1379
            polv.add(yvertex);
1380
            polv.add(zvertex);
1381
            polv.add(radius);
1382

    
1383
            entityMaker.createCircle(polv);
1384
            k++;
1385
            return k;
1386
        }
1387

    
1388
        private int createArc2D(int handle, int k, FeatureProvider feature)
1389
        throws Exception {
1390
            Arc arc = (Arc) (feature.getDefaultGeometry())
1391
            .getInternalShape();
1392
            org.gvsig.fmap.geom.primitive.Point[] pts = new org.gvsig.fmap.geom.primitive.Point[3];
1393
            pts[0] = arc.getInitPoint();
1394
            pts[1] = arc.getCenterPoint();
1395
            pts[2] = arc.getEndPoint();
1396
            org.gvsig.fmap.geom.primitive.Point center = arc.getCenterPoint();
1397
            GeometryOperationContext ctx = new GeometryOperationContext();
1398
            ctx.setAttribute("geom", pts[0]);
1399
            double radius = ((Double)geomManager.invokeOperation(PointDistance.CODE, center, ctx)).doubleValue();
1400

    
1401
            double initAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1402
            initAngle = Math.toDegrees(initAngle);
1403
            ctx.setAttribute("geom", pts[1]);
1404
            double midAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1405
            midAngle = Math.toDegrees(midAngle);
1406
            ctx.setAttribute("geom", pts[2]);
1407
            double endAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1408
            endAngle = Math.toDegrees(endAngle);
1409

    
1410
            DxfGroup ax = new DxfGroup();
1411
            DxfGroup ay = new DxfGroup();
1412
            DxfGroup ac = new DxfGroup();
1413
            DxfGroup ai = new DxfGroup();
1414
            DxfGroup ae = new DxfGroup();
1415
            ax.setCode(10);
1416
            ax.setData(new Double(center.getX()));
1417
            ay.setCode(20);
1418
            ay.setData(new Double(center.getY()));
1419
            ac.setCode(40);
1420
            ac.setData(new Double(radius));
1421
            ai.setCode(50);
1422
            ai.setData(new Double(initAngle));
1423
            ae.setCode(51);
1424
            ae.setData(new Double(endAngle));
1425
            DxfGroupVector av = updateProperties(feature, k);
1426
            av.add(ax);
1427
            av.add(ay);
1428
            av.add(ac);
1429
            av.add(ai);
1430
            av.add(ae);
1431
            entityMaker.createArc(av);
1432
            k++;
1433
            return k;
1434
        }
1435

    
1436
        private int createEllipse2D(int handle, int k, FeatureProvider feature)
1437
        throws Exception {
1438
            Ellipse ellipse = (Ellipse) (feature
1439
                .getDefaultGeometry()).getInternalShape();
1440

    
1441
            org.gvsig.fmap.geom.primitive.Point center = (org.gvsig.fmap.geom.primitive.Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM2D);
1442
            center.setCoordinateAt(0, (ellipse.getAxis1Start().getX() + ellipse.getAxis1End().getX()) / 2);
1443
            center.setCoordinateAt(1, (ellipse.getAxis1Start().getY() + ellipse.getAxis1End().getY()) / 2);
1444

    
1445
            double mAxisL = ellipse.getAxis2Dist() * 2;
1446
            GeometryOperationContext ctx = new GeometryOperationContext();
1447
            ctx.setAttribute("geom", ellipse.getAxis1End());
1448
            double maAxisL = ((Double)geomManager.invokeOperation(PointDistance.CODE, ellipse.getAxis1Start(), ctx)).doubleValue();
1449

    
1450
            Point2D endPointOfMajorAxis = new Point2D.Double(ellipse.getAxis1End().getX(), ellipse.getAxis1End().getY());
1451
            double azimut = Math
1452
            .atan2(endPointOfMajorAxis.getX() - center.getX(),
1453
                endPointOfMajorAxis.getY() - center.getY());
1454
            double azimut2 = azimut + Math.PI / 2.0;
1455
            if (azimut2 >= Math.PI * 2) {
1456
                azimut2 = azimut2 - Math.PI * 2;
1457
            }
1458
            Point2D endPointOfMinorAxis = new Point2D.Double(center.getX()
1459
                + (ellipse.getAxis2Dist() * Math.sin(azimut2)), center.getY()
1460
                + (ellipse.getAxis2Dist() * Math.cos(azimut2)));
1461

    
1462
            if (mAxisL >= maAxisL) {
1463
                // El menor debe ser menor que el mayor. Los cambiamos.
1464
                double aux = mAxisL;
1465
                mAxisL = maAxisL;
1466
                maAxisL = aux;
1467
                // Tambi?n cambiamos los puntos finales de los ejes.
1468
                Point2D pAux = endPointOfMinorAxis;
1469
                endPointOfMinorAxis = endPointOfMajorAxis;
1470
                endPointOfMajorAxis = pAux;
1471
            }
1472
            double mToMAR = mAxisL / maAxisL;
1473
            DxfGroup x = new DxfGroup();
1474
            DxfGroup y = new DxfGroup();
1475
            DxfGroup xc = new DxfGroup();
1476
            DxfGroup yc = new DxfGroup();
1477
            DxfGroup minToMaj = new DxfGroup();
1478
            x.setCode(10);
1479
            x.setData(new Double(center.getX()));
1480
            y.setCode(20);
1481
            y.setData(new Double(center.getY()));
1482
            xc.setCode(11);
1483
            xc.setData(new Double(endPointOfMajorAxis.getX() - center.getX()));
1484
            yc.setCode(21);
1485
            yc.setData(new Double(endPointOfMajorAxis.getY() - center.getY()));
1486
            minToMaj.setCode(40);
1487
            minToMaj.setData(new Double(mToMAR));
1488
            DxfGroupVector av = updateProperties(feature, k);
1489
            av.add(x);
1490
            av.add(y);
1491
            av.add(xc);
1492
            av.add(yc);
1493
            av.add(minToMaj);
1494
            entityMaker.createEllipse(av);
1495
            k++;
1496
            return k;
1497
        }
1498

    
1499
        public Envelope getEnvelope() {
1500
            return this.envelope;
1501
        }
1502

    
1503
    }
1504

    
1505
    public boolean closeResourceRequested(ResourceProvider resource) {
1506
        return true;
1507
    }
1508

    
1509
    public int getOIDType() {
1510
        return DataTypes.LONG;
1511
    }
1512

    
1513
    public boolean supportsAppendMode() {
1514
        return false;
1515
    }
1516

    
1517
    public void append(FeatureProvider featureProvider) {
1518
        try {
1519
            writer.add(featureProvider);
1520
        } catch (WriteException e) {
1521
            // TODO Auto-generated catch block
1522
            e.printStackTrace();
1523
        }
1524
    }
1525

    
1526
    public void beginAppend() {
1527
        try {
1528
            writer = new Writer().initialice((File) resource.get(), projection);
1529
            writer.begin();
1530
        } catch (AccessResourceException e) {
1531
            // TODO Auto-generated catch block
1532
            e.printStackTrace();
1533
        }
1534
    }
1535

    
1536
    public void endAppend() {
1537
        try {
1538
            resource.notifyOpen();
1539
            writer.end();
1540
            resource.notifyClose();
1541
            counterNewsOIDs = 0;
1542
        } catch (ResourceNotifyOpenException e) {
1543
            // TODO Auto-generated catch block
1544
            e.printStackTrace();
1545
        } catch (ResourceNotifyCloseException e) {
1546
            // TODO Auto-generated catch block
1547
            e.printStackTrace();
1548
        } catch (WriteException e) {
1549
            // TODO Auto-generated catch block
1550
            e.printStackTrace();
1551
        }
1552
    }
1553

    
1554
    public void saveToState(PersistentState state) throws PersistenceException {
1555
        // TODO Auto-generated method stub
1556
        throw new NotYetImplemented();
1557
    }
1558

    
1559
    public void loadFromState(PersistentState state) throws PersistenceException {
1560
        // TODO Auto-generated method stub
1561
        throw new NotYetImplemented();
1562
    }
1563

    
1564
    public Object createNewOID() {
1565
        return new Long(counterNewsOIDs++);
1566
    }
1567

    
1568
    protected void initializeFeatureTypes() throws InitializeException {
1569
        try {
1570
            this.open();
1571
        } catch (OpenException e) {
1572
            throw new InitializeException(this.getProviderName(), e);
1573
        }
1574
    }
1575

    
1576
    public Envelope getEnvelope() throws DataException {
1577
        this.open();
1578
        return this.envelope;
1579
    }
1580

    
1581
    public Object getDynValue(String name) throws DynFieldNotFoundException {
1582
        if( DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name) ) {
1583
            try {
1584
                return this.getEnvelope();
1585
            } catch (DataException e) {
1586
                return null;
1587
            }
1588
        } else {
1589
            if( DataStore.METADATA_CRS.equalsIgnoreCase(name) ) {
1590
                IProjection pro = this.getDXFParameters().getCRS();
1591
                if (pro != null){
1592
                    return pro;
1593
                }
1594
            }
1595
        }
1596
        return super.getDynValue(name);
1597
    }
1598

    
1599

    
1600
    /*
1601
     * (non-Javadoc)
1602
     *
1603
     * @see
1604
     * org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
1605
     * gvsig.fmap.dal.resource.spi.ResourceProvider)
1606
     */
1607
    public void resourceChanged(ResourceProvider resource) {
1608
        this.getStoreServices().notifyChange(
1609
            DataStoreNotification.RESOURCE_CHANGED,
1610
            resource);
1611
    }
1612

    
1613

    
1614
    public Object getSourceId() {
1615
        return this.getDXFParameters().getFile();
1616
    }
1617

    
1618
    public String getName() {
1619
        String name = this.getDXFParameters().getFile().getName();
1620
        int n = name.lastIndexOf(".");
1621
        if( n<1 ) {
1622
            return name;
1623
        }
1624
        return name.substring(0, n);
1625
    }
1626

    
1627
    public String getFullName() {
1628
        return this.getDXFParameters().getFile().getAbsolutePath();
1629
    }
1630

    
1631
    public ResourceProvider getResource() {
1632
        return resource;
1633
    }
1634

    
1635
}