Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_dalfile / src / org / gvsig / fmap / dal / store / dgn / DGNStoreProvider.java @ 29326

History | View | Annotate | Download (30.9 KB)

1
package org.gvsig.fmap.dal.store.dgn;
2

    
3
import java.awt.geom.AffineTransform;
4
import java.awt.geom.Arc2D;
5
import java.io.File;
6
import java.util.ArrayList;
7
import java.util.HashMap;
8
import java.util.Iterator;
9
import java.util.List;
10
import java.util.Map;
11

    
12
import org.cresques.cts.IProjection;
13
import org.gvsig.fmap.dal.DALLocator;
14
import org.gvsig.fmap.dal.DataManager;
15
import org.gvsig.fmap.dal.DataServerExplorer;
16
import org.gvsig.fmap.dal.DataStoreNotification;
17
import org.gvsig.fmap.dal.DataTypes;
18
import org.gvsig.fmap.dal.exception.DataException;
19
import org.gvsig.fmap.dal.exception.InitializeException;
20
import org.gvsig.fmap.dal.exception.OpenException;
21
import org.gvsig.fmap.dal.exception.ReadException;
22
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
23
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
24
import org.gvsig.fmap.dal.feature.EditableFeatureType;
25
import org.gvsig.fmap.dal.feature.FeatureStore;
26
import org.gvsig.fmap.dal.feature.FeatureType;
27
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
28
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
29
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
30
import org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider;
31
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
32
import org.gvsig.fmap.dal.resource.exception.ResourceBeginException;
33
import org.gvsig.fmap.dal.resource.file.FileResource;
34
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
35
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
36
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
37
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
38
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
39
import org.gvsig.fmap.dal.store.dgn.lib.DGNElemArc;
40
import org.gvsig.fmap.dal.store.dgn.lib.DGNElemCellHeader;
41
import org.gvsig.fmap.dal.store.dgn.lib.DGNElemComplexHeader;
42
import org.gvsig.fmap.dal.store.dgn.lib.DGNElemCore;
43
import org.gvsig.fmap.dal.store.dgn.lib.DGNElemMultiPoint;
44
import org.gvsig.fmap.dal.store.dgn.lib.DGNElemText;
45
import org.gvsig.fmap.dal.store.dgn.lib.DGNFileHeader;
46
import org.gvsig.fmap.dal.store.dgn.lib.DGNReader;
47
import org.gvsig.fmap.geom.Geometry;
48
import org.gvsig.fmap.geom.GeometryLocator;
49
import org.gvsig.fmap.geom.GeometryManager;
50
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
51
import org.gvsig.fmap.geom.Geometry.TYPES;
52
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
53
import org.gvsig.fmap.geom.exception.CreateGeometryException;
54
import org.gvsig.fmap.geom.primitive.Envelope;
55
import org.gvsig.fmap.geom.primitive.GeneralPathX;
56
import org.gvsig.fmap.geom.primitive.Point;
57
import org.gvsig.tools.ToolsLocator;
58
import org.gvsig.tools.dynobject.DynClass;
59
import org.gvsig.tools.dynobject.DynField;
60
import org.gvsig.tools.dynobject.DynObjectManager;
61
import org.gvsig.tools.dynobject.exception.DynMethodException;
62
import org.gvsig.tools.exception.NotYetImplemented;
63
import org.gvsig.tools.persistence.PersistenceException;
64
import org.gvsig.tools.persistence.PersistentState;
65
import org.slf4j.Logger;
66
import org.slf4j.LoggerFactory;
67

    
68
public class DGNStoreProvider extends AbstractMemoryStoreProvider implements
69
                ResourceConsumer {
70
        private static final Logger logger = LoggerFactory.getLogger(DGNStoreProvider.class);
71

    
72
        public static final String NAME = "DGN";
73
        public static final String DESCRIPTION = "DGN file";
74
        public static final String DYNCLASS_NAME = "DGNStore";
75
        protected static DynClass DYNCLASS = null;
76

    
77
        public static final String NAME_FIELD_ID = "ID";
78
        public static final String NAME_FIELD_GEOMETRY = "Geometry";
79
        public static final String NAME_FIELD_ENTITY = "Entity";
80
        public static final String NAME_FIELD_LAYER = "Layer";
81
        public static final String NAME_FIELD_COLOR = "Color";
82
        public static final String NAME_FIELD_ELEVATION = "Elevation";
83
        public static final String NAME_FIELD_THICKNESS = "Thickness";
84
        public static final String NAME_FIELD_TEXT = "Text";
85
        public static final String NAME_FIELD_HEIGHTTEXT = "HeightText";
86
        public static final String NAME_FIELD_ROTATIONTEXT = "Rotation";
87

    
88
        private int ID_FIELD_ID = 0;
89
        private int ID_FIELD_ENTITY = 1;
90
        private int ID_FIELD_LAYER = 2;
91
        private int ID_FIELD_COLOR = 3;
92
        private int ID_FIELD_ELEVATION = 4;
93
        private int ID_FIELD_THICKNESS = 5;
94
        private int ID_FIELD_TEXT = 6;
95
        private int ID_FIELD_HEIGHTTEXT = 7;
96
        private int ID_FIELD_ROTATIONTEXT = 8;
97
        private int ID_FIELD_GEOMETRY = 9;
98

    
99
        private IProjection projection;
100
        private ResourceProvider resource;
101
        private LegendBuilder legendBuilder;
102

    
103
        private long counterNewsOIDs = 0;
104
        protected GeometryManager geomManager = GeometryLocator.getGeometryManager();
105

    
106
        public DGNStoreProvider(DGNStoreParameters parameters,
107
                        DataStoreProviderServices storeServices) throws InitializeException {
108
                super(parameters, storeServices, ToolsLocator.getDynObjectManager()
109
                                .createDynObject(DYNCLASS));
110

    
111
                counterNewsOIDs = 0;
112
                //                projection = CRSFactory.getCRS(getParameters().getSRSID());
113

    
114
                File file = getDGNParameters().getFile();
115
                resource = this.createResource(
116
                                FileResource.NAME,
117
                                new Object[] { file.getAbsolutePath() }
118
                        );
119

    
120
                resource.addConsumer(this);
121

    
122
                this.projection = this.getDGNParameters().getSRS();
123

    
124

    
125
                try {
126
                        legendBuilder = (LegendBuilder) this.invokeDynMethod(
127
                                        LegendBuilder.DYNMETHOD_BUILDER_NAME, null);
128
                } catch (DynMethodException e) {
129
                        legendBuilder = null;
130
                } catch (Exception e) {
131
                        throw new InitializeException(e);
132
                }
133

    
134
                this.initializeFeatureTypes();
135

    
136
        }
137

    
138
        private DGNStoreParameters getDGNParameters() {
139
                return (DGNStoreParameters) this.getParameters();
140
        }
141

    
142

    
143
        public String getName() {
144
                return NAME;
145
        }
146

    
147
        public boolean allowWrite() {
148
                return true;
149
        }
150

    
151
        public Object getLegend() throws OpenException {
152
                this.open();
153
                if (legendBuilder == null) {
154
                        return null;
155
                }
156
                return legendBuilder.getLegend();
157
        }
158

    
159
        public Object getLabeling() throws OpenException {
160
                this.open();
161
                if (legendBuilder == null) {
162
                        return null;
163
                }
164
                return legendBuilder.getLabeling();
165
        }
166

    
167
        private class DGNData {
168
                public ArrayList data = null;
169
                public FeatureType defaultFType = null;
170
                public List fTypes = null;
171
                public Envelope envelope = null;
172
                public IProjection projection;
173
                public LegendBuilder legendBuilder;
174
                public Envelope getEnvelopeCopy() throws CreateEnvelopeException {
175
                        if (envelope == null) {
176
                                return null;
177
                        }
178
                        Envelope newEnvelope;
179
                        if (envelope.getDimension() == 2) {
180
                                newEnvelope = geomManager.createEnvelope(SUBTYPES.GEOM2D);
181
                        } else {
182
                                newEnvelope = geomManager.createEnvelope(SUBTYPES.GEOM3D);
183

    
184
                        }
185
                        newEnvelope.setLowerCorner(envelope.getLowerCorner());
186
                        newEnvelope.setUpperCorner(envelope.getUpperCorner());
187
                        return newEnvelope;
188
                }
189
        }
190

    
191
        public void open() throws OpenException {
192
                if (this.data != null) {
193
                        return;
194
                }
195
                try {
196
                        this.resource.begin();
197
                } catch (ResourceBeginException e2) {
198
                        try {
199
                                throw new OpenException(resource.getName(), e2);
200
                        } catch (AccessResourceException e1) {
201
                                throw new OpenException(this.getName(), e2);
202
                        }
203

    
204
                }
205
                try {
206
                        FeatureStoreProviderServices store = this.getStoreServices();
207
                        DGNData DGNData = null;
208
                        if (this.resource.getData() != null) {
209
                                DGNData = (DGNData) ((Map) this.resource.getData())
210
                                                .get(this.projection
211
                                                .getAbrev()); // OJO no es del todo correcto (puede
212
                                                                                // llevar reproyeccion)
213
                        } else {
214
                                this.resource.setData(new HashMap());
215
                        }
216
                        if (DGNData == null) {
217
                                DGNData = new DGNData();
218
                                DGNData.data = new ArrayList();
219
                                this.data = DGNData.data;
220
                                this.counterNewsOIDs = 0;
221
                                Reader reader = new Reader().initialice(
222
                                                this,
223
                                                new File((String) this.resource.get()),
224
                                                projection,
225
                                                this.legendBuilder
226
                                        );
227
                                reader.begin(store);
228
                                DGNData.defaultFType = reader.getDefaultType()
229
                                                .getNotEditableCopy();
230
                                ArrayList types = new ArrayList();
231
                                Iterator it = reader.getTypes().iterator();
232
                                EditableFeatureType fType;
233
                                while (it.hasNext()) {
234
                                        fType = (EditableFeatureType) it.next();
235
                                        if (fType.getId().equals(DGNData.defaultFType.getId())) {
236
                                                types.add(DGNData.defaultFType);
237
                                        } else {
238
                                                types.add(fType.getNotEditableCopy());
239
                                        }
240
                                }
241
                                DGNData.fTypes = types;
242

    
243
                                resource.notifyOpen();
244
                                store.setFeatureTypes(DGNData.fTypes, DGNData.defaultFType);
245
                                reader.load();
246
                                //                                this.envelope = reader.getEnvelope();
247

    
248
                                DGNData.envelope = reader.getEnvelope();
249

    
250
                                DGNData.legendBuilder = this.legendBuilder;
251

    
252
                                DGNData.projection = this.projection;
253

    
254
                                reader.end();
255
                                resource.notifyClose();
256
                                ((Map) this.resource.getData()).put(this.projection.getAbrev(),
257
                                                DGNData); // OJO la reproyeccion
258
                        }
259

    
260
                        this.data = DGNData.data;
261
                        store.setFeatureTypes(DGNData.fTypes, DGNData.defaultFType);
262
                        this.legendBuilder = DGNData.legendBuilder;
263
                        this.setDynValue("Envelope", DGNData.getEnvelopeCopy());
264
                        this.setDynValue("DefaultSRS", this.projection.getAbrev());
265
                        this.counterNewsOIDs = this.data.size();
266
                } catch (Exception e) {
267
                        this.data = null;
268
                        try {
269
                                throw new OpenException(resource.getName(), e);
270
                        } catch (AccessResourceException e1) {
271
                                throw new OpenException(this.getName(), e);
272
                        }
273
                } finally {
274
                        this.resource.end();
275
                }
276
        }
277

    
278

    
279
        public DataServerExplorer getExplorer() throws ReadException {
280
                DataManager manager = DALLocator.getDataManager();
281
                FilesystemServerExplorerParameters params;
282
                try {
283
                        params = (FilesystemServerExplorerParameters) manager
284
                                .createServerExplorerParameters(FilesystemServerExplorer.NAME);
285
                        params.setRoot(this.getDGNParameters().getFile().getParent());
286
                        return manager.createServerExplorer(params);
287
                } catch (DataException e) {
288
                        throw new ReadException(this.getName(), e);
289
                } catch (ValidateDataParametersException e) {
290
                        throw new ReadException(this.getName(), e);
291
                }
292

    
293
        }
294

    
295

    
296

    
297
        public void performChanges(Iterator deleteds, Iterator inserteds, Iterator updateds, Iterator originalFeatureTypesUpdated) throws PerformEditingException {
298
                // FIXME Exception
299
                throw new UnsupportedOperationException();
300
        }
301

    
302
        public class Reader {
303
                private File file;
304
                private String fileName;
305
                private IProjection projection;
306
                private List types;
307
                private LegendBuilder leyendBuilder;
308
                private AbstractMemoryStoreProvider store;
309
                private Envelope envelope;
310

    
311
                public Reader initialice(AbstractMemoryStoreProvider store, File file,
312
                                IProjection projection,
313
                                LegendBuilder leyendBuilder) {
314
                        this.store = store;
315
                        this.file = file;
316
                        this.fileName = file.getAbsolutePath();
317
                        this.projection = projection;
318
                        this.leyendBuilder = leyendBuilder;
319
                        if (leyendBuilder != null) {
320
                                leyendBuilder.initialize(store);
321
                        }
322
                        return this;
323
                }
324

    
325
                public Envelope getEnvelope() {
326
                        return this.envelope;
327
                }
328

    
329
                public void begin(FeatureStoreProviderServices store) {
330

    
331
                        EditableFeatureType featureType = store.createFeatureType();
332

    
333
                        featureType.setHasOID(true);
334

    
335
                        ID_FIELD_ID = featureType.add(NAME_FIELD_ID, DataTypes.INT)
336
                                        .setDefaultValue(Integer.valueOf(0))
337
                                .getIndex();
338

    
339
                        // FIXME: Cual es el size y el valor por defecto para Entity ?
340
                        ID_FIELD_ENTITY = featureType.add(NAME_FIELD_ENTITY,
341
                                        DataTypes.STRING, 100)
342
                                        .setDefaultValue("")
343
                                        .getIndex();
344

    
345
                        // FIXME: Cual es el size de Layer ?
346
                        ID_FIELD_LAYER = featureType.add(NAME_FIELD_LAYER,
347
                                        DataTypes.STRING, 100)
348
                                        .setDefaultValue(
349
                                        "default").getIndex();
350

    
351
                        ID_FIELD_COLOR = featureType.add(NAME_FIELD_COLOR,
352
                                        DataTypes.INT)
353
                                        .setDefaultValue(
354
                                        Integer.valueOf(0)).getIndex();
355

    
356
                        ID_FIELD_ELEVATION = featureType.add(NAME_FIELD_ELEVATION,
357
                                        DataTypes.DOUBLE)
358
                                        .setDefaultValue(
359
                                        Double.valueOf(0)).getIndex();
360

    
361
                        ID_FIELD_THICKNESS = featureType.add(NAME_FIELD_THICKNESS,
362
                                        DataTypes.DOUBLE)
363
                                        .setDefaultValue(
364
                                        Double.valueOf(0)).getIndex();
365

    
366
                        // FIXME: Cual es el size de Text ?
367
                        ID_FIELD_TEXT = featureType.add(NAME_FIELD_TEXT,
368
                                        DataTypes.STRING, 100)
369
                                        .setDefaultValue("")
370
                                        .getIndex();
371

    
372
                        ID_FIELD_HEIGHTTEXT = featureType.add(NAME_FIELD_HEIGHTTEXT,
373
                                        DataTypes.DOUBLE).setDefaultValue(
374
                                        Double.valueOf(10)).getIndex();
375

    
376
                        ID_FIELD_ROTATIONTEXT = featureType.add(NAME_FIELD_ROTATIONTEXT,
377
                                        DataTypes.DOUBLE).setDefaultValue(
378
                                        Double.valueOf(0)).getIndex();
379

    
380

    
381
                        EditableFeatureAttributeDescriptor attr = featureType.add(
382
                                        NAME_FIELD_GEOMETRY, DataTypes.GEOMETRY);
383
                        attr.setSRS(this.projection);
384
                        attr.setGeometryType(Geometry.TYPES.GEOMETRY);
385
                        attr.setGeometrySubType(Geometry.SUBTYPES.GEOM2DZ);
386
                        ID_FIELD_GEOMETRY = attr.getIndex();
387

    
388
                        featureType.setDefaultGeometryAttributeName(NAME_FIELD_GEOMETRY);
389

    
390

    
391
                        // FIXME: Parece que el DGN puede tener mas atributos opcionales.
392
                        // Habria que ver de pillarlos ?
393

    
394
                        types = new ArrayList();
395
                        types.add(featureType);
396

    
397
                        if (leyendBuilder != null) {
398
                                leyendBuilder.begin();
399
                        }
400

    
401
                }
402

    
403
                public void end() {
404
                        if (leyendBuilder != null) {
405
                                leyendBuilder.end();
406
                        }
407
                }
408

    
409
                public List getTypes() {
410
                        return types;
411
                }
412

    
413
                public EditableFeatureType getDefaultType() {
414
                        return (EditableFeatureType) types.get(0);
415
                }
416

    
417
                private Double toDouble(String value) {
418
                        if (value == null) {
419
                                return Double.valueOf(0);
420
                        }
421
                        return Double.valueOf(value);
422
                }
423

    
424
                public void load() throws DataException {
425

    
426
                        this.envelope = null;
427

    
428
                        DGNReader dgnReader = new DGNReader(file.getAbsolutePath());
429

    
430
                        FeatureType type = getDefaultType().getNotEditableCopy();
431
                        int fTypeSize = type.size();
432
                        Object[] auxRow = new Object[fTypeSize];
433
                        Object[] cellRow = new Object[fTypeSize];
434
                        Object[] complexRow = new Object[fTypeSize];
435

    
436
                        boolean bElementoCompuesto = false;
437
                        boolean bEsPoligono = false;
438
                        boolean bInsideCell = false;
439
                        boolean bFirstHoleEntity = false;
440
                        boolean bConnect = false; // Se usa para que los pol?gonos cierren
441
                                                                                // bien cuando son formas compuestas
442
                        int contadorSubElementos = 0;
443
                        int numSubElementos = 0;
444
                        int complex_index_fill_color = -1;
445
                        int nClass; // Para filtrar los elementos de construcci?n, etc.
446
                        GeneralPathX elementoCompuesto = new GeneralPathX(
447
                                        GeneralPathX.WIND_EVEN_ODD);
448

    
449
                        for (int id = 0; id < dgnReader.getNumEntities(); id++) {
450
                                // System.out.println("Elemento " + id + " de " +
451
                                // dgnReader.getNumEntities());
452
                                dgnReader.DGNGotoElement(id);
453

    
454
                                DGNElemCore elemento = dgnReader.DGNReadElement();
455
                                nClass = 0;
456
                                auxRow[ID_FIELD_HEIGHTTEXT] = new Double(0);
457
                                auxRow[ID_FIELD_ROTATIONTEXT] = new Double(0);
458
                                auxRow[ID_FIELD_TEXT] = null;
459

    
460
                                if (elemento.properties != 0) {
461
                                        nClass = elemento.properties & DGNFileHeader.DGNPF_CLASS;
462
                                }
463

    
464
                                if ((elemento != null) && (elemento.deleted == 0)
465
                                                && (nClass == 0)) // Leer un elemento
466
                                {
467

    
468
                                        // if ((elemento.element_id > 3800) && (elemento.element_id
469
                                        // < 3850))
470
                                        // dgnReader.DGNDumpElement(dgnReader.getInfo(),elemento,"");
471
                                        if ((elemento.stype == DGNFileHeader.DGNST_MULTIPOINT)
472
                                                        || (elemento.stype == DGNFileHeader.DGNST_ARC)
473
                                                        || (elemento.stype == DGNFileHeader.DGNST_CELL_HEADER)
474
                                                        || (elemento.stype == DGNFileHeader.DGNST_SHARED_CELL_DEFN)
475
                                                        || (elemento.stype == DGNFileHeader.DGNST_COMPLEX_HEADER)) {
476
                                                if (elemento.complex != 0) {
477
                                                        bElementoCompuesto = true;
478
                                                } else {
479
                                                        if (bElementoCompuesto) {
480
                                                                if (bInsideCell) {
481
                                                                        auxRow[ID_FIELD_ENTITY] = cellRow[ID_FIELD_ENTITY];
482
                                                                } else {
483
                                                                        auxRow = complexRow;
484
                                                                }
485

    
486
                                                                // System.err.println("Entidad compuesta. bInsideCell = "
487
                                                                // + bInsideCell + " auxRow = " +
488
                                                                // auxRow[ID_FIELD_ENTITY]);
489
                                                                // addShape(new FPolyline2D(elementoCompuesto),
490
                                                                // auxRow);
491
                                                                addShape(createMultiCurve(elementoCompuesto),
492
                                                                                auxRow, type, dgnReader);
493

    
494
                                                                if (bEsPoligono) {
495
                                                                        if (complex_index_fill_color != -1) {
496
                                                                                auxRow[ID_FIELD_COLOR] = complex_index_fill_color;
497
                                                                        }
498

    
499
                                                                        addShape(
500
                                                                                        createMultiSurface(elementoCompuesto),
501
                                                                                        auxRow, type, dgnReader);
502
                                                                }
503

    
504
                                                                elementoCompuesto = new GeneralPathX(
505
                                                                                GeneralPathX.WIND_EVEN_ODD);
506
                                                        }
507

    
508
                                                        // System.err.println("Entidad simple");
509
                                                        bElementoCompuesto = false;
510
                                                        bEsPoligono = false;
511
                                                        bConnect = false;
512

    
513
                                                        // elementoCompuesto = new GeneralPathX();
514
                                                        bInsideCell = false;
515
                                                }
516
                                        }
517

    
518
                                        switch (elemento.stype) {
519
                                        case DGNFileHeader.DGNST_SHARED_CELL_DEFN:
520
                                                bInsideCell = true;
521
                                                cellRow[ID_FIELD_ID] = elemento.element_id;
522
                                                cellRow[ID_FIELD_LAYER] = String
523
                                                                .valueOf(elemento.level);
524
                                                cellRow[ID_FIELD_COLOR] = elemento.color;
525
                                                cellRow[ID_FIELD_ENTITY] = "Shared Cell";
526

    
527
                                                break;
528

    
529
                                        case DGNFileHeader.DGNST_CELL_HEADER:
530
                                                bInsideCell = true;
531

    
532
                                                DGNElemCellHeader psCellHeader = (DGNElemCellHeader) elemento;
533
                                                cellRow[ID_FIELD_ID] = elemento.element_id;
534
                                                cellRow[ID_FIELD_LAYER] = String
535
                                                                .valueOf(elemento.level);
536
                                                cellRow[ID_FIELD_COLOR] = elemento.color;
537
                                                cellRow[ID_FIELD_ENTITY] = "Cell";
538
                                                complex_index_fill_color = dgnReader
539
                                                                .DGNGetShapeFillInfo(elemento);
540

    
541
                                                // System.err.println("Cell Header " +
542
                                                // complex_index_fill_color);
543
                                                break;
544

    
545
                                        case DGNFileHeader.DGNST_COMPLEX_HEADER:
546

    
547
                                                // bElementoCompuesto = true;
548
                                                // System.err.println("Complex Header");
549
                                                contadorSubElementos = 0;
550

    
551
                                                DGNElemComplexHeader psComplexHeader = (DGNElemComplexHeader) elemento;
552
                                                numSubElementos = psComplexHeader.numelems;
553
                                                complexRow[ID_FIELD_ID] = elemento.element_id;
554
                                                complexRow[ID_FIELD_LAYER] = String
555
                                                                .valueOf(elemento.level);
556
                                                complexRow[ID_FIELD_COLOR] = elemento.color;
557
                                                complexRow[ID_FIELD_ENTITY] = "Complex";
558

    
559
                                                if (psComplexHeader.type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER) {
560
                                                        bEsPoligono = true;
561

    
562
                                                        // Si es un agujero, no conectamos con el anterior
563
                                                        if ((psComplexHeader.properties & 0x8000) != 0) {
564
                                                                bFirstHoleEntity = true;
565
                                                        } else {
566
                                                                // Miramos si tiene color de relleno
567
                                                                // complex_index_fill_color = -1;
568
                                                                // if (elemento.attr_bytes > 0) {
569
                                                                complex_index_fill_color = dgnReader
570
                                                                                .DGNGetShapeFillInfo(elemento);
571

    
572
                                                                // System.err.println("complex shape fill color = "
573
                                                                // + elemento.color);
574
                                                                // }
575
                                                        }
576

    
577
                                                        bConnect = true;
578
                                                } else {
579
                                                        bEsPoligono = false;
580
                                                        bConnect = false;
581
                                                }
582

    
583
                                                break;
584

    
585
                                        case DGNFileHeader.DGNST_MULTIPOINT:
586

    
587
                                                // OJO: Si lo que viene en este multipoint es un
588
                                                // elemento con type=11 (curve), se trata de una
589
                                                // "parametric
590
                                                // spline curve". La vamos a tratar como si no fuera
591
                                                // curva, pero seg?n la documentaci?n, los 2 primeros
592
                                                // puntos
593
                                                // y los 2 ?ltimos puntos definen "endpoint derivatives"
594
                                                // y NO se muestran.
595
                                                // TODAV?A HAY UN PEQUE?O FALLO CON EL FICHERO
596
                                                // dgn-sample.dgn, pero lo dejo por ahora.
597
                                                // Es posible que tenga que ver con lo de los arcos
598
                                                // (arco distorsionado), que
599
                                                // todav?a no est? metido.
600
                                                DGNElemMultiPoint psLine = (DGNElemMultiPoint) elemento;
601
                                                auxRow[ID_FIELD_ID] = elemento.element_id;
602
                                                auxRow[ID_FIELD_ENTITY] = "Multipoint";
603
                                                auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
604
                                                auxRow[ID_FIELD_COLOR] = elemento.color;
605

    
606
                                                if ((psLine.num_vertices == 2)
607
                                                                && (psLine.vertices[0].x == psLine.vertices[1].x)
608
                                                                && (psLine.vertices[0].y == psLine.vertices[1].y)) {
609
                                                        auxRow[ID_FIELD_ENTITY] = "Point";
610
                                                        addShape(
611
                                                                        createPoint3D(psLine.vertices[0].x,
612
                                                                                        psLine.vertices[0].y,
613
                                                                                        psLine.vertices[0].z), auxRow,
614
                                                                        type, dgnReader);
615
                                                } else {
616
                                                        GeneralPathX elShape = new GeneralPathX(
617
                                                                        GeneralPathX.WIND_EVEN_ODD);
618

    
619
                                                        if (psLine.type == DGNFileHeader.DGNT_CURVE) {
620
                                                                psLine.num_vertices = psLine.num_vertices - 4;
621

    
622
                                                                for (int aux_n = 0; aux_n < psLine.num_vertices; aux_n++) {
623
                                                                        psLine.vertices[aux_n] = psLine.vertices[aux_n + 2];
624
                                                                }
625
                                                        }
626

    
627
                                                        if ((psLine.type == DGNFileHeader.DGNT_SHAPE)
628
                                                                        && ((psLine.properties & 0x8000) != 0)) {
629
                                                                // Invertimos el orden porque es un agujero
630
                                                                elShape
631
                                                                                .moveTo(
632
                                                                                                psLine.vertices[psLine.num_vertices - 1].x,
633
                                                                                                psLine.vertices[psLine.num_vertices - 1].y);
634

    
635
                                                                for (int i = psLine.num_vertices - 2; i >= 0; i--) {
636
                                                                        elShape.lineTo(psLine.vertices[i].x,
637
                                                                                        psLine.vertices[i].y);
638
                                                                }
639
                                                        } else {
640
                                                                elShape.moveTo(psLine.vertices[0].x,
641
                                                                                psLine.vertices[0].y);
642

    
643
                                                                for (int i = 1; i < psLine.num_vertices; i++) {
644
                                                                        elShape.lineTo(psLine.vertices[i].x,
645
                                                                                        psLine.vertices[i].y);
646
                                                                }
647
                                                        }
648

    
649
                                                        if ((psLine.vertices[0].x == psLine.vertices[psLine.num_vertices - 1].x)
650
                                                                        && (psLine.vertices[0].y == psLine.vertices[psLine.num_vertices - 1].y)) {
651
                                                                // Lo a?adimos tambi?n como pol?gono
652
                                                                bEsPoligono = true;
653

    
654
                                                                // Miramos si tiene color de relleno
655
                                                                if (elemento.attr_bytes > 0) {
656
                                                                        elemento.color = dgnReader
657
                                                                                        .DGNGetShapeFillInfo(elemento);
658

    
659
                                                                        // System.err.println("fill color = " +
660
                                                                        // elemento.color);
661
                                                                        if (elemento.color != -1) {
662
                                                                                auxRow[ID_FIELD_COLOR] = elemento.color;
663
                                                                        }
664
                                                                }
665

    
666
                                                                if (elemento.complex == 0) {
667
                                                                        addShape(createSurface(elShape), auxRow,
668
                                                                                        type, dgnReader);
669
                                                                }
670
                                                        }
671

    
672
                                                        if (elemento.complex != 0) {
673
                                                                // Si es un agujero o
674
                                                                // es la primera entidad del agujero, lo
675
                                                                // a?adimos sin unir al anterior
676
                                                                if (bFirstHoleEntity
677
                                                                                || ((psLine.type == DGNFileHeader.DGNT_SHAPE) && ((psLine.properties & 0x8000) != 0))) {
678
                                                                        elementoCompuesto.append(elShape, false);
679
                                                                        bFirstHoleEntity = false;
680
                                                                } else {
681
                                                                        elementoCompuesto.append(elShape, bConnect);
682
                                                                }
683
                                                        } else {
684
                                                                addShape(createMultiCurve(elShape), auxRow,
685
                                                                                type, dgnReader);
686
                                                        }
687
                                                }
688

    
689
                                                break;
690

    
691
                                        case DGNFileHeader.DGNST_ARC:
692

    
693
                                                // dgnReader.DGNDumpElement(dgnReader.getInfo(),
694
                                                // elemento,"");
695
                                                DGNElemArc psArc = (DGNElemArc) elemento;
696

    
697
                                                // La definici?n de arco de MicroStation es distinta a
698
                                                // la de Java.
699
                                                // En el dgn el origin se entiende que es el centro del
700
                                                // arco,
701
                                                // y a la hora de crear un Arc2D las 2 primeras
702
                                                // coordenadas son
703
                                                // la esquina inferior izquierda del rect?ngulo que
704
                                                // rodea al arco.
705
                                                // 1.- Creamos la elipse sin rotaci?n.
706
                                                // 2.- Creamos el arco
707
                                                // 3.- Rotamos el resultado
708

    
709
                                                /*
710
                                                 * System.out.println("Arco con primari axis: " +
711
                                                 * psArc.primary_axis + " start angle: " +
712
                                                 * psArc.startang + " sweepang = " + psArc.sweepang);
713
                                                 * System.out.println("secondaria axis: " +
714
                                                 * psArc.secondary_axis + " rotation = " +
715
                                                 * psArc.rotation);
716
                                                 */
717
                                                AffineTransform mT = AffineTransform.getRotateInstance(
718
                                                                Math.toRadians(psArc.rotation), psArc.origin.x,
719
                                                                psArc.origin.y);
720

    
721
                                                // mT.preConcatenate(AffineTransform.getScaleInstance(100.0,100.0));
722
                                                Arc2D.Double elArco = new Arc2D.Double(psArc.origin.x
723
                                                                - psArc.primary_axis, psArc.origin.y
724
                                                                - psArc.secondary_axis,
725
                                                                2.0 * psArc.primary_axis,
726
                                                                2.0 * psArc.secondary_axis, -psArc.startang,
727
                                                                -psArc.sweepang, Arc2D.OPEN);
728

    
729
                                                // Ellipse2D.Double elArco = new
730
                                                // Ellipse2D.Double(psArc.origin.x - psArc.primary_axis,
731
                                                // psArc.origin.y - psArc.secondary_axis,2.0 *
732
                                                // psArc.primary_axis, 2.0 * psArc.secondary_axis);
733
                                                GeneralPathX elShapeArc = new GeneralPathX(elArco);
734

    
735
                                                // Transformamos el GeneralPahtX porque si transformamos
736
                                                // elArco nos lo convierte
737
                                                // a GeneralPath y nos guarda las coordenadas en float,
738
                                                // con la correspondiente p?rdida de precisi?n
739
                                                elShapeArc.transform(mT);
740

    
741
                                                if (dgnReader.getInfo().dimension == 3) {
742
                                                        // Aqu? podr?amos hacer cosas con la coordenada Z
743
                                                }
744

    
745
                                                auxRow[ID_FIELD_ID] = elemento.element_id;
746
                                                auxRow[ID_FIELD_ENTITY] = "Arc";
747
                                                auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
748
                                                auxRow[ID_FIELD_COLOR] = elemento.color;
749

    
750
                                                /*
751
                                                 * Line2D.Double ejeMayor = new
752
                                                 * Line2D.Double(psArc.origin.x - psArc.primary_axis,
753
                                                 * psArc.origin.y, psArc.origin.x + psArc.primary_axis,
754
                                                 * psArc.origin.y);
755
                                                 *
756
                                                 * lyrLines.addShape(new
757
                                                 * FShape(FConstant.SHAPE_TYPE_POLYLINE, new
758
                                                 * GeneralPathX(ejeMayor)), auxRow);
759
                                                 */
760

    
761
                                                // lyrLines.addShape(new
762
                                                // FShape(FConstant.SHAPE_TYPE_POLYLINE, elShapeArc),
763
                                                // auxRow);
764
                                                if (elemento.complex != 0) {
765
                                                        // Esto es una posible fuente de fallos si detr?s de
766
                                                        // una
767
                                                        // elipse vienen m?s cosas pegadas. Deber?amos
768
                                                        // volver
769
                                                        // a conectar una vez pasada la elipse.
770
                                                        if (elemento.type == DGNFileHeader.DGNT_ELLIPSE) {
771
                                                                bConnect = false;
772
                                                        }
773

    
774
                                                        // SI LA ELIPSE ES UN AGUJERO, SE A?ADE SIN PEGAR
775
                                                        // Y EL ELEMENTO ES UN POLIGONO
776
                                                        if (bFirstHoleEntity
777
                                                                        || ((elemento.type == DGNFileHeader.DGNT_SHAPE) && ((elemento.properties & 0x8000) != 0))) {
778
                                                                elementoCompuesto.append(elShapeArc, false);
779
                                                                bFirstHoleEntity = false;
780
                                                        } else {
781
                                                                elementoCompuesto.append(elShapeArc, bConnect);
782
                                                        }
783
                                                } else {
784
                                                        addShape(createMultiCurve(elShapeArc), auxRow,
785
                                                                        type, dgnReader);
786

    
787
                                                        if (psArc.type == DGNFileHeader.DGNT_ELLIPSE) {
788
                                                                addShape(createSurface(elShapeArc), auxRow,
789
                                                                                type, dgnReader);
790
                                                        }
791
                                                }
792

    
793
                                                // System.err.println("Entra un Arco");
794
                                                break;
795

    
796
                                        case DGNFileHeader.DGNST_TEXT:
797

    
798
                                                DGNElemText psText = (DGNElemText) elemento;
799
                                                Geometry elShapeTxt = createPoint3D(psText.origin.x,
800
                                                                psText.origin.y, psText.origin.z);
801

    
802
                                                auxRow[ID_FIELD_ID] = elemento.element_id;
803
                                                auxRow[ID_FIELD_ENTITY] = "Text";
804
                                                auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
805
                                                auxRow[ID_FIELD_COLOR] = elemento.color;
806
                                                auxRow[ID_FIELD_HEIGHTTEXT] = psText.height_mult;
807
                                                auxRow[ID_FIELD_ROTATIONTEXT] = psText.rotation;
808
                                                auxRow[ID_FIELD_TEXT] = psText.string; // .trim();
809
                                                addShape(elShapeTxt, auxRow, type, dgnReader);
810

    
811
                                                // System.out.println("Rotaci?n texto: " +
812
                                                // psText.rotation + "Altura Texto = " + heightText);
813

    
814
                                                /*
815
                                                 * System.out.println("  origin=(" + psText.origin.x +
816
                                                 * ", " + psText.origin.y + ") rotation=" +
817
                                                 * psText.rotation + "\n" + "  font=" + psText.font_id +
818
                                                 * " just=" + psText.justification + "length_mult=" +
819
                                                 * psText.length_mult + " height_mult=" +
820
                                                 * psText.height_mult + "\n" + "  string =" + new
821
                                                 * String(psText.string).toString().trim() + "\n");
822
                                                 */
823
                                                break;
824

    
825
                                        /*
826
                                         * default:
827
                                         * dgnReader.DGNDumpElement(dgnReader.getInfo(),
828
                                         * elemento, "");
829
                                         */
830
                                        } // switch
831
                                } // if
832
                        } // for
833

    
834
                        if (bElementoCompuesto) {
835
                                if (bInsideCell) {
836
                                        auxRow = cellRow;
837
                                } else {
838
                                        auxRow = complexRow;
839
                                }
840

    
841
                                // System.err.println("Entidad compuesta. bInsideCell = " +
842
                                // bInsideCell + " auxRow = " + auxRow[ID_FIELD_ENTITY]);
843
                                addShape(createMultiCurve(elementoCompuesto), auxRow, type,
844
                                                dgnReader);
845

    
846
                                if (bEsPoligono) {
847
                                        if (complex_index_fill_color != -1) {
848
                                                auxRow[ID_FIELD_COLOR] = complex_index_fill_color;
849
                                        }
850

    
851
                                        addShape(createSurface(elementoCompuesto), auxRow, type,
852
                                                        dgnReader);
853
                                }
854
                        }
855

    
856
                }
857

    
858
                private Geometry createMultiSurface(GeneralPathX elementoCompuesto)
859
                                throws DataException {
860
                        try {
861
                                return geomManager.createMultiSurface(elementoCompuesto,
862
                                                SUBTYPES.GEOM2D);
863
                        } catch (CreateGeometryException e) {
864
                                throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(
865
                                                e);
866
                        }
867

    
868
                }
869

    
870
                private Geometry createPoint3D(double x, double y, double z)
871
                                throws DataException {
872
                        Point point;
873
                        try {
874
                                // point = (Point) geomManager.create(TYPES.POINT,
875
                                // SUBTYPES.GEOM3D);
876
                                point = (Point) geomManager.create(TYPES.POINT,
877
                                                SUBTYPES.GEOM2DZ);
878
                        } catch (CreateGeometryException e) {
879
                                throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(
880
                                                e);
881
                        }
882
                        point.setCoordinates(new double[] { x, y, z });
883

    
884
                        return point;
885
                }
886

    
887
                private void addShape(Geometry geometry, Object[] auxRow,
888
                                FeatureType type, DGNReader dgnReader) throws DataException {
889
                        FeatureProvider data = createFeatureProvider(type);
890
                        for (int i=0;i<type.size();i++){
891
                                data.set(i, auxRow[i]);
892
                        }
893
                        data.setDefaultGeometry(geometry);
894
                        addFeatureProvider(data);
895
                        if (this.envelope == null) {
896
                                this.envelope = geometry.getEnvelope();
897
                        } else {
898
                                this.envelope.add(geometry.getEnvelope());
899
                        }
900
                        if (this.leyendBuilder != null) {
901
                                this.leyendBuilder.process(data, dgnReader);
902
                        }
903
                }
904

    
905
                private Geometry createMultiCurve(GeneralPathX elementoCompuesto)
906
                                throws DataException {
907
                        try {
908
                                return geomManager.createMultiCurve(elementoCompuesto,
909
                                                SUBTYPES.GEOM2D);
910
                        } catch (CreateGeometryException e) {
911
                                throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(
912
                                                e);
913
                        }
914
                }
915

    
916
                private Geometry createSurface(GeneralPathX elementoCompuesto)
917
                                throws DataException {
918
                        try {
919
                                return geomManager.createCurve(elementoCompuesto,
920
                                                SUBTYPES.GEOM2D);
921
                        } catch (CreateGeometryException e) {
922
                                throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(
923
                                                e);
924
                        }
925

    
926
                }
927

    
928
        }
929

    
930
        public boolean closeResourceRequested(ResourceProvider resource) {
931
                return true;
932
        }
933

    
934
        public int getOIDType() {
935
                return DataTypes.LONG;
936
        }
937

    
938
        public boolean supportsAppendMode() {
939
                return false;
940
        }
941

    
942
        public void append(FeatureProvider featureProvider) {
943
                // FIXME Exception
944
                throw new UnsupportedOperationException();
945
        }
946

    
947
        public void beginAppend() {
948
                // FIXME Exception
949
                throw new UnsupportedOperationException();
950
        }
951

    
952
        public void endAppend() {
953
                // FIXME Exception
954
                throw new UnsupportedOperationException();
955
        }
956

    
957
        public void saveToState(PersistentState state) throws PersistenceException {
958
                // TODO Auto-generated method stub
959
                throw new NotYetImplemented();
960
        }
961

    
962
        public void loadFromState(PersistentState state) throws PersistenceException {
963
                // TODO Auto-generated method stub
964
                throw new NotYetImplemented();
965
        }
966

    
967
        public Object createNewOID() {
968
                return new Long(counterNewsOIDs++);
969
        }
970

    
971
        protected void initializeFeatureTypes() throws InitializeException {
972
                try {
973
                        this.open();
974
                } catch (OpenException e) {
975
                        throw new InitializeException(this.getName(), e);
976
                }
977
        }
978

    
979
        public Envelope getEnvelope() throws DataException {
980
                this.open();
981
                return (Envelope) this.getDynValue("Envelope");
982
        }
983

    
984

    
985
        /*
986
         * (non-Javadoc)
987
         *
988
         * @see
989
         * org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
990
         * gvsig.fmap.dal.resource.spi.ResourceProvider)
991
         */
992
        public void resourceChanged(ResourceProvider resource) {
993
                this.getStoreServices().notifyChange(
994
                                DataStoreNotification.RESOURCE_CHANGED,
995
                                resource);
996
        }
997

    
998
        protected static void registerDynClass() {
999
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
1000
                DynClass dynClass;
1001
                DynField field;
1002
                if (DYNCLASS == null) {
1003
                        dynClass = dynman.add(DYNCLASS_NAME, "DGN File Store");
1004
                        dynClass.extend(dynman.get(FeatureStore.DYNCLASS_NAME));
1005

    
1006
                        DYNCLASS = dynClass;
1007
                }
1008

    
1009
        }
1010

    
1011
        public Object getSourceId() {
1012
                return this.getDGNParameters().getFile();
1013
        }
1014

    
1015
}