Statistics
| Revision:

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

History | View | Annotate | Download (31.1 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.FeatureStoreProvider;
30
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
31
import org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider;
32
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
33
import org.gvsig.fmap.dal.resource.exception.ResourceBeginException;
34
import org.gvsig.fmap.dal.resource.file.FileResource;
35
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
36
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
37
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
38
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
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.DelegatedDynObject;
59
import org.gvsig.tools.dynobject.DynClass;
60
import org.gvsig.tools.dynobject.DynField;
61
import org.gvsig.tools.dynobject.DynObjectManager;
62
import org.gvsig.tools.dynobject.exception.DynMethodException;
63
import org.gvsig.tools.exception.NotYetImplemented;
64
import org.gvsig.tools.persistence.PersistenceException;
65
import org.gvsig.tools.persistence.PersistentState;
66
import org.slf4j.Logger;
67
import org.slf4j.LoggerFactory;
68

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

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

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

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

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

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

    
107

    
108

    
109
        private DGNStoreParameters getDGNParameters() {
110
                return (DGNStoreParameters) this.parameters;
111
        }
112

    
113
        public DGNStoreProvider(DGNStoreParameters parameters) {
114
                super(parameters);
115
        }
116

    
117
        public FeatureStoreProvider initialize(FeatureStoreProviderServices store)
118
                        throws InitializeException {
119
                super.initialize(store);
120

    
121
                this.metadata = (DelegatedDynObject) ToolsLocator
122
                                .getDynObjectManager().createDynObject(DYNCLASS);
123

    
124
                counterNewsOIDs = 0;
125
                //                projection = CRSFactory.getCRS(getParameters().getSRSID());
126

    
127
                File file = getDGNParameters().getFile();
128
                resource = this.createResource(
129
                                FileResource.NAME,
130
                                new Object[] { file.getAbsolutePath() }
131
                        );
132

    
133
                resource.addConsumer(this);
134

    
135
                this.projection = this.getDGNParameters().getSRS();
136

    
137

    
138
                try {
139
                        legendBuilder = (LegendBuilder) this.invokeDynMethod(
140
                                        LegendBuilder.DYNMETHOD_BUILDER_NAME, null);
141
                } catch (DynMethodException e) {
142
                        legendBuilder = null;
143
                } catch (Exception e) {
144
                        throw new InitializeException(e);
145
                }
146

    
147
                this.initializeFeatureTypes();
148
                return this;
149
        }
150

    
151
        public String getName() {
152
                return NAME;
153
        }
154

    
155
        public boolean allowWrite() {
156
                return true;
157
        }
158

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

    
167
        public Object getLabeling() throws OpenException {
168
                this.open();
169
                if (legendBuilder == null) {
170
                        return null;
171
                }
172
                return legendBuilder.getLabeling();
173
        }
174

    
175
        private class DGNData {
176
                public ArrayList data = null;
177
                public FeatureType defaultFType = null;
178
                public List fTypes = null;
179
                public Envelope envelope = null;
180
                public IProjection projection;
181
                public LegendBuilder legendBuilder;
182
                public Envelope getEnvelopeCopy() throws CreateEnvelopeException {
183
                        if (envelope == null) {
184
                                return null;
185
                        }
186
                        Envelope newEnvelope;
187
                        if (envelope.getDimension() == 2) {
188
                                newEnvelope = geomManager.createEnvelope(SUBTYPES.GEOM2D);
189
                        } else {
190
                                newEnvelope = geomManager.createEnvelope(SUBTYPES.GEOM3D);
191

    
192
                        }
193
                        newEnvelope.setLowerCorner(envelope.getLowerCorner());
194
                        newEnvelope.setUpperCorner(envelope.getUpperCorner());
195
                        return newEnvelope;
196
                }
197
        }
198

    
199
        public void open() throws OpenException {
200
                if (this.data != null) {
201
                        return;
202
                }
203
                try {
204
                        this.resource.begin();
205
                } catch (ResourceBeginException e2) {
206
                        try {
207
                                throw new OpenException(resource.getName(), e2);
208
                        } catch (AccessResourceException e1) {
209
                                throw new OpenException(this.getName(), e2);
210
                        }
211

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

    
250
                                resource.notifyOpen();
251
                                this.store
252
                                                .setFeatureTypes(DGNData.fTypes, DGNData.defaultFType);
253
                                reader.load();
254
                                //                                this.envelope = reader.getEnvelope();
255

    
256
                                DGNData.envelope = reader.getEnvelope();
257

    
258
                                DGNData.legendBuilder = this.legendBuilder;
259

    
260
                                DGNData.projection = this.projection;
261

    
262
                                reader.end();
263
                                resource.notifyClose();
264
                                ((Map) this.resource.getData()).put(this.projection.getAbrev(),
265
                                                DGNData); // OJO la reproyeccion
266
                        }
267

    
268
                        this.data = DGNData.data;
269
                        this.store.setFeatureTypes(DGNData.fTypes, DGNData.defaultFType);
270
                        this.legendBuilder = DGNData.legendBuilder;
271
                        this.metadata.setDynValue("Envelope", DGNData.getEnvelopeCopy());
272
                        this.metadata
273
                                        .setDynValue("DefaultSRS", this.projection.getAbrev());
274
                        this.counterNewsOIDs = this.data.size();
275
                } catch (Exception e) {
276
                        this.data = null;
277
                        try {
278
                                throw new OpenException(resource.getName(), e);
279
                        } catch (AccessResourceException e1) {
280
                                throw new OpenException(this.getName(), e);
281
                        }
282
                } finally {
283
                        this.resource.end();
284
                }
285
        }
