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 @ 153

History | View | Annotate | Download (64.5 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.exception.CreateGeometryException;
71
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
72
import org.gvsig.fmap.geom.operation.distance.PointDistance;
73
import org.gvsig.fmap.geom.operation.utils.PointGetAngle;
74
import org.gvsig.fmap.geom.primitive.Arc;
75
import org.gvsig.fmap.geom.primitive.Circle;
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.type.GeometryType;
81
import org.gvsig.tools.ToolsLocator;
82
import org.gvsig.tools.dispose.DisposableIterator;
83
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
84
import org.gvsig.tools.dynobject.exception.DynMethodException;
85
import org.gvsig.tools.exception.BaseException;
86
import org.gvsig.tools.exception.NotYetImplemented;
87
import org.gvsig.tools.logger.FilteredLogger;
88
import org.gvsig.tools.persistence.PersistentState;
89
import org.gvsig.tools.persistence.exception.PersistenceException;
90
import org.gvsig.tools.task.SimpleTaskStatus;
91
import org.gvsig.tools.task.TaskStatusManager;
92

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

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

    
100
    public static final String METADATA_DEFINITION_NAME = NAME;
101

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

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

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

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

    
133
    private SimpleTaskStatus taskStatus;
134

    
135

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

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

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

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

    
156
        resource.addConsumer(this);
157

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

    
160

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

    
170
        this.initializeFeatureTypes();
171

    
172
    }
173

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

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

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

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

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

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

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

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

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

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

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

    
273
                    dxfData.legendBuilder = legendBuilder;
274

    
275
                    dxfData.projection = projection;
276

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

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

    
305

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

    
320
    }
321

    
322

    
323

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

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

    
383
    public static void initializeFeatureType(EditableFeatureType featureType, IProjection projection, int geometrySubtype){
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
    }
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 DxfFeatureMaker featureMaker;
467
        private DxfHeaderManager 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 = store.createFeatureType(getName());
508
            initializeFeatureType(featureType, this.projection, geometrySubtype);
509

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

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

    
518
        }
519

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

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

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

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

    
541
        private FeatureProvider createFeature(Feature fea, FeatureType ft, int id) throws DataException {
542

    
543
            FeatureProvider feature = store.createFeatureProvider(ft);
544

    
545
            feature.setOID(new Long(id));
546
            feature.set(ID_FIELD_ID, Integer.valueOf(id));
547
            feature.set(ID_FIELD_ENTITY, fea.getProp("dxfEntity"));
548
            feature.set(ID_FIELD_LAYER, fea.getProp("layer"));
549
            feature.set(ID_FIELD_COLOR, Integer.valueOf(fea.getProp("color")));
550
            feature.set(ID_FIELD_TEXT, fea.getProp("text"));
551
            feature.set(ID_FIELD_HEIGHTTEXT, toDouble(fea.getProp("textHeight")));
552
            feature.set(ID_FIELD_ROTATIONTEXT, toDouble(fea.getProp("textRotation")));
553
            feature.set(ID_FIELD_ELEVATION, toDouble(fea.getProp("elevation")));
554
            feature.set(ID_FIELD_THICKNESS, toDouble(fea.getProp("thickness")));
555
            feature.set(ID_FIELD_GEOMETRY, null);
556
            // FIXME: Abria que pillar el resto de atributos del DXF.
557

    
558
            // FIXME: Habia una incongruencia en el codigo ya que al
559
            // campo
560
            // ID_FIELD_GEOMETRY igual le asignaba una geometria que un
561
            // valor de cadena como 'Point3D', 'Polyline2D' o
562
            // 'Polyline3D'
563
            // Faltaria un atributo ID_FIELD_FSHAPE ?
564
            //
565
            return feature;
566
        }
567

    
568
        private Geometry processPoints(GeometryManager gManager, Feature dxffeature) throws CreateGeometryException {
569
            if (dxffeature.getGeometry() instanceof org.gvsig.dxf.px.gml.Point3D) {
570
                org.gvsig.dxf.px.gml.Point3D point = (org.gvsig.dxf.px.gml.Point3D) dxffeature.getGeometry();
571
                Point3D pto = point.getPoint3D(0);
572
                org.gvsig.fmap.geom.primitive.Point geom = gManager.createPoint(pto.getX(), pto.getY(), SUBTYPES.GEOM3D);
573
                geom.setCoordinateAt(Geometry.DIMENSIONS.Z, pto.getZ());
574

    
575
                if (point.isTextPoint()) {
576
                    /// TODO labeling
577
                }
578
                return geom;
579

    
580
            }
581
            if (dxffeature.getGeometry() instanceof Point) {
582
                Point point = (Point) dxffeature.getGeometry();
583
                Point2D pto = point.get(0);
584

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

    
587
                if (point.isTextPoint()) {
588
                    /// TODO labeling
589
                }
590
                return geom;
591
            }
592
            return null;
593
        }