286

    
287

    
288
        public DataServerExplorer getExplorer() throws ReadException {
289
                DataManager manager = DALLocator.getDataManager();
290
                FilesystemServerExplorerParameters params;
291
                try {
292
                        params = (FilesystemServerExplorerParameters) manager
293
                                .createServerExplorerParameters(FilesystemServerExplorer.NAME);
294
                        params.setRoot(this.getDGNParameters().getFile().getParent());
295
                        return manager.createServerExplorer(params);
296
                } catch (DataException e) {
297
                        throw new ReadException(this.getName(), e);
298
                } catch (ValidateDataParametersException e) {
299
                        throw new ReadException(this.getName(), e);
300
                }
301

    
302
        }
303

    
304

    
305

    
306
        public void performChanges(Iterator deleteds, Iterator inserteds, Iterator updateds, Iterator originalFeatureTypesUpdated) throws PerformEditingException {
307
                // FIXME Exception
308
                throw new UnsupportedOperationException();
309
        }
310

    
311
        public class Reader {
312
                private File file;
313
                private String fileName;
314
                private IProjection projection;
315
                private List types;
316
                private LegendBuilder leyendBuilder;
317
                private AbstractMemoryStoreProvider store;
318
                private Envelope envelope;
319

    
320
                public Reader initialice(AbstractMemoryStoreProvider store, File file,
321
                                IProjection projection,
322
                                LegendBuilder leyendBuilder) {
323
                        this.store = store;
324
                        this.file = file;
325
                        this.fileName = file.getAbsolutePath();
326
                        this.projection = projection;
327
                        this.leyendBuilder = leyendBuilder;
328
                        if (leyendBuilder != null) {
329
                                leyendBuilder.initialize(store);
330
                        }
331
                        return this;
332
                }
333

    
334
                public Envelope getEnvelope() {
335
                        return this.envelope;
336
                }
337

    
338
                public void begin(FeatureStoreProviderServices store) {
339

    
340
                        EditableFeatureType featureType = store.createFeatureType();
341

    
342
                        featureType.setHasOID(true);
343

    
344
                        ID_FIELD_ID = featureType.add(NAME_FIELD_ID, DataTypes.INT)
345
                                        .setDefaultValue(Integer.valueOf(0))
346
                                .getIndex();
347

    
348
                        // FIXME: Cual es el size y el valor por defecto para Entity ?
349
                        ID_FIELD_ENTITY = featureType.add(NAME_FIELD_ENTITY,
350
                                        DataTypes.STRING, 100)
351
                                        .setDefaultValue("")
352
                                        .getIndex();
353

    
354
                        // FIXME: Cual es el size de Layer ?
355
                        ID_FIELD_LAYER = featureType.add(NAME_FIELD_LAYER,
356
                                        DataTypes.STRING, 100)
357
                                        .setDefaultValue(
358
                                        "default").getIndex();
359

    
360
                        ID_FIELD_COLOR = featureType.add(NAME_FIELD_COLOR,
361
                                        DataTypes.INT)
362
                                        .setDefaultValue(
363
                                        Integer.valueOf(0)).getIndex();
364

    
365
                        ID_FIELD_ELEVATION = featureType.add(NAME_FIELD_ELEVATION,
366
                                        DataTypes.DOUBLE)
367
                                        .setDefaultValue(
368
                                        Double.valueOf(0)).getIndex();
369

    
370
                        ID_FIELD_THICKNESS = featureType.add(NAME_FIELD_THICKNESS,
371
                                        DataTypes.DOUBLE)
372
                                        .setDefaultValue(
373
                                        Double.valueOf(0)).getIndex();
374

    
375
                        // FIXME: Cual es el size de Text ?
376
                        ID_FIELD_TEXT = featureType.add(NAME_FIELD_TEXT,
377
                                        DataTypes.STRING, 100)
378
                                        .setDefaultValue("")
379
                                        .getIndex();
380

    
381
                        ID_FIELD_HEIGHTTEXT = featureType.add(NAME_FIELD_HEIGHTTEXT,
382
                                        DataTypes.DOUBLE).setDefaultValue(
383
                                        Double.valueOf(10)).getIndex();
384

    
385
                        ID_FIELD_ROTATIONTEXT = featureType.add(NAME_FIELD_ROTATIONTEXT,
386
                                        DataTypes.DOUBLE).setDefaultValue(
387
                                        Double.valueOf(0)).getIndex();
388

    
389

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

    
397
                        featureType.setDefaultGeometryAttributeName(NAME_FIELD_GEOMETRY);
398

    
399

    
400
                        // FIXME: Parece que el DGN puede tener mas atributos opcionales.
401
                        // Habria que ver de pillarlos ?
402

    
403
                        types = new ArrayList();
404
                        types.add(featureType);
405

    
406
                        if (leyendBuilder != null) {
407
                                leyendBuilder.begin();
408
                        }
409

    
410
                }
411

    
412
                public void end() {
413
                        if (leyendBuilder != null) {
414
                                leyendBuilder.end();
415
                        }
416
                }
417

    
418
                public List getTypes() {
419
                        return types;
420
                }
421

    
422
                public EditableFeatureType getDefaultType() {
423
                        return (EditableFeatureType) types.get(0);
424
                }
425

    
426
                private Double toDouble(String value) {
427
                        if (value == null) {
428
                                return Double.valueOf(0);
429
                        }
430
                        return Double.valueOf(value);
431
                }
432

    
433
                public void load() throws DataException {
434

    
435
                        this.envelope = null;
436

    
437
                        DGNReader dgnReader = new DGNReader(file.getAbsolutePath());
438

    
439
                        FeatureType type = getDefaultType().getNotEditableCopy();
440
                        int fTypeSize = type.size();
441
                        Object[] auxRow = new Object[fTypeSize];
442
                        Object[] cellRow = new Object[fTypeSize];
443
                        Object[] complexRow = new Object[fTypeSize];
444

    
445
                        boolean bElementoCompuesto = false;
446
                        boolean bEsPoligono = false;
447
                        boolean bInsideCell = false;
448
                        boolean bFirstHoleEntity = false;
449
                        boolean bConnect = false; // Se usa para que los pol?gonos cierren
450
                                                                                // bien cuando son formas compuestas
451
                        int contadorSubElementos = 0;
452
                        int numSubElementos = 0;
453
                        int complex_index_fill_color = -1;
454
                        int nClass; // Para filtrar los elementos de construcci?n, etc.
455
                        GeneralPathX elementoCompuesto = new GeneralPathX(
456
                                        GeneralPathX.WIND_EVEN_ODD);
457

    
458
                        for (int id = 0; id < dgnReader.getNumEntities(); id++) {
459
                                // System.out.println("Elemento " + id + " de " +
460
                                // dgnReader.getNumEntities());
461
                                dgnReader.DGNGotoElement(id);
462

    
463
                                DGNElemCore elemento = dgnReader.DGNReadElement();
464
                                nClass = 0;
465
                                auxRow[ID_FIELD_HEIGHTTEXT] = new Double(0);
466
                                auxRow[ID_FIELD_ROTATIONTEXT] = new Double(0);
467
                                auxRow[ID_FIELD_TEXT] = null;
468

    
469
                                if (elemento.properties != 0) {
470
                                        nClass = elemento.properties & DGNFileHeader.DGNPF_CLASS;
471
                                }
472

    
473
                                if ((elemento != null) && (elemento.deleted == 0)
474
                                                && (nClass == 0)) // Leer un elemento
475
                                {
476

    
477
                                        // if ((elemento.element_id > 3800) && (elemento.element_id
478
                                        // < 3850))
479
                                        // dgnReader.DGNDumpElement(dgnReader.getInfo(),elemento,"");
480
                                        if ((elemento.stype == DGNFileHeader.DGNST_MULTIPOINT)
481
                                                        || (elemento.stype == DGNFileHeader.DGNST_ARC)
482
                                                        || (elemento.stype == DGNFileHeader.DGNST_CELL_HEADER)
483
                                                        || (elemento.stype == DGNFileHeader.DGNST_SHARED_CELL_DEFN)
484
                                                        || (elemento.stype == DGNFileHeader.DGNST_COMPLEX_HEADER)) {
485
                                                if (elemento.complex != 0) {
486
                                                        bElementoCompuesto = true;
487
                                                } else {
488
                                                        if (bElementoCompuesto) {
489
                                                                if (bInsideCell) {
490
                                                                        auxRow[ID_FIELD_ENTITY] = cellRow[ID_FIELD_ENTITY];
491
                                                                } else {
492
                                                                        auxRow = complexRow;
493
                                                                }
494

    
495
                                                                // System.err.println("Entidad compuesta. bInsideCell = "
496
                                                                // + bInsideCell + " auxRow = " +
497
                                                                // auxRow[ID_FIELD_ENTITY]);
498
                                                                // addShape(new FPolyline2D(elementoCompuesto),
499
                                                                // auxRow);
500
                                                                addShape(createMultiCurve(elementoCompuesto),
501
                                                                                auxRow, type, dgnReader);
502

    
503
                                                                if (bEsPoligono) {
504
                                                                        if (complex_index_fill_color != -1) {
505
                                                                                auxRow[ID_FIELD_COLOR] = complex_index_fill_color;
506
                                                                        }
507

    
508
                                                                        addShape(
509
                                                                                        createMultiSurface(elementoCompuesto),
510
                                                                                        auxRow, type, dgnReader);
511
                                                                }
512

    
513
                                                                elementoCompuesto = new GeneralPathX(
514
                                                                                GeneralPathX.WIND_EVEN_ODD);
515
                                                        }
516

    
517
                                                        // System.err.println("Entidad simple");
518
                                                        bElementoCompuesto = false;
519
                                                        bEsPoligono = false;
520
                                                        bConnect = false;
521

    
522
                                                        // elementoCompuesto = new GeneralPathX();
523
                                                        bInsideCell = false;
524
                                                }
525
                                        }
526

    
527
                                        switch (elemento.stype) {
528
                                        case DGNFileHeader.DGNST_SHARED_CELL_DEFN:
529
                                                bInsideCell = true;
530
                                                cellRow[ID_FIELD_ID] = elemento.element_id;
531
                                                cellRow[ID_FIELD_LAYER] = String
532
                                                                .valueOf(elemento.level);
533
                                                cellRow[ID_FIELD_COLOR] = elemento.color;
534
                                                cellRow[ID_FIELD_ENTITY] = "Shared Cell";
535

    
536
                                                break;
537

    
538
                                        case DGNFileHeader.DGNST_CELL_HEADER:
539
                                                bInsideCell = true;
540

    
541
                                                DGNElemCellHeader psCellHeader = (DGNElemCellHeader) elemento;
542
                                                cellRow[ID_FIELD_ID] = elemento.element_id;
543
                                                cellRow[ID_FIELD_LAYER] = String
544
                                                                .valueOf(elemento.level);
545
                                                cellRow[ID_FIELD_COLOR] = elemento.color;
546
                                                cellRow[ID_FIELD_ENTITY] = "Cell";
547
                                                complex_index_fill_color = dgnReader
548
                                                                .DGNGetShapeFillInfo(elemento);
549

    
550
                                                // System.err.println("Cell Header " +
551
                                                // complex_index_fill_color);
552
                                                break;
553

    
554
                                        case DGNFileHeader.DGNST_COMPLEX_HEADER:
555

    
556
                                                // bElementoCompuesto = true;
557
                                                // System.err.println("Complex Header");
558
                                                contadorSubElementos = 0;
559

    
560
                                                DGNElemComplexHeader psComplexHeader = (DGNElemComplexHeader) elemento;
561
                                                numSubElementos = psComplexHeader.numelems;
562
                                                complexRow[ID_FIELD_ID] = elemento.element_id;
563
                                                complexRow[ID_FIELD_LAYER] = String
564
                                                                .valueOf(elemento.level);
565
                                                complexRow[ID_FIELD_COLOR] = elemento.color;
566
                                                complexRow[ID_FIELD_ENTITY] = "Complex";
567

    
568
                                                if (psComplexHeader.type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER) {
569
                                                        bEsPoligono = true;
570

    
571
                                                        // Si es un agujero, no conectamos con el anterior
572
                                                        if ((psComplexHeader.properties & 0x8000) != 0) {
573
                                                                bFirstHoleEntity = true;
574
                                                        } else {
575
                                                                // Miramos si tiene color de relleno
576
                                                                // complex_index_fill_color = -1;
577
                                                                // if (elemento.attr_bytes > 0) {
578
                                                                complex_index_fill_color = dgnReader
579
                                                                                .DGNGetShapeFillInfo(elemento);
580

    
581
                                                                // System.err.println("complex shape fill color = "
582
                                                                // + elemento.color);
583
                                                                // }
584
                                                        }
585

    
586
                                                        bConnect = true;
587
                                                } else {
588
                                                        bEsPoligono = false;
589
                                                        bConnect = false;
590
                                                }
591

    
592
                                                break;
593

    
594
                                        case DGNFileHeader.DGNST_MULTIPOINT:
595

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

    
615
                                                if ((psLine.num_vertices == 2)
616
                                                                && (psLine.vertices[0].x == psLine.vertices[1].x)
617
                                                                && (psLine.vertices[0].y == psLine.vertices[1].y)) {
618
                                                        auxRow[ID_FIELD_ENTITY] = "Point";
619
                                                        addShape(
620
                                                                        createPoint3D(psLine.vertices[0].x,
621
                                                                                        psLine.vertices[0].y,
622
                                                                                        psLine.vertices[0].z), auxRow,
623
                                                                        type, dgnReader);
624
                                                } else {
625
                                                        GeneralPathX elShape = new GeneralPathX(
626
                                                                        GeneralPathX.WIND_EVEN_ODD);
627

    
628
                                                        if (psLine.type == DGNFileHeader.DGNT_CURVE) {
629
                                                                psLine.num_vertices = psLine.num_vertices - 4;
630

    
631
                                                                for (int aux_n = 0; aux_n < psLine.num_vertices; aux_n++) {
632
                                                                        psLine.vertices[aux_n] = psLine.vertices[aux_n + 2];
633
                                                                }
634
                                                        }
635

    
636
                                                        if ((psLine.type == DGNFileHeader.DGNT_SHAPE)
637
                                                                        && ((psLine.properties & 0x8000) != 0)) {
638
                                                                // Invertimos el orden porque es un agujero
639
                                                                elShape
640
                                                                                .moveTo(
641
                                                                                                psLine.vertices[psLine.num_vertices - 1].x,
642
                                                                                                psLine.vertices[psLine.num_vertices - 1].y);
643

    
644
                                                                for (int i = psLine.num_vertices - 2; i >= 0; i--) {
645
                                                                        elShape.lineTo(psLine.vertices[i].x,
646
                                                                                        psLine.vertices[i].y);
647
                                                                }
648
                                                        } else {
649
                                                                elShape.moveTo(psLine.vertices[0].x,
650
                                                                                psLine.vertices[0].y);
651

    
652
                                                                for (int i = 1; i < psLine.num_vertices; i++) {
653
                                                                        elShape.lineTo(psLine.vertices[i].x,
654
                                                                                        psLine.vertices[i].y);
655
                                                                }
656
                                                        }
657

    
658
                                                        if ((psLine.vertices[0].x == psLine.vertices[psLine.num_vertices - 1].x)
659
                                                                        && (psLine.vertices[0].y == psLine.vertices[psLine.num_vertices - 1].y)) {
660
                                                                // Lo a?adimos tambi?n como pol?gono
661
                                                                bEsPoligono = true;
662

    
663
                                                                // Miramos si tiene color de relleno
664
                                                                if (elemento.attr_bytes > 0) {
665
                                                                        elemento.color = dgnReader
666
                                                                                        .DGNGetShapeFillInfo(elemento);
667

    
668
                                                                        // System.err.println("fill color = " +
669
                                                                        // elemento.color);
670
                                                                        if (elemento.color != -1) {
671
                                                                                auxRow[ID_FIELD_COLOR] = elemento.color;
672
                                                                        }
673
                                                                }
674

    
675
                                                                if (elemento.complex == 0) {
676
                                                                        addShape(createSurface(elShape), auxRow,
677
                                                                                        type, dgnReader);
678
                                                                }
679
                                                        }
680

    
681
                                                        if (elemento.complex != 0) {
682
                                                                // Si es un agujero o
683
                                                                // es la primera entidad del agujero, lo
684
                                                                // a?adimos sin unir al anterior
685
                                                                if (bFirstHoleEntity
686
                                                                                || ((psLine.type == DGNFileHeader.DGNT_SHAPE) && ((psLine.properties & 0x8000) != 0))) {
687
                                                                        elementoCompuesto.append(elShape, false);
688
                                                                        bFirstHoleEntity = false;
689
                                                                } else {
690
                                                                        elementoCompuesto.append(elShape, bConnect);
691
                                                                }
692
                                                        } else {
693
                                                                addShape(createMultiCurve(elShape), auxRow,
694
                                                                                type, dgnReader);
695
                                                        }
696
                                                }
697

    
698
                                                break;
699

    
700
                                        case DGNFileHeader.DGNST_ARC:
701

    
702
                                                // dgnReader.DGNDumpElement(dgnReader.getInfo(),
703
                                                // elemento,"");
704
                                                DGNElemArc psArc = (DGNElemArc) elemento;
705

    
706
                                                // La definici?n de arco de MicroStation es distinta a
707
                                                // la de Java.
708
                                                // En el dgn el origin se entiende que es el centro del
709
                                                // arco,
710
                                                // y a la hora de crear un Arc2D las 2 primeras
711
                                                // coordenadas son
712
                                                // la esquina inferior izquierda del rect?ngulo que
713
                                                // rodea al arco.
714
                                                // 1.- Creamos la elipse sin rotaci?n.
715
                                                // 2.- Creamos el arco
716
                                                // 3.- Rotamos el resultado
717

    
718
                                                /*
719
                                                 * System.out.println("Arco con primari axis: " +
720
                                                 * psArc.primary_axis + " start angle: " +
721
                                                 * psArc.startang + " sweepang = " + psArc.sweepang);
722
                                                 * System.out.println("secondaria axis: " +
723
                                                 * psArc.secondary_axis + " rotation = " +
724
                                                 * psArc.rotation);
725
                                                 */
726
                                                AffineTransform mT = AffineTransform.getRotateInstance(
727
                                                                Math.toRadians(psArc.rotation), psArc.origin.x,
728
                                                                psArc.origin.y);
729

    
730
                                                // mT.preConcatenate(AffineTransform.getScaleInstance(100.0,100.0));
731
                                                Arc2D.Double elArco = new Arc2D.Double(psArc.origin.x
732
                                                                - psArc.primary_axis, psArc.origin.y
733
                                                                - psArc.secondary_axis,
734
                                                                2.0 * psArc.primary_axis,
735
                                                                2.0 * psArc.secondary_axis, -psArc.startang,
736
                                                                -psArc.sweepang, Arc2D.OPEN);
737

    
738
                                                // Ellipse2D.Double elArco = new
739
                                                // Ellipse2D.Double(psArc.origin.x - psArc.primary_axis,
740
                                                // psArc.origin.y - psArc.secondary_axis,2.0 *
741
                                                // psArc.primary_axis, 2.0 * psArc.secondary_axis);
742
                                                GeneralPathX elShapeArc = new GeneralPathX(elArco);
743

    
744
                                                // Transformamos el GeneralPahtX porque si transformamos
745
                                                // elArco nos lo convierte
746
                                                // a GeneralPath y nos guarda las coordenadas en float,
747
                                                // con la correspondiente p?rdida de precisi?n
748
                                                elShapeArc.transform(mT);
749

    
750
                                                if (dgnReader.getInfo().dimension == 3) {
751
                                                        // Aqu? podr?amos hacer cosas con la coordenada Z
752
                                                }
753

    
754
                                                auxRow[ID_FIELD_ID] = elemento.element_id;
755
                                                auxRow[ID_FIELD_ENTITY] = "Arc";
756
                                                auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
757
                                                auxRow[ID_FIELD_COLOR] = elemento.color;
758

    
759
                                                /*
760
                                                 * Line2D.Double ejeMayor = new
761
                                                 * Line2D.Double(psArc.origin.x - psArc.primary_axis,
762
                                                 * psArc.origin.y, psArc.origin.x + psArc.primary_axis,
763
                                                 * psArc.origin.y);
764
                                                 *
765
                                                 * lyrLines.addShape(new
766
                                                 * FShape(FConstant.SHAPE_TYPE_POLYLINE, new
767
                                                 * GeneralPathX(ejeMayor)), auxRow);
768
                                                 */
769

    
770
                                                // lyrLines.addShape(new
771
                                                // FShape(FConstant.SHAPE_TYPE_POLYLINE, elShapeArc),
772
                                                // auxRow);
773
                                                if (elemento.complex != 0) {
774
                                                        // Esto es una posible fuente de fallos si detr?s de
775
                                                        // una
776
                                                        // elipse vienen m?s cosas pegadas. Deber?amos
777
                                                        // volver
778
                                                        // a conectar una vez pasada la elipse.
779
                                                        if (elemento.type == DGNFileHeader.DGNT_ELLIPSE) {
780
                                                                bConnect = false;
781
                                                        }
782

    
783
                                                        // SI LA ELIPSE ES UN AGUJERO, SE A?ADE SIN PEGAR
784
                                                        // Y EL ELEMENTO ES UN POLIGONO
785
                                                        if (bFirstHoleEntity
786
                                                                        || ((elemento.type == DGNFileHeader.DGNT_SHAPE) && ((elemento.properties & 0x8000) != 0))) {
787
                                                                elementoCompuesto.append(elShapeArc, false);
788
                                                                bFirstHoleEntity = false;
789
                                                        } else {
790
                                                                elementoCompuesto.append(elShapeArc, bConnect);
791
                                                        }
792
                                                } else {
793
                                                        addShape(createMultiCurve(elShapeArc), auxRow,
794
                                                                        type, dgnReader);
795

    
796
                                                        if (psArc.type == DGNFileHeader.DGNT_ELLIPSE) {
797
                                                                addShape(createSurface(elShapeArc), auxRow,
798
                                                                                type, dgnReader);
799
                                                        }
800
                                                }
801

    
802
                                                // System.err.println("Entra un Arco");
803
                                                break;
804

    
805
                                        case DGNFileHeader.DGNST_TEXT:
806

    
807
                                                DGNElemText psText = (DGNElemText) elemento;
808
                                                Geometry elShapeTxt = createPoint3D(psText.origin.x,
809
                                                                psText.origin.y, psText.origin.z);
810

    
811
                                                auxRow[ID_FIELD_ID] = elemento.element_id;
812
                                                auxRow[ID_FIELD_ENTITY] = "Text";
813
                                                auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
814
                                                auxRow[ID_FIELD_COLOR] = elemento.color;
815
                                                auxRow[ID_FIELD_HEIGHTTEXT] = psText.height_mult;
816
                                                auxRow[ID_FIELD_ROTATIONTEXT] = psText.rotation;
817
                                                auxRow[ID_FIELD_TEXT] = psText.string; // .trim();
818
                                                addShape(elShapeTxt, auxRow, type, dgnReader);
819

    
820
                                                // System.out.println("Rotaci?n texto: " +
821
                                                // psText.rotation + "Altura Texto = " + heightText);
822

    
823
                                                /*
824
                                                 * System.out.println("  origin=(" + psText.origin.x +
825
                                                 * ", " + psText.origin.y + ") rotation=" +
826
                                                 * psText.rotation + "\n" + "  font=" + psText.font_id +
827
                                                 * " just=" + psText.justification + "length_mult=" +
828
                                                 * psText.length_mult + " height_mult=" +
829
                                                 * psText.height_mult + "\n" + "  string =" + new
830
                                                 * String(psText.string).toString().trim() + "\n");
831
                                                 */
832
                                                break;
833

    
834
                                        /*
835
                                         * default:
836
                                         * dgnReader.DGNDumpElement(dgnReader.getInfo(),
837
                                         * elemento, "");
838
                                         */
839
                                        } // switch
840
                                } // if
841
                        } // for
842

    
843
                        if (bElementoCompuesto) {
844
                                if (bInsideCell) {
845
                                        auxRow = cellRow;
846
                                } else {
847
                                        auxRow = complexRow;
848
                                }
849

    
850
                                // System.err.println("Entidad compuesta. bInsideCell = " +
851
                                // bInsideCell + " auxRow = " + auxRow[ID_FIELD_ENTITY]);
852
                                addShape(createMultiCurve(elementoCompuesto), auxRow, type,
853
                                                dgnReader);
854

    
855
                                if (bEsPoligono) {
856
                                        if (complex_index_fill_color != -1) {
857
                                                auxRow[ID_FIELD_COLOR] = complex_index_fill_color;
858
                                        }
859

    
860
                                        addShape(createSurface(elementoCompuesto), auxRow, type,
861
                                                        dgnReader);
862
                                }
863
                        }
864

    
865
                }
866

    
867
                private Geometry createMultiSurface(GeneralPathX elementoCompuesto)
868
                                throws DataException {
869
                        try {
870
                                return geomManager.createMultiSurface(elementoCompuesto,
871
                                                SUBTYPES.GEOM2D);
872
                        } catch (CreateGeometryException e) {
873
                                throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(
874
                                                e);
875
                        }
876

    
877
                }
878

    
879
                private Geometry createPoint3D(double x, double y, double z)
880
                                throws DataException {
881
                        Point point;
882
                        try {
883
                                // point = (Point) geomManager.create(TYPES.POINT,
884
                                // SUBTYPES.GEOM3D);
885
                                point = (Point) geomManager.create(TYPES.POINT,
886
                                                SUBTYPES.GEOM2DZ);
887
                        } catch (CreateGeometryException e) {
888
                                throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(
889
                                                e);
890
                        }
891
                        point.setCoordinates(new double[] { x, y, z });
892

    
893
                        return point;
894
                }
895

    
896
                private void addShape(Geometry geometry, Object[] auxRow,
897
                                FeatureType type, DGNReader dgnReader) throws DataException {
898
                        FeatureProvider data = createFeatureData(type);
899
                        for (int i=0;i<type.size();i++){
900
                                data.set(i, auxRow[i]);
901
                        }
902
                        data.setDefaultGeometry(geometry);
903
                        addFeatureData(data);
904
                        if (this.envelope == null) {
905
                                this.envelope = geometry.getEnvelope();
906
                        } else {
907
                                this.envelope.add(geometry.getEnvelope());
908
                        }
909
                        if (this.leyendBuilder != null) {
910
                                this.leyendBuilder.process(data, dgnReader);
911
                        }
912
                }
913

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

    
925
                private Geometry createSurface(GeneralPathX elementoCompuesto)
926
                                throws DataException {
927
                        try {
928
                                return geomManager.createCurve(elementoCompuesto,
929
                                                SUBTYPES.GEOM2D);
930
                        } catch (CreateGeometryException e) {
931
                                throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(
932
                                                e);
933
                        }
934

    
935
                }
936

    
937
        }
938

    
939
        public boolean closeResourceRequested(ResourceProvider resource) {
940
                return true;
941
        }
942

    
943
        public int getOIDType() {
944
                return DataTypes.LONG;
945
        }
946

    
947
        public boolean supportsAppendMode() {
948
                return false;
949
        }
950

    
951
        public void append(FeatureProvider featureData) {
952
                // FIXME Exception
953
                throw new UnsupportedOperationException();
954
        }
955

    
956
        public void beginAppend() {
957
                // FIXME Exception
958
                throw new UnsupportedOperationException();
959
        }
960

    
961
        public void endAppend() {
962
                // FIXME Exception
963
                throw new UnsupportedOperationException();
964
        }
965

    
966
        public void saveToState(PersistentState state) throws PersistenceException {
967
                // TODO Auto-generated method stub
968
                throw new NotYetImplemented();
969
        }
970

    
971
        public void loadFromState(PersistentState state) throws PersistenceException {
972
                // TODO Auto-generated method stub
973
                throw new NotYetImplemented();
974
        }
975

    
976
        public Object createNewOID() {
977
                return new Long(counterNewsOIDs++);
978
        }
979

    
980
        protected void initializeFeatureTypes() throws InitializeException {
981
                try {
982
                        this.open();
983
                } catch (OpenException e) {
984
                        throw new InitializeException(this.getName(), e);
985
                }
986
        }