594

    
595
        private Geometry processLines(GeometryManager gManager, Feature dxffeature) throws CreateGeometryException {
596
            if (dxffeature.getGeometry() instanceof LineString3D) {
597
                Line line = gManager.createLine(SUBTYPES.GEOM3D);
598
                for (int j = 0; j < dxffeature.getGeometry().pointNr(); j++) {
599
                    Point3D point = ((LineString3D) dxffeature.getGeometry()).getPoint3D(j);
600
                    line.addVertex(point.getX(), point.getY(), point.getZ());
601
                }
602
                return line;
603

    
604
            }
605
            if (dxffeature.getGeometry() instanceof LineString) {
606
                Line line = gManager.createLine(SUBTYPES.GEOM2D);
607
                for (int j = 0; j < dxffeature.getGeometry().pointNr(); j++) {
608
                    Point2D point = dxffeature.getGeometry().get(j);
609
                    line.addVertex(point.getX(), point.getY());
610
                }
611
                return line;
612
            }
613
            return null;
614
        }
615

    
616
        private Geometry processPolygons(GeometryManager gManager, Feature dxffeature) throws CreateGeometryException {
617
            if (dxffeature.getGeometry() instanceof Polygon3D) {
618
                org.gvsig.fmap.geom.primitive.Polygon polygon = gManager.createPolygon(SUBTYPES.GEOM3D);
619
                for (int j = 0; j < dxffeature.getGeometry().pointNr(); j++) {
620
                    Point3D point = ((Polygon3D) dxffeature.getGeometry()).getPoint3D(j);
621
                    polygon.addVertex(point.getX(), point.getY(), point.getZ());
622
                }
623
                Point3D point = ((Polygon3D) dxffeature.getGeometry()).getPoint3D(0);
624
                polygon.addVertex(point.getX(), point.getY(), point.getZ());
625
                return polygon;
626

    
627
            }
628
            if (dxffeature.getGeometry() instanceof Polygon) {
629
                org.gvsig.fmap.geom.primitive.Polygon polygon = gManager.createPolygon(SUBTYPES.GEOM2D);
630
                for (int j = 0; j < dxffeature.getGeometry().pointNr(); j++) {
631
                    Point2D point = dxffeature.getGeometry().get(j);
632
                    polygon.addVertex(point.getX(), point.getY());
633
                }
634
                Point2D point = dxffeature.getGeometry().get(0);
635
                polygon.addVertex(point.getX(), point.getY());
636
                return polygon;
637
            }
638
            return null;
639
        }
640

    
641
        private void addGeometryToFeature(Geometry geometry, FeatureProvider feature) {
642
            if( geometry != null ) {
643
                feature.set(ID_FIELD_GEOMETRY, geometry);
644
                feature.setDefaultGeometry(geometry);
645
                if (this.envelope == null) {
646
                    this.envelope = geometry.getEnvelope();
647
                } else {
648
                    this.envelope.add(geometry.getEnvelope());
649
                }
650
            }
651
        }
652

    
653
        private void addfeatureToLegend(FeatureProvider feature) {
654
            if (leyendBuilder != null) {
655
                try {
656
                    leyendBuilder.process(feature);
657
                } catch (Exception e) {
658
                    logger.warn(
659
                        MessageFormat.format(
660
                            "load: legendBuilder process fails in the feature {1}",
661
                            feature
662
                        )
663
                    );
664
                }
665
            }
666
        }
667

    
668
        public void load() throws DataException {
669

    
670
            this.envelope = null;
671

    
672
            IObjList.vector features = (IObjList.vector)featureMaker.getObjects();
673
            String acadVersion = headerManager.getAcadVersion();
674

    
675
            logger.info("load: acadVersion = '" + acadVersion + "'");
676

    
677
            GeometryManager gManager = GeometryLocator.getGeometryManager();
678

    
679
            if (!featureMaker.isDxf3DFile() && !headerManager.isWritedDxf3D()) {
680
                taskStatus.message("_fixing_3dgeometries");
681
                Feature[] features2D = new Feature[features.size()];
682
                taskStatus.setRangeOfValues(0,features.size());
683
                for (int i = 0; i < features.size(); i++) {
684
                    taskStatus.setCurValue(i);
685
                    Feature fea = (Feature) features.get(i);
686
                    if (fea.getGeometry() instanceof org.gvsig.dxf.px.gml.Point3D) {
687
                        Point point = (Point) fea.getGeometry();
688
                        Point point2 = new Point();
689
                        for (int j = 0; j < point.pointNr(); j++) {
690
                            point2.add(point.get(j));
691
                        }
692
                        point2.setTextPoint(point.isTextPoint());
693
                        fea.setGeometry(point2);
694
                        features2D[i] = fea;
695

    
696
                    } else if (fea.getGeometry() instanceof LineString3D) {
697
                        LineString lineString = (LineString) fea.getGeometry();
698
                        LineString lineString2 = new LineString();
699
                        for (int j = 0; j < lineString.pointNr(); j++) {
700
                            lineString2.add(lineString.get(j));
701
                        }
702
                        fea.setGeometry(lineString2);
703
                        features2D[i] = fea;
704
                    } else if (fea.getGeometry() instanceof Polygon3D) {
705
                        Polygon polygon = (Polygon) fea.getGeometry();
706
                        Polygon polygon2 = new Polygon();
707
                        for (int j = 0; j < polygon.pointNr(); j++) {
708
                            polygon2.add(polygon.get(j));
709
                        }
710
                        fea.setGeometry(polygon2);
711
                        features2D[i] = fea;
712
                    }
713
                }
714
                features.clear();
715
                for (int i = 0; i < features2D.length; i++) {
716
                    features.add(features2D[i]);
717
                }
718
            }
719

    
720
            FilteredLogger logger = new FilteredLogger(DXFStoreProvider.logger,"DXFLoafing",20);
721

    
722
            FeatureType ft = store.getStoreServices().getDefaultFeatureType();
723
            taskStatus.message("_loading");
724
            // Nos recorremos las geometrias tres veces para cargarlas en orden:
725
            // - poligonos
726
            // - lineas
727
            // - puntos
728
            // Y garantizar que siempre se pinten los puntos sobre lineas y
729
            // poligonos y las lineas sobre los polignos.
730
            int n = 0;
731
            taskStatus.setRangeOfValues(0,features.size()*3);
732
            for (int i = 0; i < features.size(); i++) {
733
                taskStatus.setCurValue(n++);
734
                try {
735
                    Feature dxffeature = (Feature) features.get(i);
736
                    FeatureProvider feature = createFeature(dxffeature, ft, i);
737
                    Geometry geometry = processPolygons(gManager, dxffeature);
738
                    if( geometry != null ) {
739
                        addGeometryToFeature(geometry, feature);
740
                        store.addFeatureProvider(feature);
741
                        addfeatureToLegend(feature);
742
                    }
743
                } catch (Exception e) {
744
                    logger.warn("Can't proccess feature '"+i+", of file '"+fileName+"'.", e);
745
                }
746
            }
747
            for (int i = 0; i < features.size(); i++) {
748
                taskStatus.setCurValue(n++);
749
                try {
750
                    Feature dxffeature = (Feature) features.get(i);
751
                    FeatureProvider feature = createFeature(dxffeature, ft, i);
752
                    Geometry geometry = processLines(gManager, dxffeature);
753
                    if( geometry != null ) {
754
                        addGeometryToFeature(geometry, feature);
755
                        store.addFeatureProvider(feature);
756
                        addfeatureToLegend(feature);
757
                    }
758
                } catch (Exception e) {
759
                    logger.warn("Can't proccess feature '"+i+", of file '"+fileName+"'.", e);
760
                }
761
            }
762
            for (int i = 0; i < features.size(); i++) {
763
                taskStatus.setCurValue(n++);
764
                try {
765
                    Feature dxffeature = (Feature) features.get(i);
766
                    FeatureProvider feature = createFeature(dxffeature, ft, i);
767
                    Geometry geometry = processPoints(gManager, dxffeature);
768
                    if( geometry != null ) {
769
                        addGeometryToFeature(geometry, feature);
770
                        store.addFeatureProvider(feature);
771
                        addfeatureToLegend(feature);
772
                    }
773
                } catch (Exception e) {
774
                    logger.warn("Can't proccess feature '"+i+", of file '"+fileName+"'.", e);
775
                }
776
            }
777
        }
778

    
779
    }