987

    
988
        public Envelope getEnvelope() throws DataException {
989
                this.open();
990
                return (Envelope) this.metadata.getDynValue("Envelope");
991
        }
992

    
993
        public Iterator getChilds() {
994
                // TODO Auto-generated method stub
995
                return null;
996
        }
997

    
998

    
999
        /*
1000
         * (non-Javadoc)
1001
         *
1002
         * @see
1003
         * org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
1004
         * gvsig.fmap.dal.resource.spi.ResourceProvider)
1005
         */
1006
        public void resourceChanged(ResourceProvider resource) {
1007
                this.store.notifyChange(DataStoreNotification.RESOURCE_CHANGED,
1008
                                resource);
1009
        }
1010

    
1011
        protected static void registerDynClass() {
1012
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
1013
                DynClass dynClass;
1014
                DynField field;
1015
                if (DYNCLASS == null) {
1016
                        dynClass = dynman.add(DYNCLASS_NAME, "DGN File Store");
1017
                        dynClass.extend(dynman.get(FeatureStore.DYNCLASS_NAME));
1018

    
1019
                        DYNCLASS = dynClass;
1020
                }
1021

    
1022
        }
1023

    
1024
        public Object getSourceId() {
1025
                return this.getDGNParameters().getFile();
1026
        }
1027

    
1028
}