780

    
781
    public class Writer {
782
        private Double DEFAULT_ELEVATION = new Double(0);
783

    
784
        private DxfFile.EntityFactory entityMaker;
785

    
786
        private IProjection proj = null;
787

    
788
        private int handle = 40; // Revisar porqu� es 40.
789

    
790
        private int k = 0;
791

    
792
        private boolean dxf3DFile = false;
793
        private String fileName;
794
        private Envelope envelope;
795

    
796
        public Writer initialice(File file, IProjection projection) {
797
            this.proj = projection;
798
            this.fileName = file.getAbsolutePath();
799
            entityMaker = new DxfEntityMaker(proj);
800
            return this;
801
        }
802

    
803
        public void begin() {
804
            envelope = null;
805
            entityMaker = new DxfEntityMaker(proj);
806
        }
807

    
808
        public void end() throws WriteException {
809
            try {
810
                DxfFile dxfFile = new DxfFile(null, fileName, entityMaker);
811
                dxfFile.setCadFlag(true);
812
                if (dxf3DFile) {
813
                    dxfFile.setDxf3DFlag(true);
814
                }
815
                dxfFile.save(fileName);
816
                dxfFile.close();
817
            } catch (Exception e) {
818
                throw new WriteException(fileName, e);
819
            }
820
        }
821

    
822
        public void add(FeatureProvider feature) throws WriteException {
823
            try {
824
                Geometry geom = feature.getDefaultGeometry();
825
                if(geom == null){
826
                    //FIXME: tirar al log y avisar al usuario
827
                    return;
828
                }
829
                GeometryType type = geom.getGeometryType();
830
                boolean geometrySupported = true;
831

    
832
                if ((type.isTypeOf(TYPES.POINT)) && (SUBTYPES.GEOM3D == type.getSubType())) {
833
                    dxf3DFile = true;
834
                    k = createPoint3D(handle, k, feature);
835

    
836
                } else if ((type.isTypeOf(TYPES.POINT)) && (SUBTYPES.GEOM2D == type.getSubType())) {
837
                    k = createPoint2D(handle, k, feature);
838

    
839
                } else if ((type.isTypeOf(TYPES.ARC)) && (SUBTYPES.GEOM2D == type.getSubType())) {
840
                    k = createArc2D(handle, k, feature);
841

    
842
                } else if ((type.isTypeOf(TYPES.CURVE) || type.isTypeOf(TYPES.MULTICURVE)) && (SUBTYPES.GEOM3D == type.getSubType())) {
843
                    dxf3DFile = true;
844
                    k = createPolyline3D(handle, k, feature);
845

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

    
849
                } else if ((type.isTypeOf(TYPES.CIRCLE)) && (SUBTYPES.GEOM2D == type.getSubType())) {
850
                    k = createCircle2D(handle, k, feature);
851

    
852
                } else if ((type.isTypeOf(TYPES.ELLIPSE)) && (SUBTYPES.GEOM2D == type.getSubType())) {
853
                    k = createEllipse2D(handle, k, feature);
854

    
855
                } else if ((type.isTypeOf(TYPES.SURFACE) || (type.isTypeOf(TYPES.MULTISURFACE))) && (SUBTYPES.GEOM3D == type.getSubType())) {
856
                    dxf3DFile = true;
857
                    k = createPolyline3D(handle, k, feature);
858

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

    
862
                } else {
863
                    geometrySupported = false;
864
                    logger.warn(
865
                        MessageFormat.format(
866
                            "Geometry '{1}' not yet supported",
867
                            new Object[] {geom.getClass().getName()}
868
                        )
869
                    );
870
                    k++;
871
                }
872
                if (geometrySupported){
873
                    if (this.envelope != null){
874
                        this.envelope.add(feature.getDefaultEnvelope());
875
                    } else {
876
                        this.envelope = feature.getDefaultEnvelope().getGeometry().getEnvelope();
877
                    }
878
                }
879
            } catch (Exception e) {
880
                throw new WriteException(fileName, e);
881
            }
882

    
883
        }
884

    
885
        private boolean hasText(FeatureProvider feature) {
886
            if (feature.isNull(ID_FIELD_TEXT)) {
887
                return false;
888
            }
889
            if (feature.get(ID_FIELD_TEXT).equals("")) {
890
                return false;
891
            }
892
            return true;
893
        }
894

    
895
        private DxfGroupVector updateProperties(FeatureProvider feature, int k) {
896
            DxfGroupVector polv = new DxfGroupVector();
897

    
898
            String layer = (String) feature.get(ID_FIELD_LAYER);
899
            Integer color = (Integer) feature.get(ID_FIELD_COLOR);
900
            Double thickness = (Double) feature.get(ID_FIELD_THICKNESS);
901

    
902
            DxfGroup geometryLayer = new DxfGroup(8, layer);
903

    
904
            DxfGroup handleGroup = new DxfGroup();
905
            handleGroup.setCode(5);
906
            handleGroup.setData(new Integer(handle + k).toString());
907

    
908
            DxfGroup handleColor = new DxfGroup();
909
            handleColor.setCode(62);
910
            handleColor.setData(color);
911

    
912
            DxfGroup handleThickness = new DxfGroup();
913
            handleThickness.setCode(39);
914
            handleThickness.setData(thickness);
915

    
916
            polv.add(geometryLayer);
917
            polv.add(handleGroup);
918
            polv.add(handleColor);
919
            return polv;
920
        }
921

    
922
        private int createPoint2D(int handle, int k, FeatureProvider feature)
923
        throws Exception {
924

    
925
            if (hasText(feature)) {
926
                return createText2D(handle, k, feature);
927
            }
928
            org.gvsig.fmap.geom.primitive.Point point = geomManager.createPoint(0, 0, SUBTYPES.GEOM2D);
929
            double[] pointCoords = new double[6];
930
            PathIterator pointIt = (feature.getDefaultGeometry())
931
            .getPathIterator(null);
932
            while (!pointIt.isDone()) {
933
                pointIt.currentSegment(pointCoords);
934
                point = geomManager.createPoint(pointCoords[0], pointCoords[1], SUBTYPES.GEOM2D);
935
                pointIt.next();
936
            }
937
            Point2D pto = new Point2D.Double(point.getX(), point.getY());
938

    
939
            DxfGroup px = new DxfGroup();
940
            DxfGroup py = new DxfGroup();
941
            DxfGroup pz = new DxfGroup();
942
            px.setCode(10);
943
            px.setData(new Double(pto.getX()));
944
            py.setCode(20);
945
            py.setData(new Double(pto.getY()));
946
            pz.setCode(30);
947
            // FIXME: POINT del DXF tiene cota. Le asigno cero arbitrariamente.
948
            pz.setData(new Double(0.0));
949
            DxfGroupVector pv = updateProperties(feature, k);
950
            pv.add(px);
951
            pv.add(py);
952
            pv.add(pz);
953
            entityMaker.createPoint(pv);
954
            k++;
955
            return k;
956
        }
957

    
958
        private int createText2D(int handle, int k, FeatureProvider feature)
959
        throws Exception {
960

    
961
            String text = feature.get(ID_FIELD_TEXT).toString();
962
            Double heightText = (Double) feature.get(ID_FIELD_HEIGHTTEXT);
963
            Double rotationText = (Double) feature.get(ID_FIELD_ROTATIONTEXT);
964

    
965
            DxfGroup handleText = new DxfGroup();
966
            handleText.setCode(1);
967
            handleText.setData(text);
968

    
969
            DxfGroup handleHeightText = new DxfGroup();
970
            handleHeightText.setCode(40);
971
            handleHeightText.setData(heightText);
972

    
973
            DxfGroup handleRotationText = new DxfGroup();
974
            handleRotationText.setCode(50);
975
            handleRotationText.setData(rotationText);
976

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

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

    
1051
            DxfGroupVector pv = updateProperties(feature, k);
1052
            pv.add(handleElevation);
1053
            pv.add(px);
1054
            pv.add(py);
1055
            pv.add(pz);
1056
            entityMaker.createPoint(pv);
1057
            k++;
1058
            return k;
1059
        }
1060

    
1061
        private int createText3D(int handle, int k, FeatureProvider feature)
1062
        throws Exception {
1063

    
1064
            double velev = ((org.gvsig.fmap.geom.primitive.Point) feature.getDefaultGeometry())
1065
            .getCoordinateAt(0);
1066

    
1067
            Double elevation = new Double(velev);
1068
            String text = feature.get(ID_FIELD_TEXT).toString();
1069
            Double heightText = (Double) feature.get(ID_FIELD_HEIGHTTEXT);
1070
            Double rotationText = (Double) feature.get(ID_FIELD_ROTATIONTEXT);
1071

    
1072
            DxfGroup handleText = new DxfGroup();
1073
            handleText.setCode(1);
1074
            handleText.setData(text);
1075

    
1076
            DxfGroup handleHeightText = new DxfGroup();
1077
            handleHeightText.setCode(40);
1078
            handleHeightText.setData(heightText);
1079

    
1080
            DxfGroup handleRotationText = new DxfGroup();
1081
            handleRotationText.setCode(50);
1082
            handleRotationText.setData(rotationText);
1083

    
1084
            DxfGroup handleElevation = new DxfGroup();
1085
            handleElevation.setCode(38);
1086
            handleElevation.setData(elevation);
1087

    
1088
            org.gvsig.fmap.geom.primitive.Point point =
1089
                (org.gvsig.fmap.geom.primitive.Point) (feature
1090
                    .getDefaultGeometry());
1091

    
1092
            DxfGroup handleGroup = new DxfGroup();
1093
            handleGroup.setCode(5);
1094
            handleGroup.setData(new Integer(handle + k).toString());
1095
            DxfGroup px = new DxfGroup();
1096
            DxfGroup py = new DxfGroup();
1097
            DxfGroup pz = new DxfGroup();
1098
            px.setCode(10);
1099
            px.setData(new Double(point.getX()));
1100
            py.setCode(20);
1101
            py.setData(new Double(point.getY()));
1102
            pz.setCode(30);
1103
            pz.setData(new Double(point.getCoordinateAt(2)));
1104
            DxfGroupVector pv = updateProperties(feature, k);
1105
            pv.add(handleElevation);
1106
            pv.add(handleText);
1107
            pv.add(handleHeightText);
1108
            pv.add(handleRotationText);
1109
            pv.add(handleGroup);
1110
            pv.add(px);
1111
            pv.add(py);
1112
            pv.add(pz);
1113
            entityMaker.createText(pv);
1114
            k++;
1115
            return k;
1116
        }
1117

    
1118
        private int createLwPolyline2D(int handle, int k, FeatureProvider feature,
1119
            boolean isPolygon) throws Exception {
1120
            boolean first = true;
1121
            DxfGroupVector polv = updateProperties(feature, k);
1122
            Vector vpoints = new Vector();
1123

    
1124
            DxfGroup polylineFlag = new DxfGroup();
1125
            polylineFlag.setCode(70);
1126
            if (isPolygon) {
1127
                polylineFlag.setData(new Integer(1)); // cerrada
1128
            } else {
1129
                polylineFlag.setData(new Integer(0)); // abierta
1130
            }
1131

    
1132
            PathIterator theIterator = (feature.getDefaultGeometry())
1133
            .getPathIterator(null, geomManager.getFlatness()); // polyLine.
1134
            // getPathIterator
1135
            // (null,
1136
            // flatness);
1137

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

    
1161
                        entityMaker.createLwPolyline(polv);
1162
                        k++;
1163
                        polv = updateProperties(feature, k);
1164

    
1165
                    }
1166
                    first = false;
1167
                    polv.add(polylineFlag);
1168
                    vpoints.clear();
1169
                    vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1170
                    break;
1171
                case PathIterator.SEG_LINETO:
1172
                    vpoints.add(geomManager.createPoint(theData[0], theData[1], SUBTYPES.GEOM2D));
1173
                    break;
1174
                case PathIterator.SEG_QUADTO:
1175
                    break;
1176
                case PathIterator.SEG_CUBICTO:
1177
                    break;
1178
                case PathIterator.SEG_CLOSE:
1179
                    polylineFlag.setData(new Integer(1)); // cerrada
1180
                    break;
1181

    
1182
                }
1183
                theIterator.next();
1184
            }
1185

    
1186
            for (int j = 0; j < vpoints.size(); j++) {
1187
                DxfGroup xvertex = new DxfGroup();
1188
                xvertex.setCode(10);
1189
                xvertex
1190
                .setData(new Double(
1191
                    ((org.gvsig.fmap.geom.primitive.Point) vpoints
1192
                        .get(j)).getX()));
1193
                DxfGroup yvertex = new DxfGroup();
1194
                yvertex.setCode(20);
1195
                yvertex
1196
                .setData(new Double(
1197
                    ((org.gvsig.fmap.geom.primitive.Point) vpoints
1198
                        .get(j)).getY()));
1199
                polv.add(xvertex);
1200
                polv.add(yvertex);
1201
            }
1202

    
1203
            entityMaker.createLwPolyline(polv);
1204
            k++;
1205
            return k;
1206
        }
1207

    
1208
        private int createPolyline3D(int handle, int k, FeatureProvider feature)
1209
        throws Exception {
1210
            DxfGroupVector polv = updateProperties(feature, k);
1211
            Vector vpoints = new Vector();
1212
            PathIterator theIterator = (feature.getDefaultGeometry())
1213
            .getPathIterator(null, geomManager.getFlatness()); // polyLine.
1214
            // getPathIterator
1215
            // (null,
1216
            // flatness);
1217
            double[] theData = new double[6];
1218
            OrientablePrimitive curve = (OrientablePrimitive) feature.getDefaultGeometry();
1219
            double[] velev = new double[curve.getNumVertices()];
1220
            for (int i = 0; i < curve.getNumVertices(); i++) {
1221
                velev[i] = curve.getCoordinateAt(i, 2);
1222
            }
1223

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

    
1330
        private boolean constantElevation(double[] velev) {
1331
            boolean constant = true;
1332
            for (int i = 0; i < velev.length; i++) {
1333
                for (int j = 0; j < velev.length; j++) {
1334
                    if (j > i) {
1335
                        if (velev[i] != velev[j]) {
1336
                            constant = false;
1337
                            break;
1338
                        }
1339
                    }
1340
                }
1341
                break;
1342
            }
1343
            return constant;
1344
        }
1345

    
1346
        private int createCircle2D(int handle, int k, FeatureProvider feature)
1347
        throws Exception {
1348
            DxfGroupVector polv = updateProperties(feature, k);
1349
            DxfGroup circleFlag = new DxfGroup();
1350
            circleFlag.setCode(100);
1351
            polv.add(circleFlag);
1352

    
1353
            DxfGroup xvertex = new DxfGroup();
1354
            xvertex.setCode(10);
1355
            Circle circle = (Circle) (feature
1356
                .getDefaultGeometry());
1357
            xvertex.setData(new Double(circle.getCenter().getX()));
1358
            DxfGroup yvertex = new DxfGroup();
1359
            yvertex.setCode(20);
1360
            yvertex.setData(new Double(circle.getCenter().getY()));
1361
            DxfGroup zvertex = new DxfGroup();
1362
            zvertex.setCode(30);
1363
            // TODO: COORDENADA Z. REVISAR ESTO PARA ENTIDADES 3D
1364
            zvertex.setData(new Double(0));
1365

    
1366
            DxfGroup radius = new DxfGroup();
1367
            radius.setCode(40);
1368
            radius.setData(new Double(circle.getRadious()));
1369

    
1370
            polv.add(xvertex);
1371
            polv.add(yvertex);
1372
            polv.add(zvertex);
1373
            polv.add(radius);
1374

    
1375
            entityMaker.createCircle(polv);
1376
            k++;
1377
            return k;
1378
        }
1379

    
1380
        private int createArc2D(int handle, int k, FeatureProvider feature)
1381
        throws Exception {
1382
            Arc arc = (Arc) (feature.getDefaultGeometry());
1383

    
1384
            org.gvsig.fmap.geom.primitive.Point[] pts = new org.gvsig.fmap.geom.primitive.Point[3];
1385
            pts[0] = arc.getInitPoint();
1386
            pts[1] = arc.getMiddlePoint();
1387
            pts[2] = arc.getEndPoint();
1388
            org.gvsig.fmap.geom.primitive.Point center = arc.getCenterPoint();
1389
            GeometryOperationContext ctx = new GeometryOperationContext();
1390
            ctx.setAttribute("geom", pts[0]);
1391
            double radius = ((Double)geomManager.invokeOperation(PointDistance.CODE, center, ctx)).doubleValue();
1392

    
1393
            double initAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1394
            initAngle = Math.toDegrees(initAngle);
1395
            ctx.setAttribute("geom", pts[1]);
1396
            double midAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1397
            midAngle = Math.toDegrees(midAngle);
1398
            ctx.setAttribute("geom", pts[2]);
1399
            double endAngle = ((Double)geomManager.invokeOperation(PointGetAngle.CODE, center, ctx)).doubleValue();
1400
            endAngle = Math.toDegrees(endAngle);
1401

    
1402
            double aux;
1403
            if(initAngle<=endAngle){
1404
                if(initAngle<=midAngle && midAngle<=endAngle){
1405
                    //do nothing
1406
                } else {
1407
                    aux = initAngle;
1408
                    initAngle = endAngle;
1409
                    endAngle = aux;
1410
                }
1411
            } else {
1412
                if(initAngle>=midAngle && midAngle>=endAngle){
1413
                    aux = initAngle;
1414
                    initAngle = endAngle;
1415
                    endAngle = aux;
1416
                } else {
1417
                    //do nothing
1418
                }
1419
            }
1420

    
1421
            DxfGroup ax = new DxfGroup();
1422
            DxfGroup ay = new DxfGroup();
1423
            DxfGroup ac = new DxfGroup();
1424
            DxfGroup ai = new DxfGroup();
1425
            DxfGroup ae = new DxfGroup();
1426
            ax.setCode(10);
1427
            ax.setData(new Double(center.getX()));
1428
            ay.setCode(20);
1429
            ay.setData(new Double(center.getY()));
1430
            ac.setCode(40);
1431
            ac.setData(new Double(radius));
1432
            ai.setCode(50);
1433
            ai.setData(new Double(initAngle));
1434
            ae.setCode(51);
1435
            ae.setData(new Double(endAngle));
1436
            DxfGroupVector av = updateProperties(feature, k);
1437
            av.add(ax);
1438
            av.add(ay);
1439
            av.add(ac);
1440
            av.add(ai);
1441
            av.add(ae);
1442
            entityMaker.createArc(av);
1443
            k++;
1444
            return k;
1445
        }
1446

    
1447
        private int createEllipse2D(int handle, int k, FeatureProvider feature)
1448
        throws Exception {
1449
            Ellipse ellipse = (Ellipse) (feature
1450
                .getDefaultGeometry());
1451

    
1452
            org.gvsig.fmap.geom.primitive.Point center = (org.gvsig.fmap.geom.primitive.Point)geomManager.create(TYPES.POINT, SUBTYPES.GEOM2D);
1453
            center.setCoordinateAt(0, (ellipse.getAxis1Start().getX() + ellipse.getAxis1End().getX()) / 2);
1454
            center.setCoordinateAt(1, (ellipse.getAxis1Start().getY() + ellipse.getAxis1End().getY()) / 2);
1455

    
1456
            double mAxisL = ellipse.getAxis2Dist() * 2;
1457
            GeometryOperationContext ctx = new GeometryOperationContext();
1458
            ctx.setAttribute("geom", ellipse.getAxis1End());
1459
            double maAxisL = ((Double)geomManager.invokeOperation(PointDistance.CODE, ellipse.getAxis1Start(), ctx)).doubleValue();
1460

    
1461
            Point2D endPointOfMajorAxis = new Point2D.Double(ellipse.getAxis1End().getX(), ellipse.getAxis1End().getY());
1462
            double azimut = Math
1463
            .atan2(endPointOfMajorAxis.getX() - center.getX(),
1464
                endPointOfMajorAxis.getY() - center.getY());
1465
            double azimut2 = azimut + Math.PI / 2.0;
1466
            if (azimut2 >= Math.PI * 2) {
1467
                azimut2 = azimut2 - Math.PI * 2;
1468
            }
1469
            Point2D endPointOfMinorAxis = new Point2D.Double(center.getX()
1470
                + (ellipse.getAxis2Dist() * Math.sin(azimut2)), center.getY()
1471
                + (ellipse.getAxis2Dist() * Math.cos(azimut2)));
1472

    
1473
            if (mAxisL >= maAxisL) {
1474
                // El menor debe ser menor que el mayor. Los cambiamos.
1475
                double aux = mAxisL;
1476
                mAxisL = maAxisL;
1477
                maAxisL = aux;
1478
                // Tambi�n cambiamos los puntos finales de los ejes.
1479
                Point2D pAux = endPointOfMinorAxis;
1480
                endPointOfMinorAxis = endPointOfMajorAxis;
1481
                endPointOfMajorAxis = pAux;
1482
            }
1483
            double mToMAR = mAxisL / maAxisL;
1484
            DxfGroup x = new DxfGroup();
1485
            DxfGroup y = new DxfGroup();
1486
            DxfGroup xc = new DxfGroup();
1487
            DxfGroup yc = new DxfGroup();
1488
            DxfGroup minToMaj = new DxfGroup();
1489
            x.setCode(10);
1490
            x.setData(new Double(center.getX()));
1491
            y.setCode(20);
1492
            y.setData(new Double(center.getY()));
1493
            xc.setCode(11);
1494
            xc.setData(new Double(endPointOfMajorAxis.getX() - center.getX()));
1495
            yc.setCode(21);
1496
            yc.setData(new Double(endPointOfMajorAxis.getY() - center.getY()));
1497
            minToMaj.setCode(40);
1498
            minToMaj.setData(new Double(mToMAR));
1499
            DxfGroupVector av = updateProperties(feature, k);
1500
            av.add(x);
1501
            av.add(y);
1502
            av.add(xc);
1503
            av.add(yc);
1504
            av.add(minToMaj);
1505
            entityMaker.createEllipse(av);
1506
            k++;
1507
            return k;
1508
        }
1509

    
1510
        public Envelope getEnvelope() {
1511
            return this.envelope;
1512
        }
1513

    
1514
    }
1515

    
1516
    public boolean closeResourceRequested(ResourceProvider resource) {
1517
        return true;
1518
    }
1519

    
1520
    public int getOIDType() {
1521
        return DataTypes.LONG;
1522
    }
1523

    
1524
    public boolean supportsAppendMode() {
1525
        return false;
1526
    }
1527

    
1528
    public void append(FeatureProvider featureProvider) {
1529
        try {
1530
            writer.add(featureProvider);
1531
        } catch (WriteException e) {
1532
            // TODO Auto-generated catch block
1533
            e.printStackTrace();
1534
        }
1535
    }
1536

    
1537
    public void beginAppend() {
1538
        try {
1539
            writer = new Writer().initialice((File) resource.get(), projection);
1540
            writer.begin();
1541
        } catch (AccessResourceException e) {
1542
            // TODO Auto-generated catch block
1543
            e.printStackTrace();
1544
        }
1545
    }
1546

    
1547
    public void endAppend() {
1548
        try {
1549
            resource.notifyOpen();
1550
            writer.end();
1551
            resource.notifyClose();
1552
            counterNewsOIDs = 0;
1553
        } catch (ResourceNotifyOpenException e) {
1554
            // TODO Auto-generated catch block
1555
            e.printStackTrace();
1556
        } catch (ResourceNotifyCloseException e) {
1557
            // TODO Auto-generated catch block
1558
            e.printStackTrace();
1559
        } catch (WriteException e) {
1560
            // TODO Auto-generated catch block
1561
            e.printStackTrace();
1562
        }
1563
    }
1564

    
1565
    public void saveToState(PersistentState state) throws PersistenceException {
1566
        // TODO Auto-generated method stub
1567
        throw new NotYetImplemented();
1568
    }
1569

    
1570
    public void loadFromState(PersistentState state) throws PersistenceException {
1571
        // TODO Auto-generated method stub
1572
        throw new NotYetImplemented();
1573
    }
1574

    
1575
    public Object createNewOID() {
1576
        return new Long(counterNewsOIDs++);
1577
    }
1578

    
1579
    protected void initializeFeatureTypes() throws InitializeException {
1580
        try {
1581
            this.open();
1582
        } catch (OpenException e) {
1583
            throw new InitializeException(this.getProviderName(), e);
1584
        }
1585
    }
1586

    
1587
    public Envelope getEnvelope() throws DataException {
1588
        this.open();
1589
        return this.envelope;
1590
    }
1591

    
1592
    public Object getDynValue(String name) throws DynFieldNotFoundException {
1593
        if( DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name) ) {
1594
            try {
1595
                return this.getEnvelope();
1596
            } catch (DataException e) {
1597
                return null;
1598
            }
1599
        } else {
1600
            if( DataStore.METADATA_CRS.equalsIgnoreCase(name) ) {
1601
                IProjection pro = this.getDXFParameters().getCRS();
1602
                if (pro != null){
1603
                    return pro;
1604
                }
1605
            }
1606
        }
1607
        return super.getDynValue(name);
1608
    }
1609

    
1610

    
1611
    /*
1612
     * (non-Javadoc)
1613
     *
1614
     * @see
1615
     * org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
1616
     * gvsig.fmap.dal.resource.spi.ResourceProvider)
1617
     */
1618
    public void resourceChanged(ResourceProvider resource) {
1619
        this.getStoreServices().notifyChange(
1620
            DataStoreNotification.RESOURCE_CHANGED,
1621
            resource);
1622
    }
1623

    
1624

    
1625
    public Object getSourceId() {
1626
        return this.getDXFParameters().getFile();
1627
    }
1628

    
1629
    public String getName() {
1630
        String name = this.getDXFParameters().getFile().getName();
1631
        int n = name.lastIndexOf(".");
1632
        if( n<1 ) {
1633
            return name;
1634
        }
1635
        return name.substring(0, n);
1636
    }
1637

    
1638
    public String getFullName() {
1639
        return this.getDXFParameters().getFile().getAbsolutePath();
1640
    }
1641

    
1642
    public ResourceProvider getResource() {
1643
        return resource;
1644
    }
1645

    
1646
    /* (non-Javadoc)
1647
     * @see org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider#doDispose()
1648
     */
1649
    @Override
1650
    protected void doDispose() throws BaseException {
1651
        super.doDispose();
1652
        resource.removeConsumer(this);
1653
    }
1654

    
1655
}